def _get_vod_streams(self, channelname): res = http.get(self.url) match = re.search('autoURL%22%3A%22(.*?)%22', res.text) if not match: raise PluginError('Error retrieving manifest url') manifest_url = unquote(match.group(1)).replace('\\', '') try: res = http.get(manifest_url) manifest = http.json(res) except: raise PluginError('Error retrieving manifest') # A fallback host (http://proxy-xx...) is sometimes provided # that we could make us of. streams = {} for params in manifest.get('alternates', []): name = params.get('name') template = params.get('template') if not (name and template): continue name = '{0}p'.format(name) streams[name] = self._create_flv_playlist(template) return streams
def _parse_gox_file(self, data): try: dom = xml.dom.minidom.parseString(data) except Exception as err: raise PluginError(("Unable to parse gox file: {0})").format(err)) entries = [] for xentry in dom.getElementsByTagName("ENTRY"): entry = {} for child in xentry.childNodes: if isinstance(child, xml.dom.minidom.Element): if child.tagName == "REF": href = child.getAttribute("href") # SQ and SQTest streams can be gomp2p links, with actual stream address passed as a parameter. if href.startswith("gomp2p://"): href, n = re.subn("^.*LiveAddr=", "", href) href = unquote(href) entry[child.tagName] = href else: entry[child.tagName] = self._get_node_text(child) entries.append(entry) return entries
def get_limelight_live_streams(self): res = self._get_live_page(self.res) match = re.search('jQuery.post\("/live/ajaxGetLimelight.gom", ({.+?}),', res.text) if not match: raise NoStreamsError(self.url) ajaxparams = match.group(1) ajaxparams = dict(re.findall("(\w+):(\d+)", ajaxparams)) levels = re.findall("setFlashLevel\((\d+)\);", res.text) streams = {} for level in levels: params = ajaxparams.copy() params["level"] = level res = urlopen(self.GetLimelightStreamURL, data=params, session=self.rsession) url = unquote(res.text) if url.startswith("http"): continue try: playlist_entries = self._limelight_soap_playlist_items(url) streams.update(playlist_entries) except PluginError as err: self.logger.warning("Unable to access Limelight playlist: {0}", err) continue return streams
def get_alt_live_streams(self): res = self._get_live_page(self.res) match = re.search('jQuery.post\("/live/ajaxGetUrl.gom", ({.+?}),', res.text) if not match: raise NoStreamsError(self.url) ajaxparams = match.group(1) ajaxparams = dict(re.findall("(\w+):(\d+)", ajaxparams)) levels = re.findall("setFlashLevel\((\d+)\);.+?<span class=\"qtype\">(\w+)</span>", res.text) streams = {} for level, quality in levels: params = ajaxparams.copy() params["level"] = level quality = quality.lower() res = urlopen(self.GetStreamURL, data=params, session=self.rsession) url = unquote(res.text) if not urlparse(url).path.endswith(".f4m"): continue try: s = HDSStream.parse_manifest(self.session, url) if len(s) > 0: bitrate, stream = list(s.items())[0] streams[quality] = stream except IOError: self.logger.warning("Unable to parse manifest") return streams
def _get_streams(self): self.logger.debug("Fetching stream info") res = http.get(self.url) match = re.search('"file":[\t]+"([^"]+)".+embedSWF\("([^"]+)"', res.text, re.DOTALL) if not match: raise NoStreamsError(self.url) rtmp = unquote(match.group(1)) swfurl = match.group(2) streams = {} streams["live"] = RTMPStream( self.session, {"rtmp": rtmp, "pageUrl": self.url, "swfVfy": swfurl, "live": True}, redirect=True ) return streams
def _parse(self, entry): for child in entry: if child.tag == "REF": href = child.attrib.get("href") reftype = child.attrib.get("reftype") # Streams can be gomp2p links, with actual stream # URL passed as a parameter if href.startswith("gomp2p://"): href, n = re.subn("^.*LiveAddr=", "", href) href = unquote(href) href = href.replace("&", "&") val = (href, reftype) else: val = child.text attr = child.tag.lower() setattr(self, attr, val)
def _parse_gox_file(self, data): # Grabbing the gomcmd URL try: patternstream = '<REF href="([^"]*)"\s*/>' match = re.search(patternstream, data).group(1) except AttributeError: raise PluginError("Unable to find the gomcmd URL in the GOX XML file") match = match.replace("&", "&") match = unquote(match) # SQ and SQTest streams can be gomp2p links, with actual stream address passed as a parameter. if match.startswith("gomp2p://"): match, n = re.subn("^.*LiveAddr=", "", match) # Cosmetics, getting rid of the HTML entity, we don't # need either of the " character or " match = match.replace(""", "") return match
def _get_streams(self): self.logger.debug("Fetching stream info") res = urlget(self.url) match = re.search(".+?flashvars=\"&streamer=(.+)?&file=(.+?).flv&.+?\"", res.text) if not match: raise NoStreamsError(self.url) rtmp = unquote(match.group(1)) playpath = match.group(2) streams = {} streams["live"] = RTMPStream(self.session, { "rtmp": rtmp, "pageUrl": self.url, "swfVfy": self.SWFURL, "playpath" : playpath, "live": True }, redirect=True) return streams
def _parse_gox_file(self, data): # Grabbing the gomcmd URL try: patternstream = '<REF href="([^"]*)"\s*/>' match = re.search(patternstream, data).group(1) except AttributeError: raise PluginError( "Unable to find the gomcmd URL in the GOX XML file") match = match.replace("&", "&") match = unquote(match) # SQ and SQTest streams can be gomp2p links, with actual stream address passed as a parameter. if match.startswith("gomp2p://"): match, n = re.subn("^.*LiveAddr=", "", match) # Cosmetics, getting rid of the HTML entity, we don't # need either of the " character or " match = match.replace(""", "") return match
def _get_streams(self): self.logger.debug("Fetching stream info") res = http.get(self.url) match = re.search("\"file\":[\t]+\"([^\"]+)\".+embedSWF\(\"([^\"]+)\"", res.text, re.DOTALL) if not match: raise NoStreamsError(self.url) rtmp = unquote(match.group(1)) swfurl = match.group(2) streams = {} streams["live"] = RTMPStream(self.session, { "rtmp": rtmp, "pageUrl": self.url, "swfVfy": swfurl, "live": True }, redirect=True) return streams
def get_alt_live_streams(self): res = self._get_live_page(self.res) match = re.search('jQuery.post\("/live/ajaxGetUrl.gom", ({.+?}),', res.text) if not match: raise NoStreamsError(self.url) ajaxparams = match.group(1) ajaxparams = dict(re.findall("(\w+):(\d+)", ajaxparams)) levels = re.findall( "setFlashLevel\((\d+)\);.+?<span class=\"qtype\">(\w+)</span>", res.text) streams = {} for level, quality in levels: params = ajaxparams.copy() params["level"] = level quality = quality.lower() res = urlopen(self.GetStreamURL, data=params, session=self.rsession) url = unquote(res.text) if not urlparse(url).path.endswith(".f4m"): continue try: s = HDSStream.parse_manifest(self.session, url) if len(s) > 0: bitrate, stream = list(s.items())[0] streams[quality] = stream except IOError: self.logger.warning("Unable to parse manifest") return streams
def get_alt_live_streams(self): res = self._get_live_page(self.res) match = re.search('jQuery.post\("/live/ajaxGetUrl.gom", ({.+?}),', res.text) if not match: raise NoStreamsError(self.url) ajaxparams = match.group(1) ajaxparams = dict(re.findall("(\w+):(\d+)", ajaxparams)) levels = re.findall("setFlashLevel\((\d+)\);", res.text) streams = {} for level in levels: params = ajaxparams.copy() params["level"] = level res = urlopen(self.GetStreamURL, data=params, session=self.rsession) url = unquote(res.text) if not urlparse(url).path.endswith(".f4m"): continue try: s = HDSStream.parse_manifest(self.session, url) streams.update(s) except IOError: self.logger.warning("Unable to parse manifest") # Hack to rename incorrect bitrate specified by GOM to something # more sane. for name, stream in streams.items(): if name == "1k": streams["1000k"] = stream del streams[name] return streams
def _parse_gox_file(self, data): dom = parse_xml(data, "GOX XML") entries = [] for xentry in dom.getElementsByTagName("ENTRY"): entry = {} for child in xentry.childNodes: if isinstance(child, xml.dom.minidom.Element): if child.tagName == "REF": href = child.getAttribute("href") # SQ and SQTest streams can be gomp2p links, with actual stream address passed as a parameter. if href.startswith("gomp2p://"): href, n = re.subn("^.*LiveAddr=", "", href) href = unquote(href) entry[child.tagName] = href else: entry[child.tagName] = get_node_text(child) entries.append(entry) return entries
def _parse(self, dom): for child in dom.childNodes: if isinstance(child, xml.dom.minidom.Element): if child.tagName == "REF": href = child.getAttribute("href") if child.hasAttribute("reftype"): reftype = child.getAttribute("reftype") else: reftype = None # Streams can be gomp2p links, with actual stream # URL passed as a parameter if href.startswith("gomp2p://"): href, n = re.subn("^.*LiveAddr=", "", href) href = unquote(href) href = href.replace("&", "&") val = (href, reftype) else: val = get_node_text(child) attr = child.tagName.lower() setattr(self, attr, val)
def get_limelight_live_streams(self): res = self._get_live_page(self.res) match = re.search( 'jQuery.post\("/live/ajaxGetLimelight.gom", ({.+?}),', res.text) if not match: raise NoStreamsError(self.url) ajaxparams = match.group(1) ajaxparams = dict(re.findall("(\w+):(\d+)", ajaxparams)) levels = re.findall("setFlashLevel\((\d+)\);", res.text) streams = {} for level in levels: params = ajaxparams.copy() params["level"] = level res = urlopen(self.GetLimelightStreamURL, data=params, session=self.rsession) url = unquote(res.text) if url.startswith("http"): continue try: playlist_entries = self._limelight_soap_playlist_items(url) streams.update(playlist_entries) except PluginError as err: self.logger.warning("Unable to access Limelight playlist: {0}", err) continue return streams