validate.optional("data"): object, }) _media_schema = validate.Schema( { "stream_data": validate.any( None, { "streams": validate.all( [{ "quality": validate.text, "url": validate.url( scheme="http", path=validate.endswith(".m3u8") ) }], validate.filter(lambda s: s["quality"] != "adaptive") ) } ) }, validate.get("stream_data") ) _login_schema = validate.Schema({ "auth": validate.text, "expires": validate.all( validate.text, validate.transform(parse_timestamp) ), "user": { "username": validate.text }
/(?P<media_id>[^_?/]+) """, re.VERBOSE, ) _media_inner_schema = validate.Schema( [ { "layerList": [ { "name": validate.text, validate.optional("sequenceList"): [ { "layerList": validate.all( [{"name": validate.text, validate.optional("param"): dict}], validate.filter(lambda l: l["name"] in ("video", "reporting")), ) } ], } ] } ] ) _media_schema = validate.Schema( validate.any(_media_inner_schema, validate.all({"sequence": _media_inner_schema}, validate.get("sequence"))) ) _vod_playlist_schema = validate.Schema({"duration": float, "fragments": [[int, float]], "template": validate.text}) _vod_manifest_schema = validate.Schema( {"alternates": [{"height": int, "template": validate.text, validate.optional("failover"): [validate.text]}]} )
} _stream_id_re = re.compile( r"<meta content='.+/([\w_-]+).+' property='og:video'>") _url_re = re.compile("http(s)?://(\w+\.)?(majorleaguegaming\.com|mlg\.tv)") _config_schema = validate.Schema({"media": [{"channel": validate.text}]}) _stream_schema = validate.Schema( { "data": { "items": validate.all([{ "format": validate.text, "url": validate.text }], validate.filter(lambda s: s["format"] in STREAM_TYPES)) } }, validate.get("data", {}), validate.get("items", [])) class MLGTV(Plugin): @classmethod def can_handle_url(self, url): return _url_re.match(url) def _find_channel_id(self, text): match = _stream_id_re.search(text) if match: return match.group(1) def _get_stream_id(self, channel_id):
validate.transform(int), validate.transform(bool) ), "media_id": validate.text }], }, validate.get("livestream"), validate.length(1), validate.get(0) ) _player_schema = validate.Schema( { "clip": { "baseUrl": validate.any(None, validate.text), "bitrates": validate.all( validate.filter(lambda b: b.get("url") and b.get("label")), [{ "label": validate.text, "url": validate.text, }], ) }, validate.optional("playlist"): [{ validate.optional("connectionProvider"): validate.text, validate.optional("netConnectionUrl"): validate.text, validate.optional("bitrates"): [{ "label": validate.text, "url": validate.text, "provider": validate.text }] }],
# For now we only handle MP4. STREAM_FORMATS = "mp4" INFO_URL = "http://www.vgtv.no/data/actions/videostatus/" _url_re = re.compile("https?://(www\.)?(vgtv|vg).no") _content_id_re = re.compile('(?:data-videoid="|videostatus/\?id=)(\d+)') _url_id_re = re.compile(("https?://(?:www\.)?vgtv.no/" "(?:(?:#!/)?video/|(?:#!|\?)id=)(\d+)")) _video_schema = validate.Schema( { "status": 200, "formats": validate.all( dict, validate.filter(lambda k, v: k in STREAM_TYPES), { validate.text: validate.all( dict, validate.filter(lambda k, v: k in STREAM_FORMATS), { validate.text: [ { "bitrate": int, "paths": [ { "address": validate.text, "port": int, "path": validate.text, "filename": validate.text, "application": validate.text,
from livestreamer.plugin import Plugin from livestreamer.plugin.api import http, validate from livestreamer.stream import HDSStream API_URL = "http://api.sh.nhk.fivecool.tv/api/cdn/?publicId=3bz2huey&playerId=7Dy" _url_re = re.compile("http(s)?://(\w+\.)?nhk.or.jp/nhkworld") _schema = validate.Schema({ "live-streams": [{ "streams": validate.all([{ "protocol": validate.text, "streamUrl": validate.text }], validate.filter(lambda s: s["protocol"] in ("http-flash", "http-hds"))) }] }) class NHKWorld(Plugin): @classmethod def can_handle_url(cls, url): return _url_re.match(url) def _get_streams(self): res = http.get(API_URL) data = http.json(res, schema=_schema) streams = {} for livestreams in data["live-streams"]:
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("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)
# For now we only handle MP4. STREAM_FORMATS = ("mp4") INFO_URL = "http://www.vgtv.no/data/actions/videostatus/" _url_re = re.compile("https?://(www\.)?(vgtv|vg).no") _content_id_re = re.compile("(?:data-videoid=\"|videostatus/\?id=)(\d+)") _url_id_re = re.compile(("https?://(?:www\.)?vgtv.no/" "(?:(?:#!/)?video/|(?:#!|\?)id=)(\d+)")) _video_schema = validate.Schema({ "status": 200, "formats": validate.all( dict, validate.filter(lambda k, v: k in STREAM_TYPES), { validate.text: validate.all( dict, validate.filter(lambda k, v: k in STREAM_FORMATS), { validate.text: [{ "bitrate": int, "paths": [{ "address": validate.text, "port": int, "path": validate.text, "filename": validate.text, "application": validate.text, }], }] })
"media": { "stream_name": validate.text } }, validate.get("media", {}), validate.get("stream_name") ) _stream_schema = validate.Schema( { "data": { "items": validate.all( [{ "format": validate.text, "url": validate.text }], validate.filter(lambda s: s["format"] in STREAM_TYPES) ) } }, validate.get("data", {}), validate.get("items", []) ) class MLGTV(Plugin): @classmethod def can_handle_url(self, url): return _url_re.match(url) def _find_channel_id(self, text): match = _stream_id_re.search(text)
def test_filter(self): assert validate(filter(lambda i: i > 5), [10,5,4,6,7]) == [10,6,7]
from livestreamer.plugin.api import http, validate from livestreamer.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("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)
validate.all([{ "LinkType": validate.text, "Qualities": [ validate.all( { "Streams": validate.all([ validate.all({"Stream": validate.text}, validate.get("Stream")) ], validate.get(0)) }, validate.get("Streams")) ], "Server": validate.text }], validate.filter(lambda s: s["LinkType"] in STREAMING_TYPES)) }] }, validate.get("Data", {})) _video_schema = validate.Schema( { "Data": [{ "Assets": validate.all([{ validate.optional("Links"): validate.all([{ "Target": validate.text, "Uri": validate.text }], validate.filter(lambda l: l["Target"] in STREAMING_TYPES)) }], validate.filter(lambda a: "Links" in a)) }]
def test_filter(self): assert validate(filter(lambda i: i > 5), [10, 5, 4, 6, 7]) == [10, 6, 7]
{ "token": validate.text, "sig": validate.text }, validate.union(( validate.get("sig"), validate.get("token") )) ) _token_schema = validate.Schema( { "chansub": { "restricted_bitrates": validate.all( [validate.text], validate.filter( lambda n: not re.match(r"(.+_)?archives|live|chunked", n) ) ) } }, validate.get("chansub") ) _viewer_info_schema = validate.Schema( { validate.optional("login"): validate.text }, validate.get("login") ) _viewer_token_schema = validate.Schema( { validate.optional("token"): validate.text
http(s)?://(\w+\.)? dailymotion.com (/embed)?/(video|live) /(?P<media_id>[^_?/]+) """, re.VERBOSE) _media_inner_schema = validate.Schema([{ "layerList": [{ "name": validate.text, validate.optional("sequenceList"): [{ "layerList": validate.all([{ "name": validate.text, validate.optional("param"): dict }], validate.filter(lambda l: l["name"] in ("video", "reporting"))) }] }] }]) _media_schema = validate.Schema( validate.any( _media_inner_schema, validate.all({"sequence": _media_inner_schema}, validate.get("sequence")))) _vod_playlist_schema = validate.Schema({ "duration": float, "fragments": [[int, float]], "template": validate.text }) _vod_manifest_schema = validate.Schema({ "alternates": [{
validate.transform(int), validate.transform(bool) ), "media_id": validate.text }], }, validate.get("livestream"), validate.length(1), validate.get(0) ) _player_schema = validate.Schema( { "clip": { "baseUrl": validate.any(None, validate.text), "bitrates": validate.all( validate.filter(lambda b: b.get("url") and b.get("label")), [{ "label": validate.text, "url": validate.text }], ) }, validate.optional("playlist"): [{ validate.optional("connectionProvider"): validate.text, validate.optional("netConnectionUrl"): validate.text, validate.optional("bitrates"): [{ "label": validate.text, "url": validate.text }] }], "plugins": {
svtplay | svtflow | oppetarkiv ) .se """, re.VERBOSE) _video_schema = validate.Schema( { "video": { "videoReferences": validate.all( [{ "url": validate.text, "playerType": validate.text }], validate.filter(lambda r: r["playerType"] in STREAM_TYPES) ), } }, validate.get("video"), validate.get("videoReferences") ) class SVTPlay(Plugin): @classmethod def can_handle_url(self, url): return _url_re.match(url) def _get_streams(self): res = http.get(self.url, params=dict(output="json"))
{ "livestream": [{ "media_is_live": validate.all(validate.text, validate.transform(int), validate.transform(bool)), "media_id": validate.text }], }, validate.get("livestream"), validate.length(1), validate.get(0)) _player_schema = validate.Schema({ "clip": { "baseUrl": validate.any(None, validate.text), "bitrates": validate.all( validate.filter(lambda b: b.get("url") and b.get("label")), [{ "label": validate.text, "url": validate.text }], ) }, validate.optional("playlist"): [{ validate.optional("connectionProvider"): validate.text, validate.optional("netConnectionUrl"): validate.text, validate.optional("bitrates"): [{ "label": validate.text, "url": validate.text }]
from livestreamer.plugin import Plugin from livestreamer.plugin.api import http, validate from livestreamer.stream import HDSStream API_URL = "http://api.sh.nhk.fivecool.tv/api/cdn/?publicId=3bz2huey&playerId=7Dy" _url_re = re.compile("http(s)?://(\w+\.)?nhk.or.jp/nhkworld") _schema = validate.Schema({ "live-streams": [{ "streams": validate.all( [{ "protocol": validate.text, "streamUrl": validate.text }], validate.filter(lambda s: s["protocol"] in ("http-flash", "http-hds")) ) }] }) class NHKWorld(Plugin): @classmethod def can_handle_url(cls, url): return _url_re.match(url) def _get_streams(self): res = http.get(API_URL) data = http.json(res, schema=_schema) streams = {}
{ "livestream": [{ "media_is_live": validate.all(validate.text, validate.transform(int), validate.transform(bool)), "media_id": validate.text }], }, validate.get("livestream"), validate.length(1), validate.get(0)) _player_schema = validate.Schema({ "clip": { "baseUrl": validate.any(None, validate.text), "bitrates": validate.all( validate.filter(lambda b: b.get("url") and b.get("label")), [{ "label": validate.text, "url": validate.text, }], ) }, validate.optional("playlist"): [{ validate.optional("connectionProvider"): validate.text, validate.optional("netConnectionUrl"): validate.text, validate.optional("bitrates"): [{ "label": validate.text, "url": validate.text, "provider": validate.text
(?: svtplay | svtflow | oppetarkiv ) .se """, re.VERBOSE) _video_schema = validate.Schema( { "video": { "videoReferences": validate.all([{ "url": validate.text, "playerType": validate.text }], validate.filter(lambda r: r["playerType"] in STREAM_TYPES)), } }, validate.get("video"), validate.get("videoReferences")) class SVTPlay(Plugin): @classmethod def can_handle_url(self, url): return _url_re.match(url) def _get_streams(self): res = http.get(self.url, params=dict(output="json")) videos = http.json(res, schema=_video_schema) streams = {} for video in videos: url = video["url"]
tv(3|6|8|10)play | viasat4play ) \. (?: dk|ee|lt|lv|no|se|com ) /.+/ (?P<stream_id>\d+) """, re.VERBOSE) _stream_schema = validate.Schema( { "streams": validate.all( {validate.text: validate.any(validate.text, int, None)}, validate.filter(lambda k, v: isinstance(v, validate.text)) ) }, validate.get("streams") ) class Viasat(Plugin): @classmethod def can_handle_url(cls, url): return _url_re.match(url) def _get_swf_url(self): res = http.get(self.url) match = _swf_url_re.search(res.text) if not match:
play.tv3 ) \. (?: dk|ee|lt|lv|no|se|com ) (/.+?/|/embed\?id=) (?P<stream_id>\d+) """, re.VERBOSE) _stream_schema = validate.Schema( { "streams": validate.all( {validate.text: validate.any(validate.text, int, None)}, validate.filter(lambda k, v: isinstance(v, validate.text))) }, validate.get("streams")) class Viasat(Plugin): @classmethod def can_handle_url(cls, url): return _url_re.match(url) def _get_swf_url(self): res = http.get(self.url) match = _swf_url_re.search(res.text) if not match: raise PluginError("Unable to find SWF URL in the HTML") return match.group(1)
"LinkType": validate.text, "Qualities": [ validate.all( { "Streams": validate.all( [validate.all({"Stream": validate.text}, validate.get("Stream"))], validate.get(0), ) }, validate.get("Streams"), ) ], "Server": validate.text, } ], validate.filter(lambda s: s["LinkType"] in STREAMING_TYPES), ), } ] }, validate.get("Data", {}), ) _video_schema = validate.Schema( { "Data": [ { "Assets": validate.all( [ { validate.optional("Links"): validate.all(