from livestreamer.stream import HTTPStream API_URL = "http://www.douyutv.com/api/client/room/{0}" _url_re = re.compile( """ http(s)?://(www\.)?douyutv.com /(?P<channel>[^/]+) """, re.VERBOSE) _room_schema = validate.Schema( { "data": validate.any( None, { "show_status": validate.all(validate.text, validate.transform(int)), "rtmp_url": validate.text, "rtmp_live": validate.text }) }, validate.get("data")) class Douyutv(Plugin): @classmethod def can_handle_url(self, url): return _url_re.match(url) def _get_streams(self): match = _url_re.match(self.url) channel = match.group("channel")
import re from livestreamer.plugin import Plugin from livestreamer.plugin.api import http, validate from livestreamer.stream import HLSStream _url_re = re.compile("http(s)?://chaturbate.com/[^/?&]+") _playlist_url_re = re.compile("html \+= \"src='(?P<url>[^']+)'\";") _schema = validate.Schema( validate.transform(_playlist_url_re.search), validate.any( None, validate.all( validate.get("url"), validate.url( scheme="http", path=validate.endswith(".m3u8") ) ) ) ) class Chaturbate(Plugin): @classmethod def can_handle_url(self, url): return _url_re.match(url) def _get_streams(self): playlist_url = http.get(self.url, schema=_schema) if not playlist_url:
SHOW_STATUS_OFFLINE = 2 STREAM_WEIGHTS = {"middle": 540, "source": 1080} _url_re = re.compile( """ http(s)?://(www\.)?douyutv.com /(?P<channel>[^/]+) """, re.VERBOSE) _room_schema = validate.Schema( { "data": validate.any( None, { "show_status": validate.all(validate.text, validate.transform(int)), "rtmp_url": validate.text, "rtmp_live": validate.text, "rtmp_multi_bitrate": validate.all(validate.any([], {validate.text: validate.text}), validate.transform(dict)) }) }, validate.get("data")) class Douyutv(Plugin): @classmethod def can_handle_url(self, url): return _url_re.match(url)
import re from livestreamer.plugin import Plugin from livestreamer.plugin.api import http, validate from livestreamer.stream import RTMPStream _url_re = re.compile("http(s)?://(\w+.)?beam.pro/(?P<channel>[^/]+)") CHANNEL_INFO = "https://beam.pro/api/v1/channels/{0}" CHANNEL_MANIFEST = "https://beam.pro/api/v1/channels/{0}/manifest.smil" _assets_schema = validate.Schema( validate.union({ "base": validate.all( validate.xml_find("./head/meta"), validate.get("base"), validate.url(scheme="rtmp") ), "videos": validate.all( validate.xml_findall(".//video"), [ validate.union({ "src": validate.all( validate.get("src"), validate.text ), "height": validate.all( validate.get("height"), validate.text, validate.transform(int) )
http(s)?://(\w+\.)? (?P<domain>vaughnlive|breakers|instagib|vapers).tv /(?P<channel>[^/&?]+) """, re.VERBOSE) _channel_not_found_re = re.compile("<title>Channel Not Found") def decode_token(token): return token.replace("0m0", "") _schema = validate.Schema( validate.transform(lambda s: s.split(";:mvnkey-")), validate.length(2), validate.union({ "server": validate.all( validate.get(0), validate.text ), "token": validate.all( validate.get(1), validate.text, validate.transform(decode_token) ) }) ) class VaughnLive(Plugin): @classmethod def can_handle_url(cls, url): return _url_re.match(url)
_access_token_schema = validate.Schema( { "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
_live_schema = validate.Schema({ validate.any("primary", "secondary"): { validate.text: { "rtmp_flash": { validate.text: { "name": validate.text, "server": validate.url(scheme="rtmp") } } } } }) _schema = validate.Schema( validate.union({ "lang": validate.all(validate.transform(_lang_re.search), validate.get(1)), "live": validate.all(validate.transform(_live_check_re.search), validate.transform(bool)), "videos": validate.all(validate.transform(_video_re.findall), [(validate.url(scheme="http"), validate.text)]) })) class Euronews(Plugin): @classmethod def can_handle_url(self, url): return _url_re.match(url) def _get_live_streams(self, lang):
"<embed width=\"486\" height=\"326\" flashvars=\"([^\"]+)\"" ) _live_schema = validate.Schema({ "streams": [{ "name": validate.text, "quality": validate.text, "url": validate.url(scheme="rtmp") }] }) _schema = validate.Schema( validate.union({ "export_url": validate.all( validate.transform(_live_export_re.search), validate.any( None, validate.get(1), ) ), "video_flashvars": validate.all( validate.transform(_video_flashvars_re.search), validate.any( None, validate.all( validate.get(1), validate.transform(parse_query), { "_111pix_serverURL": validate.url(scheme="rtmp"), "en_flash_providerName": validate.text } )
def test_all(self): assert validate(all(int, lambda n: 0 < n < 5), 3) == 3 assert validate(all(transform(int), lambda n: 0 < n < 5), 3.33) == 3
from livestreamer.stream import RTMPStream BALANCER_URL = "http://www.mips.tv:1935/loadbalancer" PLAYER_URL = "http://mips.tv/embedplayer/{0}/1/500/400" SWF_URL = "http://mips.tv/content/scripts/eplayer.swf" _url_re = re.compile("http(s)?://(\w+.)?mips.tv/(?P<channel>[^/&?]+)") _flashvars_re = re.compile("'FlashVars', '([^']+)'") _rtmp_re = re.compile("redirect=(.+)") _schema = validate.Schema( validate.transform(_flashvars_re.search), validate.any( None, validate.all(validate.get(1), validate.transform(parse_query), { "id": validate.transform(int), validate.optional("s"): validate.text }))) _rtmp_schema = validate.Schema( validate.transform(_rtmp_re.search), validate.get(1), ) class Mips(Plugin): @classmethod def can_handle_url(self, url): return _url_re.match(url) def _get_streams(self): match = _url_re.match(self.url) channel = match.group("channel")
_player_config_schema = validate.Schema( { "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)
from livestreamer.stream import RTMPStream RTMP_URL = "rtmp://{0}/app/{1}" CHANNEL_DETAILS_URI = "https://api.streamup.com/1.0/channels/{0}?access_token={1}" REDIRECT_SERVICE_URI = "https://lancer.streamup.com/api/redirect/{0}" _url_re = re.compile("http(s)?://(\w+\.)?streamup.com/(?P<channel>[^/?]+)") _flashvars_re = re.compile("flashvars\.(?P<var>\w+)\s?=\s?'(?P<value>[^']+)';") _swf_url_re = re.compile("swfobject.embedSWF\(\s*\"(?P<player_url>[^\"]+)\",") _schema = validate.Schema( validate.union({ "vars": validate.all(validate.transform(_flashvars_re.findall), validate.transform(dict), { "owner": validate.text, validate.optional("token"): validate.text }), "swf": validate.all(validate.transform(_swf_url_re.search), validate.get("player_url"), validate.endswith(".swf")) })) _channel_details_schema = validate.Schema( {"channel": { "live": bool, "slug": validate.text }}) class StreamupCom(Plugin):
BALANCER_URL = "http://www.mips.tv:1935/loadbalancer" PLAYER_URL = "http://mips.tv/embedplayer/{0}/1/500/400" SWF_URL = "http://mips.tv/content/scripts/eplayer.swf" _url_re = re.compile("http(s)?://(\w+.)?mips.tv/(?P<channel>[^/&?]+)") _flashvars_re = re.compile("'FlashVars', '([^']+)'") _rtmp_re = re.compile("redirect=(.+)") _schema = validate.Schema( validate.transform(_flashvars_re.search), validate.any( None, validate.all( validate.get(1), validate.transform(parse_query), { "id": validate.transform(int), validate.optional("s"): validate.text } ) ) ) _rtmp_schema = validate.Schema( validate.transform(_rtmp_re.search), validate.get(1), ) class Mips(Plugin): @classmethod def can_handle_url(self, url): return _url_re.match(url)
_token_schema = validate.Schema( { "token": validate.text }, validate.get("token") ) _schema = validate.Schema( validate.transform(_rtmp_re.search), validate.any( None, validate.all( validate.transform(methodcaller("groupdict")), { "rtmp_playpath": validate.text, "rtmp_url": validate.all( validate.transform(methodcaller("replace", "\\/", "/")), validate.url(scheme="rtmp"), ), "swf_url": validate.url(scheme="http"), "token_url": validate.url(scheme="http") } ) ) ) class ILive(Plugin): @classmethod def can_handle_url(self, url): return _url_re.match(url) def _get_streams(self):
def parse_fmt_list(formatsmap): formats = {} if not formatsmap: return formats for format in formatsmap.split(","): s = format.split("/") (w, h) = s[1].split("x") formats[int(s[0])] = "{0}p".format(h) return formats _config_schema = validate.Schema({ validate.optional("fmt_list"): validate.all(validate.text, validate.transform(parse_fmt_list)), validate.optional("url_encoded_fmt_stream_map"): validate.all(validate.text, validate.transform(parse_stream_map), [{ "itag": validate.all(validate.text, validate.transform(int)), "quality": validate.text, "url": validate.url(scheme="http"), validate.optional("s"): validate.text, validate.optional("stereo3d"): validate.all(validate.text, validate.transform(int), validate.transform(bool)), }]), validate.optional("adaptive_fmts"):
def test_list(self): assert validate([1, 0], [1, 0, 1, 1]) == [1, 0, 1, 1] assert validate([1, 0], []) == [] assert validate(all([0, 1], lambda l: len(l) > 2), [0, 1, 0]) == [0, 1, 0]
(/embed)?/video /(?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]}]} )
import re from itertools import chain from livestreamer.compat import urlparse from livestreamer.plugin import Plugin from livestreamer.plugin.api import http, validate from livestreamer.stream import HLSStream, HTTPStream, RTMPStream SWF_URL = "http://www.arte.tv/player/v2/jwplayer6/mediaplayer.6.6.swf" _url_re = re.compile("http(s)?://(\w+\.)?arte.tv/") _json_re = re.compile('arte_vp_(?:live-)?url="([^"]+)"') _schema = validate.Schema( validate.transform(_json_re.search), validate.any(None, validate.all(validate.get(1), validate.url(scheme="http"))) ) _video_schema = validate.Schema( { "videoJsonPlayer": { "VSR": validate.any( [], { validate.text: { "height": int, "mediaType": validate.text, "url": validate.text, validate.optional("streamer"): validate.text, } }, ),
_quality_re = re.compile("(\d+p)$") _url_re = re.compile(""" http(s)?://(www\.)?hitbox.tv /(?P<channel>[^/]+) (?: /(?P<media_id>[^/]+) )? """, re.VERBOSE) _live_schema = validate.Schema( { "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")),
validate.url(scheme="http"), validate.optional("m3u8_url"): validate.url(scheme="http", path=validate.endswith(".m3u8")), }, None) }, validate.optional("viewerPlusSwfUrl"): validate.url(scheme="http"), validate.optional("hdPlayerSwfUrl"): validate.text }) _smil_schema = validate.Schema( validate.union({ "http_base": validate.all( validate.xml_find("{http://www.w3.org/2001/SMIL20/Language}head/" "{http://www.w3.org/2001/SMIL20/Language}meta" "[@name='httpBase']"), validate.xml_element(attrib={"content": validate.text}), validate.get("content")), "videos": validate.all( validate.xml_findall( "{http://www.w3.org/2001/SMIL20/Language}body/" "{http://www.w3.org/2001/SMIL20/Language}switch/" "{http://www.w3.org/2001/SMIL20/Language}video"), [ validate.all( validate.xml_element( attrib={ "src": validate.text, "system-bitrate":
http(s)?:// (www\.)? (?: svtplay | svtflow | oppetarkiv ) .se """, re.VERBOSE) _video_schema = validate.Schema( { "video": { "videoReferences": validate.all( [{ "url": validate.text, "playerType": validate.text }], ), } }, validate.get("video"), validate.get("videoReferences") ) class SVTPlay(Plugin): @classmethod def can_handle_url(self, url): return _url_re.match(url) def _create_streams(self, stream_type, parser, video):
_url_re = re.compile( """ 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({
)? (?: 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):
(www\.)? (?: 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)
validate.optional("play_url"): validate.url(scheme="http"), validate.optional("m3u8_url"): validate.url( scheme="http", path=validate.endswith(".m3u8") ), }, None) }, validate.optional("viewerPlusSwfUrl"): validate.url(scheme="http"), validate.optional("hdPlayerSwfUrl"): validate.text }) _smil_schema = validate.Schema(validate.union({ "http_base": validate.all( validate.xml_find("{http://www.w3.org/2001/SMIL20/Language}head/" "{http://www.w3.org/2001/SMIL20/Language}meta" "[@name='httpBase']"), validate.xml_element(attrib={ "content": validate.text }), validate.get("content") ), "videos": validate.all( validate.xml_findall("{http://www.w3.org/2001/SMIL20/Language}body/" "{http://www.w3.org/2001/SMIL20/Language}switch/" "{http://www.w3.org/2001/SMIL20/Language}video"), [ validate.all( validate.xml_element(attrib={ "src": validate.text, "system-bitrate": validate.all( validate.text, validate.transform(int)
import re 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)
viasat4play | 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")
http(s)?://(\w+\.)? (?P<domain>vaughnlive|breakers|instagib|vapers).tv /(?P<channel>[^/&?]+) """, re.VERBOSE) _channel_not_found_re = re.compile("<title>Channel Not Found") def decode_token(token): return token.replace("0m0", "") _schema = validate.Schema( validate.transform(lambda s: s.split(";:mvnkey%")), validate.length(2), validate.union({ "server": validate.all(validate.get(0), validate.text), "token": validate.all(validate.get(1), validate.text, validate.transform(decode_token)) })) class VaughnLive(Plugin): @classmethod def can_handle_url(cls, url): return _url_re.match(url) def _get_streams(self): res = http.get(self.url) if _channel_not_found_re.search(res.text): return
_live_schema = validate.Schema({ validate.any("primary", "secondary"): { validate.text: { "rtmp_flash": { validate.text: { "name": validate.text, "server": validate.url(scheme="rtmp") } } } } }) _schema = validate.Schema( validate.union({ "lang": validate.all( validate.transform(_lang_re.search), validate.get(1) ), "live": validate.all( validate.transform(_live_check_re.search), validate.transform(bool) ), "videos": validate.all( validate.transform(_video_re.findall), [(validate.url(scheme="http"), validate.text)] ) }) ) class Euronews(Plugin): @classmethod
_embed_re = re.compile("<iframe src=\"(http://tv.aftonbladet.se[^\"]+)\"") _aptoma_id_re = re.compile("<div id=\"drvideo\".+data-aptomaId=\"([^\"]+)\"") _live_re = re.compile("data-isLive=\"true\"") _url_re = re.compile("http(s)?://(\w+.)?.aftonbladet.se") _video_schema = validate.Schema( { "formats": validate.all( { validate.text: { validate.text: validate.all( dict, validate.filter(lambda k,v: k in STREAM_FORMATS), { validate.text: [{ "address": validate.text, "filename": validate.text, "path": validate.text }] }, ) } }, validate.filter(lambda k,v: k in STREAM_TYPES) ) } ) class Aftonbladet(Plugin): @classmethod def can_handle_url(cls, url):
formats = {} if not formatsmap: return formats for format in formatsmap.split(","): s = format.split("/") (w, h) = s[1].split("x") formats[int(s[0])] = "{0}p".format(h) return formats _config_schema = validate.Schema( { validate.optional("fmt_list"): validate.all( validate.text, validate.transform(parse_fmt_list) ), validate.optional("url_encoded_fmt_stream_map"): validate.all( validate.text, validate.transform(parse_stream_map), [{ "itag": validate.all( validate.text, validate.transform(int) ), "quality": validate.text, "url": validate.text, validate.optional("s"): validate.text, validate.optional("stereo3d"): validate.all( validate.text, validate.transform(int),
(?: (?P<seconds>\d+)s )? """, re.VERBOSE) _access_token_schema = validate.Schema( { "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")) _user_schema = validate.Schema( {validate.optional("display_name"): validate.text}, validate.get("display_name")) _video_schema = validate.Schema({ "chunks": { validate.text: [{ "length": int, "url": validate.any(None, validate.url(scheme="http")), "upkeep": validate.any("pass", "fail", None) }] }, "restrictions": {
from livestreamer.plugin import Plugin from livestreamer.plugin.api import http, validate from livestreamer.stream import HTTPStream, RTMPStream from livestreamer.plugin.api.support_plugin import common_jwplayer as jwplayer BASE_VOD_URL = "https://www.connectcast.tv" SWF_URL = "https://www.connectcast.tv/jwplayer/jwplayer.flash.swf" _url_re = re.compile("http(s)?://(\w+\.)?connectcast.tv/") _smil_schema = validate.Schema( validate.union({ "base": validate.all( validate.xml_find("head/meta"), validate.get("base"), validate.url(scheme="rtmp") ), "videos": validate.all( validate.xml_findall("body/video"), [validate.get("src")] ) }) ) class ConnectCast(Plugin): @classmethod def can_handle_url(self, url): return _url_re.match(url)
SHOW_STATUS_OFFLINE = 2 STREAM_WEIGHTS = { "middle": 540, "source": 1080 } _url_re = re.compile(""" http(s)?://(www\.)?douyutv.com /(?P<channel>[^/]+) """, re.VERBOSE) _room_schema = validate.Schema( { "data": validate.any(None, { "show_status": validate.all( validate.text, validate.transform(int) ), "rtmp_url": validate.text, "rtmp_live": validate.text, "rtmp_multi_bitrate": validate.all( validate.any([], { validate.text: validate.text }), validate.transform(dict) ) }) }, validate.get("data") )
_url_re = re.compile("http(s)?://(\w+\.)?ssh101\.com/") _live_re = re.compile(""" \s*jwplayer\(\"player\"\)\.setup\({.*? \s*primary:\s+"([^"]+)".*? \s*file:\s+"([^"]+)" """, re.DOTALL) _live_schema = validate.Schema( validate.transform(_live_re.search), validate.any( None, validate.union({ "type": validate.get(1), "url": validate.all( validate.get(2), validate.url(scheme="http"), ), }) ) ) class SSH101(Plugin): @classmethod def can_handle_url(self, url): return _url_re.match(url) def _get_streams(self): res = http.get(self.url, schema=_live_schema) if not res: return
http(s)?:// (www\.)? (?: 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:
from livestreamer.plugin import Plugin from livestreamer.plugin.api import http, validate from livestreamer.stream import HTTPStream, RTMPStream from livestreamer.plugin.api.support_plugin import common_jwplayer as jwplayer BASE_VOD_URL = "https://www.connectcast.tv" SWF_URL = "https://www.connectcast.tv/jwplayer/jwplayer.flash.swf" _url_re = re.compile("http(s)?://(\w+\.)?connectcast.tv/") _smil_schema = validate.Schema( validate.union({ "base": validate.all(validate.xml_find("head/meta"), validate.get("base"), validate.url(scheme="rtmp")), "videos": validate.all(validate.xml_findall("body/video"), [validate.get("src")]) })) class ConnectCast(Plugin): @classmethod def can_handle_url(self, url): return _url_re.match(url) def _get_smil_streams(self, url): res = http.get(url, verify=False) smil = http.xml(res, schema=_smil_schema) for video in smil["videos"]:
} _url_re = re.compile(""" http(s)?://(\w+\.)?zdf.de/zdfmediathek(\#)?/.+ /(live|video) /(?P<video_id>\d+) """, re.VERBOSE | re.IGNORECASE) _schema = validate.Schema( validate.xml_findall("video/formitaeten/formitaet"), [ validate.union({ "type": validate.get("basetype"), "quality": validate.xml_findtext("quality"), "url": validate.all( validate.xml_findtext("url"), validate.url() ) }) ] ) class zdf_mediathek(Plugin): @classmethod def can_handle_url(cls, url): return _url_re.match(url) @classmethod def stream_weight(cls, key): weight = QUALITY_WEIGHTS.get(key) if weight:
_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, }], }] }) }) }) class VGTV(Plugin): @classmethod def can_handle_url(self, url): return _url_re.match(url)
""" 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"))))) })) class Aliez(Plugin): @classmethod def can_handle_url(self, url):
_quality_re = re.compile("(\d+p)$") _url_re = re.compile( """ http(s)?://(www\.)?hitbox.tv /(?P<channel>[^/]+) (?: /(?P<media_id>[^/]+) )? """, re.VERBOSE) _live_schema = validate.Schema( { "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 }],
_api_schema = validate.Schema({ "error": bool, validate.optional("code"): validate.text, validate.optional("message"): validate.text, 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) ),
formats = {} if not formatsmap: return formats for format in formatsmap.split(","): s = format.split("/") (w, h) = s[1].split("x") formats[int(s[0])] = "{0}p".format(h) return formats _config_schema = validate.Schema( { validate.optional("fmt_list"): validate.all( validate.text, validate.transform(parse_fmt_list) ), validate.optional("url_encoded_fmt_stream_map"): validate.all( validate.text, validate.transform(parse_stream_map), [{ "itag": validate.all( validate.text, validate.transform(int) ), "quality": validate.text, "url": validate.url(scheme="http"), validate.optional("s"): validate.text, validate.optional("stereo3d"): validate.all( validate.text, validate.transform(int),
)? """, re.VERBOSE) _channel_id_re = re.compile("\"channelId\":(\d+)") HLS_PLAYLIST_URL = ("http://iphone-streaming.ustream.tv" "/uhls/{0}/streams/live/iphone/playlist.m3u8") RECORDED_URL = "http://tcdn.ustream.tv/video/{0}" RTMP_URL = "rtmp://r{0}-1-{1}-channel-live.ums.ustream.tv:1935/ustream" SWF_URL = "http://static-cdn1.ustream.tv/swf/live/viewer.rsl:505.swf" _module_info_schema = validate.Schema(list, validate.length(1), validate.get(0), dict) _amf3_array = validate.Schema( validate.any( validate.all( {int: object}, validate.transform(lambda a: list(a.values())), ), list)) _recorded_schema = validate.Schema({ validate.optional("stream"): validate.all(_amf3_array, [{ "name": validate.text, "streams": validate.all( _amf3_array, [{ "streamName": validate.text, "bitrate": float, }], ), validate.optional("url"):
_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, } ], } ] }, ) }, ), } )
SHOW_STATUS_OFFLINE = 2 STREAM_WEIGHTS = {"low": 540, "middle": 720, "source": 1080} _url_re = re.compile( """ http(s)?://(www\.)?douyu.com /(?P<channel>[^/]+) """, re.VERBOSE) _json_re = re.compile(r"var\s*\$ROOM\s*=\s*({.+?});") _room_id_schema = validate.Schema( validate.all( validate.transform(_json_re.search), validate.any( None, validate.all(validate.get(1), validate.transform(parse_json), { "room_id": validate.any(validate.text, validate.transform(int)) })))) _room_schema = validate.Schema( { "data": validate.any(None, { "show_status": validate.all(validate.text, validate.transform(int)) }) }, validate.get("data")) _lapi_schema = validate.Schema( {
_quality_re = re.compile("(\d+p)$") _url_re = re.compile( """ http(s)?://(www\.)?hitbox.tv /(?P<channel>[^/]+) (?: /(?P<media_id>[^/]+) )? """, re.VERBOSE) _live_schema = validate.Schema( { "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, }],
from livestreamer.plugin.api import validate from livestreamer.plugin.api.utils import parse_json __all__ = ["parse_playlist"] _playlist_re = re.compile("\(?\{.*playlist: (\[.*\]),.*?\}\)?;", re.DOTALL) _js_to_json = partial(re.compile("(\w+):\s").sub, r'"\1":') _playlist_schema = validate.Schema( validate.transform(_playlist_re.search), validate.any( None, validate.all( validate.get(1), validate.transform(_js_to_json), validate.transform(parse_json), [{ "sources": [{ "file": validate.text, validate.optional("label"): validate.text }] }] ) ) ) def parse_playlist(res): """Attempts to parse a JWPlayer playlist in a HTTP response body.""" return _playlist_schema.validate(res.text)
import re 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)
from livestreamer.stream import RTMPStream RTMP_URL = "rtmp://{0}/app/{1}" CHANNEL_DETAILS_URI = "https://api.streamup.com/1.0/channels/{0}?access_token={1}" REDIRECT_SERVICE_URI = "https://lancer.streamup.com/api/redirect/{0}" _url_re = re.compile("http(s)?://(\w+\.)?streamup.com/(?P<channel>[^/?]+)") _flashvars_re = re.compile("flashvars\.(?P<var>\w+)\s?=\s?'(?P<value>[^']+)';") _swf_url_re = re.compile('swfobject.embedSWF\(\s*"(?P<player_url>[^"]+)",') _schema = validate.Schema( validate.union( { "vars": validate.all( validate.transform(_flashvars_re.findall), validate.transform(dict), {"owner": validate.text, validate.optional("token"): validate.text}, ), "swf": validate.all( validate.transform(_swf_url_re.search), validate.get("player_url"), validate.endswith(".swf") ), } ) ) _channel_details_schema = validate.Schema({"channel": {"live": bool, "slug": validate.text}}) class StreamupCom(Plugin): @classmethod def can_handle_url(cls, 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:
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") ) ) ) )
"hls": HLSStream.parse_variant_playlist, "hds": HDSStream.parse_manifest } _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)
from itertools import chain from livestreamer.compat import urlparse from livestreamer.plugin import Plugin from livestreamer.plugin.api import http, validate from livestreamer.stream import HLSStream, HTTPStream, RTMPStream SWF_URL = "http://www.arte.tv/player/v2/jwplayer6/mediaplayer.6.6.swf" _url_re = re.compile("http(s)?://(\w+\.)?arte.tv/") _json_re = re.compile("arte_vp_(?:live-)?url=(['\"])(.+?)\\1") _schema = validate.Schema( validate.transform(_json_re.search), validate.any(None, validate.all(validate.get(2), validate.url(scheme="http")))) _video_schema = validate.Schema({ "videoJsonPlayer": { "VSR": validate.any( [], { validate.text: { "height": int, "mediaType": validate.text, "url": validate.text, validate.optional("streamer"): validate.text }, }, ), "VTY":
from livestreamer.plugin.api import http, validate from livestreamer.stream import HLSStream STREAM_INFO_URL = "https://api.periscope.tv/api/v2/getAccessPublic" STATUS_GONE = 410 STATUS_UNAVAILABLE = (STATUS_GONE,) _url_re = re.compile(r"http(s)?://(www\.)?periscope.tv/w/(?P<token>[\w\-\=]+)") _stream_schema = validate.Schema( validate.any( None, validate.union({ "hls_url": validate.all( {"hls_url": validate.url(scheme="http")}, validate.get("hls_url") ), }), validate.union({ "replay_url": validate.all( {"replay_url": validate.url(scheme="http")}, validate.get("replay_url") ), }), ), ) class Periscope(Plugin): @classmethod def can_handle_url(cls, url):