Exemple #1
0
    def _get_streams(self):
        res = http.get(self.url)
        match = _player_js.search(res.text)
        if match:
            player_js = match.group(0)
            self.logger.info("Found player js {0}", player_js)
        else:
            self.logger.info(
                "Didn't find player js. Probably this page doesn't contain a video"
            )
            return

        res = http.get(player_js)

        jsonp_start = res.text.find('(') + 1
        jsonp_end = res.text.rfind(')')

        if jsonp_start <= 0 or jsonp_end <= 0:
            self.logger.info(
                "Couldn't extract json metadata from player.js: {0}",
                player_js)
            return

        json_s = res.text[jsonp_start:jsonp_end]

        stream_metadata = json.loads(json_s)

        return HDSStream.parse_manifest(
            self.session,
            stream_metadata['mediaResource']['dflt']['videoURL']).items()
Exemple #2
0
    def _get_streams(self):

        # Discover root
        match = _url_re.search(self.url)
        root = match.group(1)

        # Download main URL
        res = http.get(self.url)

        # Find playlist
        match = _playlist_re.search(res.text)
        playlist_url = root + match.group(1) + "d"

        # Download playlist
        res = http.get(playlist_url)

        # Find manifest
        match = _manifest_re.search(res.text)
        manifest_url = match.group(1)

        # Find SWF
        match = _swf_re.search(res.text)
        swf_url = match.group(1)

        streams = {}
        streams.update(
            HDSStream.parse_manifest(self.session, manifest_url,
                                     pvswf=swf_url))

        return streams
Exemple #3
0
    def _get_vod_stream(self):
        vod_url = self.url
        if vod_url.endswith('/'):
            vod_url = vod_url[:-1]

        json_url = '{0}.securevideo.json'.format(vod_url)

        res = http.get(json_url)
        match = _json_re.search(res.text)
        if not match:
            return
        data = parse_json(match.group(1))

        res = http.get(API_VOD.format(data['clientid'], data['mzid']))
        data = http.json(res, schema=_stream_schema)

        for d in data['targetUrls']:
            if d['type'] == 'HDS':
                hds_url = d['url']
                for s in HDSStream.parse_manifest(self.session,
                                                  hds_url).items():
                    yield s

            if d['type'] == 'HLS':
                hls_url = d['url']
                for s in HLSStream.parse_variant_playlist(
                        self.session, hls_url).items():
                    yield s
Exemple #4
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)
Exemple #5
0
    def _get_vod_streams(self, params):
        manifest_url = params.get("autoURL")
        if not manifest_url:
            return

        res = http.get(manifest_url)
        if res.headers.get("Content-Type") == "application/f4m+xml":
            streams = HDSStream.parse_manifest(self.session, res.url)

            # TODO: Replace with "yield from" when dropping Python 2.
            for __ in streams.items():
                yield __
        elif res.headers.get(
                "Content-Type") == "application/vnd.apple.mpegurl":
            streams = HLSStream.parse_variant_playlist(self.session, res.url)

            # TODO: Replace with "yield from" when dropping Python 2.
            for __ in streams.items():
                yield __
        else:
            manifest = http.json(res, schema=_vod_manifest_schema)
            for params in manifest["alternates"]:
                name = "{0}p".format(params["height"])
                stream = self._create_flv_playlist(params["template"])
                yield name, stream

                failovers = params.get("failover", [])
                for failover in failovers:
                    stream = self._create_flv_playlist(failover)
                    yield name, stream
Exemple #6
0
    def _get_streams(self):
        url, params = parse_url_params(self.url)

        urlnoproto = self._url_re.match(url).group(2)
        urlnoproto = update_scheme("http://", urlnoproto)

        return HDSStream.parse_manifest(self.session, urlnoproto, **params)
Exemple #7
0
    def _resolve_playlist(self, res, playlist_all):
        """ yield for _resolve_res

        Args:
            res: Content from self._res_text
            playlist_all: List of streams

        Returns:
            yield every stream
        """
        # m_base is used for .f4m files that doesn't have a base_url
        m_base = self._stream_base_re.search(res)
        if m_base:
            stream_base = m_base.group("base")
        else:
            stream_base = ""

        playlist_list = self._make_url_list(playlist_all, self.url,
                                            stream_base)
        self.logger.debug("Found URL: {0}".format(", ".join(playlist_list)))
        endswith_blacklist = (".mp3", ".mp4", ".vtt")
        for url in playlist_list:
            if ".m3u8" in url and not url.endswith(endswith_blacklist):
                try:
                    streams = HLSStream.parse_variant_playlist(
                        self.session, url, headers=self.headers).items()
                    if not streams:
                        yield "live", HLSStream(self.session,
                                                url,
                                                headers=self.headers)
                    for s in streams:
                        yield s
                except Exception:
                    self.logger.error("Skipping hls_url: {0}".format(url))
            elif ".f4m" in url and not url.endswith(endswith_blacklist):
                try:
                    for s in HDSStream.parse_manifest(
                            self.session, url, headers=self.headers).items():
                        yield s
                except Exception:
                    self.logger.error("Skipping hds_url: {0}".format(url))
            elif self.list_in_item(url, [
                    ".mp3", ".mp4"
            ]) and not self.list_in_item(url, [".f4m", ".m3u8", ".mpd"]):
                try:
                    name = "live"
                    m = self._httpstream_bitrate_re.search(url)
                    if m:
                        name = "{0}k".format(m.group("bitrate"))
                    yield name, HTTPStream(self.session,
                                           url,
                                           headers=self.headers)
                except Exception:
                    self.logger.error("Skipping http_url: {0}".format(url))
            elif ".mpd" in url and not url.endswith(endswith_blacklist):
                try:
                    self.logger.info("Found mpd: {0}".format(url))
                except Exception:
                    self.logger.error("Skipping mpd_url: {0}".format(url))
Exemple #8
0
    def _get_streams(self):
        # Get video ID and channel from URL
        match = self._url_re.match(self.url)
        video_id = match.group('video_id')
        if video_id is None:
            # Retrieve URL page and search for video ID
            res = http.get(self.url)
            match = self._video_id_re.search(res.text)
            if match is None:
                return
            video_id = match.group('video_id')

        res = http.get(self.API_URL.format(video_id))
        videos = http.json(res, schema=self._api_schema)
        parsed = []
        headers = {'User-Agent': self._user_agent}

        # Some videos may be also available on Dailymotion (especially on CNews)
        if videos['ID_DM'] != '':
            for stream in self.session.streams('https://www.dailymotion.com/video/' + videos['ID_DM']).items():
                yield stream

        for quality, video_url in list(videos['MEDIA']['VIDEOS'].items()):
            # Ignore empty URLs
            if video_url == '':
                continue

            # Ignore duplicate video URLs
            if video_url in parsed:
                continue
            parsed.append(video_url)

            try:
                # HDS streams don't seem to work for live videos
                if '.f4m' in video_url and 'LIVE' not in videos['TYPE']:
                    for stream in HDSStream.parse_manifest(self.session,
                                                           video_url,
                                                           params={'hdcore': self.HDCORE_VERSION},
                                                           headers=headers).items():
                        yield stream
                elif '.m3u8' in video_url:
                    for stream in HLSStream.parse_variant_playlist(self.session,
                                                                   video_url,
                                                                   headers=headers).items():
                        yield stream
                elif '.mp4' in video_url:
                    # Get bitrate from video filename
                    match = self._mp4_bitrate_re.match(video_url)
                    if match is not None:
                        bitrate = match.group('bitrate')
                    else:
                        bitrate = quality
                    yield bitrate, HTTPStream(self.session,
                                              video_url,
                                              params={'secret': self.SECRET},
                                              headers=headers)
            except IOError as err:
                if '403 Client Error' in str(err):
                    self.logger.error('Failed to access stream, may be due to geo-restriction')
Exemple #9
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
Exemple #10
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
Exemple #11
0
    def _get_streams(self):
        res = http.get(self.url)
        match = self.player_re.search(res.text)
        if match:
            channel_id = match.group(1)

            stream_api = self.stream_api.format(
                id=channel_id,
                time=int(time.time()),
                hash=''.join(
                    random.choice("abcdef0123456789") for x in range(28)))

            res = http.get(stream_api)
            f4m_url = self.manifest_re.search(res.text)
            if f4m_url:
                return HDSStream.parse_manifest(self.session, f4m_url.group(1))
Exemple #12
0
 def mediaselector(self, vpid):
     for platform in self.platforms:
         url = self.api_url.format(vpid=vpid,
                                   vpid_hash=self._hash_vpid(vpid),
                                   platform=platform)
         self.logger.debug("Info API request: {0}", url)
         stream_urls = http.get(url, schema=self.mediaselector_schema)
         for media in stream_urls:
             for connection in media["connection"]:
                 if connection.get("transferFormat") == "hds":
                     for s in HDSStream.parse_manifest(
                             self.session, connection["href"]).items():
                         yield s
                 if connection.get("transferFormat") == "hls":
                     for s in HLSStream.parse_variant_playlist(
                             self.session, connection["href"]).items():
                         yield s
Exemple #13
0
    def _resolve_playlist(self, res, playlist_all):
        """ yield for _resolve_res

        Args:
            res: Content from self._res_text
            playlist_all: List of streams

        Returns:
            yield every stream
        """
        for url in playlist_all:
            parsed_url = urlparse(url)
            if parsed_url.path.endswith((".m3u8")):
                try:
                    streams = HLSStream.parse_variant_playlist(self.session, url, headers=self.headers).items()
                    if not streams:
                        yield "live", HLSStream(self.session, url, headers=self.headers)
                    for s in streams:
                        yield s
                except Exception as e:
                    self.logger.error("Skipping hls_url - {0}".format(str(e)))
                    self.help_info_e(e)
            elif parsed_url.path.endswith((".f4m")):
                try:
                    for s in HDSStream.parse_manifest(self.session, url, headers=self.headers).items():
                        yield s
                except Exception as e:
                    self.logger.error("Skipping hds_url - {0}".format(str(e)))
                    self.help_info_e(e)
            elif parsed_url.path.endswith((".mp3", ".mp4")):
                try:
                    name = "live"
                    m = self._httpstream_bitrate_re.search(url)
                    if m:
                        name = "{0}k".format(m.group("bitrate"))
                    yield name, HTTPStream(self.session, url, headers=self.headers)
                except Exception as e:
                    self.logger.error("Skipping http_url - {0}".format(str(e)))
                    self.help_info_e(e)
            elif parsed_url.path.endswith((".mpd")):
                try:
                    self.logger.info("Found mpd: {0}".format(url))
                except Exception as e:
                    self.logger.error("Skipping mpd_url - {0}".format(str(e)))
                    self.help_info_e(e)
Exemple #14
0
    def _get_hds_streams(self, channel):
        channel = self.hds_channel_remap.get(channel,
                                             "{0}live".format(channel))
        manifest_url = http.get(self.api_url.format(channel),
                                params={
                                    "getURL": 1
                                },
                                headers={
                                    "User-Agent": useragents.FIREFOX
                                }).text

        for s in HDSStream.parse_manifest(self.session,
                                          manifest_url,
                                          pvswf=self.swf_url,
                                          headers={
                                              "User-Agent": useragents.FIREFOX
                                          }).items():
            yield s
Exemple #15
0
    def _create_stream(self, stream, language):
        stream_name = "{0}p".format(stream["height"])
        stream_type = stream["mediaType"]
        stream_url = stream["url"]
        stream_language = stream["versionShortLibelle"]

        if language == "de":
            language = ["DE", "VOST-DE", "VA", "VOA", "Dt. Live", "OV", "OmU"]
        elif language == "en":
            language = ["ANG", "VOST-ANG"]
        elif language == "es":
            language = ["ESP", "VOST-ESP"]
        elif language == "fr":
            language = [
                "FR", "VOST-FR", "VF", "VOF", "Frz. Live", "VO", "ST mal"
            ]
        elif language == "pl":
            language = ["POL", "VOST-POL"]

        if stream_language in language:
            if stream_type in ("hls", "mp4"):
                if urlparse(stream_url).path.endswith("m3u8"):
                    try:
                        streams = HLSStream.parse_variant_playlist(
                            self.session, stream_url)

                        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 == "f4m":
                try:
                    streams = HDSStream.parse_manifest(self.session,
                                                       stream_url)

                    for stream in streams.items():
                        yield stream
                except IOError as err:
                    self.logger.error("Failed to extract HDS streams: {0}",
                                      err)
Exemple #16
0
    def _get_streams(self):
        m_url = self._url_re.match(self.url)
        if not m_url:
            return

        video_id = m_url.group("id")
        appname = self.appname_map[m_url.group("host")]
        apiname = self.apiname_map[appname]

        headers = {
            "User-Agent": useragents.FIREFOX,
            "Referer": self.url
        }

        res = http.get(self.api_url.format(apiname, video_id, appname), headers=headers)
        data = http.json(res, schema=self._video_schema)

        title = data.get("title")
        streamurls = data.get("streamUrls")

        if title:
            self.stream_title = title

        if streamurls:
            hls_url = streamurls.get("hls")
            if hls_url:
                self.logger.debug("HLS URL: {0}".format(hls_url))
                streams = HLSStream.parse_variant_playlist(self.session, hls_url, headers=headers).items()
                if not streams:
                    yield "live", HLSStream(self.session, hls_url, headers=headers)
                for s in streams:
                    yield s

            hds_url = streamurls.get("hds")
            if hds_url:
                self.logger.debug("HDS URL: {0}".format(hds_url))
                for s in HDSStream.parse_manifest(self.session, hds_url, headers=headers).items():
                    yield s

            mp4_url = streamurls.get("mp4")
            if mp4_url:
                self.logger.debug("MP4 URL: {0}".format(mp4_url))
                name = "live"
                yield name, HTTPStream(self.session, mp4_url, headers=headers)
Exemple #17
0
    def _get_streams(self):
        hls_urls = []
        hds_urls = []
        http.headers.update({'User-Agent': useragents.FIREFOX})

        match = self._url_re.match(self.url)
        if match is None:
            return

        video_id = match.group('id')
        self.logger.debug('video_id: {0}'.format(video_id))

        res = http.get(self.api_play.format(video_id, self.url))
        data = http.json(res, schema=self._video_schema)

        live_data = data.get('live_streams')
        vod_data = data.get('video_balancer')

        if live_data:
            self.logger.debug('Found live_data')
            for d in live_data['hls']:
                hls_urls.append(d['url'])
            for e in live_data['hds']:
                hds_urls.append(e['url'])
        elif vod_data:
            self.logger.debug('Found vod_data')
            hls_urls.append(vod_data['m3u8'])
            hds_urls.append(vod_data['default'])
        else:
            self.logger.error(
                'restricted access to this video for your region')
            raise NoStreamsError(self.url)

        for hls_url in hls_urls:
            self.logger.debug('HLS URL: {0}'.format(hls_url))
            for s in HLSStream.parse_variant_playlist(self.session,
                                                      hls_url).items():
                yield s

        for hds_url in hds_urls:
            self.logger.debug('HDS URL: {0}'.format(hds_url))
            for s in HDSStream.parse_manifest(self.session, hds_url).items():
                yield s
Exemple #18
0
    def _resolve_playlist(self, playlist_all):
        """ create streams

        Args:
            playlist_all: List of stream urls

        Returns:
            all streams
        """
        http.headers.update({"Referer": self.url})
        for url in playlist_all:
            parsed_url = urlparse(url)
            if parsed_url.path.endswith((".m3u8")):
                try:
                    streams = HLSStream.parse_variant_playlist(
                        self.session, url).items()
                    if not streams:
                        yield "live", HLSStream(self.session, url)
                    for s in streams:
                        yield s
                except Exception as e:
                    self.logger.error("Skipping hls_url - {0}".format(str(e)))
            elif parsed_url.path.endswith((".f4m")):
                try:
                    for s in HDSStream.parse_manifest(self.session,
                                                      url).items():
                        yield s
                except Exception as e:
                    self.logger.error("Skipping hds_url - {0}".format(str(e)))
            elif parsed_url.path.endswith((".mp3", ".mp4")):
                try:
                    name = "live"
                    m = self._httpstream_bitrate_re.search(url)
                    if m:
                        name = "{0}k".format(m.group("bitrate"))
                    yield name, HTTPStream(self.session, url)
                except Exception as e:
                    self.logger.error("Skipping http_url - {0}".format(str(e)))
            elif parsed_url.path.endswith((".mpd")):
                try:
                    self.logger.info("Found mpd: {0}".format(url))
                except Exception as e:
                    self.logger.error("Skipping mpd_url - {0}".format(str(e)))
Exemple #19
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
Exemple #20
0
    def _get_live_streams(self, params, swf_url):
        for key, quality in QUALITY_MAP.items():
            key_url = "{0}URL".format(key)
            url = params.get(key_url)

            if not url:
                continue

            try:
                res = http.get(url, exception=IOError)
            except IOError:
                continue

            if quality == "hds":
                self.logger.debug('PLAYLIST URL: {0}'.format(res.url))
                try:
                    streams = HDSStream.parse_manifest(self.session, res.url)
                except BaseException:
                    streams = HLSStream.parse_variant_playlist(
                        self.session, res.url)

                for name, stream in streams.items():
                    if key == "source":
                        name += "+"

                    yield name, stream
            elif res.text.startswith("rtmp"):
                match = _rtmp_re.match(res.text)
                if not match:
                    continue

                stream = RTMPStream(
                    self.session, {
                        "rtmp": match.group("host"),
                        "app": match.group("app"),
                        "playpath": match.group("playpath"),
                        "swfVfy": swf_url,
                        "live": True
                    })

                yield quality, stream
Exemple #21
0
    def _get_hds_streams(self, channel):
        channel = self.hds_channel_remap.get(channel,
                                             "{0}live".format(channel))
        manifest_url = http.get(self.api_url.format(channel),
                                params={
                                    "getURL": 1
                                },
                                headers={
                                    "User-Agent": useragents.FIREFOX
                                }).text
        self.logger.debug("OLD HDS URL: {0}".format(manifest_url))
        manifest_url = filter_urlquery(manifest_url, ["hdnea"], True)
        self.logger.debug("NEW HDS URL: {0}".format(manifest_url))

        for s in HDSStream.parse_manifest(self.session,
                                          manifest_url,
                                          pvswf=self.swf_url,
                                          headers={
                                              "User-Agent": useragents.FIREFOX
                                          }).items():
            yield s
Exemple #22
0
    def _get_streams(self):
        match = self._player_embed_re.match(self.url)
        if match:
            channel_id = match.group("channel_id")
        else:
            try:
                res = http.get(self.url)
            except Exception:
                raise NoStreamsError(self.url)
            channel_id = self._find_channel_id(res.text)

        if not channel_id:
            return
        self.logger.info("Channel ID: {0}".format(channel_id))

        res = http.get(self.PLAYER_EMBED_URL.format(channel_id))
        items = self._find_stream_id(res.text)
        if not items:
            return

        a = b = False
        for stream in items:
            if stream["abr"] == "hls":
                try:
                    for s in HLSStream.parse_variant_playlist(
                            self.session, stream["streamUrl"]).items():
                        yield s
                except IOError:
                    a = True
            elif stream["abr"] == "hds":
                try:
                    for s in HDSStream.parse_manifest(
                            self.session, stream["streamUrl"]).items():
                        yield s
                except IOError:
                    b = True

        if a and b:
            self.logger.warning(
                "Could not open the stream, perhaps the channel is offline")
Exemple #23
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)).decode("utf8")
                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
Exemple #24
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
Exemple #25
0
    def _get_streams(self):
        match = self._url_re.match(self.url)
        channel = match.group('channel')

        res = http.get(self.FORMATS_URL.format(channel))
        streams = http.json(res, schema=self._formats_schema)['streams']
        if streams == []:
            self.logger.error(
                'Channel may be geo-restricted, not directly provided by PlayTV or not freely available'
            )
            return

        for language in streams:
            for protocol, bitrates in list(streams[language].items()):
                # - Ignore non-supported protocols (RTSP, DASH)
                # - Ignore deprecated Flash (RTMPE/HDS) streams (PlayTV doesn't provide anymore a Flash player)
                if protocol in ['rtsp', 'flash', 'dash', 'hds']:
                    continue

                for bitrate in bitrates['bitrates']:
                    if bitrate['value'] == 0:
                        continue
                    api_url = self.API_URL.format(channel, protocol, language,
                                                  bitrate['value'])
                    res = http.get(api_url)
                    video_url = http.json(res, schema=self._api_schema)['url']
                    bs = '{0}k'.format(bitrate['value'])

                    if protocol == 'hls':
                        for _, stream in HLSStream.parse_variant_playlist(
                                self.session, video_url).items():
                            yield bs, stream
                    elif protocol == 'hds':
                        for _, stream in HDSStream.parse_manifest(
                                self.session, video_url).items():
                            yield bs, stream
Exemple #26
0
    def _get_streams(self):
        if '/news/videos/' in self.url:
            # VOD
            streams = self._get_vod_streams()
        else:
            # Live
            streams = self._get_live_streams()

        for video_url in streams:
            if '.f4m' in video_url:
                for stream in HDSStream.parse_manifest(self.session,
                                                       video_url).items():
                    yield stream
            elif '.m3u8' in video_url:
                for stream in HLSStream.parse_variant_playlist(
                        self.session, video_url).items():
                    yield stream
            if '.mp4' in video_url:
                match = self._mp4_bitrate_re.match(video_url)
                if match is not None:
                    bitrate = match.group('bitrate') + 'k'
                else:
                    bitrate = 'vod'
                yield bitrate, HTTPStream(self.session, video_url)
Exemple #27
0
    def _get_streams(self):
        # Retrieve geolocation data
        res = http.get(self.GEO_URL)
        geo = http.json(res, schema=self._geo_schema)
        country_code = geo['reponse']['geo_info']['country_code']

        # Retrieve URL page and search for video ID
        res = http.get(self.url)
        if 'france.tv' in self.url:
            match = self._pluzz_video_id_re.search(res.text)
        elif 'ludo.fr' in self.url or 'zouzous.fr' in self.url:
            match = self._jeunesse_video_id_re.search(res.text)
        elif 'france3-regions.francetvinfo.fr' in self.url:
            match = self._f3_regions_video_id_re.search(res.text)
        elif 'sport.francetvinfo.fr' in self.url:
            match = self._sport_video_id_re.search(res.text)
        if match is None:
            return
        video_id = match.group('video_id')

        # Retrieve SWF player URL
        swf_url = None
        res = http.get(self.PLAYER_GENERATOR_URL)
        player_url = update_scheme(
            self.url,
            http.json(res, schema=self._player_schema)['result'])
        res = http.get(player_url)
        match = self._swf_re.search(res.text)
        if match is not None:
            swf_url = update_scheme(self.url, match.group(0))

        res = http.get(self.API_URL.format(video_id))
        videos = http.json(res, schema=self._api_schema)
        now = time.time()

        offline = False
        geolocked = False
        drm = False
        expired = False

        streams = []
        for video in videos['videos']:
            video_url = video['url']

            # Check whether video format is available
            if video['statut'] != 'ONLINE':
                offline = offline or True
                continue

            # Check whether video format is geo-locked
            if video['geoblocage'] is not None and country_code not in video[
                    'geoblocage']:
                geolocked = geolocked or True
                continue

            # Check whether video is DRM-protected
            if video['drm']:
                drm = drm or True
                continue

            # Check whether video format is expired
            available = False
            for interval in video['plages_ouverture']:
                available = (interval['debut'] or 0) <= now <= (interval['fin']
                                                                or sys.maxsize)
                if available:
                    break
            if not available:
                expired = expired or True
                continue

            # TODO: add DASH streams once supported
            if '.mpd' in video_url:
                continue

            if '.f4m' in video_url or 'france.tv' in self.url:
                res = http.get(self.TOKEN_URL.format(video_url))
                video_url = res.text

            if '.f4m' in video_url and swf_url is not None:
                for bitrate, stream in HDSStream.parse_manifest(
                        self.session, video_url, is_akamai=True,
                        pvswf=swf_url).items():
                    # HDS videos with data in their manifest fragment token
                    # doesn't seem to be supported by HDSStream. Ignore such
                    # stream (but HDS stream having only the hdntl parameter in
                    # their manifest token will be provided)
                    pvtoken = stream.request_params['params'].get(
                        'pvtoken', '')
                    match = self._hds_pv_data_re.search(pvtoken)
                    if match is None:
                        streams.append((bitrate, stream))
            elif '.m3u8' in video_url:
                for stream in HLSStream.parse_variant_playlist(
                        self.session, video_url).items():
                    streams.append(stream)
            # HBB TV streams are not provided anymore by France Televisions
            elif '.mp4' in video_url and '/hbbtv/' not in video_url:
                match = self._mp4_bitrate_re.match(video_url)
                if match is not None:
                    bitrate = match.group('bitrate')
                else:
                    # Fallback bitrate (seems all France Televisions MP4 videos
                    # seem have such bitrate)
                    bitrate = '1500k'
                streams.append((bitrate, HTTPStream(self.session, video_url)))

        if self.get_option("mux_subtitles") and videos['subtitles'] != []:
            substreams = {}
            for subtitle in videos['subtitles']:
                # TTML subtitles are available but not supported by FFmpeg
                if subtitle['format'] == 'ttml':
                    continue
                substreams[subtitle['type']] = HTTPStream(
                    self.session, subtitle['url'])

            for quality, stream in streams:
                yield quality, MuxedStream(self.session,
                                           stream,
                                           subtitles=substreams)
        else:
            for stream in streams:
                yield stream

        if offline:
            self.logger.error(
                'Failed to access stream, may be due to offline content')
        if geolocked:
            self.logger.error(
                'Failed to access stream, may be due to geo-restricted content'
            )
        if drm:
            self.logger.error(
                'Failed to access stream, may be due to DRM-protected content')
        if expired:
            self.logger.error(
                'Failed to access stream, may be due to expired content')
Exemple #28
0
    def _get_streams(self):
        res = http.get(self.url)
        match = self._player_js.search(res.text)
        if match:
            player_js = match.group(0)
            self.logger.info("Found player js {0}", player_js)
        else:
            self.logger.info(
                "Didn't find player js. Probably this page doesn't contain a video"
            )
            return

        res = http.get(player_js)
        m = self._data_re.search(res.text)
        if not m:
            self.logger.info(
                "Couldn't extract json metadata from player.js: {0}",
                player_js)
            return

        stream_metadata = json.loads(m.group("data"))
        is_video = stream_metadata["mediaType"] in ["live", "vod"]
        is_audio = stream_metadata["mediaType"] == "aod"

        media_version = tuple([
            int(d)
            for d in stream_metadata["mediaVersion"].split("-")[0].split(".")
        ])

        if is_video or is_audio:
            media_url = stream_metadata["mediaResource"]["dflt"][
                "videoURL" if is_video else "audioURL"]
            media_url_alt = stream_metadata["mediaResource"]["alt"][
                "videoURL" if is_video else "audioURL"]
            media_name = "audio" if is_audio else "vod"

            if media_version >= (1, 2, 0):
                media_format = stream_metadata["mediaResource"]["dflt"][
                    "mediaFormat"]
                media_format_alt = stream_metadata["mediaResource"]["alt"][
                    "mediaFormat"]
            else:
                media_format = stream_metadata["mediaFormat"]
                media_format_alt = media_url_alt[-4:]

            stream_url = {
                "url": media_url,
                "format": media_format,
                "name": media_name
            }

            stream_url_alt = {
                "url": media_url_alt,
                "format": media_format_alt,
                "name": media_name
            }

            for stream in [stream_url, stream_url_alt]:
                url = update_scheme("http://", stream["url"])
                try:
                    if stream["format"] in ["hds", ".f4m"]:
                        for s in HDSStream.parse_manifest(
                                self.session, url, is_akamai=True).items():
                            yield s
                    elif stream["format"] in ["hls", "m3u8"]:
                        streams = HLSStream.parse_variant_playlist(
                            self.session, url).items()
                        if not streams:
                            yield "live", HLSStream(self.session, url)
                        for s in streams:
                            yield s
                    elif stream["format"] in ["mp3", "mp4", ".mp3", ".mp4"]:
                        yield stream["name"], HTTPStream(self.session, url)
                except IOError as err:
                    self.logger.error("Failed to extract {0} streams: {1}",
                                      stream["format"], err)
Exemple #29
0
 def _get_hds_streams(self, info):
     # Needs the hdcore parameter added
     url = info["_stream"] + HDCORE_PARAMETER
     return HDSStream.parse_manifest(self.session, url,
                                     pvswf=SWF_URL).items()
Exemple #30
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