aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/livestreamer/plugins/justintv.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/livestreamer/plugins/justintv.py')
-rw-r--r--src/livestreamer/plugins/justintv.py80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/livestreamer/plugins/justintv.py b/src/livestreamer/plugins/justintv.py
new file mode 100644
index 0000000..6607ae4
--- /dev/null
+++ b/src/livestreamer/plugins/justintv.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python3
+
+from livestreamer.plugins import Plugin, register_plugin
+from livestreamer.utils import CommandLine
+
+import urllib.request, urllib.error, urllib.parse
+import xml.dom.minidom, re
+
+class JustinTV(object):
+ StreamInfoURL = "http://usher.justin.tv/find/%s.xml?type=any"
+ SWFURL = "http://www.justin.tv/widgets/live_embed_player.swf"
+
+ def can_handle_url(self, url):
+ return ("justin.tv" in url) or ("twitch.tv" in url)
+
+ def get_channel_name(self, url):
+ fd = urllib.request.urlopen(url)
+ data = fd.read()
+ fd.close()
+
+ match = re.search(b"live_facebook_embed_player\.swf\?channel=(\w+)", data)
+ if match:
+ return str(match.group(1), "ascii")
+
+
+ def get_streams(self, url):
+ def get_node_text(element):
+ res = []
+ for node in element.childNodes:
+ if node.nodeType == node.TEXT_NODE:
+ res.append(node.data)
+ return "".join(res)
+
+ def clean_tag(tag):
+ if tag[0] == "_":
+ return tag[1:]
+ else:
+ return tag
+
+ channelname = self.get_channel_name(url)
+
+ if not channelname:
+ return False
+
+ fd = urllib.request.urlopen(self.StreamInfoURL % channelname)
+ data = fd.read()
+ fd.close()
+
+ # fix invalid xml
+ data = re.sub(b"<(\d+)", b"<_\g<1>", data)
+ data = re.sub(b"</(\d+)", b"</_\g<1>", data)
+
+ streams = {}
+ dom = xml.dom.minidom.parseString(data)
+ nodes = dom.getElementsByTagName("nodes")[0]
+
+ for node in nodes.childNodes:
+ stream = {}
+ for child in node.childNodes:
+ stream[child.tagName] = get_node_text(child)
+
+ sname = clean_tag(node.tagName)
+ streams[sname] = stream
+
+ return streams
+
+ def stream_cmdline(self, stream, filename):
+ cmd = CommandLine("rtmpdump")
+ cmd.arg("rtmp", ("{0}/{1}").format(stream["connect"], stream["play"]))
+ cmd.arg("swfUrl", self.SWFURL)
+ cmd.arg("live", True)
+ cmd.arg("flv", filename)
+
+ if "token" in stream:
+ cmd.arg("jtv", stream["token"])
+
+ return cmd.format()
+
+
+register_plugin("justintv", JustinTV)