def _get_streams(self): flashvars = http.get(self.url, schema=_flashvars_schema) if not flashvars: return params = { "rt": "json", "lc": "en_US", "pt": "view", "bpw": "", "bid": flashvars["id"], "adok": "", "bno": "" } if re.search(_url_re_tw, self.url): res = http.get(VIEW_LIVE_API_URL_TW, params=params) elif re.search(_url_re_jp, self.url): res = http.get(VIEW_LIVE_API_URL_JP, params=params) else: res = http.get(VIEW_LIVE_API_URL, params=params) streams = http.json(res, schema=_view_live_schema) for stream in streams: stream_name = "{0}p".format(stream["bps"]) stream_params = { "rtmp": stream["purl"], "live": True } yield stream_name, RTMPStream(self.session, stream_params)
def _get_streams(self): res = http.get(self.url) match = _embed_re.search(res.text) if match: res = http.get(match.group(1)) match = _aptoma_id_re.search(res.text) if not match: return aptoma_id = match.group(1) if not _live_re.search(res.text): res = http.get(METADATA_URL.format(aptoma_id)) metadata = http.json(res) video_id = metadata["videoId"] else: video_id = aptoma_id res = http.get(VIDEO_INFO_URL, params=dict(id=video_id)) video = http.json(res, schema=_video_schema) streams = {} for fmt, providers in video["formats"].items(): for name, provider in providers.items(): for ext, playlists in provider.items(): for playlist in playlists: url = PLAYLIST_URL_FORMAT.format(**playlist) parser = STREAM_TYPES[fmt] try: streams.update(parser(self.session, url)) except IOError as err: self.logger.error("Failed to extract {0} streams: {1}", fmt.upper(), err) return streams
def _get_streams(self): res = http.get(self.url) match = self._video_id_re.search(res.text) or self._video_id_alt_re.search(res.text) if match is None: return broadcaster_id = match.group('broadcaster_id') video_type = match.group('video_type') video_id = match.group('video_id') videos = http.get(self.DACAST_API_URL.format(broadcaster_id, video_type, video_id), schema=self._api_schema) token = http.get(self.DACAST_TOKEN_URL.format(broadcaster_id, video_type, video_id), schema=self._token_schema) parsed = [] for video_url in videos: video_url += token # Ignore duplicate video URLs if video_url in parsed: continue parsed.append(video_url) # Ignore HDS streams (broken) if '.m3u8' in video_url: for s in HLSStream.parse_variant_playlist(self.session, video_url).items(): yield s
def _get_streams(self): """ Finds the streams from tvcatchup.com. """ token = self.login(self.get_option("username"), self.get_option("password")) m = self._url_re.match(self.url) scode = m and m.group("scode") or self.get_option("station_code") res = http.get(self._guide_url) channels = {} for t in itertags(res.text, "a"): if t.attributes.get('cs'): channels[t.attributes.get('cs').lower()] = t.attributes.get('title').replace("Watch ", "") if not scode: self.logger.error("Station code not provided, use --ustvnow-station-code.") self.logger.error("Available stations are: {0}", ", ".join(channels.keys())) return if scode in channels: self.logger.debug("Finding streams for: {0}", channels.get(scode)) r = http.get(self._stream_url, params={"scode": scode, "token": token, "br_n": "Firefox", "br_v": "52", "br_d": "desktop"}, headers={"User-Agent": useragents.FIREFOX}) data = http.json(r) return HLSStream.parse_variant_playlist(self.session, data["stream"]) else: self.logger.error("Invalid station-code: {0}", scode)
def _get_streams(self): headers = { "Referer": self.url } res = http.get(self.url, headers=headers) match = _ddos_re.search(res.text) if match: self.logger.debug("Anti-DDOS bypass...") headers["Cookie"] = match.group(1) res = http.get(self.url, headers=headers) match = _apidata_re.search(res.text) channel_info = match and parse_json(match.group("data")) if not channel_info: self.logger.error("Could not find channel info") return self.logger.debug("Found channel info: channelkey={channelkey} pid={streamkey} online={status}", **channel_info) if not channel_info['status']: self.logger.debug("Channel appears to be offline") streams = {} for name, url_suffix in QUALITIES.items(): url = HLS_URL_FORMAT.format(channel_info['streamkey'], url_suffix) if not self._check_stream(url): continue streams[name] = HLSStream(self.session, url) return streams
def _get_streams(self): user = self.login(self.options.get("email"), self.options.get("password")) if user: self.logger.debug("Logged in to Schoolism as {0}", user) res = http.get(self.url, headers={"User-Agent": useragents.SAFARI_8}) lesson_playlist = self.playlist_schema.validate(res.text) part = self.options.get("part") self.logger.info("Attempting to play lesson Part {0}", part) found = False # make request to key-time api, to get key specific headers res = http.get(self.key_time_url, headers={"User-Agent": useragents.SAFARI_8}) for i, video in enumerate(lesson_playlist, 1): if video["sources"] and i == part: found = True for source in video["sources"]: for s in HLSStream.parse_variant_playlist(self.session, source["src"], headers={"User-Agent": useragents.SAFARI_8, "Referer": self.url}).items(): yield s if not found: self.logger.error("Could not find lesson Part {0}", part)
def _get_streams(self): match = _url_re.match(self.url) vid = match.group("vid") if vid: res = http.get(VOD_API_URL.format(vid)) data = http.json(res, schema=_vod_schema) yield "source", HLSStream( self.session, data["live_info"]["video"]) return channel = match.group("channel") res = http.get(API_URL.format(channel)) room = http.json(res, schema=_room_schema) if not room: self.logger.info("Not a valid room url.") return live_info = room["live_info"] if live_info["live_status"] != STATUS_ONLINE: self.logger.info("Stream currently unavailable.") return for item in live_info["stream_items"]: quality = item["title"] if quality == u"\u6700\u4f73": # "Best" in Chinese quality = "source" yield quality, HTTPStream(self.session, item["video"])
def _get_streams(self): if "eltrecetv.com.ar/vivo" in self.url.lower(): try: http.headers = {'Referer': self.url, 'User-Agent': useragents.ANDROID} res = http.get('https://api.iamat.com/metadata/atcodes/eltrece') yt_id = parse_json(res.text)["atcodes"][0]["context"]["ahora"]["vivo"]["youtubeVideo"] yt_url = "https://www.youtube.com/watch?v={0}".format(yt_id) return self.session.streams(yt_url) except BaseException: self.logger.info("Live content is temporarily unavailable. Please try again later.") else: try: http.headers = {'Referer': self.url, 'User-Agent': useragents.CHROME} res = http.get(self.url) _player_re = re.compile(r'''data-kaltura="([^"]+)"''') match = _player_re.search(res.text) if not match: return entry_id = parse_json(match.group(1).replace(""", '"'))["entryId"] hls_url = "https://vodgc.com/p/111/sp/11100/playManifest/entryId/{0}/format/applehttp/protocol/https/a.m3u8".format(entry_id) return HLSStream.parse_variant_playlist(self.session, hls_url) except BaseException: self.logger.error("The requested VOD content is unavailable.")
def _get_streams(self): headers = { "Referer": self.url } res = http.get(self.url, headers=headers) match = _ddos_re.search(res.text) if (match): headers["Cookie"] = match.group(1) res = http.get(self.url, headers=headers) match = _stream_re.search(res.text) if not match: return stream_id = match.group(1) streams = {} for name, url_suffix in QUALITIES.items(): url = HLS_URL_FORMAT.format(stream_id, url_suffix) if not self._check_stream(url): continue streams[name] = HLSStream(self.session, url) return streams
def _get_streams(self): match = _url_re.match(self.url) channel = match.group("channel") domain = match.group("domain") headers = { "Referer": self.url, "User-Agent": useragents.FIREFOX } if domain == "canlitv.plus": res = http.get(EMBED_URL_1.format(channel), headers=headers) elif domain == "ecanlitvizle.net": res = http.get(EMBED_URL_2.format(channel), headers=headers) else: res = http.get(self.url, headers=headers) url_match = _m3u8_re.search(res.text) if url_match: hls_url = url_match.group("url") if domain in ("canlitvlive.live", "canlitvlive.site"): hls_url = "http:" + hls_url self.logger.debug("Found URL: {0}".format(hls_url)) try: s = [] for s in HLSStream.parse_variant_playlist(self.session, hls_url).items(): yield s if not s: yield "live", HLSStream(self.session, hls_url) except IOError as err: self.logger.error("Failed to extract streams: {0}", err)
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): 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): match = _url_re.match(self.url) if not match: return channel, media_id = match.group("channel", "media_id") self.logger.debug("Matched URL: channel={0}, media_id={1}".format(channel, media_id)) if not media_id: res = http.get(LIVE_API.format(channel)) livestream = http.json(res, schema=_live_schema) if livestream.get("media_hosted_media"): hosted = _live_schema.validate(livestream["media_hosted_media"]) self.logger.info("{0} is hosting {1}", livestream["media_user_name"], hosted["media_user_name"]) livestream = hosted if not livestream["media_is_live"]: return media_id = livestream["media_id"] media_type = "live" else: media_type = "video" res = http.get(PLAYER_API.format(media_type, media_id)) player = http.json(res, schema=_player_schema) if media_type == "live": return self._get_live_streams(player) else: return self._get_video_streams(player)
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_qq_streams(self, vid): res = http.get(QQ_STREAM_INFO_URL % (vid, 1)) info = http.json(res, schema=_qq_schema) yield "live", HTTPStream(self.session, info) res = http.get(QQ_STREAM_INFO_URL % (vid, 2)) info = http.json(res, schema=_qq_schema) yield "live_http", HLSStream(self.session, info)
def _get_stream_info(self, url): res = http.get(url, headers=HEADERS) match = re.search(r"embed.swf\?p=(\d+)", res.text) if not match: return program = match.group(1) res = http.get(BEAT_PROGRAM.format(program), headers=HEADERS) return http.json(res, schema=_schema)
def _get_live_streams(self): meta = self._get_meta() stream = [x for x in meta['streams'] if x['type'] == 'hls'][0]['url'] url = 'http://ida.omroep.nl/aapi/?type=jsonp&stream={}&token={}'.format(stream, self.get_token()) streamdata = http.get(url, headers=HTTP_HEADERS).json() deeplink = http.get(streamdata['stream'], headers=HTTP_HEADERS).text deeplink = re.compile('"(.*?)"', re.DOTALL + re.IGNORECASE).search(deeplink).group(1) playlist_url = deeplink.replace("\\/", "/") return HLSStream.parse_variant_playlist(self.session, playlist_url)
def _get_streams(self): res = http.get(self.url) for iframe in itertags(res.text, "iframe"): self.logger.debug("Found iframe: {0}".format(iframe)) iframe_res = http.get(iframe.attributes['src'], headers={"Referer": self.url}) m = self.src_re.search(iframe_res.text) surl = m and m.group("url") if surl: self.logger.debug("Found stream URL: {0}".format(surl)) return HLSStream.parse_variant_playlist(self.session, surl)
def _get_streams(self): headers = {"User-Agent": useragents.CHROME} hls_url = http.get(self.url, headers=headers, schema=self._schema) headers["Referer"] = self.url if self.isVod: url = self._url_vod.format(quote(hls_url, safe="")) hls_url = http.get(url, headers=headers, schema=self._schema_vod) return HLSStream.parse_variant_playlist(self.session, hls_url, headers=headers)
def _get_vod_streams(self): # 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.VOD_API_URL.format(video_id)) streams = http.json(res, schema=self._vod_api_schema) return streams
def _get_live_streams(self, subdomain): """ Get the live stream in a particular language :param subdomain: :return: """ res = http.get(self._live_api_url.format(subdomain)) live_res = http.json(res, schema=self._live_schema) api_res = http.get(live_res[u"url"]) stream_data = http.json(api_res, schema=self._stream_api_schema) return HLSStream.parse_variant_playlist(self.session, stream_data[u'primary'])
def _get_streams(self): res = http.get(self.url, headers={"User-Agent": useragents.CHROME}) m = self.js_re.search(res.text) if m: self.logger.debug("Found js key: {0}", m.group(1)) js_url = m.group(0) res = http.get(urljoin(self.url, js_url)) for url in self.player_re.findall(res.text): if "adblock" not in url: yield "live", HLSStream(self.session, url)
def _get_vod_streams(self): url = 'http://ida.omroep.nl/odi/?prid={}&puboptions=adaptive,h264_bb,h264_sb,h264_std&adaptive=no&part=1&token={}'\ .format(quote(self.npo_id), quote(self.get_token())) res = http.get(url, headers=HTTP_HEADERS); data = res.json() streams = {} stream = http.get(data['streams'][0].replace('jsonp', 'json'), headers=HTTP_HEADERS).json() streams['best'] = streams['high'] = HTTPStream(self.session, stream['url']) return streams
def _get_streams(self): http.headers = {"User-Agent": useragents.CHROME} res = http.get(self.url) iframe_url = self.find_iframe(res) if iframe_url: self.logger.debug("Found iframe: {0}", iframe_url) res = http.get(iframe_url, headers={"Referer": self.url}) stream_url = update_scheme(self.url, self.stream_schema.validate(res.text)) return HLSStream.parse_variant_playlist(self.session, stream_url, headers={"User-Agent": useragents.CHROME})
def _get_streams(self): """ Get the config object from the page source and call the API to get the list of streams :return: """ # attempt a login self.login() res = http.get(self.url) # decode the config for the page matches = self.config_re.finditer(res.text) try: config = self.config_schema.validate(dict( [m.group("key", "value") for m in matches] )) except PluginError: return if config["selectedVideoHID"]: self.logger.debug("Found video hash ID: {0}", config["selectedVideoHID"]) api_url = urljoin(self.url, urljoin(config["videosURL"], config["selectedVideoHID"])) elif config["livestreamURL"]: self.logger.debug("Found live stream URL: {0}", config["livestreamURL"]) api_url = urljoin(self.url, config["livestreamURL"]) else: return ares = http.get(api_url) data = http.json(ares, schema=self.api_schema) viewing_urls = data["viewing_urls"] if "error" in viewing_urls: self.logger.error("Failed to load streams: {0}", viewing_urls["error"]) else: for url in viewing_urls["urls"]: try: label = "{0}p".format(url.get("res", url["label"])) except KeyError: label = "live" if url["type"] == "rtmp/mp4" and RTMPStream.is_usable(self.session): params = { "rtmp": url["src"], "pageUrl": self.url, "live": True, } yield label, RTMPStream(self.session, params) elif url["type"] == "application/x-mpegURL": for s in HLSStream.parse_variant_playlist(self.session, url["src"]).items(): yield s
def _get_streams(self): url_channel_name = self._url_re.match(self.url).group(1) # Handle VODs first, since their "channel name" is different if url_channel_name.endswith(".flv"): self.logger.debug("Possible VOD stream...") page = http.get(self.url) vod_streams = self._get_vod_stream(page) if vod_streams: for s in vod_streams.items(): yield s return else: self.logger.warning("Probably a VOD stream but no VOD found?") ci = http.get(self.CHANNEL_API_URL.format(channel=url_channel_name), raise_for_status=False) if ci.status_code == 404: self.logger.error("The channel {0} does not exist".format(url_channel_name)) return channel_api_json = json.loads(ci.text) if channel_api_json["online"] != True: self.logger.error("The channel {0} is currently offline".format(url_channel_name)) return server = None token = "public" channel = channel_api_json["name"] # Extract preferred edge server and available techs from the undocumented channel API channel_server_res = http.post(self.VIDEO_API_URL, data={"loadbalancinginfo": channel}) info_json = json.loads(channel_server_res.text) pref = info_json["preferedEdge"] for i in info_json["edges"]: if i["id"] == pref: server = i["ep"] break self.logger.debug("Using load balancing server {0} : {1} for channel {2}", pref, server, channel) for i in info_json["techs"]: if i["label"] == "HLS": for s in self._create_hls_stream(server, channel, token).items(): yield s elif i["label"] == "RTMP Flash": stream = self._create_flash_stream(server, channel, token) yield "live", stream
def _get_playlist_url(self): # get the id content = http.get(self.url) match = _id_re.match(content.text.replace("\n", "")) if not match: return # get the m3u8 file url player_url = _stream_player_url.format(match.group(1)) content = http.get(player_url) match = _file_re.match(content.text.replace("\n", "")) if match: return match.group(1)
def _get_streams(self): res = http.get(self.url) match = _embed_re.search(res.text) if match: iframe_url = "https://cyro.se{0}".format(match.group(1)) res = http.get(iframe_url) match = _embed_re.search(res.text) if match: iframe_url = "https://cyro.se{0}".format(match.group(1)) res = http.get(iframe_url) match = _embed_re.search(res.text) if match: url = match.group(1) return self.session.streams(url)
def _get_streams(self): try: url_content = "" http.headers = {'User-Agent': useragents.ANDROID} if "#channel" in self.url.lower(): requested_channel = self.url.lower()[self.url.lower().index('#channel') + 8:] url_content = http.get('http://webcast.gov.in/mobilevideo.asp?id=div' + requested_channel).text else: url_content = http.get(self.url).text hls_url = url_content[: url_content.rindex('master.m3u8') + 11] hls_url = hls_url[hls_url.rindex('"') + 1:] return HLSStream.parse_variant_playlist(self.session, hls_url) except BaseException: self.logger.error("The requested channel is unavailable.")
def passphrase(self): self.logger.debug("passphrase ...") res = http.get(self.url, headers=self._headers) passphrase_m = self.passphrase_re.search(res.text) return passphrase_m and passphrase_m.group("passphrase").encode("utf8")
def video_info(self): page = http.get(self.url) for div in itertags(page.text, 'div'): if div.attributes.get("id") == "video": return div.attributes
def _get_api_video(self, username): res = http.get(self.API_URL_VIDEO.format( username, str(random.randint(1000, 99999))), headers=self.headers) data_video = http.json(res, schema=_api_video_schema) return data_video
def _get_streams(self): playlist_url = http.get(self.url, schema=_schema) if not playlist_url: return return HLSStream.parse_variant_playlist(self.session, playlist_url)
def time(self): res = http.get(self.get_time_url) data = http.json(res) return str(data.get("serverTime", int(time.time() * 1000)))
def _get_streams(self): http.headers = {"User-Agent": useragents.CHROME} res = http.get(self.url) rlanguage = self.get_option("language") id_m = self.experience_id_re.search(res.text) experience_id = id_m and int(id_m.group(1)) if experience_id: self.logger.debug("Found experience ID: {0}", experience_id) exp = Experience(experience_id) self.logger.debug("Found episode: {0}", exp.episode_info["episodeTitle"]) self.logger.debug(" has languages: {0}", ", ".join(exp.episode_info["languages"].keys())) self.logger.debug(" requested language: {0}", rlanguage) self.logger.debug(" current language: {0}", exp.language) if rlanguage != exp.language: self.logger.debug("switching language to: {0}", rlanguage) exp.set_language(rlanguage) if exp.language != rlanguage: self.logger.warning( "Requested language {0} is not available, continuing with {1}", rlanguage, exp.language) else: self.logger.debug("New experience ID: {0}", exp.experience_id) subtitles = None stream_metadata = {} disposition = {} for subtitle in exp.subtitles(): self.logger.info("Subtitles: {0}", subtitle["src"]) if subtitle["src"].endswith( ".vtt") or subtitle["src"].endswith(".srt"): sub_lang = {"en": "eng", "ja": "jpn"}[subtitle["language"]] # pick the first suitable subtitle stream subtitles = subtitles or HTTPStream( self.session, subtitle["src"]) stream_metadata["s:s:0"] = [ "language={0}".format(sub_lang) ] stream_metadata["s:a:0"] = [ "language={0}".format(exp.language_code) ] for item in exp.sources()["items"]: url = item["src"] if ".m3u8" in url: for q, s in HLSStream.parse_variant_playlist( self.session, url).items(): if self.get_option("mux_subtitles") and subtitles: yield q, MuxedStream(self.session, s, subtitles, metadata=stream_metadata, disposition=disposition) else: yield q, s elif ".mp4" in url: # TODO: fix quality s = HTTPStream(self.session, url) if self.get_option("mux_subtitles") and subtitles: yield self.mp4_quality, MuxedStream( self.session, s, subtitles, metadata=stream_metadata, disposition=disposition) else: yield self.mp4_quality, s else: self.logger.error("Could not find experience ID?!")
def _get_streams(self): page = http.get(self.url, schema=_schema) if not page: return pubkey_pem = get_public_key(self.cache, urljoin(self.url, page["clientlibs"])) if not pubkey_pem: raise PluginError("Unable to get public key") flashvars = page["flashvars"] params = {"cashPath": int(time.time() * 1000)} res = http.get(urljoin(self.url, flashvars["country"]), params=params) if not res: return language = http.xml(res, schema=_language_schema) api_params = {} for key in ("ss_id", "mv_id", "device_cd", "ss1_prm", "ss2_prm", "ss3_prm"): if flashvars.get(key, ""): api_params[key] = flashvars[key] aeskey = number.long_to_bytes(random.getrandbits(8 * 32), 32) params = { "s": flashvars["s"], "c": language, "e": self.url, "d": aes_encrypt(aeskey, json.dumps(api_params)), "a": rsa_encrypt(pubkey_pem, aeskey) } res = http.get(urljoin(self.url, flashvars["init"]), params=params) if not res: return rtn = http.json(res, schema=_init_schema) if not rtn: return init_data = parse_json(aes_decrypt(aeskey, rtn)) parsed = urlparse(init_data["play_url"]) if parsed.scheme != "https" or not parsed.path.startswith( "/i/") or not parsed.path.endswith("/master.m3u8"): return hlsstream_url = init_data["play_url"] streams = HLSStream.parse_variant_playlist(self.session, hlsstream_url) if "caption_url" in init_data: if self.get_option("mux_subtitles") and FFMPEGMuxer.is_usable( self.session): res = http.get(init_data["caption_url"]) srt = http.xml(res, ignore_ns=True, schema=_xml_to_srt_schema) subfiles = [] metadata = {} for i, lang, srt in ((i, s[0], s[1]) for i, s in enumerate(srt)): subfile = tempfile.TemporaryFile() subfile.write(srt.encode("utf8")) subfile.seek(0) subfiles.append(FileStream(self.session, fileobj=subfile)) metadata["s:s:{0}".format(i)] = [ "language={0}".format(lang) ] for n, s in streams.items(): yield n, MuxedStream(self.session, s, *subfiles, maps=list(range(0, len(metadata) + 1)), metadata=metadata) return else: self.logger.info("Subtitles: {0}".format( init_data["caption_url"])) for s in streams.items(): yield s
def find_tvip(self, url): self.logger.debug("Looking for tvip on {0}", url) res = http.get(url) m = self.tvip_re.search(res.text) return m and m.group(1)
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) match = self._pluzz_video_id_re.search( res.text) or self._other_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 find_vpid(self, url): self.logger.debug("Looking for vpid on {0}", url) res = http.get(url) m = self.vpid_re.search(res.text) return m and m.group(1)
def _get_live_cubeid(self): res = http.get(API_URL_APP, params=dict(mode="get_live")) root = http.xml(res) return root.findtext("./cube/cubeid")
def _get_stream_info(self, room_id): res = http.get(_api_stream_url.format(room_id=room_id), headers=self._headers) return http.json(res, schema=_api_stream_schema)
def api_call(self, endpoint, schema=None, params=None): url = self.api_url.format(endpoint=endpoint) res = http.get(url, params=params) return http.json(res, schema=schema)
def vod(self, vod_id): res = http.get(self.vod_url.format(vod_id)) return http.json(res, schema=self.api_schema)
def _get_api_user(self, username): res = http.get(self.API_URL_USER.format(username), headers=self.headers) data_user = http.json(res, schema=_api_user_schema) return data_user
def _get_content_id(self): # check the page to find the contentId res = http.get(self.url) m = self.content_id_re.search(res.text) if m: return m.group(1)
def _get_streams(self): channel_id = http.get(self.url, schema=_youtube_url_schema) if channel_id: return self.session.streams(YOUTUBE_URL.format(channel_id))
def get_csrf_tokens(self): return http.get(self.csrf_tokens_url, schema=self.token_schema)
def _get_streams(self): # Get domain name self.domain = _url_re.match(self.url).group('domain') # Set header data for user-agent hdr = {'User-Agent': USER_AGENT.format('sv_SE')} # Parse video ID from data received from supplied URL res = http.get(self.url, headers=hdr).text match = _videoid_re.search(res) if not match: # Video ID not found self.logger.error('Failed to parse video ID') return {} videoId = match.group('id') # Get data from general API to validate that stream is playable res = http.get(GENERAL_API_URL.format(self.domain, videoId), headers=hdr) data = http.json(res, schema=_api_schema) if not data['data']: # No data item found self.logger.error( 'Unable to find "data" item in general API response') return {} if not self._is_playable(data): # Stream not playable self.logger.error( 'Stream is not playable (Premium or DRM-protected content)') return {} # Get geo data, validate and form cookie consisting of # geo data + expiry timestamp (current time + 1 hour) res = http.get(GEO_DATA_URL.format(self.domain), headers=hdr) geo = http.json(res, schema=_geo_schema) timestamp = (int(time.time()) + 3600) * 1000 cookie = 'dsc-geo=%s' % quote('{"countryCode":"%s","expiry":%s}' % (geo, timestamp)) # Append cookie to headers hdr['Cookie'] = cookie # Get available streams using stream API try: res = http.get(STREAM_API_URL.format(self.domain, videoId, 'hls'), headers=hdr, verify=False) data = http.json(res, schema=_media_schema) media = data.copy() res = http.get(STREAM_API_URL.format(self.domain, videoId, 'hds'), headers=hdr, verify=False) data = http.json(res, schema=_media_schema) media.update(data) except PluginError as err: # Likely geo-restricted if any(e in str(err) for e in ('401 Client Error', '403 Client Error')): self.logger.error('Failed to access stream API, ' 'may be due to geo-restriction') raise NoStreamsError(self.url) else: raise # Reformat data into list with stream format and url streams = [{'format': k, 'url': media[k]} for k in media] # Create mapper for supported stream types (HLS/HDS) mapper = StreamMapper(cmp=lambda type, video: video['format'] == type) mapper.map('hls', self._create_streams, HLSStream.parse_variant_playlist) mapper.map('hds', self._create_streams, HDSStream.parse_manifest) # Feed stream data to mapper and return all streams found return mapper(streams)
def channel(self, channel): res = http.get(self.channel_url.format(channel)) return http.json(res, schema=self.api_schema)
def _check_stream(self, url): res = http.get(url, acceptable_status=(200, 404)) if res.status_code == 200: return True
def _get_iframe_url(self, url): res = http.get(url) for iframe in itertags(res.text, 'iframe'): src = iframe.attributes.get("src") if src: return src
def request(self, data, *args, **kwargs): res = http.get(self.base_url + self.encrypt(data), *args, **kwargs) return self.decrypt(res.content)
def _get_streams(self): res = http.get(self.url) match = self.playervars_re.search(res.text) if match: stream_url = match.group(1) return HLSStream.parse_variant_playlist(self.session, stream_url)
def _get_meta_url(self, url): res = http.get(url, exception=IOError) root = http.xml(res, exception=IOError) return root.findtext("default-stream-url")
def _update(self): api_url = self.show_api_url.format(experience_id=self.experience_id) res = http.get(api_url) data = http.json(res) self.cache[self.experience_id] = data
def _get_content_id(self): res = http.get(self.url) m = self.content_id_re.search(res.text) return m and int(m.group(1))
def _get_subtitles(self, content_id): res = http.get(self.subtitles_api.format(id=content_id)) return http.json(res, schema=self.subtitles_schema)
def passphrase(self): res = http.get(self.url) passphrase_m = self.passphrase_re.search(res.text) return passphrase_m and passphrase_m.group("passphrase").encode("utf8")
def hls_session(self): res = http.get(update_scheme(self.url, self._session_api)) data = http.json(res) # the values are already quoted, we don't want them quoted return dict((k, unquote(v)) for k, v in data.items())