From 03ff523bfe2f2a3848470ce0ca46f2ef7116453c Mon Sep 17 00:00:00 2001 From: Christopher Rosell Date: Mon, 15 Aug 2011 04:37:22 +0200 Subject: Initial commit. --- src/livestreamer/plugins/justintv.py | 80 ++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/livestreamer/plugins/justintv.py (limited to 'src/livestreamer/plugins/justintv.py') 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"", 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) -- cgit v1.2.3