def _get_streams(self): res = http.get(self.url) match = _player_js.search(res.text) if match: player_js = match.group(0) self.logger.info("Found player js {0}", player_js) else: self.logger.info( "Didn't find player js. Probably this page doesn't contain a video" ) return res = http.get(player_js) jsonp_start = res.text.find('(') + 1 jsonp_end = res.text.rfind(')') if jsonp_start <= 0 or jsonp_end <= 0: self.logger.info( "Couldn't extract json metadata from player.js: {0}", player_js) return json_s = res.text[jsonp_start:jsonp_end] stream_metadata = json.loads(json_s) return HDSStream.parse_manifest( self.session, stream_metadata['mediaResource']['dflt']['videoURL']).items()
def _get_streams(self): # Discover root match = _url_re.search(self.url) root = match.group(1) # Download main URL res = http.get(self.url) # Find playlist match = _playlist_re.search(res.text) playlist_url = root + match.group(1) + "d" # Download playlist res = http.get(playlist_url) # Find manifest match = _manifest_re.search(res.text) manifest_url = match.group(1) # Find SWF match = _swf_re.search(res.text) swf_url = match.group(1) streams = {} streams.update( HDSStream.parse_manifest(self.session, manifest_url, pvswf=swf_url)) return streams
def _get_vod_stream(self): vod_url = self.url if vod_url.endswith('/'): vod_url = vod_url[:-1] json_url = '{0}.securevideo.json'.format(vod_url) res = http.get(json_url) match = _json_re.search(res.text) if not match: return data = parse_json(match.group(1)) res = http.get(API_VOD.format(data['clientid'], data['mzid'])) data = http.json(res, schema=_stream_schema) for d in data['targetUrls']: if d['type'] == 'HDS': hds_url = d['url'] for s in HDSStream.parse_manifest(self.session, hds_url).items(): yield s if d['type'] == 'HLS': hls_url = d['url'] for s in HLSStream.parse_variant_playlist( self.session, hls_url).items(): yield s
def _get_streams(self): data_url = http.get(self.url, schema=self._player_url_schema) if data_url: res = http.get(urljoin(self.url, data_url)) stream_info = http.xml(res, schema=self._livestream_schema) for stream in stream_info: url = stream["url"] try: if ".m3u8" in url: for s in HLSStream.parse_variant_playlist( self.session, url, name_key="bitrate").items(): yield s elif ".f4m" in url: for s in HDSStream.parse_manifest( self.session, url, pvswf=self.swf_url, is_akamai=True).items(): yield s elif ".mp4" in url: yield "{0}k".format(stream["bitrate"]), HTTPStream( self.session, url) except IOError as err: self.logger.warning("Error parsing stream: {0}", err)
def _get_vod_streams(self, params): manifest_url = params.get("autoURL") if not manifest_url: return res = http.get(manifest_url) if res.headers.get("Content-Type") == "application/f4m+xml": streams = HDSStream.parse_manifest(self.session, res.url) # TODO: Replace with "yield from" when dropping Python 2. for __ in streams.items(): yield __ elif res.headers.get( "Content-Type") == "application/vnd.apple.mpegurl": streams = HLSStream.parse_variant_playlist(self.session, res.url) # TODO: Replace with "yield from" when dropping Python 2. for __ in streams.items(): yield __ else: manifest = http.json(res, schema=_vod_manifest_schema) for params in manifest["alternates"]: name = "{0}p".format(params["height"]) stream = self._create_flv_playlist(params["template"]) yield name, stream failovers = params.get("failover", []) for failover in failovers: stream = self._create_flv_playlist(failover) yield name, stream
def _get_streams(self): url, params = parse_url_params(self.url) urlnoproto = self._url_re.match(url).group(2) urlnoproto = update_scheme("http://", urlnoproto) return HDSStream.parse_manifest(self.session, urlnoproto, **params)
def _resolve_playlist(self, res, playlist_all): """ yield for _resolve_res Args: res: Content from self._res_text playlist_all: List of streams Returns: yield every stream """ # m_base is used for .f4m files that doesn't have a base_url m_base = self._stream_base_re.search(res) if m_base: stream_base = m_base.group("base") else: stream_base = "" playlist_list = self._make_url_list(playlist_all, self.url, stream_base) self.logger.debug("Found URL: {0}".format(", ".join(playlist_list))) endswith_blacklist = (".mp3", ".mp4", ".vtt") for url in playlist_list: if ".m3u8" in url and not url.endswith(endswith_blacklist): try: streams = HLSStream.parse_variant_playlist( self.session, url, headers=self.headers).items() if not streams: yield "live", HLSStream(self.session, url, headers=self.headers) for s in streams: yield s except Exception: self.logger.error("Skipping hls_url: {0}".format(url)) elif ".f4m" in url and not url.endswith(endswith_blacklist): try: for s in HDSStream.parse_manifest( self.session, url, headers=self.headers).items(): yield s except Exception: self.logger.error("Skipping hds_url: {0}".format(url)) elif self.list_in_item(url, [ ".mp3", ".mp4" ]) and not self.list_in_item(url, [".f4m", ".m3u8", ".mpd"]): try: name = "live" m = self._httpstream_bitrate_re.search(url) if m: name = "{0}k".format(m.group("bitrate")) yield name, HTTPStream(self.session, url, headers=self.headers) except Exception: self.logger.error("Skipping http_url: {0}".format(url)) elif ".mpd" in url and not url.endswith(endswith_blacklist): try: self.logger.info("Found mpd: {0}".format(url)) except Exception: self.logger.error("Skipping mpd_url: {0}".format(url))
def _get_streams(self): # Get video ID and channel from URL match = self._url_re.match(self.url) video_id = match.group('video_id') if video_id is None: # Retrieve URL page and search for video ID res = http.get(self.url) match = self._video_id_re.search(res.text) if match is None: return video_id = match.group('video_id') res = http.get(self.API_URL.format(video_id)) videos = http.json(res, schema=self._api_schema) parsed = [] headers = {'User-Agent': self._user_agent} # Some videos may be also available on Dailymotion (especially on CNews) if videos['ID_DM'] != '': for stream in self.session.streams('https://www.dailymotion.com/video/' + videos['ID_DM']).items(): yield stream for quality, video_url in list(videos['MEDIA']['VIDEOS'].items()): # Ignore empty URLs if video_url == '': continue # Ignore duplicate video URLs if video_url in parsed: continue parsed.append(video_url) try: # HDS streams don't seem to work for live videos if '.f4m' in video_url and 'LIVE' not in videos['TYPE']: for stream in HDSStream.parse_manifest(self.session, video_url, params={'hdcore': self.HDCORE_VERSION}, headers=headers).items(): yield stream elif '.m3u8' in video_url: for stream in HLSStream.parse_variant_playlist(self.session, video_url, headers=headers).items(): yield stream elif '.mp4' in video_url: # Get bitrate from video filename match = self._mp4_bitrate_re.match(video_url) if match is not None: bitrate = match.group('bitrate') else: bitrate = quality yield bitrate, HTTPStream(self.session, video_url, params={'secret': self.SECRET}, headers=headers) except IOError as err: if '403 Client Error' in str(err): self.logger.error('Failed to access stream, may be due to geo-restriction')
def _get_streams(self): res = http.get(self.url) match = _meta_xmlurl_id_re.search(res.text) if not match: return xml_info_url = STREAMS_INFO_URL.format(match.group(1)) video_info_res = http.get(xml_info_url) parsed_info = http.xml(video_info_res) live_el = parsed_info.find("live") live = live_el is not None and live_el.text == "1" streams = {} hdsurl_el = parsed_info.find("hdsurl") if hdsurl_el is not None and hdsurl_el.text is not None: hdsurl = hdsurl_el.text streams.update(HDSStream.parse_manifest(self.session, hdsurl)) if live: vurls_el = parsed_info.find("vurls") if vurls_el is not None: for i, vurl_el in enumerate(vurls_el): bitrate = vurl_el.get("bitrate") name = bitrate + "k" if bitrate is not None else "rtmp{0}".format( i) params = { "rtmp": vurl_el.text, } streams[name] = RTMPStream(self.session, params) parsed_urls = set() mobileurls_el = parsed_info.find("mobileurls") if mobileurls_el is not None: for mobileurl_el in mobileurls_el: text = mobileurl_el.text if not text: continue if text in parsed_urls: continue parsed_urls.add(text) url = urlparse(text) if url[0] == "http" and url[2].endswith("m3u8"): streams.update( HLSStream.parse_variant_playlist(self.session, text)) return streams
def _get_smil_streams(self, info): res = http.get(info["_stream"]) smil = http.xml(res, "SMIL config", schema=_smil_schema) for video in smil["videos"]: url = "{0}/{1}{2}".format(smil["base"], video, HDCORE_PARAMETER) streams = HDSStream.parse_manifest( self.session, url, pvswf=SWF_URL, is_akamai=smil["cdn"] == "akamai") for stream in streams.items(): yield stream
def _get_streams(self): res = http.get(self.url) match = self.player_re.search(res.text) if match: channel_id = match.group(1) stream_api = self.stream_api.format( id=channel_id, time=int(time.time()), hash=''.join( random.choice("abcdef0123456789") for x in range(28))) res = http.get(stream_api) f4m_url = self.manifest_re.search(res.text) if f4m_url: return HDSStream.parse_manifest(self.session, f4m_url.group(1))
def mediaselector(self, vpid): for platform in self.platforms: url = self.api_url.format(vpid=vpid, vpid_hash=self._hash_vpid(vpid), platform=platform) self.logger.debug("Info API request: {0}", url) stream_urls = http.get(url, schema=self.mediaselector_schema) for media in stream_urls: for connection in media["connection"]: if connection.get("transferFormat") == "hds": for s in HDSStream.parse_manifest( self.session, connection["href"]).items(): yield s if connection.get("transferFormat") == "hls": for s in HLSStream.parse_variant_playlist( self.session, connection["href"]).items(): yield s
def _resolve_playlist(self, res, playlist_all): """ yield for _resolve_res Args: res: Content from self._res_text playlist_all: List of streams Returns: yield every stream """ for url in playlist_all: parsed_url = urlparse(url) if parsed_url.path.endswith((".m3u8")): try: streams = HLSStream.parse_variant_playlist(self.session, url, headers=self.headers).items() if not streams: yield "live", HLSStream(self.session, url, headers=self.headers) for s in streams: yield s except Exception as e: self.logger.error("Skipping hls_url - {0}".format(str(e))) self.help_info_e(e) elif parsed_url.path.endswith((".f4m")): try: for s in HDSStream.parse_manifest(self.session, url, headers=self.headers).items(): yield s except Exception as e: self.logger.error("Skipping hds_url - {0}".format(str(e))) self.help_info_e(e) elif parsed_url.path.endswith((".mp3", ".mp4")): try: name = "live" m = self._httpstream_bitrate_re.search(url) if m: name = "{0}k".format(m.group("bitrate")) yield name, HTTPStream(self.session, url, headers=self.headers) except Exception as e: self.logger.error("Skipping http_url - {0}".format(str(e))) self.help_info_e(e) elif parsed_url.path.endswith((".mpd")): try: self.logger.info("Found mpd: {0}".format(url)) except Exception as e: self.logger.error("Skipping mpd_url - {0}".format(str(e))) self.help_info_e(e)
def _get_hds_streams(self, channel): channel = self.hds_channel_remap.get(channel, "{0}live".format(channel)) manifest_url = http.get(self.api_url.format(channel), params={ "getURL": 1 }, headers={ "User-Agent": useragents.FIREFOX }).text for s in HDSStream.parse_manifest(self.session, manifest_url, pvswf=self.swf_url, headers={ "User-Agent": useragents.FIREFOX }).items(): yield s
def _create_stream(self, stream, language): stream_name = "{0}p".format(stream["height"]) stream_type = stream["mediaType"] stream_url = stream["url"] stream_language = stream["versionShortLibelle"] if language == "de": language = ["DE", "VOST-DE", "VA", "VOA", "Dt. Live", "OV", "OmU"] elif language == "en": language = ["ANG", "VOST-ANG"] elif language == "es": language = ["ESP", "VOST-ESP"] elif language == "fr": language = [ "FR", "VOST-FR", "VF", "VOF", "Frz. Live", "VO", "ST mal" ] elif language == "pl": language = ["POL", "VOST-POL"] if stream_language in language: if stream_type in ("hls", "mp4"): if urlparse(stream_url).path.endswith("m3u8"): try: streams = HLSStream.parse_variant_playlist( self.session, stream_url) for stream in streams.items(): yield stream except IOError as err: self.logger.error("Failed to extract HLS streams: {0}", err) else: yield stream_name, HTTPStream(self.session, stream_url) elif stream_type == "f4m": try: streams = HDSStream.parse_manifest(self.session, stream_url) for stream in streams.items(): yield stream except IOError as err: self.logger.error("Failed to extract HDS streams: {0}", err)
def _get_streams(self): m_url = self._url_re.match(self.url) if not m_url: return video_id = m_url.group("id") appname = self.appname_map[m_url.group("host")] apiname = self.apiname_map[appname] headers = { "User-Agent": useragents.FIREFOX, "Referer": self.url } res = http.get(self.api_url.format(apiname, video_id, appname), headers=headers) data = http.json(res, schema=self._video_schema) title = data.get("title") streamurls = data.get("streamUrls") if title: self.stream_title = title if streamurls: hls_url = streamurls.get("hls") if hls_url: self.logger.debug("HLS URL: {0}".format(hls_url)) streams = HLSStream.parse_variant_playlist(self.session, hls_url, headers=headers).items() if not streams: yield "live", HLSStream(self.session, hls_url, headers=headers) for s in streams: yield s hds_url = streamurls.get("hds") if hds_url: self.logger.debug("HDS URL: {0}".format(hds_url)) for s in HDSStream.parse_manifest(self.session, hds_url, headers=headers).items(): yield s mp4_url = streamurls.get("mp4") if mp4_url: self.logger.debug("MP4 URL: {0}".format(mp4_url)) name = "live" yield name, HTTPStream(self.session, mp4_url, headers=headers)
def _get_streams(self): hls_urls = [] hds_urls = [] http.headers.update({'User-Agent': useragents.FIREFOX}) match = self._url_re.match(self.url) if match is None: return video_id = match.group('id') self.logger.debug('video_id: {0}'.format(video_id)) res = http.get(self.api_play.format(video_id, self.url)) data = http.json(res, schema=self._video_schema) live_data = data.get('live_streams') vod_data = data.get('video_balancer') if live_data: self.logger.debug('Found live_data') for d in live_data['hls']: hls_urls.append(d['url']) for e in live_data['hds']: hds_urls.append(e['url']) elif vod_data: self.logger.debug('Found vod_data') hls_urls.append(vod_data['m3u8']) hds_urls.append(vod_data['default']) else: self.logger.error( 'restricted access to this video for your region') raise NoStreamsError(self.url) for hls_url in hls_urls: self.logger.debug('HLS URL: {0}'.format(hls_url)) for s in HLSStream.parse_variant_playlist(self.session, hls_url).items(): yield s for hds_url in hds_urls: self.logger.debug('HDS URL: {0}'.format(hds_url)) for s in HDSStream.parse_manifest(self.session, hds_url).items(): yield s
def _resolve_playlist(self, playlist_all): """ create streams Args: playlist_all: List of stream urls Returns: all streams """ http.headers.update({"Referer": self.url}) for url in playlist_all: parsed_url = urlparse(url) if parsed_url.path.endswith((".m3u8")): try: streams = HLSStream.parse_variant_playlist( self.session, url).items() if not streams: yield "live", HLSStream(self.session, url) for s in streams: yield s except Exception as e: self.logger.error("Skipping hls_url - {0}".format(str(e))) elif parsed_url.path.endswith((".f4m")): try: for s in HDSStream.parse_manifest(self.session, url).items(): yield s except Exception as e: self.logger.error("Skipping hds_url - {0}".format(str(e))) elif parsed_url.path.endswith((".mp3", ".mp4")): try: name = "live" m = self._httpstream_bitrate_re.search(url) if m: name = "{0}k".format(m.group("bitrate")) yield name, HTTPStream(self.session, url) except Exception as e: self.logger.error("Skipping http_url - {0}".format(str(e))) elif parsed_url.path.endswith((".mpd")): try: self.logger.info("Found mpd: {0}".format(url)) except Exception as e: self.logger.error("Skipping mpd_url - {0}".format(str(e)))
def _get_streams(self): match = _url_re.match(self.url) video_id = match.group("video_id") res = http.get(ASSET_URL.format(video_id)) assets = http.xml(res, schema=_asset_schema) streams = {} for asset in assets: base = asset["base"] url = asset["url"] if urlparse(url).path.endswith(".f4m"): streams.update( HDSStream.parse_manifest(self.session, url, pvswf=SWF_URL)) elif base.startswith("rtmp"): name = "{0}k".format(asset["bitrate"]) params = {"rtmp": asset["base"], "playpath": url, "live": True} streams[name] = RTMPStream(self.session, params) return streams
def _get_live_streams(self, params, swf_url): for key, quality in QUALITY_MAP.items(): key_url = "{0}URL".format(key) url = params.get(key_url) if not url: continue try: res = http.get(url, exception=IOError) except IOError: continue if quality == "hds": self.logger.debug('PLAYLIST URL: {0}'.format(res.url)) try: streams = HDSStream.parse_manifest(self.session, res.url) except BaseException: streams = HLSStream.parse_variant_playlist( self.session, res.url) for name, stream in streams.items(): if key == "source": name += "+" yield name, stream elif res.text.startswith("rtmp"): match = _rtmp_re.match(res.text) if not match: continue stream = RTMPStream( self.session, { "rtmp": match.group("host"), "app": match.group("app"), "playpath": match.group("playpath"), "swfVfy": swf_url, "live": True }) yield quality, stream
def _get_hds_streams(self, channel): channel = self.hds_channel_remap.get(channel, "{0}live".format(channel)) manifest_url = http.get(self.api_url.format(channel), params={ "getURL": 1 }, headers={ "User-Agent": useragents.FIREFOX }).text self.logger.debug("OLD HDS URL: {0}".format(manifest_url)) manifest_url = filter_urlquery(manifest_url, ["hdnea"], True) self.logger.debug("NEW HDS URL: {0}".format(manifest_url)) for s in HDSStream.parse_manifest(self.session, manifest_url, pvswf=self.swf_url, headers={ "User-Agent": useragents.FIREFOX }).items(): yield s
def _get_streams(self): match = self._player_embed_re.match(self.url) if match: channel_id = match.group("channel_id") else: try: res = http.get(self.url) except Exception: raise NoStreamsError(self.url) channel_id = self._find_channel_id(res.text) if not channel_id: return self.logger.info("Channel ID: {0}".format(channel_id)) res = http.get(self.PLAYER_EMBED_URL.format(channel_id)) items = self._find_stream_id(res.text) if not items: return a = b = False for stream in items: if stream["abr"] == "hls": try: for s in HLSStream.parse_variant_playlist( self.session, stream["streamUrl"]).items(): yield s except IOError: a = True elif stream["abr"] == "hds": try: for s in HDSStream.parse_manifest( self.session, stream["streamUrl"]).items(): yield s except IOError: b = True if a and b: self.logger.warning( "Could not open the stream, perhaps the channel is offline")
def _get_streams(self): args = dict(parse_qsl(urlparse(self.url).query)) if "k" in args: self.logger.debug("Loading channel: {k}", **args) res = http.get(self.url) stream_data_m = self.stream_data_re.search(res.text) if stream_data_m: script_vars = b64decode(stream_data_m.group(1)).decode("utf8") url_m = self.m3u8_re.search(script_vars) hls_url = url_m and url_m.group("url") if hls_url: for s in HLSStream.parse_variant_playlist( self.session, hls_url).items(): yield s f4m_m = self.f4mm_re.search(script_vars) f4m_url = f4m_m and f4m_m.group("url") if f4m_url: for n, s in HDSStream.parse_manifest( self.session, f4m_url).items(): yield n, s
def _get_streams(self): match = self._url_re.match(self.url) video_id = match.group('video_id') if video_id is not None: # VOD res = http.get(self.VOD_API_URL.format(video_id)) stream_data = http.json(res, schema=self._vod_api_schema) # Check whether video format is expired current_date = datetime.strptime(stream_data['current_date'], '%Y-%m-%dT%H:%M:%S.%f') valid_start = datetime.strptime(stream_data['shows']['valid_start'], '%Y-%m-%dT%H:%M:%S') valid_end = datetime.strptime(stream_data['shows']['valid_end'], '%Y-%m-%dT%H:%M:%S') if current_date < valid_start or current_date > valid_end: self.logger.error('Failed to access stream, may be due to expired content') return streams = stream_data['shows']['media:group'] else: # Live channel_id = match.group('channel_id') # Get live streams for desktop res = http.get(self.LIVE_API_URL, params={'channelid': channel_id}) streams = http.xml(res, schema=self._live_api_schema) # Get HLS streams for Iphone res = http.get(self.LIVE_API_URL, params={'channelid': channel_id, 'platform': 'iphone'}) stream = http.json(res, schema=self._live_api_iphone_schema) if stream != 'none': streams.append(stream) for stream in streams: if '.f4m' in stream: for s in HDSStream.parse_manifest(self.session, stream).items(): yield s if '.m3u8' in stream: for s in HLSStream.parse_variant_playlist(self.session, stream).items(): yield s
def _get_streams(self): match = self._url_re.match(self.url) channel = match.group('channel') res = http.get(self.FORMATS_URL.format(channel)) streams = http.json(res, schema=self._formats_schema)['streams'] if streams == []: self.logger.error( 'Channel may be geo-restricted, not directly provided by PlayTV or not freely available' ) return for language in streams: for protocol, bitrates in list(streams[language].items()): # - Ignore non-supported protocols (RTSP, DASH) # - Ignore deprecated Flash (RTMPE/HDS) streams (PlayTV doesn't provide anymore a Flash player) if protocol in ['rtsp', 'flash', 'dash', 'hds']: continue for bitrate in bitrates['bitrates']: if bitrate['value'] == 0: continue api_url = self.API_URL.format(channel, protocol, language, bitrate['value']) res = http.get(api_url) video_url = http.json(res, schema=self._api_schema)['url'] bs = '{0}k'.format(bitrate['value']) if protocol == 'hls': for _, stream in HLSStream.parse_variant_playlist( self.session, video_url).items(): yield bs, stream elif protocol == 'hds': for _, stream in HDSStream.parse_manifest( self.session, video_url).items(): yield bs, stream
def _get_streams(self): if '/news/videos/' in self.url: # VOD streams = self._get_vod_streams() else: # Live streams = self._get_live_streams() for video_url in streams: if '.f4m' in video_url: for stream in HDSStream.parse_manifest(self.session, video_url).items(): yield stream elif '.m3u8' in video_url: for stream in HLSStream.parse_variant_playlist( self.session, video_url).items(): yield stream if '.mp4' in video_url: match = self._mp4_bitrate_re.match(video_url) if match is not None: bitrate = match.group('bitrate') + 'k' else: bitrate = 'vod' yield bitrate, HTTPStream(self.session, video_url)
def _get_streams(self): # Retrieve geolocation data res = http.get(self.GEO_URL) geo = http.json(res, schema=self._geo_schema) country_code = geo['reponse']['geo_info']['country_code'] # Retrieve URL page and search for video ID res = http.get(self.url) if 'france.tv' in self.url: match = self._pluzz_video_id_re.search(res.text) elif 'ludo.fr' in self.url or 'zouzous.fr' in self.url: match = self._jeunesse_video_id_re.search(res.text) elif 'france3-regions.francetvinfo.fr' in self.url: match = self._f3_regions_video_id_re.search(res.text) elif 'sport.francetvinfo.fr' in self.url: match = self._sport_video_id_re.search(res.text) if match is None: return video_id = match.group('video_id') # Retrieve SWF player URL swf_url = None res = http.get(self.PLAYER_GENERATOR_URL) player_url = update_scheme( self.url, http.json(res, schema=self._player_schema)['result']) res = http.get(player_url) match = self._swf_re.search(res.text) if match is not None: swf_url = update_scheme(self.url, match.group(0)) res = http.get(self.API_URL.format(video_id)) videos = http.json(res, schema=self._api_schema) now = time.time() offline = False geolocked = False drm = False expired = False streams = [] for video in videos['videos']: video_url = video['url'] # Check whether video format is available if video['statut'] != 'ONLINE': offline = offline or True continue # Check whether video format is geo-locked if video['geoblocage'] is not None and country_code not in video[ 'geoblocage']: geolocked = geolocked or True continue # Check whether video is DRM-protected if video['drm']: drm = drm or True continue # Check whether video format is expired available = False for interval in video['plages_ouverture']: available = (interval['debut'] or 0) <= now <= (interval['fin'] or sys.maxsize) if available: break if not available: expired = expired or True continue # TODO: add DASH streams once supported if '.mpd' in video_url: continue if '.f4m' in video_url or 'france.tv' in self.url: res = http.get(self.TOKEN_URL.format(video_url)) video_url = res.text if '.f4m' in video_url and swf_url is not None: for bitrate, stream in HDSStream.parse_manifest( self.session, video_url, is_akamai=True, pvswf=swf_url).items(): # HDS videos with data in their manifest fragment token # doesn't seem to be supported by HDSStream. Ignore such # stream (but HDS stream having only the hdntl parameter in # their manifest token will be provided) pvtoken = stream.request_params['params'].get( 'pvtoken', '') match = self._hds_pv_data_re.search(pvtoken) if match is None: streams.append((bitrate, stream)) elif '.m3u8' in video_url: for stream in HLSStream.parse_variant_playlist( self.session, video_url).items(): streams.append(stream) # HBB TV streams are not provided anymore by France Televisions elif '.mp4' in video_url and '/hbbtv/' not in video_url: match = self._mp4_bitrate_re.match(video_url) if match is not None: bitrate = match.group('bitrate') else: # Fallback bitrate (seems all France Televisions MP4 videos # seem have such bitrate) bitrate = '1500k' streams.append((bitrate, HTTPStream(self.session, video_url))) if self.get_option("mux_subtitles") and videos['subtitles'] != []: substreams = {} for subtitle in videos['subtitles']: # TTML subtitles are available but not supported by FFmpeg if subtitle['format'] == 'ttml': continue substreams[subtitle['type']] = HTTPStream( self.session, subtitle['url']) for quality, stream in streams: yield quality, MuxedStream(self.session, stream, subtitles=substreams) else: for stream in streams: yield stream if offline: self.logger.error( 'Failed to access stream, may be due to offline content') if geolocked: self.logger.error( 'Failed to access stream, may be due to geo-restricted content' ) if drm: self.logger.error( 'Failed to access stream, may be due to DRM-protected content') if expired: self.logger.error( 'Failed to access stream, may be due to expired content')
def _get_streams(self): res = http.get(self.url) match = self._player_js.search(res.text) if match: player_js = match.group(0) self.logger.info("Found player js {0}", player_js) else: self.logger.info( "Didn't find player js. Probably this page doesn't contain a video" ) return res = http.get(player_js) m = self._data_re.search(res.text) if not m: self.logger.info( "Couldn't extract json metadata from player.js: {0}", player_js) return stream_metadata = json.loads(m.group("data")) is_video = stream_metadata["mediaType"] in ["live", "vod"] is_audio = stream_metadata["mediaType"] == "aod" media_version = tuple([ int(d) for d in stream_metadata["mediaVersion"].split("-")[0].split(".") ]) if is_video or is_audio: media_url = stream_metadata["mediaResource"]["dflt"][ "videoURL" if is_video else "audioURL"] media_url_alt = stream_metadata["mediaResource"]["alt"][ "videoURL" if is_video else "audioURL"] media_name = "audio" if is_audio else "vod" if media_version >= (1, 2, 0): media_format = stream_metadata["mediaResource"]["dflt"][ "mediaFormat"] media_format_alt = stream_metadata["mediaResource"]["alt"][ "mediaFormat"] else: media_format = stream_metadata["mediaFormat"] media_format_alt = media_url_alt[-4:] stream_url = { "url": media_url, "format": media_format, "name": media_name } stream_url_alt = { "url": media_url_alt, "format": media_format_alt, "name": media_name } for stream in [stream_url, stream_url_alt]: url = update_scheme("http://", stream["url"]) try: if stream["format"] in ["hds", ".f4m"]: for s in HDSStream.parse_manifest( self.session, url, is_akamai=True).items(): yield s elif stream["format"] in ["hls", "m3u8"]: streams = HLSStream.parse_variant_playlist( self.session, url).items() if not streams: yield "live", HLSStream(self.session, url) for s in streams: yield s elif stream["format"] in ["mp3", "mp4", ".mp3", ".mp4"]: yield stream["name"], HTTPStream(self.session, url) except IOError as err: self.logger.error("Failed to extract {0} streams: {1}", stream["format"], err)
def _get_hds_streams(self, info): # Needs the hdcore parameter added url = info["_stream"] + HDCORE_PARAMETER return HDSStream.parse_manifest(self.session, url, pvswf=SWF_URL).items()
def _get_streams(self): """ Find all the streams for the ITV url :return: Mapping of quality to stream """ soap_message = self._soap_request() headers = { 'Content-Length': '{0:d}'.format(len(soap_message)), 'Content-Type': 'text/xml; charset=utf-8', 'Host': 'secure-mercury.itv.com', 'Origin': 'http://www.itv.com', 'Referer': 'http://www.itv.com/Mercury/Mercury_VideoPlayer.swf?v=null', 'SOAPAction': "http://tempuri.org/PlaylistService/GetPlaylist", 'User-Agent': ITV_PLAYER_USER_AGENT, "X-Requested-With": "ShockwaveFlash/16.0.0.305" } res = http.post( "https://secure-mercury.itv.com/PlaylistService.svc?wsdl", headers=headers, data=soap_message) # Parse XML xmldoc = http.xml(res) # Check that geo region has been accepted faultcode = xmldoc.find('.//faultcode') if faultcode is not None: if 'InvalidGeoRegion' in faultcode.text: self.logger.error('Failed to retrieve playlist data ' '(invalid geo region)') return None # Look for <MediaFiles> tag (RTMP streams) mediafiles = xmldoc.find('.//VideoEntries//MediaFiles') # Look for <ManifestFile> tag (HDS streams) manifestfile = xmldoc.find('.//VideoEntries//ManifestFile') # No streams if not mediafiles and not manifestfile: return None streams = {} # Proxy not needed for media retrieval (Note: probably better to use flag) # for x in ('http', 'https'): # if x in http.proxies: # http.proxies.pop(x); # Parse RTMP streams if mediafiles: rtmp = mediafiles.attrib['base'] for mediafile in mediafiles.findall("MediaFile"): playpath = mediafile.find("URL").text rtmp_url = urlparse(rtmp) app = (rtmp_url.path[1:] + '?' + rtmp_url.query).rstrip('?') live = app == "live" params = dict( rtmp="{u.scheme}://{u.netloc}{u.path}".format(u=rtmp_url), app=app.rstrip('?'), playpath=playpath, swfVfy=LIVE_SWF_URL if live else ONDEMAND_SWF_URL, timeout=10) if live: params['live'] = True bitrate = int(mediafile.attrib['bitrate']) / 1000 quality = "{0:d}k".format(int(bitrate)) streams[quality] = RTMPStream(self.session, params) # Parse HDS streams if manifestfile: url = manifestfile.find('URL').text if urlparse(url).path.endswith('f4m'): streams.update( HDSStream.parse_manifest(self.session, url, pvswf=LIVE_SWF_URL)) return streams