src/streamlink/stream/dash.py
def parse_manifest(cls, session, url_or_manifest, **args):
        """
        Attempt to parse a DASH manifest file and return its streams

        :param session: Streamlink session instance
        :param url_or_manifest: URL of the manifest file or an XML manifest string
        :return: a dict of name -> DASHStream instances
        """
        ret = {}

        if url_or_manifest.startswith('<?xml'):
            mpd = MPD(parse_xml(url_or_manifest, ignore_ns=True))
        else:
            res = session.http.get(url_or_manifest, **args)
            url = res.url

            urlp = list(urlparse(url))
            urlp[2], _ = urlp[2].rsplit("/", 1)

            mpd = MPD(session.http.xml(res, ignore_ns=True), base_url=urlunparse(urlp), url=url)

        video, audio = [], []

        # Search for suitable video and audio representations
        for aset in mpd.periods[0].adaptationSets:
            if aset.contentProtection:
                raise PluginError("{} is protected by DRM".format(url))
            for rep in aset.representations:
                if rep.mimeType.startswith("video"):
                    video.append(rep)
                elif rep.mimeType.startswith("audio"):
                    audio.append(rep)

        if not video:
            video = [None]

        if not audio:
            audio = [None]

        locale = session.localization
        locale_lang = locale.language
        lang = None
        available_languages = set()

        # if the locale is explicitly set, prefer that language over others
        for aud in audio:
            if aud and aud.lang:
                available_languages.add(aud.lang)
                try:
                    if locale.explicit and aud.lang and Language.get(aud.lang) == locale_lang:
                        lang = aud.lang
                except LookupError:
                    continue

        if not lang:
            # filter by the first language that appears
            lang = audio[0] and audio[0].lang

        log.debug("Available languages for DASH audio streams: {0} (using: {1})".format(", ".join(available_languages) or "NONE", lang or "n/a"))

        # if the language is given by the stream, filter out other languages that do not match
        if len(available_languages) > 1:
            audio = list(filter(lambda a: a.lang is None or a.lang == lang, audio))

        for vid, aud in itertools.product(video, audio):
            stream = DASHStream(session, mpd, vid, aud, **args)
            stream_name = []

            if vid:
                stream_name.append("{:0.0f}{}".format(vid.height or vid.bandwidth_rounded, "p" if vid.height else "k"))
            if audio and len(audio) > 1:
                stream_name.append("a{:0.0f}k".format(aud.bandwidth))
            ret['+'.join(stream_name)] = stream
        return ret
def parse_manifest(cls, session, url_or_manifest, **args):
        ret = {}

        if url_or_manifest.startswith('<?xml'):
            mpd = MPD(parse_xml(url_or_manifest, ignore_ns=True))
        else:
            res = session.http.get(url_or_manifest, **args)
            url = res.url

            urlp = list(urlparse(url))
            urlp[2], _ = urlp[2].rsplit("/", 1)

            mpd = MPD(session.http.xml(res, ignore_ns=True), base_url=urlunparse(urlp), url=url)

        video, audio = [], []

        # Search for suitable video and audio representations
        for aset in mpd.periods[0].adaptationSets:
            if aset.contentProtection:
                raise PluginError("{} is protected by DRM".format(url))
            for rep in aset.representations:
                if rep.mimeType.startswith("video"):
                    video.append(rep)
                elif rep.mimeType.startswith("audio"):
                    audio.append(rep)

        if not video:
            video = [None]

        if not audio:
            audio = [None]

        locale = session.localization
        locale_lang = locale.language
        lang = None
        available_languages = set()

        # if the locale is explicitly set, prefer that language over others
        for aud in audio:
            if aud and aud.lang:
                available_languages.add(aud.lang)
                try:
                    if locale.explicit and aud.lang and Language.get(aud.lang) == locale_lang:
                        lang = aud.lang
                except LookupError:
                    continue

        if not lang:
            # filter by the first language that appears
            lang = audio[0] and audio[0].lang

        log.debug("Available languages for DASH audio streams: {0} (using: {1})".format(", ".join(available_languages) or "NONE", lang or "n/a"))

        # if the language is given by the stream, filter out other languages that do not match
        if len(available_languages) > 1:
            audio = list(filter(lambda a: a.lang is None or a.lang == lang, audio))

        for vid, aud in itertools.product(video, audio):
            stream = DASHStream(session, mpd, vid, aud, **args)
            stream_name = []

            if vid:
                stream_name.append("{:0.0f}{}".format(vid.height or vid.bandwidth_rounded, "p" if vid.height else "k"))
            if audio and len(audio) > 1:
                stream_name.append("a{:0.0f}k".format(aud.bandwidth))
            ret['+'.join(stream_name)] = stream
        return ret
def parse_manifest ( cls , session , url_or_manifest , * * args ) : ret = { } if url_or_manifest . startswith ( '<?xml' ) : mpd = MPD ( parse_xml ( url_or_manifest , ignore_ns = True ) ) else : res = session . http . get ( url_or_manifest , * * args ) url = res . url urlp = list ( urlparse ( url ) ) urlp [ 2 ] , _ = urlp [ 2 ] . rsplit ( "/" , 1 ) mpd = MPD ( session . http . xml ( res , ignore_ns = True ) , base_url = urlunparse ( urlp ) , url = url ) video , audio = [ ] , [ ] # Search for suitable video and audio representations for aset in mpd . periods [ 0 ] . adaptationSets : if aset . contentProtection : raise PluginError ( "{} is protected by DRM" . format ( url ) ) for rep in aset . representations : if rep . mimeType . startswith ( "video" ) : video . append ( rep ) elif rep . mimeType . startswith ( "audio" ) : audio . append ( rep ) if not video : video = [ None ] if not audio : audio = [ None ] locale = session . localization locale_lang = locale . language lang = None available_languages = set ( ) # if the locale is explicitly set, prefer that language over others for aud in audio : if aud and aud . lang : available_languages . add ( aud . lang ) try : if locale . explicit and aud . lang and Language . get ( aud . lang ) == locale_lang : lang = aud . lang except LookupError : continue if not lang : # filter by the first language that appears lang = audio [ 0 ] and audio [ 0 ] . lang log . debug ( "Available languages for DASH audio streams: {0} (using: {1})" . format ( ", " . join ( available_languages ) or "NONE" , lang or "n/a" ) ) # if the language is given by the stream, filter out other languages that do not match if len ( available_languages ) > 1 : audio = list ( filter ( lambda a : a . lang is None or a . lang == lang , audio ) ) for vid , aud in itertools . product ( video , audio ) : stream = DASHStream ( session , mpd , vid , aud , * * args ) stream_name = [ ] if vid : stream_name . append ( "{:0.0f}{}" . format ( vid . height or vid . bandwidth_rounded , "p" if vid . height else "k" ) ) if audio and len ( audio ) > 1 : stream_name . append ( "a{:0.0f}k" . format ( aud . bandwidth ) ) ret [ '+' . join ( stream_name ) ] = stream return ret
Attempt to parse a DASH manifest file and return its streams

        :param session: Streamlink session instance
        :param url_or_manifest: URL of the manifest file or an XML manifest string
        :return: a dict of name -> DASHStream instances
Attempt to parse a DASH manifest file and return its streams