Пример #1
0
 def test_parse_xml_validate(self):
     expected = ET.Element("test", {"foo": "bar"})
     actual = parse_xml(u"""<test foo="bar"/>""",
                        schema=validate.Schema(
                            xml_element(tag="test", attrib={"foo": text})))
     self.assertEqual(expected.tag, actual.tag)
     self.assertEqual(expected.attrib, actual.attrib)
Пример #2
0
    def _get_show_streams(self,
                          stream_data,
                          show,
                          episode,
                          platform="desktop"):
        video_id = parse_json(stream_data.group(1), schema=self.vod_id_schema)
        res = http.get(self.vod_api,
                       params={
                           "platform": platform,
                           "id": video_id
                       })

        # create a unique list of the stream manifest URLs
        streams = []
        urldups = []
        for stream in parse_xml(res.text, schema=self._vod_api_schema):
            if stream["url"] not in urldups:
                streams.append(stream)
                urldups.append(stream["url"])

        mapper = StreamMapper(lambda fmt, strm: strm["url"].endswith(fmt))
        mapper.map(".m3u8", self._make_hls_hds_stream,
                   HLSStream.parse_variant_playlist)
        mapper.map(".f4m",
                   self._make_hls_hds_stream,
                   HDSStream.parse_manifest,
                   is_akamai=True)
        mapper.map(
            ".mp4", lambda s:
            (s["bitrate"] + "k", HTTPStream(self.session, s["url"])))

        for q, s in mapper(streams):
            yield q, s
Пример #3
0
 def test_parse_xml_entities(self):
     expected = ET.Element("test", {"foo": "bar &"})
     actual = parse_xml(u"""<test foo="bar &"/>""",
                        schema=validate.Schema(xml_element(tag="test", attrib={"foo": text})),
                        invalid_char_entities=True)
     self.assertEqual(expected.tag, actual.tag)
     self.assertEqual(expected.attrib, actual.attrib)
Пример #4
0
 def test_parse_xml_entities(self):
     expected = ET.Element("test", {"foo": "bar &"})
     actual = parse_xml("""<test foo="bar &"/>""",
                        schema=validate.Schema(xml_element(tag="test", attrib={"foo": text})),
                        invalid_char_entities=True)
     self.assertEqual(expected.tag, actual.tag)
     self.assertEqual(expected.attrib, actual.attrib)
Пример #5
0
    def _get_show_streams(self, stream_data, show, episode, platform="desktop"):
        video_id = parse_json(stream_data.group(1), schema=self.vod_id_schema)
        res = http.get(self.vod_api, params={"platform": platform, "id": video_id})

        # create a unique list of the stream manifest URLs
        streams = []
        urldups = []
        for stream in parse_xml(res.text, schema=self._vod_api_schema):
            if stream["url"] not in urldups:
                streams.append(stream)
                urldups.append(stream["url"])

        mapper = StreamMapper(lambda fmt, strm: strm["url"].endswith(fmt))
        mapper.map(".m3u8", self._make_hls_hds_stream, HLSStream.parse_variant_playlist)
        mapper.map(".f4m", self._make_hls_hds_stream, HDSStream.parse_manifest, is_akamai=True)
        mapper.map(".mp4", lambda s: (s["bitrate"] + "k", HTTPStream(self.session, s["url"])))

        for q, s in mapper(streams):
            yield q, s
Пример #6
0
    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
        """

        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))

        ret = []
        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.append(('+'.join(stream_name), stream))

        # rename duplicate streams
        dict_value_list = defaultdict(list)
        for k, v in ret:
            dict_value_list[k].append(v)

        ret_new = {}
        for q in dict_value_list:
            items = dict_value_list[q]
            for n in range(len(items)):
                if n == 0:
                    ret_new[q] = items[n]
                elif n == 1:
                    ret_new[f'{q}_alt'] = items[n]
                else:
                    ret_new[f'{q}_alt{n}'] = items[n]
        return ret_new
Пример #7
0
 def test_parse_xml_ns(self):
     expected = ET.Element("{foo:bar}test", {"foo": "bar"})
     actual = parse_xml(u"""<h:test foo="bar" xmlns:h="foo:bar"/>""")
     self.assertEqual(expected.tag, actual.tag)
     self.assertEqual(expected.attrib, actual.attrib)
Пример #8
0
 def test_parse_xml_ns_ignore_tab(self):
     expected = ET.Element("test", {"foo": "bar"})
     actual = parse_xml(u"""<test	foo="bar"	xmlns="foo:bar"/>""",
                        ignore_ns=True)
     self.assertEqual(expected.tag, actual.tag)
     self.assertEqual(expected.attrib, actual.attrib)
Пример #9
0
 def test_parse_xml_ns(self):
     expected = ET.Element("{foo:bar}test", {"foo": "bar"})
     actual = parse_xml(u"""<h:test foo="bar" xmlns:h="foo:bar"/>""")
     self.assertEqual(expected.tag, actual.tag)
     self.assertEqual(expected.attrib, actual.attrib)
Пример #10
0
 def test_parse_xml_ns_ignore_tab(self):
     expected = ET.Element("test", {"foo": "bar"})
     actual = parse_xml(u"""<test	foo="bar"	xmlns="foo:bar"/>""", ignore_ns=True)
     self.assertEqual(expected.tag, actual.tag)
     self.assertEqual(expected.attrib, actual.attrib)
Пример #11
0
 def xml(cls, res, *args, **kwargs):
     """Parses XML from a response."""
     return parse_xml(res.text, *args, **kwargs)