@classmethod<EOL><INDENT>def parse_variant_playlist(cls, session_, url, name_key="<STR_LIT:name>",<EOL>name_prefix="<STR_LIT>", check_streams=False,<EOL>force_restart=False, name_fmt=None,<EOL>start_offset=<NUM_LIT:0>, duration=None,<EOL>**request_params):<DEDENT>
locale = session_.localization<EOL>name_key = request_params.pop("<STR_LIT>", name_key)<EOL>name_prefix = request_params.pop("<STR_LIT>", name_prefix)<EOL>audio_select = session_.options.get("<STR_LIT>") or []<EOL>res = session_.http.get(url, exception=IOError, **request_params)<EOL>try:<EOL><INDENT>parser = hls_playlist.load(res.text, base_uri=res.url)<EOL><DEDENT>except ValueError as err:<EOL><INDENT>raise IOError("<STR_LIT>".format(err))<EOL><DEDENT>streams = {}<EOL>for playlist in filter(lambda p: not p.is_iframe, parser.playlists):<EOL><INDENT>names = dict(name=None, pixels=None, bitrate=None)<EOL>audio_streams = []<EOL>fallback_audio = []<EOL>default_audio = []<EOL>preferred_audio = []<EOL>for media in playlist.media:<EOL><INDENT>if media.type == "<STR_LIT>" and media.name:<EOL><INDENT>names["<STR_LIT:name>"] = media.name<EOL><DEDENT>elif media.type == "<STR_LIT>":<EOL><INDENT>audio_streams.append(media)<EOL><DEDENT><DEDENT>for media in audio_streams:<EOL><INDENT>if not media.uri:<EOL><INDENT>continue<EOL><DEDENT>if not fallback_audio and media.default:<EOL><INDENT>fallback_audio = [media]<EOL><DEDENT>if not default_audio and (media.autoselect and locale.equivalent(language=media.language)):<EOL><INDENT>default_audio = [media]<EOL><DEDENT>if (('<STR_LIT:*>' in audio_select or media.language in audio_select or media.name in audio_select) or<EOL>((not preferred_audio or media.default) and locale.explicit and locale.equivalent(<EOL>language=media.language))):<EOL><INDENT>preferred_audio.append(media)<EOL><DEDENT><DEDENT>fallback_audio = fallback_audio or (len(audio_streams) and<EOL>audio_streams[<NUM_LIT:0>].uri and [audio_streams[<NUM_LIT:0>]])<EOL>if playlist.stream_info.resolution:<EOL><INDENT>width, height = playlist.stream_info.resolution<EOL>names["<STR_LIT>"] = "<STR_LIT>".format(height)<EOL><DEDENT>if playlist.stream_info.bandwidth:<EOL><INDENT>bw = playlist.stream_info.bandwidth<EOL>if bw >= <NUM_LIT:1000>:<EOL><INDENT>names["<STR_LIT>"] = "<STR_LIT>".format(int(bw / <NUM_LIT>))<EOL><DEDENT>else:<EOL><INDENT>names["<STR_LIT>"] = "<STR_LIT>".format(bw / <NUM_LIT>)<EOL><DEDENT><DEDENT>if name_fmt:<EOL><INDENT>stream_name = name_fmt.format(**names)<EOL><DEDENT>else:<EOL><INDENT>stream_name = (names.get(name_key) or names.get("<STR_LIT:name>") or<EOL>names.get("<STR_LIT>") or names.get("<STR_LIT>"))<EOL><DEDENT>if not stream_name:<EOL><INDENT>continue<EOL><DEDENT>if stream_name in streams:  <EOL><INDENT>stream_name = "<STR_LIT>".format(stream_name)<EOL>num_alts = len(list(filter(lambda n: n.startswith(stream_name), streams.keys())))<EOL>if num_alts >= <NUM_LIT:2>:<EOL><INDENT>continue<EOL><DEDENT>elif num_alts > <NUM_LIT:0>:<EOL><INDENT>stream_name = "<STR_LIT>".format(stream_name, num_alts + <NUM_LIT:1>)<EOL><DEDENT><DEDENT>if check_streams:<EOL><INDENT>try:<EOL><INDENT>session_.http.get(playlist.uri, **request_params)<EOL><DEDENT>except KeyboardInterrupt:<EOL><INDENT>raise<EOL><DEDENT>except Exception:<EOL><INDENT>continue<EOL><DEDENT><DEDENT>external_audio = preferred_audio or default_audio or fallback_audio<EOL>if external_audio and FFMPEGMuxer.is_usable(session_):<EOL><INDENT>external_audio_msg = "<STR_LIT:U+002CU+0020>".join([<EOL>"<STR_LIT>".format(x.language, (x.name or "<STR_LIT>"))<EOL>for x in external_audio<EOL>])<EOL>log.debug("<STR_LIT>", name_prefix + stream_name,<EOL>external_audio_msg)<EOL>stream = MuxedHLSStream(session_,<EOL>video=playlist.uri,<EOL>audio=[x.uri for x in external_audio if x.uri],<EOL>force_restart=force_restart,<EOL>start_offset=start_offset,<EOL>duration=duration,<EOL>**request_params)<EOL><DEDENT>else:<EOL><INDENT>stream = cls(session_,<EOL>playlist.uri,<EOL>force_restart=force_restart,<EOL>start_offset=start_offset,<EOL>duration=duration,<EOL>**request_params)<EOL><DEDENT>streams[name_prefix + stream_name] = stream<EOL><DEDENT>return streams<EOL>
Attempts to parse a variant playlist and return its streams.

        :param url: The URL of the variant playlist.
        :param name_key: Prefer to use this key as stream name, valid keys are:
                         name, pixels, bitrate.
        :param name_prefix: Add this prefix to the stream names.
        :param check_streams: Only allow streams that are accessible.
        :param force_restart: Start at the first segment even for a live stream
        :param name_fmt: A format string for the name, allowed format keys are
                         name, pixels, bitrate.