Beispiel #1
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
Beispiel #2
0
    def _parse_smil(self, url, swf_url):
        res = http.get(url)
        smil = http.xml(res, "SMIL config", schema=_smil_schema)

        for src, bitrate in smil["videos"]:
            url = urljoin(smil["http_base"], src)
            yield bitrate, AkamaiHDStream(self.session, url, swf=swf_url)
    def _get_streams(self):
        # get the HLS xml from the same sub domain as the main url, defaulting to www
        sdomain = _url_re.match(self.url).group(1) or "www"
        res = http.get(API_URL.format(sdomain))

        stream_url = http.xml(res, schema=_schema)
        return HLSStream.parse_variant_playlist(self.session, stream_url)
    def _get_streams(self):
        match = _url_re.match(self.url)
        video_id = match.group("video_id")
        res = http.get(API_URL, params=dict(ak="web", id=video_id))
        fmts = http.xml(res, schema=_schema)

        streams = {}
        for fmt in fmts:
            if fmt["type"] in STREAMING_TYPES:
                name, parser = STREAMING_TYPES[fmt["type"]]
                try:
                    streams.update(parser(self.session, fmt["url"]))
                except IOError as err:
                    self.logger.error("Failed to extract {0} streams: {1}",
                                      name, err)

            elif fmt["type"] == "h264_aac_mp4_rtmp_zdfmeta_http":
                name = fmt["quality"]
                try:
                    streams[name] = self._create_rtmp_stream(fmt["url"])
                except IOError as err:
                    self.logger.error("Failed to extract RTMP stream '{0}': {1}",
                                      name, err)

        return streams
    def _get_streams(self):
        data_url = http.get(self.url, schema=self._player_url_schema)
        if data_url:
            res = http.get(urljoin(self.url, data_url))
            stream_info = http.xml(res, schema=self._livestream_schema)

            for stream in stream_info:
                url = stream["url"]
                try:
                    if ".m3u8" in url:
                        for s in HLSStream.parse_variant_playlist(
                                self.session, url, name_key="bitrate").items():
                            yield s
                    elif ".f4m" in url:
                        for s in HDSStream.parse_manifest(
                                self.session,
                                url,
                                pvswf=self.swf_url,
                                is_akamai=True).items():
                            yield s
                    elif ".mp4" in url:
                        yield "{0}k".format(stream["bitrate"]), HTTPStream(
                            self.session, url)
                except IOError as err:
                    self.logger.warning("Error parsing stream: {0}", err)
Beispiel #6
0
    def _get_streams(self):
        # get the HLS xml from the same sub domain as the main url, defaulting to www
        sdomain = _url_re.match(self.url).group(1) or "www"
        res = http.get(API_URL.format(sdomain))

        stream_url = http.xml(res, schema=_schema)
        return HLSStream.parse_variant_playlist(self.session, stream_url)
Beispiel #7
0
    def _parse_smil(self, url, swf_url):
        res = http.get(url)
        smil = http.xml(res, "SMIL config", schema=_smil_schema)

        for src, bitrate in smil["videos"]:
            url = urljoin(smil["http_base"], src)
            yield bitrate, AkamaiHDStream(self.session, url, swf=swf_url)
    def _get_smil_streams(self, info):
        res = http.get(info["_stream"])
        smil = http.xml(res, "SMIL config", schema=_smil_schema)

        for video in smil["videos"]:
            url = "{0}/{1}{2}".format(smil["base"], video, HDCORE_PARAMETER)
            streams = HDSStream.parse_manifest(self.session, url, pvswf=SWF_URL, is_akamai=smil["cdn"] == "akamai")

            for stream in streams.items():
                yield stream
Beispiel #9
0
 def _login(self, username, password):
     res = http.post(self.auth_url, data={
         "username": username,
         "password": password,
         "cookielink": False
     })
     login_status = http.xml(res, schema=self.auth_schema)
     self.logger.debug("Login status for {0}: {1}", username, login_status)
     if login_status == "loginlocked":
         self.logger.error("The account {0} has been locked, the password needs to be reset")
     return login_status == "loginsuccess"
    def _get_smil_streams(self, info):
        res = http.get(info["_stream"])
        smil = http.xml(res, "SMIL config", schema=_smil_schema)

        for video in smil["videos"]:
            url = "{0}/{1}{2}".format(smil["base"], video, HDCORE_PARAMETER)
            streams = HDSStream.parse_manifest(self.session, url, pvswf=SWF_URL)

            # TODO: Replace with "yield from" when dropping Python 2.
            for stream in streams.items():
                yield stream
Beispiel #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
Beispiel #12
0
    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 = {}
        for (name, parser), url in urls.items():
            try:
                streams.update(parser(self.session, url))
            except IOError as err:
                self.logger.warning("Unable to extract {0} streams: {1}", name, err)

        return streams
Beispiel #13
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
Beispiel #14
0
 def _login(self, username, password):
     res = http.post(self.auth_url.format(self._domain),
                     data={
                         "username": username,
                         "password": password,
                         "cookielink": False
                     })
     login_status = http.xml(res, schema=self.auth_schema)
     self.logger.debug("Login status for {0}: {1}", username, login_status)
     if login_status == "loginlocked":
         self.logger.error(
             "The account {0} has been locked, the password needs to be reset"
         )
     return login_status == "loginsuccess"
Beispiel #15
0
    def _get_smil_streams(self, info):
        res = http.get(info["_stream"])
        smil = http.xml(res, "SMIL config", schema=_smil_schema)

        for video in smil["videos"]:
            url = "{0}/{1}{2}".format(smil["base"], video, HDCORE_PARAMETER)
            streams = HDSStream.parse_manifest(
                self.session,
                url,
                pvswf=SWF_URL,
                is_akamai=smil["cdn"] == "akamai")

            for stream in streams.items():
                yield stream
    def _get_rtmp_stream(self, channel_name):
        params = {
            "l": "info",
            "a": "xmlClipPath",
            "clip_id": channel_name,
            "rid": time()
        }
        res = http.get(API_URL, params=params)
        rtmp_url = http.xml(res, schema=_rtmp_schema)

        return RTMPStream(self.session, {
            "rtmp": rtmp_url,
            "swfVfy": SWF_URL,
            "live": True
        })
Beispiel #17
0
    def _get_rtmp_stream(self, channel_name):
        params = {
            "l": "info",
            "a": "xmlClipPath",
            "clip_id": channel_name,
            "rid": time()
        }
        res = http.get(API_URL, params=params)
        rtmp_url = http.xml(res, schema=_rtmp_schema)

        return RTMPStream(self.session, {
            "rtmp": rtmp_url,
            "swfVfy": SWF_URL,
            "live": True
        })
Beispiel #18
0
    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 = {}
        for (name, parser), url in urls.items():
            try:
                streams.update(parser(self.session, url))
            except IOError as err:
                self.logger.warning("Unable to extract {0} streams: {1}", name,
                                    err)

        return streams
Beispiel #19
0
    def _get_streams(self):
        match = self._url_re.match(self.url)
        video_id = match.group('video_id')

        if video_id is not None:
            # VOD
            res = http.get(self.VOD_API_URL.format(video_id))
            stream_data = http.json(res, schema=self._vod_api_schema)

            # Check whether video format is expired
            current_date = datetime.strptime(stream_data['current_date'],
                                             '%Y-%m-%dT%H:%M:%S.%f')
            valid_start = datetime.strptime(
                stream_data['shows']['valid_start'], '%Y-%m-%dT%H:%M:%S')
            valid_end = datetime.strptime(stream_data['shows']['valid_end'],
                                          '%Y-%m-%dT%H:%M:%S')
            if current_date < valid_start or current_date > valid_end:
                self.logger.error(
                    'Failed to access stream, may be due to expired content')
                return

            streams = stream_data['shows']['media:group']
        else:
            # Live
            channel_id = match.group('channel_id')
            # Get live streams for desktop
            res = http.get(self.LIVE_API_URL, params={'channelid': channel_id})
            streams = http.xml(res, schema=self._live_api_schema)

            # Get HLS streams for Iphone
            res = http.get(self.LIVE_API_URL,
                           params={
                               'channelid': channel_id,
                               'platform': 'iphone'
                           })
            stream = http.json(res, schema=self._live_api_iphone_schema)
            if stream != 'none':
                streams.append(stream)

        for stream in streams:
            if '.f4m' in stream:
                for s in HDSStream.parse_manifest(self.session,
                                                  stream).items():
                    yield s
            if '.m3u8' in stream:
                for s in HLSStream.parse_variant_playlist(
                        self.session, stream).items():
                    yield s
Beispiel #20
0
    def _get_streams(self):
        cubeid = self._get_live_cubeid()
        if not cubeid:
            return

        res = http.get(API_URL_LIVE, params=dict(cubeid=cubeid))
        entries = http.xml(res, schema=_entries_schema)
        streams = {}
        for url in entries:
            try:
                streams.update(
                    HLSStream.parse_variant_playlist(self.session, url))
            except IOError as err:
                self.logger.error("Failed to open playlist: {0}", err)

        return streams
Beispiel #21
0
    def _get_streams(self):
        cubeid = self._get_live_cubeid()
        if not cubeid:
            return

        res = http.get(API_URL_LIVE, params=dict(cubeid=cubeid))
        entries = http.xml(res, schema=_entries_schema)
        streams = {}
        for url in entries:
            try:
                streams.update(
                    HLSStream.parse_variant_playlist(self.session, url)
                )
            except IOError as err:
                self.logger.error("Failed to open playlist: {0}", err)

        return streams
    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
Beispiel #23
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
Beispiel #24
0
 def _get_media_info(self, content_id):
     """
     Get the info about the content, based on the ID
     :param content_id:
     :return:
     """
     params = {"identityPointId": self._session_attributes.get("ipid"),
               "fingerprint": self._session_attributes.get("fprt"),
               "contentId": content_id,
               "playbackScenario": self.playback_scenario,
               "platform": "WEB_MEDIAPLAYER_5",
               "subject": "LIVE_EVENT_COVERAGE",
               "frameworkURL": "https://ws.media.net.wwe.com",
               "_": int(time.time())}
     if self.session_key:
         params["sessionKey"] = self.session_key
     url = self.api_url.format(id=content_id)
     res = http.get(url, params=params)
     return http.xml(res, ignore_ns=True, schema=self._info_schema)
Beispiel #25
0
    def _get_streams(self):
        data_url = http.get(self.url, schema=self._player_url_schema)
        if data_url:
            res = http.get(urljoin(self.url, data_url))
            stream_info = http.xml(res, schema=self._livestream_schema)

            for stream in stream_info:
                url = stream["url"]
                try:
                    if ".m3u8" in url:
                        for s in HLSStream.parse_variant_playlist(self.session, url, name_key="bitrate").items():
                            yield s
                    elif ".f4m" in url:
                        for s in HDSStream.parse_manifest(self.session, url, pvswf=self.swf_url, is_akamai=True).items():
                            yield s
                    elif ".mp4" in url:
                        yield "{0}k".format(stream["bitrate"]), HTTPStream(self.session, url)
                except IOError as err:
                    self.logger.warning("Error parsing stream: {0}", err)
Beispiel #26
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        channel = match.group("channel")
        res = http.get(CHANNEL_INFO.format(channel))
        channel_info = http.json(res)

        if not channel_info["online"]:
            return

        res = http.get(CHANNEL_MANIFEST.format(channel_info["id"]))
        assets = http.xml(res, schema=_assets_schema)
        streams = {}
        for video in assets["videos"]:
            name = "{0}p".format(video["height"])
            stream = RTMPStream(self.session,{
                "rtmp"     : "{0}/{1}".format(assets["base"], video["src"])
            })
            streams[name] = stream

        return streams
Beispiel #27
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
Beispiel #28
0
    def _get_live_stream(self, channel):
        res = http.get(self.api_url.format(type="channels", id=channel))
        channel_info = http.json(res)

        if not channel_info["online"]:
            return

        res = http.get(self.channel_manifest.format(id=channel_info["id"], type="smil"))
        assets = http.xml(res, schema=self._assets_schema)

        for video in assets["videos"]:
            name = "{0}p".format(video["height"])
            stream = RTMPStream(self.session, {
                "rtmp": "{0}/{1}".format(assets["base"], video["src"])
            })
            yield name, stream

        for s in HLSStream.parse_variant_playlist(self.session,
                                                  self.channel_manifest.format(id=channel_info["id"], type="m3u8")).items():
            yield s
Beispiel #29
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        channel = match.group("channel")
        res = http.get(CHANNEL_INFO.format(channel))
        channel_info = http.json(res)

        if not channel_info["online"]:
            return

        res = http.get(CHANNEL_MANIFEST.format(channel_info["id"]))
        assets = http.xml(res, schema=_assets_schema)
        streams = {}
        for video in assets["videos"]:
            name = "{0}p".format(video["height"])
            stream = RTMPStream(self.session, {
                "rtmp": "{0}/{1}".format(assets["base"], video["src"])
            })
            streams[name] = stream

        return streams
Beispiel #30
0
 def _get_media_info(self, content_id):
     """
     Get the info about the content, based on the ID
     :param content_id:
     :return:
     """
     params = {
         "identityPointId": self._session_attributes.get("ipid"),
         "fingerprint": self._session_attributes.get("fprt"),
         "contentId": content_id,
         "playbackScenario": self.playback_scenario,
         "platform": "WEB_MEDIAPLAYER_5",
         "subject": "LIVE_EVENT_COVERAGE",
         "frameworkURL": "https://ws.media.net.wwe.com",
         "_": int(time.time())
     }
     if self.session_key:
         params["sessionKey"] = self.session_key
     url = self.api_url.format(id=content_id)
     res = http.get(url, params=params)
     return http.xml(res, ignore_ns=True, schema=self._info_schema)
Beispiel #31
0
    def _get_streams(self):
        match = self._url_re.match(self.url)
        video_id = match.group('video_id')

        if video_id is not None:
            # VOD
            res = http.get(self.VOD_API_URL.format(video_id))
            stream_data = http.json(res, schema=self._vod_api_schema)

            # Check whether video format is expired
            current_date = datetime.strptime(stream_data['current_date'], '%Y-%m-%dT%H:%M:%S.%f')
            valid_start = datetime.strptime(stream_data['shows']['valid_start'], '%Y-%m-%dT%H:%M:%S')
            valid_end = datetime.strptime(stream_data['shows']['valid_end'], '%Y-%m-%dT%H:%M:%S')
            if current_date < valid_start or current_date > valid_end:
                self.logger.error('Failed to access stream, may be due to expired content')
                return

            streams = stream_data['shows']['media:group']
        else:
            # Live
            channel_id = match.group('channel_id')
            # Get live streams for desktop
            res = http.get(self.LIVE_API_URL, params={'channelid': channel_id})
            streams = http.xml(res, schema=self._live_api_schema)

            # Get HLS streams for Iphone
            res = http.get(self.LIVE_API_URL, params={'channelid': channel_id, 'platform': 'iphone'})
            stream = http.json(res, schema=self._live_api_iphone_schema)
            if stream != 'none':
                streams.append(stream)

        for stream in streams:
            if '.f4m' in stream:
                for s in HDSStream.parse_manifest(self.session, stream).items():
                    yield s
            if '.m3u8' in stream:
                for s in HLSStream.parse_variant_playlist(self.session, stream).items():
                    yield s
Beispiel #32
0
    def _get_vod_streams(self, stream_type, page):
        m = self.stream_vod_data_re.search(page.text)
        if m is None:
            return
        stream_url, stream_id = m.groups()

        if stream_type == "video":
            stream_api_id = "v-{}".format(stream_id)
            default_quality = "vod"
        elif stream_type == "audio":
            stream_api_id = "a-{}".format(stream_id)
            default_quality = "audio"
        else:
            return

        # Retrieve stream embedded in web page
        yield self._create_stream(stream_url, default_quality)

        # Retrieve streams using API
        res = http.get(self.smil_api_url.format(stream_api_id))
        videos = http.xml(res, schema=self.smil_schema)

        for video in videos['streams']:
            url = videos["base"] + video["src"]
            if url == stream_url or url.replace("_dwdownload.",
                                                ".") == stream_url:
                continue

            if video["system-bitrate"] > 0:
                # If width is available, use it to select the best stream
                # amongst those with same bitrate
                quality = "{}k".format(
                    (video["system-bitrate"] + video.get("width", 0)) // 1000)
            else:
                quality = default_quality

            yield self._create_stream(url, quality)
Beispiel #33
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': 'secure-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("https://secure-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
 def _get_meta_url(self, url):
     res = http.get(url, exception=IOError)
     root = http.xml(res, exception=IOError)
     return root.findtext("default-stream-url")
Beispiel #35
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': 'secure-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("https://secure-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
Beispiel #36
0
 def _get_live_cubeid(self):
     res = http.get(API_URL_APP, params=dict(mode="get_live"))
     root = http.xml(res)
     return root.findtext("./cube/cubeid")
Beispiel #37
0
    def _get_streams(self):
        page = http.get(self.url, schema=_schema)
        if not page:
            return

        pubkey_pem = get_public_key(self.cache, urljoin(self.url, page["clientlibs"]))
        if not pubkey_pem:
            raise PluginError("Unable to get public key")

        flashvars = page["flashvars"]

        params = {
            "cashPath": int(time.time() * 1000)
        }
        res = http.get(urljoin(self.url, flashvars["country"]), params=params)
        if not res:
            return
        language = http.xml(res, schema=_language_schema)

        api_params = {}
        for key in ("ss_id", "mv_id", "device_cd", "ss1_prm", "ss2_prm", "ss3_prm"):
            if flashvars.get(key, ""):
                api_params[key] = flashvars[key]

        aeskey = number.long_to_bytes(random.getrandbits(8 * 32), 32)

        params = {
            "s": flashvars["s"],
            "c": language,
            "e": self.url,
            "d": aes_encrypt(aeskey, json.dumps(api_params)),
            "a": rsa_encrypt(pubkey_pem, aeskey)
        }
        res = http.get(urljoin(self.url, flashvars["init"]), params=params)
        if not res:
            return
        rtn = http.json(res, schema=_init_schema)
        if not rtn:
            return

        init_data = parse_json(aes_decrypt(aeskey, rtn))

        parsed = urlparse(init_data["play_url"])
        if parsed.scheme != "https" or not parsed.path.startswith("/i/") or not parsed.path.endswith("/master.m3u8"):
            return
        hlsstream_url = init_data["play_url"]

        streams = HLSStream.parse_variant_playlist(self.session, hlsstream_url)

        if "caption_url" in init_data:
            if self.get_option("mux_subtitles") and FFMPEGMuxer.is_usable(self.session):
                res = http.get(init_data["caption_url"])
                srt = http.xml(res, ignore_ns=True, schema=_xml_to_srt_schema)
                subfiles = []
                metadata = {}
                for i, lang, srt in ((i, s[0], s[1]) for i, s in enumerate(srt)):
                    subfile = tempfile.TemporaryFile()
                    subfile.write(srt.encode("utf8"))
                    subfile.seek(0)
                    subfiles.append(FileStream(self.session, fileobj=subfile))
                    metadata["s:s:{0}".format(i)] = ["language={0}".format(lang)]

                for n, s in streams.items():
                    yield n, MuxedStream(self.session, s, *subfiles,
                                         maps=list(range(0, len(metadata) + 1)),
                                         metadata=metadata)
                return
            else:
                self.logger.info("Subtitles: {0}".format(init_data["caption_url"]))

        for s in streams.items():
            yield s
Beispiel #38
0
 def _get_live_cubeid(self):
     res = http.get(API_URL_APP, params=dict(mode="get_live"))
     root = http.xml(res)
     return root.findtext("./cube/cubeid")