Ejemplo n.º 1
0
    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}
Ejemplo n.º 2
0
    def _get_stream_info(self, url):
        match = _url_re.match(url)
        user = match.group("user")
        live_channel = match.group("liveChannel")

        if user:
            video_id = self._find_channel_video()
        elif live_channel:
            return self._find_canonical_stream_info()
        else:
            video_id = match.group("video_id")
            video_id2 = match.group("video_id2")
            if video_id2:
                video_id = video_id2

            if video_id == "live_stream":
                query_info = dict(parse_qsl(urlparse(url).query))
                if "channel" in query_info:
                    video_id = self._get_channel_video(query_info["channel"])

        if not video_id:
            return

        params = {
            "video_id": video_id,
        }
        res = http.get(API_VIDEO_INFO, params=params, headers=HLS_HEADERS)
        return parse_query(res.text, name="config", schema=_config_schema)
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        video_id = match.group("video_id")
        res = http.get(ASSET_URL.format(video_id))
        assets = http.xml(res, schema=_asset_schema)

        streams = {}
        for asset in assets:
            base = asset["base"]
            url = asset["url"]

            if urlparse(url).path.endswith(".f4m"):
                streams.update(
                    HDSStream.parse_manifest(self.session, url, pvswf=SWF_URL)
                )
            elif base.startswith("rtmp"):
                name = "{0}k".format(asset["bitrate"])
                params = {
                    "rtmp": asset["base"],
                    "playpath": url,
                    "live": True
                }
                streams[name] = RTMPStream(self.session, params)

        return streams
Ejemplo n.º 6
0
    def _parse_vod_streams(self, vod):
        for name, stream in vod["streams"].items():
            scheme = urlparse(stream["url"]).scheme

            if scheme == "http":
                yield name, HLSStream(self.session, stream["url"])
            elif scheme == "rtmp":
                yield name, self._create_rtmp_stream(stream, live=False)
Ejemplo n.º 7
0
    def _get_streams(self):
        res = http.get(self.url, schema=_live_schema)
        if not res:
            return

        if res["type"] == "hls" and urlparse(res["url"]).path.endswith("m3u8"):
            stream = HLSStream(self.session, res["url"])
            return dict(hls=stream)
Ejemplo n.º 8
0
    def _get_video_streams(self, player):
        base_url = player["clip"]["baseUrl"] or VOD_BASE_URL
        mapper = StreamMapper(cmp=lambda ext, bitrate: urlparse(bitrate["url"])
                              .path.endswith(ext))
        mapper.map(".m3u8", self._create_video_stream, HLSStream, base_url)
        mapper.map(".mp4", self._create_video_stream, HTTPStream, base_url)
        mapper.map(".flv", self._create_video_stream, HTTPStream, base_url)

        return mapper(player["clip"]["bitrates"])
Ejemplo n.º 9
0
    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)
Ejemplo n.º 10
0
    def _create_rtmp_stream(self, cdn, stream_name):
        parsed = urlparse(cdn)
        params = {
            "rtmp": cdn,
            "app": parsed.path[1:],
            "playpath": stream_name,
            "pageUrl": self.url,
            "swfUrl": SWF_URL,
            "live": True
        }

        return RTMPStream(self.session, params)
Ejemplo n.º 11
0
    def _get_streams(self):
        res = http.get(self.url)

        match = _meta_xmlurl_id_re.search(res.text)
        if not match:
            return

        xml_info_url = STREAMS_INFO_URL.format(match.group(1))
        video_info_res = http.get(xml_info_url)
        parsed_info = http.xml(video_info_res)

        live_el = parsed_info.find("live")
        live = live_el is not None and live_el.text == "1"

        streams = {}

        hdsurl_el = parsed_info.find("hdsurl")
        if hdsurl_el is not None and hdsurl_el.text is not None:
            hdsurl = hdsurl_el.text
            streams.update(HDSStream.parse_manifest(self.session, hdsurl))

        if live:
            vurls_el = parsed_info.find("vurls")
            if vurls_el is not None:
                for i, vurl_el in enumerate(vurls_el):
                    bitrate = vurl_el.get("bitrate")
                    name = bitrate + "k" if bitrate is not None else "rtmp{0}".format(
                        i)
                    params = {
                        "rtmp": vurl_el.text,
                    }
                    streams[name] = RTMPStream(self.session, params)

        parsed_urls = set()
        mobileurls_el = parsed_info.find("mobileurls")
        if mobileurls_el is not None:
            for mobileurl_el in mobileurls_el:
                text = mobileurl_el.text
                if not text:
                    continue

                if text in parsed_urls:
                    continue

                parsed_urls.add(text)
                url = urlparse(text)

                if url[0] == "http" and url[2].endswith("m3u8"):
                    streams.update(
                        HLSStream.parse_variant_playlist(self.session, text))

        return streams
Ejemplo n.º 12
0
    def can_handle_url(self, url):
        self.url = url
        self.scheme = None

        try:
            parsed = urlparse(url)
            self.domain = parsed.netloc
            self.scheme = self.get_scheme(self.domain)
        except Exception as e:
            self.logger.error("Failed to get scheme for '{0}'. {1}", url,
                              str(e))

        return self.scheme != None
Ejemplo n.º 13
0
    def _get_streams(self):
        url_params = dict(parse_qsl(urlparse(self.url).query))
        video_id = url_params.get("videoid")

        if video_id:
            self.logger.debug("Found Video ID: {}", video_id)
            res = http.get(self.api_url.format(id=video_id))
            data = http.json(res, schema=self.api_schema)
            hls = self._make_stream(data["video_info"]["hlsvideosource"])
            video = self._make_stream(data["video_info"]["videosource"])
            if hls:
                yield "live", hls
            if video:
                yield "live", video
Ejemplo n.º 14
0
    def _get_streams(self):
        parsed = urlparse(self.url)
        cls = PROTOCOL_MAP.get(parsed.scheme)

        if not cls:
            return

        split = self.url.split(" ")
        url = split[0]
        urlnoproto = re.match("^\w+://(.+)", url).group(1)

        # Prepend http:// if needed.
        if cls != RTMPStream and not len(urlparse(urlnoproto).scheme):
            urlnoproto = "http://{0}".format(urlnoproto)

        params = (" ").join(split[1:])
        params = self._parse_params(params)

        if cls == RTMPStream:
            params["rtmp"] = url

            for boolkey in ("live", "realtime", "quiet", "verbose", "debug"):
                if boolkey in params:
                    params[boolkey] = bool(params[boolkey])

            stream = cls(self.session, params)
        elif cls == HLSStream.parse_variant_playlist or cls == HDSStream.parse_manifest:
            try:
                streams = cls(self.session, urlnoproto, **params)
            except IOError as err:
                raise PluginError(err)

            return streams
        else:
            stream = cls(self.session, urlnoproto, **params)

        return dict(live=stream)
Ejemplo n.º 15
0
    def __init__(self, url):
        Plugin.__init__(self, url)
        match = _url_re.match(url).groupdict()
        self.channel = match.get("channel").lower()
        self.subdomain = match.get("subdomain")
        self.video_type = match.get("video_type")
        self.video_id = match.get("video_id")
        self.clip_name = match.get("clip_name")
        self._hosted_chain = []

        parsed = urlparse(url)
        self.params = parse_query(parsed.query)

        self.api = TwitchAPI(beta=self.subdomain == "beta")
        self.usher = UsherService()
Ejemplo n.º 16
0
    def _create_rtmp_stream(self, url):
        parsed = urlparse(url)
        if parsed.query:
            app = "{0}?{1}".format(parsed.path[1:], parsed.query)
        else:
            app = parsed.path[1:]

        params = {
            "rtmp": url,
            "app": app,
            "pageUrl": self.url,
            "live": True
        }

        stream = RTMPStream(self.session, params)
        return "live", stream
Ejemplo n.º 17
0
    def _parse_live_streams(self, channel):
        for stream in channel["streams"]:
            name = stream["quality"]
            scheme = urlparse(stream["url"]).scheme

            if scheme == "http":
                try:
                    streams = HLSStream.parse_variant_playlist(
                        self.session, stream["url"])
                    for __, stream in streams.items():
                        yield name, stream

                except IOError as err:
                    self.logger.error(
                        "Failed to extract HLS stream '{0}': {1}", name, err)

            elif scheme == "rtmp":
                yield name, self._create_rtmp_stream(stream)
Ejemplo n.º 18
0
    def _get_playlist(self, **params):
        res = http.get(PLAYLIST_URL, params=params)
        playlist = http.xml(res, schema=_playlist_schema)
        streams = {}
        for video in playlist["videos"]:
            name = "{0}p".format(video["height"])
            stream = RTMPStream(
                self.session, {
                    "rtmp": "{0}/{1}".format(playlist["base"], video["src"]),
                    "app": urlparse(playlist["base"]).path[1:],
                    "pageUrl": self.url,
                    "rtmp": playlist["base"],
                    "playpath": video["src"],
                    "live": True
                })
            streams[name] = stream

        return streams
Ejemplo n.º 19
0
    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
Ejemplo n.º 20
0
    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)
Ejemplo n.º 21
0
    def __init__(self, url):
        Plugin.__init__(self, url)
        self._hosted_chain = []
        match = _url_re.match(url).groupdict()
        parsed = urlparse(url)
        self.params = parse_query(parsed.query)
        self.subdomain = match.get("subdomain")
        self.video_id = None
        self.video_type = None
        self._channel_id = None
        self._channel = None
        self.clip_name = None

        if self.subdomain == "player":
            # pop-out player
            if self.params.get("video"):
                try:
                    self.video_type = self.params["video"][0]
                    self.video_id = self.params["video"][1:]
                except IndexError:
                    self.logger.debug("Invalid video param: {0}", self.params["video"])
            self._channel = self.params.get("channel")
        elif self.subdomain == "clips":
            # clip share URL
            self.clip_name = match.get("channel")

            # handle embed:
            # https://clips.twitch.tv/embed?clip=ImportantSlipperyEndiveBudStar
            if self.clip_name.startswith("embed?clip="):
                self.clip_name = self.clip_name.replace("embed?clip=", "")
        else:
            self._channel = match.get("channel") and match.get("channel").lower()
            self.video_type = match.get("video_type")
            if match.get("videos_id"):
                self.video_type = "v"
            self.video_id = match.get("video_id") or match.get("videos_id")
            self.clip_name = match.get("clip_name")

        self.api = TwitchAPI(beta=self.subdomain == "beta", version=5)
        self.usher = UsherService()
Ejemplo n.º 22
0
    def _get_streams(self):
        args = dict(parse_qsl(urlparse(self.url).query))
        if "k" in args:
            self.logger.debug("Loading channel: {k}", **args)
            res = http.get(self.url)
            stream_data_m = self.stream_data_re.search(res.text)
            if stream_data_m:
                script_vars = b64decode(stream_data_m.group(1))
                url_m = self.m3u8_re.search(script_vars)

                hls_url = url_m and url_m.group("url")
                if hls_url:
                    for s in HLSStream.parse_variant_playlist(
                            self.session, hls_url).items():
                        yield s

                f4m_m = self.f4mm_re.search(script_vars)
                f4m_url = f4m_m and f4m_m.group("url")
                if f4m_url:
                    for n, s in HDSStream.parse_manifest(
                            self.session, f4m_url).items():
                        yield n, s
Ejemplo n.º 23
0
    def _create_rtmp_stream(self, stream, live=True):
        rtmp = stream["url"]
        playpath = stream["name"]
        parsed = urlparse(rtmp)
        if parsed.query:
            app = "{0}?{1}".format(parsed.path[1:], parsed.query)
        else:
            app = parsed.path[1:]

        if playpath.endswith(".mp4"):
            playpath = "mp4:" + playpath

        params = {
            "rtmp": rtmp,
            "pageUrl": self.url,
            "swfUrl": SWF_URL,
            "playpath": playpath,
            "app": app,
        }
        if live:
            params["live"] = True

        return RTMPStream(self.session, params)
Ejemplo n.º 24
0
    def _get_live_stream(self, export_url):
        res = http.get(export_url)
        match = _live_json_re.search(res.text)
        if not match:
            return

        json = parse_json(match.group(1), schema=_live_schema)
        streams = {}
        for stream in json["streams"]:
            stream_name = stream["quality"]
            parsed = urlparse(stream["url"])

            stream = RTMPStream(
                self.session, {
                    "rtmp": stream["url"],
                    "app": "{0}?{1}".format(parsed.path[1:], parsed.query),
                    "playpath": stream["name"],
                    "swfVfy": SWF_LIVE_URL,
                    "pageUrl": self.url,
                    "live": True
                })
            streams[stream_name] = stream

        return streams
Ejemplo n.º 25
0
 def can_handle_url(cls, url):
     if cls.url_re.match(url) is not None:
         args = dict(parse_qsl(urlparse(url).query))
         return args.get("y") == "tv"
Ejemplo n.º 26
0
    def can_handle_url(self, url):
        parsed = urlparse(url)

        return parsed.scheme in PROTOCOL_MAP
Ejemplo n.º 27
0
    def _get_streams(self):
        """
            Find all the streams for the ITV url
            :return: Mapping of quality to stream
        """
        soap_message = self._soap_request()

        headers = {
            'Content-Length': '{0:d}'.format(len(soap_message)),
            'Content-Type': 'text/xml; charset=utf-8',
            'Host': 'mercury.itv.com',
            'Origin': 'http://www.itv.com',
            'Referer':
            'http://www.itv.com/Mercury/Mercury_VideoPlayer.swf?v=null',
            'SOAPAction': "http://tempuri.org/PlaylistService/GetPlaylist",
            'User-Agent': ITV_PLAYER_USER_AGENT,
            "X-Requested-With": "ShockwaveFlash/16.0.0.305"
        }

        res = http.post("http://mercury.itv.com/PlaylistService.svc?wsdl",
                        headers=headers,
                        data=soap_message)

        # Parse XML
        xmldoc = http.xml(res)

        # Check that geo region has been accepted
        faultcode = xmldoc.find('.//faultcode')
        if faultcode is not None:
            if 'InvalidGeoRegion' in faultcode.text:
                self.logger.error('Failed to retrieve playlist data '
                                  '(invalid geo region)')
            return None

        # Look for <MediaFiles> tag (RTMP streams)
        mediafiles = xmldoc.find('.//VideoEntries//MediaFiles')

        # Look for <ManifestFile> tag (HDS streams)
        manifestfile = xmldoc.find('.//VideoEntries//ManifestFile')

        # No streams
        if not mediafiles and not manifestfile:
            return None

        streams = {}

        # Proxy not needed for media retrieval (Note: probably better to use flag)
        # for x in ('http', 'https'):
        #     if x in http.proxies:
        #         http.proxies.pop(x);

        # Parse RTMP streams
        if mediafiles:
            rtmp = mediafiles.attrib['base']

            for mediafile in mediafiles.findall("MediaFile"):
                playpath = mediafile.find("URL").text

                rtmp_url = urlparse(rtmp)
                app = (rtmp_url.path[1:] + '?' + rtmp_url.query).rstrip('?')
                live = app == "live"

                params = dict(
                    rtmp="{u.scheme}://{u.netloc}{u.path}".format(u=rtmp_url),
                    app=app.rstrip('?'),
                    playpath=playpath,
                    swfVfy=LIVE_SWF_URL if live else ONDEMAND_SWF_URL,
                    timeout=10)
                if live:
                    params['live'] = True

                bitrate = int(mediafile.attrib['bitrate']) / 1000
                quality = "{0:d}k".format(int(bitrate))
                streams[quality] = RTMPStream(self.session, params)

        # Parse HDS streams
        if manifestfile:
            url = manifestfile.find('URL').text

            if urlparse(url).path.endswith('f4m'):
                streams.update(
                    HDSStream.parse_manifest(self.session,
                                             url,
                                             pvswf=LIVE_SWF_URL))

        return streams