def get_streams(self, url): def get_amf_value(data, key): pattern = ("{0}\W\W\W(.+?)\x00").format(key) match = re.search(bytes(pattern, "ascii"), data) if match: return str(match.group(1), "ascii") channelid = self.get_channel_id(url) if not channelid: return False fd = urllib.urlopen(self.AMFURL.format(channelid)) data = fd.read() fd.close() stream = {} playpath = get_amf_value(data, "streamName") cdnurl = get_amf_value(data, "cdnUrl") fmsurl = get_amf_value(data, "fmsUrl") if not playpath: return False stream["playpath"] = playpath stream["rtmp"] = cdnurl or fmsurl stream["url"] = url return {"live": stream}
def get_channel_id(self, url): fd = urllib.urlopen(url) data = fd.read() fd.close() match = re.search(b"channelId=(\d+)", data) if match: return int(match.group(1))
def _get_channel_name(self, url): fd = urllib.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 swfverify(url): fd = urllib.urlopen(url) swf = fd.read() fd.close() if swf[:3] == b"CWS": swf = b"F" + swf[1:8] + zlib.decompress(swf[8:]) h = hmac.new(SWF_KEY, swf, hashlib.sha256) return h.hexdigest(), len(swf)
def get_streams(self, url): def clean_tag(tag): if tag[0] == "_": return tag[1:] else: return tag randomp = int(random.random() * 999999) channelname = self._get_channel_name(url) if not channelname: return False metadata = self._get_metadata(channelname, self.args.jtv_cookie) if "chansub_guid" in metadata: fd = urllib.urlopen(self.StreamInfoURLSub.format(channelname, randomp, metadata["chansub_guid"])) else: fd = urllib.urlopen(self.StreamInfoURL.format(channelname, randomp)) 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] = self._get_node_text(child) sname = clean_tag(node.tagName) streams[sname] = stream return streams
def urlget(url, data=None, timeout=None, opener=None): try: if opener is not None: fd = opener.open(url) else: fd = urllib.urlopen(url, data, timeout) data = fd.read() fd.close() except IOError as err: if type(err) is urllib.URLError: raise PluginError(err.reason) else: raise PluginError(err) return data
def _get_metadata(self, channel, cookie=None): if cookie: headers = {"Cookie": cookie} req = urllib.Request(self.MetadataURL.format(channel), headers=headers) else: req = urllib.Request(self.MetadataURL.format(channel)) fd = urllib.urlopen(req) data = fd.read() fd.close() dom = xml.dom.minidom.parseString(data) meta = dom.getElementsByTagName("meta")[0] metadata = {} metadata["title"] = self._get_node_if_exists(dom, "title") metadata["chansub_guid"] = self._get_node_if_exists(dom, "chansub_guid") return metadata
def get_streams(self, url): channelid = self.get_channel_id(url) if not channelid: return False fd = urllib.urlopen(self.ConfigURL.format(channelid)) data = fd.read() fd.close() streams = {} dom = xml.dom.minidom.parseString(data) channels = dom.getElementsByTagName("channels")[0] clip = channels.getElementsByTagName("clip")[0] streams = {} for item in clip.getElementsByTagName("item"): base = item.getAttribute("base") if not base: continue if base[0] == "$": ref = re.match("\${(.+)}", base).group(1) base = self.CDN[ref] for streamel in item.getElementsByTagName("stream"): name = streamel.getAttribute("label").lower().replace(" ", "_") playpath = streamel.getAttribute("name") if not name in streams: streams[name] = { "base": base, "name": name, "playpath": playpath } return streams