def _get_streams(self): streams = {} # streaming.media.ccc.de match = _url_streaming_media_re.match(self.url) if match: query_url = API_URL_STREAMING_MEDIA live_streams = parse_streaming_media_json(get_json(query_url),\ match.group('room')) for stream_name, stream_url in live_streams.items(): if re.search(r"m3u8", live_streams[stream_name]): streams[stream_name] = HLSStream(self.session,\ stream_url) else: streams[stream_name] = HTTPStream(self.session,\ stream_url) # media.ccc.de elif _url_media_re.search(self.url): event_id = get_event_id(self.url) query_url = "%s/public/events/%i" % (API_URL_MEDIA, event_id) recordings = parse_media_json(get_json(query_url)) for name, stream_url in recordings.items(): streams[name] = HTTPStream(self.session, stream_url) if not streams: raise PluginError("This plugin does not support your " "selected video.") return streams
def _create_video_clip(self, chunks, start_offset, stop_offset): playlist_duration = stop_offset - start_offset playlist_offset = 0 playlist_streams = [] playlist_tags = [] for chunk in chunks: chunk_url = chunk["url"] chunk_length = chunk["length"] chunk_start = playlist_offset chunk_stop = chunk_start + chunk_length chunk_stream = HTTPStream(self.session, chunk_url) if chunk_start <= start_offset <= chunk_stop: try: headers = extract_flv_header_tags(chunk_stream) except IOError as err: raise StreamError("Error while parsing FLV: {0}", err) if not headers.metadata: raise StreamError("Missing metadata tag in the first chunk") metadata = headers.metadata.data.value keyframes = metadata.get("keyframes") if not keyframes: if chunk["upkeep"] == "fail": raise StreamError("Unable to seek into muted chunk, try another timestamp") else: raise StreamError("Missing keyframes info in the first chunk") keyframe_offset = None keyframe_offsets = keyframes.get("filepositions") keyframe_times = [playlist_offset + t for t in keyframes.get("times")] for time, offset in zip(keyframe_times, keyframe_offsets): if time > start_offset: break keyframe_offset = offset if keyframe_offset is None: raise StreamError("Unable to find a keyframe to seek to " "in the first chunk") chunk_headers = dict(Range="bytes={0}-".format(int(keyframe_offset))) chunk_stream = HTTPStream(self.session, chunk_url, headers=chunk_headers) playlist_streams.append(chunk_stream) for tag in headers: playlist_tags.append(tag) elif start_offset <= chunk_start < stop_offset: playlist_streams.append(chunk_stream) playlist_offset += chunk_length return FLVPlaylist(self.session, playlist_streams, tags=playlist_tags, duration=playlist_duration)
def _get_streams(self): match = _url_re.match(self.url) channel = match.group("channel") http.headers.update({'User-Agent': USER_AGENT}) http.verify = False http.mount('https://', HTTPAdapter(max_retries=99)) #Thanks to @ximellon for providing method. try: channel = int(channel) except ValueError: channel = http.get(self.url, schema=_room_id_schema) if channel == 0: channel = http.get(self.url, schema=_room_id_alt_schema) res = http.get(MAPI_URL.format(channel)) room = http.json(res, schema=_room_schema) if not room: return if room["show_status"] != SHOW_STATUS_ONLINE: return ts = int(time.time() / 60) did = uuid.uuid4().hex.upper() sign = hashlib.md5( ("{0}{1}{2}{3}".format(channel, did, LAPI_SECRET, ts)).encode("utf-8")).hexdigest() data = {"cdn": "ws", "rate": "0", "tt": ts, "did": did, "sign": sign} res = http.post(LAPI_URL.format(channel), data=data) room = http.json(res, schema=_lapi_schema) url = "{room[rtmp_url]}/{room[rtmp_live]}".format(room=room) stream = HTTPStream(self.session, url) yield "source", stream data = {"cdn": "ws", "rate": "2", "tt": ts, "did": did, "sign": sign} res = http.post(LAPI_URL.format(channel), data=data) room = http.json(res, schema=_lapi_schema) url = "{room[rtmp_url]}/{room[rtmp_live]}".format(room=room) stream = HTTPStream(self.session, url) yield "middle", stream data = {"cdn": "ws", "rate": "1", "tt": ts, "did": did, "sign": sign} res = http.post(LAPI_URL.format(channel), data=data) room = http.json(res, schema=_lapi_schema) url = "{room[rtmp_url]}/{room[rtmp_live]}".format(room=room) stream = HTTPStream(self.session, url) yield "low", stream
def _get_streams(self): info = self._get_stream_info(self.url) if not info: return formats = info.get("fmt_list") streams = {} protected = False for stream_info in info.get("url_encoded_fmt_stream_map", []): if stream_info.get("s"): protected = True continue stream = HTTPStream(self.session, stream_info["url"]) name = formats.get(stream_info["itag"]) or stream_info["quality"] if stream_info.get("stereo3d"): name += "_3d" streams[name] = stream # Extract audio streams from the DASH format list for stream_info in info.get("adaptive_fmts", []): if stream_info.get("s"): protected = True continue stream_type, stream_format = stream_info["type"] if stream_type != "audio": continue stream = HTTPStream(self.session, stream_info["url"]) name = "audio_{0}".format(stream_format) streams[name] = stream hls_playlist = info.get("hlsvp") if hls_playlist: try: hls_streams = HLSStream.parse_variant_playlist( self.session, hls_playlist, headers=HLS_HEADERS, namekey="pixels") streams.update(hls_streams) except IOError as err: self.logger.warning("Failed to extract HLS streams: {0}", err) if not streams and protected: raise AccessDeniedError( "This plugin does not support protected videos, " "try youtube-dl instead") return streams
def _create_playlist_streams(self, videos): start_offset = int(videos.get("start_offset", 0)) stop_offset = int(videos.get("end_offset", 0)) streams = {} for quality, chunks in videos.get("chunks").items(): if not chunks: if videos.get("restrictions", {}).get(quality) == "chansub": self.logger.warning( "The quality '{0}' is not available " "since it requires a subscription.", quality) continue # Rename 'live' to 'source' if quality == "live": quality = "source" chunks_filtered = list(filter(lambda c: c["url"], chunks)) if len(chunks) != len(chunks_filtered): self.logger.warning( "The video '{0}' contains invalid chunks. " "There will be missing data.", quality) chunks = chunks_filtered chunks_duration = sum(c.get("length") for c in chunks) # If it's a full broadcast we just use all the chunks if start_offset == 0 and chunks_duration == stop_offset: # No need to use the FLV concat if it's just one chunk if len(chunks) == 1: url = chunks[0].get("url") stream = HTTPStream(self.session, url) else: chunks = [ HTTPStream(self.session, c.get("url")) for c in chunks ] stream = FLVPlaylist(self.session, chunks, duration=chunks_duration) else: try: stream = self._create_video_clip(chunks, start_offset, stop_offset) except StreamError as err: self.logger.error("Error while creating video '{0}': {1}", quality, err) continue streams[quality] = stream return streams
def _get_streams(self): res = http.get(self.url) match = _info_re.search(res.text) if not match: return info = parse_json(match.group(1), schema=_schema) stream_name = info["mode"] mp4_url = info.get("mp4_url") ios_url = info.get("ios_url") swf_url = info.get("swf_url") if mp4_url: stream = HTTPStream(self.session, mp4_url) yield stream_name, stream if ios_url: if urlparse(ios_url).path.endswith(".m3u8"): streams = HLSStream.parse_variant_playlist( self.session, ios_url) # TODO: Replace with "yield from" when dropping Python 2. for stream in streams.items(): yield stream if swf_url: stream = self._get_rtmp_stream(swf_url) if stream: yield stream_name, stream
def _get_streams(self): match = _url_re.match(self.url) videoid = match.group('id') streams = {} # Set header data for user-agent hdr = {'User-Agent': USER_AGENT} # Parse video ID from data received from supplied URL res = http.get(VK_VIDEO_URL + videoid.strip(), headers=hdr) for match in re.findall(SINGLE_VIDEO_URL, res.text): url = match[0].replace("\\/", "/") streams[match[2]] = HTTPStream(self.session, url) if not streams: # try to check is live match = VK_LIVE_HASH.search(res.text) params = videoid.split('_') if match and match.group('hash'): url = VK_EXT_URL.format(params[0].replace('video', "").replace('-', ""), params[1], match.group('hash')) res = http.get(url, headers=hdr) match = SINGLE_HLS_URL.search(res.text) if match and match.group('playlist'): hls_streams = HLSStream.parse_variant_playlist(self.session, match.group('playlist').replace("\\/", "/"), namekey="pixels") streams.update(hls_streams) return streams
def _get_streams(self): self.url = http.resolve_url(self.url) match = _url_re.match(self.url) parsed = urlparse(self.url) if parsed.fragment: channel_id = parsed.fragment elif parsed.path[:3] == '/v/': channel_id = parsed.path.split('/')[-1] else: channel_id = match.group("channel") if not channel_id: return channel_id = channel_id.lower().replace("/", "_") res = http.get(API_URL.format(channel_id)) info = http.json(res, schema=_schema) if not info["success"]: return if info.get("isLive"): name = "live" else: name = "vod" stream = HTTPStream(self.session, info["payload"]) # Wrap the stream in a FLVPlaylist to verify the FLV tags stream = FLVPlaylist(self.session, [stream]) return {name: stream}
def _get_streams(self): # Set header data for user-agent hdr = {'User-Agent': USER_AGENT} # Parse video ID from data received from supplied URL res = http.get(self.url, headers=hdr) if not res: return {} try: bs = BeautifulSoup(res.text, "html5lib") bs = bs.find('video', {'id': "my-video"}) if not bs: return {} src = bs.find('source', {'data-quality': "hd"}) if not src: src = bs.find('video') if not src or not src.get('src'): return {} return {"best": HTTPStream(self.session, src.get('src'))} except Exception as e: self.logger.error("Failed to decode player params: {0}", e) return {}
def _create_stream(self, stream, is_live): stream_name = "{0}p".format(stream["height"]) stream_type = stream["mediaType"] stream_url = stream["url"] if stream_type in ("hls", "mp4"): if urlparse(stream_url).path.endswith("m3u8"): try: streams = HLSStream.parse_variant_playlist( self.session, stream_url) # TODO: Replace with "yield from" when dropping Python 2. 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 == "rtmp": params = { "rtmp": stream["streamer"], "playpath": stream["url"], "swfVfy": SWF_URL, "pageUrl": self.url, } if is_live: params["live"] = True else: params["playpath"] = "mp4:{0}".format(params["playpath"]) stream = RTMPStream(self.session, params) yield stream_name, stream
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_vod_stream(self): """ Find the VOD video url :return: video url """ res = http.get(self.url) video_urls = self._re_vod.findall(res.text) if len(video_urls): return dict(vod=HTTPStream(self.session, video_urls[0]))
def _get_clips(self): quality_options = self.api.clip_status(self.channel, self.clip_name, schema=_quality_options_schema) streams = {} for quality_option in quality_options: streams[quality_option["quality"]] = HTTPStream( self.session, quality_option["source"]) return streams
def _get_http_streams(self, info): name = QUALITY_MAP.get(info["_quality"], "vod") urls = info["_stream"] if not isinstance(info["_stream"], list): urls = [urls] for url in urls: stream = HTTPStream(self.session, url) yield name, stream
def _get_streams(self): match = _url_re.match(self.url) channel = match.group("channel") url = ROOM_API + channel res = http.get(url) data = http.json(res, schema=_room_schema) if not isinstance(data, dict): self.logger.error("Please Check PandaTV Room API") return videoinfo = data.get('videoinfo') if not videoinfo or not videoinfo.get('status'): self.logger.error("Please Check PandaTV Room API") return if videoinfo.get('status') != '2': self.logger.info("Channel offline now!") return streams = {} plflag = videoinfo.get('plflag') if not plflag or not '_' in plflag: self.logger.error("Please Check PandaTV Room API") return plflag = plflag.split('_')[1] room_key = videoinfo.get('room_key') # SD(Super high Definition) has higher quality than HD(High Definition) which # conflict with existing code, use ehq and hq instead. stream_addr = videoinfo.get('stream_addr') if stream_addr and stream_addr.get('SD') == '1': streams['ehq'] = HTTPStream( self.session, SD_URL_PATTERN.format(plflag, room_key)) if stream_addr and stream_addr.get('HD') == '1': streams['hq'] = HTTPStream(self.session, HD_URL_PATTERN.format(plflag, room_key)) return streams
def _get_streams(self): res = http.get(self.url, schema=_schema) if not res: return if res["type"] == "channel" and urlparse( res["url"]).path.endswith("m3u8"): return HLSStream.parse_variant_playlist(self.session, res["url"]) elif res["type"] == "video": stream = HTTPStream(self.session, res["url"]) return dict(video=stream)
def _get_source_streams(self): res = http.get(self.url) streams = {} sources = _source_re.findall(res.text) for source in sources: src = _source_src_re.search(source).group("src") pixels = _source_type_re.search(source).group("type") streams[pixels] = HTTPStream(self.session, src) return streams
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_plu_streams(self, cid): res = http.get(PLU_STREAM_INFO_URL % cid) info = http.json(res, schema=_plu_schema) for source in info["urls"]: quality = self._get_quality(source["resolution"]) if source["ext"] == "m3u8": yield quality, HLSStream(self.session, source["securityUrl"]) elif source["ext"] == "flv": yield quality, HTTPStream(self.session, source["securityUrl"]) elif source["ext"] == "rtmp": yield quality, RTMPStream(self.session, { "rtmp": source["securityUrl"], "live": True })
def _get_recorded_streams(self, video_id): if HAS_LIBRTMP: recording = self._get_module_info("recorded", video_id, schema=_recorded_schema) if not isinstance(recording.get("stream"), list): return for provider in recording["stream"]: base_url = provider.get("url") for stream_info in provider["streams"]: bitrate = int(stream_info.get("bitrate", 0)) stream_name = (bitrate > 0 and "{0}k".format(bitrate) or "recorded") url = stream_info["streamName"] if base_url: url = base_url + url if url.startswith("http"): yield stream_name, HTTPStream(self.session, url) elif url.startswith("rtmp"): params = dict(rtmp=url, pageUrl=self.url) yield stream_name, RTMPStream(self.session, params) else: self.logger.warning( "The proper API could not be used without python-librtmp " "installed. Stream URL is not guaranteed to be valid") url = RECORDED_URL.format(video_id) random_hash = "{0:02x}{1:02x}".format(randint(0, 255), randint(0, 255)) params = dict(hash=random_hash) stream = HTTPStream(self.session, url, params=params) yield "recorded", stream
def _get_streams(self): res = http.get(self.url, schema=_schema) if res["export_url"]: return self._get_live_stream(res["export_url"]) elif res["video_flashvars"]: stream = RTMPStream( self.session, { "rtmp": res["video_flashvars"]["_111pix_serverURL"], "playpath": res["video_flashvars"]["en_flash_providerName"], "swfVfy": SWF_VIDEO_URL, "pageUrl": self.url }) return dict(video=stream) elif res["standby_video"]: for stream in res["standby_video"]: stream = HTTPStream(self.session, stream["streamName"]) return dict(replay=stream) elif res["history_video"]: stream = HTTPStream(self.session, res["history_video"]) return dict(history=stream) return
def _get_streams(self): match = _url_re.match(self.url) videoid = match.group('videoid') get_return = http.get(VIDEO_GET_URL.format(videoid)) json_decode = http.json(get_return) streams = {} quality_list = [] for stream in json_decode: if SINGLE_VIDEO_URL.match(stream['direct_url']): quality_list.append(int(stream['video_bitrate'])) if len(quality_list) == 0: return quality_dict = get_quality_dict(quality_list) for stream in json_decode: if SINGLE_VIDEO_URL.match(stream['direct_url']): streams[quality_dict[stream['video_bitrate']]] = HTTPStream(self.session, stream['direct_url']) return streams
def _get_streams(self): res = http.get(self.url, schema=_schema) streams = {} for url in res["urls"]: parsed = urlparse(url) if parsed.scheme.startswith("rtmp"): params = {"rtmp": url, "pageUrl": self.url, "live": True} if res["swf"]: params["swfVfy"] = res["swf"] stream = RTMPStream(self.session, params) streams["live"] = stream elif parsed.scheme.startswith("http"): name = splitext(parsed.path)[1][1:] stream = HTTPStream(self.session, url) streams[name] = stream return streams
def _get_streams(self): res = http.get(self.url) match = _streams_re.findall(res.content.decode('utf-8')) for url, stream_type in match: if stream_type == "rtmp/mp4" and RTMPStream.is_usable( self.session): params = { "rtmp": url, "pageUrl": self.url, "live": True, } yield 'live', RTMPStream(self.session, params) elif stream_type == "application/x-mpegURL": for s in HLSStream.parse_variant_playlist(self.session, url).items(): yield s elif stream_type == "video/mp4": yield 'vod', HTTPStream(self.session, url)
def _create_flv_playlist(self, template): res = http.get(template) playlist = http.json(res, schema=_vod_playlist_schema) parsed = urlparse(template) url_template = "{0}://{1}{2}".format(parsed.scheme, parsed.netloc, playlist["template"]) segment_max = reduce(lambda i, j: i + j[0], playlist["fragments"], 0) substreams = [ HTTPStream(self.session, url_template.replace("$fragment$", str(i))) for i in range(1, segment_max + 1) ] return FLVPlaylist(self.session, duration=playlist["duration"], flatten_timestamps=True, skip_header=True, streams=substreams)
def _get_streams(self): match = self._url_re.match(self.url) film_id, episode_id = match.groups() headers = {"Referer": self.url, "User-Agent": self._user_agent} # Get the info about the Episode, including the Grabber API URL info_res = http.get(self._episode_info_url, params=dict(update=0, film=film_id, id=episode_id), headers=headers) info = http.json(info_res, schema=self._info_schema) # Get the data about the streams from the Grabber API stream_list_res = http.get(info["grabber"], params=info["params"], headers=headers) stream_data = http.json(stream_list_res, schema=self._streams_schema) for stream in stream_data["data"]: yield stream["label"], HTTPStream(self.session, stream["file"])
def _get_streams(self): match = _url_re.match(self.url) videoid = match.group('id') # Set header data for user-agent hdr = {'User-Agent': USER_AGENT} # Parse video ID from data received from supplied URL res = http.get(self.url, headers=hdr) if not res: return {} for match in re.findall(_direct_url, res.text): try: return {"original": HTTPStream(self.session, match)} except Exception as e: self.logger.error("Failed to extract video url: {0}", e) return {}
def _get_streams(self): match = _url_re.match(self.url) channel = match.group("channel") html_page = http.get(self.url).content.decode('utf-8') room_id = _room_re.search(html_page).group(1) ts = int(time.time() / 60) sign = hashlib.md5(("{0}{1}".format(channel, API_SECRET, ts)).encode("utf-8")).hexdigest() res = http.get(API_URL.format(room_id, sign)) room = http.json(res) if not room: return for stream_list in room["durl"]: name = "source" url = stream_list["url"] stream = HTTPStream(self.session, url) yield name, stream
def _make_stream(self, url): if url and url.endswith("flv"): return HTTPStream(self.session, url) elif url and url.endswith("m3u8"): return HLSStream(self.session, url)
def _get_streams(self): streams = {} match = _url_re.match(self.url) videoid = match.group('id') embed_params = match.group('embed_params') if not videoid and embed_params: query_params = urlparse.parse_qs(embed_params, True) if not 'oid' in query_params: self.logger.error("missing 'oid'") return streams if not 'id' in query_params: self.logger.error("missing 'id'") return streams _oid = query_params['oid'][0] _id = query_params['id'][0] # _hash = query_params['hash'][0] videoid = "video%s_%s" % (_oid, _id) # Set header data for user-agent hdr = {'User-Agent': USER_AGENT} # Parse video ID from data received from supplied URL res = http.get(VK_VIDEO_URL + videoid.strip(), headers=hdr) for match in re.findall(SINGLE_VIDEO_URL, res.text): url = match[0].replace("\\/", "/") try: # follow possible redirects and get final url res = http.get(url, headers=hdr, verify=False, allow_redirects=True, stream=True) streams[match[2]] = HTTPStream(self.session, res.url) except: pass if not streams: # try live for match in re.findall(SINGLE_HLS_URL, res.text): url = match.replace("\\/", "/") streams = {"variant": HLSStream(self.session, url)} break if not streams: # try to check is live match = VK_LIVE_HASH.search(res.text) params = videoid.split('_') if match and match.group('hash'): url = VK_EXT_URL.format( params[0].replace('video', "").replace('-', ""), params[1], match.group('hash')) res = http.get(url, headers=hdr) match = SINGLE_HLS_URL.search(res.text) if match and match.group('playlist'): url = match.group('playlist').replace("\\/", "/") streams = {"variant": HLSStream(self.session, url)} return streams