class Welt(Plugin): _re_url = re.compile(r"""https?://(\w+\.)?welt\.de/?""", re.IGNORECASE) _re_url_vod = re.compile(r"""mediathek""", re.IGNORECASE) _url_vod = "https://www.welt.de/onward/video/play/{0}" _schema = validate.Schema( validate.transform(get_json), validate.transform(parse_json), validate.get("sources"), validate.filter(lambda obj: obj["extension"] == "m3u8"), validate.map(lambda obj: obj["src"]), validate.get(0)) @classmethod def can_handle_url(cls, url): return cls._re_url.match(url) is not None def __init__(self, url): Plugin.__init__(self, url) self.url = url self.isVod = self._re_url_vod.search(url) is not None def _get_streams(self): headers = {"User-Agent": useragents.CHROME} hls_url = self.session.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 = self.session.http.get(url, headers=headers).url return HLSStream.parse_variant_playlist(self.session, hls_url, headers=headers)
class Looch(Plugin): url_re = re.compile(r"https?://(?:www\.)?looch\.tv/channel/(?P<name>[^/]+)(/videos/(?P<video_id>\d+))?") api_base = "https://api.looch.tv" channel_api = api_base + "/channels/{name}" video_api = api_base + "/videos/{id}" playback_schema = validate.Schema({"weight": int, "uri": validate.url()}) data_schema = validate.Schema({ "type": validate.text, "attributes": { validate.optional("playback"): [playback_schema], validate.optional("resolution"): {"width": int, "height": int} }}) channel_schema = validate.Schema( validate.transform(parse_json), {"included": validate.all( [data_schema], validate.filter(lambda x: x["type"] == "active_streams"), validate.map(lambda x: x["attributes"].get("playback")), validate.transform(lambda x: list(itertools.chain(*x))) ), }, validate.get("included")) video_schema = validate.Schema( validate.transform(parse_json), {"data": data_schema}, validate.get("data"), validate.get("attributes")) @classmethod def can_handle_url(cls, url): return cls.url_re.match(url) is not None def _get_live_stream(self, channel): url = self.channel_api.format(name=channel) self.logger.debug("Channel API call: {0}", url) data = http.get(url, schema=self.channel_schema) self.logger.debug("Got {0} channel playback items", len(data)) for playback in data: for s in HLSStream.parse_variant_playlist(self.session, playback["uri"]).items(): yield s def _get_video_stream(self, video_id): url = self.video_api.format(id=video_id) self.logger.debug("Video API call: {0}", url) data = http.get(url, schema=self.video_schema) self.logger.debug("Got video {0} playback items", len(data["playback"])) res = data["resolution"]["height"] for playback in data["playback"]: yield "{0}p".format(res), HTTPStream(self.session, playback["uri"]) def _get_streams(self): match = self.url_re.match(self.url) self.logger.debug("Matched URL: name={name}, video_id={video_id}", **match.groupdict()) if match.group("video_id"): return self._get_video_stream(match.group("video_id")) elif match.group("name"): return self._get_live_stream(match.group("name"))
def _get_streams(self): params = self.session.http.get( self.url, schema=validate.Schema( validate.transform(self._re_player_manager.search), validate.any( None, validate.all( validate.get("json"), validate.parse_json(), { "contentId": validate.any(str, int), validate.optional("streamId"): str, validate.optional("idec"): str, validate.optional("token"): str })))) if not params: log.error("Could not find player manager data") return params.update({ "video": (unquote(params.pop("token")) if params.get("token") is not None else params.pop("streamId")), "noflash": "yes", "embedded": "0", }) url_parsed = urlparse(self.url) skip_vods = url_parsed.netloc.endswith( "m4sport.hu") and url_parsed.path.startswith("/elo") self.session.http.headers.update({"Referer": self.url}) playlists = self.session.http.get( self.PLAYER_URL, params=params, schema=validate.Schema( validate.transform(self._re_player_json.search), validate.any( None, validate.all( validate.get("json"), validate.parse_json(), {"playlist": [{ "file": validate.url(), "type": str }]}, validate.get("playlist"), validate.filter(lambda p: p["type"] == "hls"), validate.filter( lambda p: not skip_vods or "vod" not in p["file"]), validate.map( lambda p: update_scheme("https://", p["file"])))))) for url in playlists or []: yield from HLSStream.parse_variant_playlist(self.session, url).items()
class Welt(Plugin): _url_vod = "https://www.welt.de/onward/video/token/{0}" _re_url = re.compile(r"""https?://(\w+\.)?welt\.de/?""", re.IGNORECASE) _re_url_vod = re.compile(r"""mediathek""", re.IGNORECASE) _re_json = re.compile( r""" <script>\s* var\s+funkotron\s*=\s* \{\s* config\s*:\s*(?P<json>\{.+?\})\s* \}\s*;?\s* </script> """, re.VERBOSE | re.DOTALL | re.IGNORECASE) _schema = validate.Schema(validate.transform(_re_json.search), validate.get("json"), validate.transform(parse_json), validate.get("page"), validate.get("content"), validate.get("media"), validate.get(0), validate.get("sources"), validate.map(lambda obj: obj["file"]), validate.filter(_filter_url), validate.get(0)) _schema_url = validate.Schema( validate.url(scheme="https", path=validate.endswith(".m3u8"))) _schema_vod = validate.Schema(validate.transform(parse_json), validate.get("urlWithToken"), _schema_url) @classmethod def can_handle_url(cls, url): return cls._re_url.match(url) is not None def __init__(self, url): Plugin.__init__(self, url) self.url = url self.isVod = self._re_url_vod.search(url) is not None def _get_streams(self): headers = {"User-Agent": useragents.CHROME} hls_url = self.session.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 = self.session.http.get(url, headers=headers, schema=self._schema_vod) return HLSStream.parse_variant_playlist(self.session, hls_url, headers=headers)
def __init__(self, url: str): super().__init__(url) self._json_data_re = re.compile(r'teliaPlayer\((\{.*?\})\);', re.DOTALL) self.main_page_schema = validate.Schema( validate.parse_html(), validate.xml_xpath_string( ".//iframe[contains(@src, 'ltv.lsm.lv/embed')][1]/@src"), validate.url()) self.embed_code_schema = validate.Schema( validate.parse_html(), validate.xml_xpath_string(".//live[1]/@*[name()=':embed-data']"), str, validate.parse_json(), {"source": { "embed_code": str }}, validate.get(("source", "embed_code")), validate.parse_html(), validate.xml_xpath_string(".//iframe[@src][1]/@src"), ) self.player_apicall_schema = validate.Schema( validate.transform(self._json_data_re.search), validate.any( None, validate.all( validate.get(1), validate.transform(lambda s: s.replace("'", '"')), validate.transform( lambda s: re.sub(r",\s*\}", "}", s, flags=re.DOTALL)), validate.parse_json(), {"channel": str}, validate.get("channel")))) self.sources_schema = validate.Schema( validate.parse_json(), { "source": { "sources": validate.all([{ "type": str, "src": validate.url() }], validate.filter(lambda src: src["type"] == "application/x-mpegURL"), validate.map(lambda src: src.get("src"))), } }, validate.get(("source", "sources")))
def test_map(self): assert validate(map(lambda v: v[0]), [(1, 2), (3, 4)]) == [1, 3]
"14": "block_time", "16": "reconnect_time", "20": "multibitrate", "73": "token" } BLOCKED_MSG_FORMAT = ( "You have crossed the free viewing limit. You have been blocked for " "{0} minutes. Try again in {1} minutes" ) BLOCK_TYPE_VIEWING_LIMIT = 1 BLOCK_TYPE_NO_SLOTS = 11 _url_re = re.compile(r"http(s)?://(\w+\.)?weeb.tv/(channel|online)/(?P<channel>[^/&?]+)") _schema = validate.Schema( dict, validate.map(lambda k, v: (PARAMS_KEY_MAP.get(k, k), v)), validate.any( { "status": validate.transform(int), "rtmp": validate.url(scheme="rtmp"), "playpath": validate.text, "multibitrate": validate.all( validate.transform(int), validate.transform(bool) ), "block_type": validate.transform(int), validate.optional("token"): validate.text, validate.optional("block_time"): validate.text, validate.optional("reconnect_time"): validate.text, }, {
from streamlink.stream import HLSStream, HDSStream STREAM_INFO_URL = "http://live.daserste.de/{0}/livestream.xml" SWF_URL = "http://live.daserste.de/lib/br-player/swf/main.swf" STREAMING_TYPES = { "streamingUrlLive": ("HDS", partial(HDSStream.parse_manifest, pvswf=SWF_URL)), "streamingUrlIPhone": ("HLS", HLSStream.parse_variant_playlist) } _url_re = re.compile(r"http(s)?://live.daserste.de/(?P<channel>[^/?]+)?") _livestream_schema = validate.Schema( validate.xml_findall("video/*"), validate.filter(lambda e: e.tag in STREAMING_TYPES), validate.map(lambda e: (STREAMING_TYPES.get(e.tag), e.text)), validate.transform(dict), ) class ard_live(Plugin): @classmethod def can_handle_url(cls, url): return _url_re.match(url) def _get_streams(self): match = _url_re.match(self.url) channel = match.group("channel") res = http.get(STREAM_INFO_URL.format(channel)) urls = http.xml(res, schema=_livestream_schema)
from streamlink.stream.file import FileStream HDCORE_VERSION = "3.2.0" _url_re = re.compile(r"https?://www.daisuki.net/[^/]+/[^/]+/anime/watch\..+") _flashvars_re = re.compile(r"var\s+flashvars\s*=\s*\{([^}]*?)};", re.DOTALL) _flashvar_re = re.compile(r"""(['"])(.*?)\1\s*:\s*(['"])(.*?)\3""") _clientlibs_re = re.compile(r"""<script.*?src=(['"])(.*?/clientlibs_anime_watch.*?\.js)\1""") _schema = validate.Schema( validate.union({ "flashvars": validate.all( validate.transform(_flashvars_re.search), validate.get(1), validate.transform(_flashvar_re.findall), validate.map(lambda v: (v[1], v[3])), validate.transform(dict), { "s": validate.text, "country": validate.text, "init": validate.text, validate.optional("ss_id"): validate.text, validate.optional("mv_id"): validate.text, validate.optional("device_cd"): validate.text, validate.optional("ss1_prm"): validate.text, validate.optional("ss2_prm"): validate.text, validate.optional("ss3_prm"): validate.text } ), "clientlibs": validate.all( validate.transform(_clientlibs_re.search),
"13": "block_type", "14": "block_time", "16": "reconnect_time", "20": "multibitrate", "73": "token" } BLOCKED_MSG_FORMAT = ( "You have crossed the free viewing limit. You have been blocked for " "{0} minutes. Try again in {1} minutes") BLOCK_TYPE_VIEWING_LIMIT = 1 BLOCK_TYPE_NO_SLOTS = 11 _url_re = re.compile( r"http(s)?://(\w+\.)?weeb.tv/(channel|online)/(?P<channel>[^/&?]+)") _schema = validate.Schema( dict, validate.map(lambda k, v: (PARAMS_KEY_MAP.get(k, k), v)), validate.any( { "status": validate.transform(int), "rtmp": validate.url(scheme="rtmp"), "playpath": validate.text, "multibitrate": validate.all(validate.transform(int), validate.transform(bool)), "block_type": validate.transform(int), validate.optional("token"): validate.text, validate.optional("block_time"):
http(s)?://(\w+\.)?aliez.tv (?: /live/[^/]+ )? (?: /video/\d+/[^/]+ )? """, re.VERBOSE) _file_re = re.compile("\"?file\"?:\s+['\"]([^'\"]+)['\"]") _swf_url_re = re.compile("swfobject.embedSWF\(\"([^\"]+)\",") _schema = validate.Schema( validate.union({ "urls": validate.all( validate.transform(_file_re.findall), validate.map(unquote), [validate.url()] ), "swf": validate.all( validate.transform(_swf_url_re.search), validate.any( None, validate.all( validate.get(1), validate.url( scheme="http", path=validate.endswith("swf") ) ) ) )
SWF_URL = "http://live.daserste.de/lib/br-player/swf/main.swf" STREAMING_TYPES = { "streamingUrlLive": ( "HDS", partial(HDSStream.parse_manifest, pvswf=SWF_URL) ), "streamingUrlIPhone": ( "HLS", HLSStream.parse_variant_playlist ) } _url_re = re.compile("http(s)?://live.daserste.de/(?P<channel>[^/?]+)?") _livestream_schema = validate.Schema( validate.xml_findall("video/*"), validate.filter(lambda e: e.tag in STREAMING_TYPES), validate.map(lambda e: (STREAMING_TYPES.get(e.tag), e.text)), validate.transform(dict), ) class ard_live(Plugin): @classmethod def can_handle_url(cls, url): return _url_re.match(url) def _get_streams(self): match = _url_re.match(self.url) channel = match.group("channel") res = http.get(STREAM_INFO_URL.format(channel)) urls = http.xml(res, schema=_livestream_schema) streams = {}
def test_map_dict(self): assert validate(map(lambda k, v: (v, k)), {"foo": "bar"}) == { "bar": "foo" }
ASSET_URL = "http://prima.tv4play.se/api/web/asset/{0}/play" SWF_URL = "http://www.tv4play.se/flash/tv4video.swf" _url_re = re.compile( """ http(s)?://(www\.)? (?: tv4play.se/program/[^\?/]+| fotbollskanalen.se/video ) .+(video_id|videoid)=(?P<video_id>\d+) """, re.VERBOSE) _asset_schema = validate.Schema(validate.xml_findall("items/item"), [ validate.all( validate.xml_findall("*"), validate.map(lambda e: (e.tag, e.text)), validate.transform(dict), { "base": validate.text, "bitrate": validate.all(validate.text, validate.transform(int)), "url": validate.text }) ]) class TV4Play(Plugin): @classmethod def can_handle_url(cls, url): return _url_re.match(url) def _get_streams(self): match = _url_re.match(self.url)
HDCORE_VERSION = "3.2.0" _url_re = re.compile(r"https?://www.daisuki.net/[^/]+/[^/]+/anime/watch\..+") _flashvars_re = re.compile(r"var\s+flashvars\s*=\s*\{([^}]*?)};", re.DOTALL) _flashvar_re = re.compile(r"""(['"])(.*?)\1\s*:\s*(['"])(.*?)\3""") _clientlibs_re = re.compile( r"""<script.*?src=(['"])(.*?/clientlibs_anime_watch.*?\.js)\1""") _schema = validate.Schema( validate.union({ "flashvars": validate.all( validate.transform(_flashvars_re.search), validate.get(1), validate.transform(_flashvar_re.findall), validate.map(lambda v: (v[1], v[3])), validate.transform(dict), { "s": validate.text, "country": validate.text, "init": validate.text, validate.optional("ss_id"): validate.text, validate.optional("mv_id"): validate.text, validate.optional("device_cd"): validate.text, validate.optional("ss1_prm"): validate.text, validate.optional("ss2_prm"): validate.text, validate.optional("ss3_prm"): validate.text }), "clientlibs": validate.all(validate.transform(_clientlibs_re.search), validate.get(2), validate.text) }))
def test_sequence(self): schema = validate.map(lambda k: k + 1) value = (0, 1, 2, 3) assert validate.validate(schema, value) == (1, 2, 3, 4)
def test_dict(self): schema = validate.map(lambda k, v: (k + 1, v + 1)) value = {0: 0, 1: 1, 2: 0, 3: 1} assert validate.validate(schema, value) == {1: 1, 2: 2, 3: 1, 4: 2}
from streamlink.plugin import Plugin from streamlink.plugin.api import http, validate from streamlink.stream import HTTPStream, RTMPStream _url_re = re.compile(r""" https?://(\w+\.)?aliez.\w+/ (?:live/[^/]+|video/\d+/[^/]+) """, re.VERBOSE) _file_re = re.compile(r"\"?file\"?:\s+['\"]([^'\"]+)['\"]") _swf_url_re = re.compile(r"swfobject.embedSWF\(\"([^\"]+)\",") _schema = validate.Schema( validate.union({ "urls": validate.all( validate.transform(_file_re.findall), validate.map(unquote), [validate.url()] ), "swf": validate.all( validate.transform(_swf_url_re.search), validate.any( None, validate.all( validate.get(1), validate.url( scheme="http", path=validate.endswith("swf") ) ) ) )
def test_map_dict(self): assert validate(map(lambda k, v: (v, k)), {"foo": "bar"}) == {"bar": "foo"}
from streamlink.plugin.api import validate from streamlink.stream import HTTPStream, RTMPStream _url_re = re.compile( r""" https?://(\w+\.)?aliez.\w+/ (?:live/[^/]+|video/\d+/[^/]+) """, re.VERBOSE) _file_re = re.compile(r"\"?file\"?:\s+['\"]([^'\"]+)['\"]") _swf_url_re = re.compile(r"swfobject.embedSWF\(\"([^\"]+)\",") _schema = validate.Schema( validate.union({ "urls": validate.all(validate.transform(_file_re.findall), validate.map(unquote), [validate.url()]), "swf": validate.all( validate.transform(_swf_url_re.search), validate.any( None, validate.all( validate.get(1), validate.url(scheme="http", path=validate.endswith("swf"))))) })) class Aliez(Plugin): @classmethod def can_handle_url(self, url):
_url_re = re.compile(r""" http(s)?://(www\.)? (?: tv4play.se/program/[^\?/]+| fotbollskanalen.se/video ) .+(video_id|videoid)=(?P<video_id>\d+) """, re.VERBOSE) _asset_schema = validate.Schema( validate.xml_findall("items/item"), [ validate.all( validate.xml_findall("*"), validate.map(lambda e: (e.tag, e.text)), validate.transform(dict), { "base": validate.text, "bitrate": validate.all( validate.text, validate.transform(int) ), "url": validate.text } ) ] ) class TV4Play(Plugin): @classmethod