Ejemplo n.º 1
0
    def _create_adaptive_streams(self, adaptive_formats):
        streams = {}
        adaptive_streams = {}
        best_audio_itag = None

        # Extract audio streams from the adaptive format list
        for url, label, itag, mimeType in adaptive_formats:
            if url is None:
                continue
            # extract any high quality streams only available in adaptive formats
            adaptive_streams[itag] = url
            stream_type, stream_codecs = mimeType

            if stream_type == "audio":
                streams[f"audio_{stream_codecs}"] = HTTPStream(self.session, url)

                # find the best quality audio stream m4a, opus or vorbis
                if best_audio_itag is None or self.adp_audio[itag] > self.adp_audio[best_audio_itag]:
                    best_audio_itag = itag

        if best_audio_itag and adaptive_streams and MuxedStream.is_usable(self.session):
            aurl = adaptive_streams[best_audio_itag]
            for itag, name in self.adp_video.items():
                if itag not in adaptive_streams:
                    continue
                vurl = adaptive_streams[itag]
                log.debug(f"MuxedStream: v {itag} a {best_audio_itag} = {name}")
                streams[name] = MuxedStream(
                    self.session,
                    HTTPStream(self.session, vurl),
                    HTTPStream(self.session, aurl)
                )

        return streams
Ejemplo n.º 2
0
    def _create_adaptive_streams(self, info, streams):
        adaptive_streams = {}
        best_audio_itag = None

        # Extract audio streams from the adaptive format list
        streaming_data = info.get("player_response",
                                  {}).get("streamingData", {})
        for stream_info in streaming_data.get("adaptiveFormats", []):
            if "url" not in stream_info:
                continue
            stream_params = dict(parse_qsl(stream_info["url"]))
            if "itag" not in stream_params:
                continue
            itag = int(stream_params["itag"])
            # extract any high quality streams only available in adaptive formats
            adaptive_streams[itag] = stream_info["url"]

            stream_type, stream_format = stream_info["mimeType"]

            if stream_type == "audio":
                stream = HTTPStream(self.session, stream_info["url"])
                name = "audio_{0}".format(stream_format)
                streams[name] = stream

                # find the best quality audio stream m4a, opus or vorbis
                if best_audio_itag is None or self.adp_audio[
                        itag] > self.adp_audio[best_audio_itag]:
                    best_audio_itag = itag

        if best_audio_itag and adaptive_streams and MuxedStream.is_usable(
                self.session):
            aurl = adaptive_streams[best_audio_itag]
            for itag, name in self.adp_video.items():
                if itag in adaptive_streams:
                    vurl = adaptive_streams[itag]
                    log.debug(
                        "MuxedStream: v {video} a {audio} = {name}".format(
                            audio=best_audio_itag,
                            name=name,
                            video=itag,
                        ))
                    streams[name] = MuxedStream(self.session,
                                                HTTPStream(self.session, vurl),
                                                HTTPStream(self.session, aurl))

        return streams
Ejemplo n.º 3
0
    def _get_streams(self):
        if not MuxedStream.is_usable(self.session):
            return

        media_id, application = self._get_media_app()
        if not media_id:
            return

        wsclient = UStreamTVWsClient(
            self.session,
            media_id,
            application,
            referrer=self.url,
            cluster="live",
            password=self.get_option("password")
        )
        log.debug(
            f"Connecting to UStream API:"
            f" media_id={media_id},"
            f" application={application},"
            f" referrer={self.url},"
            f" cluster=live"
        )
        wsclient.start()

        log.debug(f"Waiting for stream data (for at most {self.STREAM_READY_TIMEOUT} seconds)...")
        if (
            not wsclient.ready.wait(self.STREAM_READY_TIMEOUT)
            or not wsclient.is_alive()
            or wsclient.stream_error
        ):
            log.error(wsclient.stream_error or "Waiting for stream data timed out.")
            wsclient.close()
            return

        if not wsclient.stream_formats_audio:
            for video in wsclient.stream_formats_video:
                yield f"{video.height}p", UStreamTVStream(self.session, "video", wsclient, video)
        else:
            for video in wsclient.stream_formats_video:
                for audio in wsclient.stream_formats_audio:
                    yield f"{video.height}p+a{audio.bitrate}k", MuxedStream(
                        self.session,
                        UStreamTVStream(self.session, "video", wsclient, video),
                        UStreamTVStream(self.session, "audio", wsclient, audio)
                    )
Ejemplo n.º 4
0
    def _create_adaptive_streams(self, info, streams, protected):
        adaptive_streams = {}
        best_audio_itag = None

        # Extract audio streams from the DASH format list
        for stream_info in info.get("adaptive_fmts", []):
            if stream_info.get("s"):
                protected = True
                continue

            stream_params = dict(parse_qsl(stream_info["url"]))
            if "itag" not in stream_params:
                continue
            itag = int(stream_params["itag"])
            # extract any high quality streams only available in adaptive formats
            adaptive_streams[itag] = stream_info["url"]

            stream_type, stream_format = stream_info["type"]
            if stream_type == "audio":
                stream = HTTPStream(self.session, stream_info["url"])
                name = "audio_{0}".format(stream_format)
                streams[name] = stream

                # find the best quality audio stream m4a, opus or vorbis
                if best_audio_itag is None or self.adp_audio[itag] > self.adp_audio[best_audio_itag]:
                    best_audio_itag = itag

        if best_audio_itag and adaptive_streams and MuxedStream.is_usable(self.session):
            aurl = adaptive_streams[best_audio_itag]
            for itag, name in self.adp_video.items():
                if itag in adaptive_streams:
                    vurl = adaptive_streams[itag]
                    log.debug("MuxedStream: v {video} a {audio} = {name}".format(
                        audio=best_audio_itag,
                        name=name,
                        video=itag,
                    ))
                    streams[name] = MuxedStream(self.session,
                                                HTTPStream(self.session, vurl),
                                                HTTPStream(self.session, aurl))

        return streams, protected
Ejemplo n.º 5
0
    def ytdl_fallback(self):
        '''Basic support for m3u8 URLs with youtube-dl'''
        log.debug(f'Fallback {youtube_dl.__name__} {youtube_dl.version.__version__}')

        class YTDL_Logger(object):
            def debug(self, msg):
                log.debug(msg)

            def warning(self, msg):
                log.warning(msg)

            def error(self, msg):
                log.trace(msg)

        ydl_opts = {
            'call_home': False,
            'forcejson': True,
            'logger': YTDL_Logger(),
            'no_color': True,
            'noplaylist': True,
            'no_warnings': True,
            'verbose': False,
            'quiet': True,
        }

        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            try:
                info = ydl.extract_info(self.url, download=False)
            except Exception:
                return

            if not info or not info.get('formats'):
                return

        self.title = info['title']

        streams = []
        for stream in info['formats']:
            if stream['protocol'] in ['m3u8', 'm3u8_native'] and stream['ext'] == 'mp4':
                log.trace('{0!r}'.format(stream))
                name = stream.get('height') or stream.get('width')
                if name:
                    name = '{0}p'.format(name)
                    streams.append((name, HLSStream(self.session,
                                                    stream['url'],
                                                    headers=stream['http_headers'])))

        if not streams:
            if ('youtube.com' in self.url
                    and info.get('requested_formats')
                    and len(info.get('requested_formats')) == 2
                    and MuxedStream.is_usable(self.session)):
                audio_url = audio_format = video_url = video_format = video_name = None
                for stream in info.get('requested_formats'):
                    if stream.get('format_id') == '135':
                        url = stream.get('manifest_url')
                        if not url:
                            return
                        return DASHStream.parse_manifest(self.session, url).items()
                    if not stream.get('height'):
                        audio_url = stream.get('url')
                        audio_format = stream.get('format_id')
                    if stream.get('height'):
                        video_url = stream.get('url')
                        video_format = stream.get('format_id')
                        video_name = '{0}p'.format(stream.get('height'))

                log.debug('MuxedStream: v {video} a {audio} = {name}'.format(
                    audio=audio_format,
                    name=video_name,
                    video=video_format,
                ))
                streams.append((video_name,
                                MuxedStream(self.session,
                                            HTTPStream(self.session, video_url, headers=stream['http_headers']),
                                            HTTPStream(self.session, audio_url, headers=stream['http_headers']))
                                ))
        return streams
Ejemplo n.º 6
0
    def _get_streams(self):
        info = self._get_stream_info(self.url)
        if not info:
            return

        formats = info.get("fmt_list")
        streams = {}
        protected = False
        for stream_info in info.get("url_encoded_fmt_stream_map", []):
            if stream_info.get("s"):
                protected = True
                continue

            stream = HTTPStream(self.session, stream_info["url"])
            name = formats.get(stream_info["itag"]) or stream_info["quality"]

            if stream_info.get("stereo3d"):
                name += "_3d"

            streams[name] = stream

        adaptive_streams = {}
        best_audio_itag = None

        # Extract audio streams from the DASH format list
        for stream_info in info.get("adaptive_fmts", []):
            if stream_info.get("s"):
                protected = True
                continue

            stream_params = dict(parse_qsl(stream_info["url"]))
            if "itag" not in stream_params:
                continue
            itag = int(stream_params["itag"])
            # extract any high quality streams only available in adaptive formats
            adaptive_streams[itag] = stream_info["url"]

            stream_type, stream_format = stream_info["type"]
            if stream_type == "audio":
                stream = HTTPStream(self.session, stream_info["url"])
                name = "audio_{0}".format(stream_format)
                streams[name] = stream

                # find the best quality audio stream m4a, opus or vorbis
                if best_audio_itag is None or self.adp_audio[
                        itag] > self.adp_audio[best_audio_itag]:
                    best_audio_itag = itag

        if best_audio_itag and adaptive_streams and MuxedStream.is_usable(
                self.session):
            aurl = adaptive_streams[best_audio_itag]
            for itag, name in self.adp_video.items():
                if itag in adaptive_streams:
                    vurl = adaptive_streams[itag]
                    streams[name] = MuxedStream(self.session,
                                                HTTPStream(self.session, vurl),
                                                HTTPStream(self.session, aurl))

        hls_playlist = info.get("hlsvp")
        if hls_playlist:
            try:
                hls_streams = HLSStream.parse_variant_playlist(
                    self.session,
                    hls_playlist,
                    headers=HLS_HEADERS,
                    namekey="pixels")
                streams.update(hls_streams)
            except IOError as err:
                self.logger.warning("Failed to extract HLS streams: {0}", err)

        if not streams and protected:
            raise PluginError("This plugin does not support protected videos, "
                              "try youtube-dl instead")

        return streams
Ejemplo n.º 7
0
    def _get_streams(self):
        info = self._get_stream_info(self.url)
        if not info:
            return

        formats = info.get("fmt_list")
        streams = {}
        protected = False
        for stream_info in info.get("url_encoded_fmt_stream_map", []):
            if stream_info.get("s"):
                protected = True
                continue

            stream = HTTPStream(self.session, stream_info["url"])
            name = formats.get(stream_info["itag"]) or stream_info["quality"]

            if stream_info.get("stereo3d"):
                name += "_3d"

            streams[name] = stream

        adaptive_streams = {}
        best_audio_itag = None

        # Extract audio streams from the DASH format list
        for stream_info in info.get("adaptive_fmts", []):
            if stream_info.get("s"):
                protected = True
                continue

            stream_params = dict(parse_qsl(stream_info["url"]))
            if "itag" not in stream_params:
                continue
            itag = int(stream_params["itag"])
            # extract any high quality streams only available in adaptive formats
            adaptive_streams[itag] = stream_info["url"]

            stream_type, stream_format = stream_info["type"]
            if stream_type == "audio":
                stream = HTTPStream(self.session, stream_info["url"])
                name = "audio_{0}".format(stream_format)
                streams[name] = stream

                # find the best quality audio stream m4a, opus or vorbis
                if best_audio_itag is None or self.adp_audio[itag] > self.adp_audio[best_audio_itag]:
                    best_audio_itag = itag

        if best_audio_itag and adaptive_streams and MuxedStream.is_usable(self.session):
            aurl = adaptive_streams[best_audio_itag]
            for itag, name in self.adp_video.items():
                if itag in adaptive_streams:
                    vurl = adaptive_streams[itag]
                    streams[name] = MuxedStream(self.session,
                                                HTTPStream(self.session, vurl),
                                                HTTPStream(self.session, aurl))

        hls_playlist = info.get("hlsvp")
        if hls_playlist:
            try:
                hls_streams = HLSStream.parse_variant_playlist(
                    self.session, hls_playlist, headers=HLS_HEADERS, namekey="pixels"
                )
                streams.update(hls_streams)
            except IOError as err:
                self.logger.warning("Failed to extract HLS streams: {0}", err)

        if not streams and protected:
            raise PluginError("This plugin does not support protected videos, "
                              "try youtube-dl instead")

        return streams
Ejemplo n.º 8
0
    def _create_adaptive_streams(self, info, streams):
        if not MuxedStream.is_usable(self.session):
            log.info("Cannot use FFMPEG")
            return streams

        adaptive_streams = {}
        best_audio_itag = None
        adp_video = self.adp_video_h264.copy()
        vp9 = "vp9" if hostname() in self.stb_vp9_1 or hostname(
        ) in self.stb_vp9_2 else ""
        if not vp9:
            log.debug("STB w/o vp9 4K support detected")
            if self.get_option("yes-vp9-codecs"):
                vp9 = "vp9"
        elif self.get_option("no-vp9-codecs"):
            vp9 = ""
            log.info("VP9 Codecs are skipped")
        if vp9:
            adp_video.update(self.adp_video_vp9)
            if self.get_option(
                    "yes-vp9-hdr-codecs") or hostname() in self.stb_vp9_2:
                adp_video.update(self.adp_video_vp9_hdr)

        # Extract streams from the DASH format list
        for stream_info in info.get("formats", []):
            itag = int(stream_info["format_id"])
            if itag not in self.adp_audio and itag not in adp_video:
                log.debug(
                    "Skipped format:{}, Codec:{}",
                    stream_info["format"],
                    stream_info["acodec"] if stream_info["acodec"] != "none"
                    else stream_info["vcodec"],
                )
                continue

            # extract any high quality streams only available in adaptive formats and not skipped
            adaptive_streams[itag] = stream_info["url"]
            stream_format = stream_info["ext"]
            if itag in self.adp_audio:
                if self.get_option(
                        "no-opus-codec") and stream_info["acodec"] == "opus":
                    log.debug("Skipped format:{}, Codec:{}",
                              stream_info["format"], stream_info["acodec"])
                    continue

                stream = HTTPStream(self.session, stream_info["url"])
                name = "audio_{0}".format(stream_format)
                streams[name] = stream

                # find the best quality audio stream m4a, opus or vorbis
                if best_audio_itag is None or self.adp_audio[
                        itag] > self.adp_audio[best_audio_itag]:
                    best_audio_itag = itag

        if best_audio_itag and adaptive_streams and MuxedStream.is_usable(
                self.session):
            aurl = adaptive_streams[best_audio_itag]
            for itag, name in adp_video.items():
                if itag in adaptive_streams:
                    vurl = adaptive_streams[itag]
                    log.debug(
                        "MuxedStream: v {video} a {audio} = {name}".format(
                            audio=best_audio_itag,
                            name=name,
                            video=itag,
                        ))
                    streams[name] = MuxedStream(self.session,
                                                HTTPStream(self.session, vurl),
                                                HTTPStream(self.session, aurl))

        return streams