예제 #1
0
def convert_video_xml(res):
    dom = res_xml(res)
    data = dict(play_offset=0, start_offset=0, end_offset=0,
                chunks=defaultdict(list), restrictions={})
    total_duration = 0

    for archive in dom.findall("archive"):
        duration = int(archive.findtext("length", 0))
        total_duration += duration

        # Add 'source' chunk
        chunk = dict(url=archive.findtext("video_file_url"),
                     length=duration)
        data["chunks"]["source"].append(chunk)

        # Find transcode chunks
        for transcode in archive.find("transcode_file_urls"):
            match = re.match("transcode_(\w+)", transcode.tag)
            if match:
                name = match.group(1)
                chunk = dict(url=transcode.text,
                             length=duration)
                data["chunks"][name].append(chunk)

    data["play_offset"] = dom.findtext("bracket_start") or 0
    data["start_offset"] = dom.findtext("bracket_start") or 0
    data["end_offset"] = dom.findtext("bracket_end") or total_duration

    restrictions = dom.findtext("archive_restrictions/restriction")
    if restrictions == "archives":
        data["restrictions"] = dict((n, "chansub") for n in data["chunks"])

    return data
예제 #2
0
    def _get_rtmp_streams(self, channelname):
        options = dict(l="info",
                       a="xmlClipPath",
                       clip_id=channelname,
                       rid=time())
        res = urlget(self.APIURL, params=options)

        dom = res_xml(res)
        rtmpurl = dom.getElementsByTagName("url")
        rtmp = None

        if len(rtmpurl) > 0:
            rtmp = get_node_text(rtmpurl[0])
        else:
            raise PluginError(
                ("No RTMP Streams found on URL {0}").format(self.url))

        rtmplist = {}
        rtmplist["live"] = RTMPStream(self.session, {
            "rtmp": rtmp,
            "swfVfy": self.SWFURL,
            "live": True
        })

        return rtmplist
예제 #3
0
    def _is_live(self, liveid):
        res = urlget(self.StatusAPIURL.format(liveid))

        dom = res_xml(res, "status XML")

        live = dom.getElementsByTagName("live_is_live")

        if len(live) > 0:
            return get_node_text(live[0]) == "1"

        return False
예제 #4
0
    def _get_streams(self):
        (liveid, swfurl) = self._get_channel_info(self.url)

        if not (liveid and swfurl):
            raise NoStreamsError(self.url)

        if not self._is_live(liveid):
            raise NoStreamsError(self.url)

        self.logger.debug("Fetching stream info")
        res = urlget(self.ConfigURL.format(liveid))

        dom = res_xml(res, "config XML")

        streams = {}
        channels = dom.getElementsByTagName("channels")[0]
        clip = channels.getElementsByTagName("clip")[0]
        items = clip.getElementsByTagName("item")

        for item in items:
            base = item.getAttribute("base")
            if not base:
                continue

            if base[0] == "$":
                ref = re.match("\${(.+)}", base).group(1)
                base = self.CDN[ref]

            for streamel in item.getElementsByTagName("stream"):
                name = streamel.getAttribute("label").lower().replace(" ", "_")
                playpath = streamel.getAttribute("name")

                stream = RTMPStream(self.session, {
                    "rtmp": ("{0}/{1}").format(base, playpath),
                    "live": True,
                    "swfVfy": swfurl,
                    "pageUrl": self.url
                })

                if not name in streams:
                    streams[name] = stream
                else:
                    index = items.index(item)

                    if index == 1:
                        streams[name + "_alt"] = stream
                    else:
                        streams[name + "_alt" + str(index)] = stream

        return streams
예제 #5
0
    def call(self, path, format="json", host=None, **extra_params):
        params = dict(as3="t", **extra_params)

        if self.oauth_token:
            params["oauth_token"] = self.oauth_token

        url = "https://api.{0}{1}.{2}".format(host or self.host, path, format)
        res = urlget(url, params=params, session=self.session)

        if format == "json":
            return res_json(res)
        elif format == "xml":
            return res_xml(res)
        else:
            return res
예제 #6
0
    def call(self, path, format="json", host=None, **extra_params):
        params = dict(as3="t", **extra_params)

        if self.oauth_token:
            params["oauth_token"] = self.oauth_token

        url = "https://api.{0}{1}.{2}".format(host or self.host, path, format)
        res = urlget(url, params=params, session=self.session)

        if format == "json":
            return res_json(res)
        elif format == "xml":
            return res_xml(res)
        else:
            return res
예제 #7
0
    def _limelight_soap_playlist_items(self, channelid):
        payload = """<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                                         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                                         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                       <SOAP-ENV:Body>
                         <tns:getPlaylistWithNItemsByChannelId xmlns:tns="http://service.data.media.pluggd.com">
                           <tns:in0>{0}</tns:in0>
                           <tns:in1>0</tns:in1>
                           <tns:in2>7</tns:in2>
                         </tns:getPlaylistWithNItemsByChannelId>
                       </SOAP-ENV:Body>
                     </SOAP-ENV:Envelope>""".format(channelid)

        headers = {
            "Content-Type": "text/xml; charset=utf-8",
            "Referer": "http://assets.delvenetworks.com/player/loader.swf",
            "x-page-url": self.url
        }

        res = urlopen(self.LimelightSOAPURL, data=payload, headers=headers)
        dom = res_xml(res)

        streams = {}
        for item in dom.getElementsByTagName("PlaylistItem"):
            for stream in dom.getElementsByTagName("Stream"):
                for url in stream.getElementsByTagName("url"):
                    url = get_node_text(url)
                    break
                else:
                    continue

                for height in stream.getElementsByTagName(
                        "videoHeightInPixels"):
                    height = get_node_text(height)
                    break
                else:
                    continue

                streamname = "{0}p".format(height)
                parsed = urlparse(url)

                if parsed.scheme.startswith("rtmp"):
                    params = dict(rtmp=url, live=True)
                    streams[streamname] = RTMPStream(self.session, params)

        return streams
예제 #8
0
    def _limelight_soap_playlist_items(self, channelid):
        payload = """<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                                         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                                         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                       <SOAP-ENV:Body>
                         <tns:getPlaylistWithNItemsByChannelId xmlns:tns="http://service.data.media.pluggd.com">
                           <tns:in0>{0}</tns:in0>
                           <tns:in1>0</tns:in1>
                           <tns:in2>7</tns:in2>
                         </tns:getPlaylistWithNItemsByChannelId>
                       </SOAP-ENV:Body>
                     </SOAP-ENV:Envelope>""".format(channelid)

        headers = {
            "Content-Type": "text/xml; charset=utf-8",
            "Referer": "http://assets.delvenetworks.com/player/loader.swf",
            "x-page-url": self.url
        }

        res = urlopen(self.LimelightSOAPURL, data=payload, headers=headers)
        dom = res_xml(res)

        streams = {}
        for item in dom.getElementsByTagName("PlaylistItem"):
            for stream in dom.getElementsByTagName("Stream"):
                for url in stream.getElementsByTagName("url"):
                    url = get_node_text(url)
                    break
                else:
                    continue

                for height in stream.getElementsByTagName("videoHeightInPixels"):
                    height = get_node_text(height)
                    break
                else:
                    continue

                streamname = "{0}p".format(height)
                parsed = urlparse(url)

                if parsed.scheme.startswith("rtmp"):
                    params = dict(rtmp=url, live=True)
                    streams[streamname] = RTMPStream(self.session, params)

        return streams
예제 #9
0
    def _limelight_soap_playlist_items(self, channelid):
        payload = """<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                                         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                                         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                       <SOAP-ENV:Body>
                         <tns:getPlaylistWithNItemsByChannelId xmlns:tns="http://service.data.media.pluggd.com">
                           <tns:in0>{0}</tns:in0>
                           <tns:in1>0</tns:in1>
                           <tns:in2>7</tns:in2>
                         </tns:getPlaylistWithNItemsByChannelId>
                       </SOAP-ENV:Body>
                     </SOAP-ENV:Envelope>""".format(channelid)

        headers = {
            "Content-Type": "text/xml; charset=utf-8",
            "Referer": "http://assets.delvenetworks.com/player/loader.swf",
            "x-page-url": self.url
        }

        res = urlopen(self.LimelightSOAPURL, data=payload, headers=headers)
        playlist = res_xml(res)

        streams = {}
        items = playlist.findall(
            ".//*{http://service.data.media.pluggd.com}playlistItems/")

        for item in items:
            streams_ = item.findall(
                "./{http://service.data.media.pluggd.com}streams/")

            for stream in streams_:
                url = stream.findtext(
                    "{http://service.data.media.pluggd.com}url")
                height = stream.findtext(
                    "{http://service.data.media.pluggd.com}videoHeightInPixels"
                )

                streamname = "{0}p".format(height)
                parsed = urlparse(url)

                if parsed.scheme.startswith("rtmp"):
                    params = dict(rtmp=url, live=True)
                    streams[streamname] = RTMPStream(self.session, params)

        return streams
예제 #10
0
    def _get_metadata(self):
        url = self.MetadataURL.format(self.channelname)

        headers = {}
        cookie = self.options.get("cookie")

        if cookie:
            headers["Cookie"] = cookie

        res = urlget(url, headers=headers)
        dom = res_xml(res, "metadata XML")

        metadata = {}
        metadata["title"] = self._get_node_if_exists(dom, "title")
        metadata["access_guid"] = self._get_node_if_exists(dom, "access_guid")
        metadata["login"] = self._get_node_if_exists(dom, "login")

        return metadata
예제 #11
0
    def _get_metadata(self):
        url = self.MetadataURL.format(self.channelname)

        headers = {}
        cookie = self.options.get("cookie")

        if cookie:
            headers["Cookie"] = cookie

        res = urlget(url, headers=headers)
        dom = res_xml(res, "metadata XML")

        metadata = {}
        metadata["title"] = self._get_node_if_exists(dom, "title")
        metadata["access_guid"] = self._get_node_if_exists(dom, "access_guid")
        metadata["login"] = self._get_node_if_exists(dom, "login")

        return metadata
예제 #12
0
    def _get_rtmp_streams(self, channelname):
        options = dict(l="info", a="xmlClipPath", clip_id=channelname,
                       rid=time())
        res = urlget(self.APIURL, params=options)
        clip = res_xml(res)
        rtmpurl = clip.findtext("./info/url")

        if rtmpurl is None:
            raise PluginError(("No RTMP Streams found on URL {0}").format(self.url))

        rtmplist = {}
        rtmplist["live"] = RTMPStream(self.session, {
            "rtmp": rtmpurl,
            "swfVfy": self.SWFURL,
            "live": True
        })

        return rtmplist
예제 #13
0
    def _get_metadata(self):
        url = self.MetadataURL.format(self.channelname)

        headers = {}
        cookie = self.options.get("cookie")

        if cookie:
            headers["Cookie"] = cookie

        res = urlget(url, headers=headers)
        meta = res_xml(res, "metadata XML")

        metadata = {}
        metadata["access_guid"] = meta.findtext("access_guid")
        metadata["login"] = meta.findtext("login")
        metadata["title"] = meta.findtext("title")

        return metadata
    def _get_metadata(self):
        url = self.MetadataURL.format(self.channelname)

        headers = {}
        cookie = self.options.get("cookie")

        if cookie:
            headers["Cookie"] = cookie

        res = urlget(url, headers=headers)
        meta = res_xml(res, "metadata XML")

        metadata = {}
        metadata["access_guid"] = meta.findtext("access_guid")
        metadata["login"] = meta.findtext("login")
        metadata["title"] = meta.findtext("title")

        return metadata
예제 #15
0
파일: gomexp.py 프로젝트: Am2k/livestreamer
    def _get_streams(self):
        cubeid = self._get_live_cubeid()
        if not cubeid:
            return

        res = urlget(API_URL_LIVE, params=dict(cubeid=cubeid))
        root = res_xml(res)

        streams = {}
        for entry in root.findall("./ENTRY/*/[@reftype='live'][@href]"):
            url = entry.get("href")

            try:
                hls_streams = HLSStream.parse_variant_playlist(self.session,
                                                               url)
                streams.update(hls_streams)
            except IOError as err:
                self.logger.error("Failed to open playlist: {0}", err)

        return streams
예제 #16
0
    def _get_streams(self):
        cubeid = self._get_live_cubeid()
        if not cubeid:
            return

        res = urlget(API_URL_LIVE, params=dict(cubeid=cubeid))
        root = res_xml(res)

        streams = {}
        for entry in root.findall("./ENTRY/*/[@reftype='live'][@href]"):
            url = entry.get("href")

            try:
                hls_streams = HLSStream.parse_variant_playlist(
                    self.session, url)
                streams.update(hls_streams)
            except IOError as err:
                self.logger.error("Failed to open playlist: {0}", err)

        return streams
예제 #17
0
    def _get_metadata(self):
        url = METADATA_URL.format(self.channel)
        cookies = {}

        for cookie in self.options.get("cookie").split(";"):
            try:
                name, value = cookie.split("=")
            except ValueError:
                continue

            cookies[name.strip()] = value.strip()

        res = urlget(url, cookies=cookies)
        meta = res_xml(res, "metadata XML")

        metadata = {}
        metadata["access_guid"] = meta.findtext("access_guid")
        metadata["login"] = meta.findtext("login")
        metadata["title"] = meta.findtext("title")

        return metadata
    def _get_rtmp_streams(self, channelname):
        options = dict(l="info",
                       a="xmlClipPath",
                       clip_id=channelname,
                       rid=time())
        res = urlget(self.APIURL, params=options)
        clip = res_xml(res)
        rtmpurl = clip.findtext("./info/url")

        if rtmpurl is None:
            raise PluginError(
                ("No RTMP Streams found on URL {0}").format(self.url))

        rtmplist = {}
        rtmplist["live"] = RTMPStream(self.session, {
            "rtmp": rtmpurl,
            "swfVfy": self.SWFURL,
            "live": True
        })

        return rtmplist
예제 #19
0
    def _parse_smil(self, url):
        res = urlget(url)
        dom = res_xml(res, "config XML")

        httpbase = None
        streams = {}

        for meta in dom.getElementsByTagName("meta"):
            if meta.getAttribute("name") == "httpBase":
                httpbase = meta.getAttribute("content")
                break

        if not httpbase:
            raise PluginError("Missing HTTP base in SMIL")

        for video in dom.getElementsByTagName("video"):
            url = "{0}/{1}".format(httpbase, video.getAttribute("src"))
            bitrate = int(video.getAttribute("system-bitrate"))
            streams[bitrate] = AkamaiHDStream(self.session, url)

        return streams
예제 #20
0
    def _parse_smil(self, url):
        res = urlget(url)
        dom = res_xml(res, "config XML")

        httpbase = None
        streams = {}

        for meta in dom.getElementsByTagName("meta"):
            if meta.getAttribute("name") == "httpBase":
                httpbase = meta.getAttribute("content")
                break

        if not httpbase:
            raise PluginError("Missing HTTP base in SMIL")

        for video in dom.getElementsByTagName("video"):
            url = "{0}/{1}".format(httpbase, video.getAttribute("src"))
            bitrate = int(video.getAttribute("system-bitrate"))
            streams[bitrate] = AkamaiHDStream(self.session, url)

        return streams
예제 #21
0
    def _limelight_soap_playlist_items(self, channelid):
        payload = """<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                                         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                                         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                       <SOAP-ENV:Body>
                         <tns:getPlaylistWithNItemsByChannelId xmlns:tns="http://service.data.media.pluggd.com">
                           <tns:in0>{0}</tns:in0>
                           <tns:in1>0</tns:in1>
                           <tns:in2>7</tns:in2>
                         </tns:getPlaylistWithNItemsByChannelId>
                       </SOAP-ENV:Body>
                     </SOAP-ENV:Envelope>""".format(channelid)

        headers = {
            "Content-Type": "text/xml; charset=utf-8",
            "Referer": "http://assets.delvenetworks.com/player/loader.swf",
            "x-page-url": self.url
        }

        res = urlopen(self.LimelightSOAPURL, data=payload, headers=headers)
        playlist = res_xml(res)

        streams = {}
        items = playlist.findall(".//*{http://service.data.media.pluggd.com}playlistItems/")

        for item in items:
            streams_ = item.findall("./{http://service.data.media.pluggd.com}streams/")

            for stream in streams_:
                url = stream.findtext("{http://service.data.media.pluggd.com}url")
                height = stream.findtext("{http://service.data.media.pluggd.com}videoHeightInPixels")

                streamname = "{0}p".format(height)
                parsed = urlparse(url)

                if parsed.scheme.startswith("rtmp"):
                    params = dict(rtmp=url, live=True)
                    streams[streamname] = RTMPStream(self.session, params)

        return streams
예제 #22
0
    def _get_rtmp_streams(self, channelname):
        options = dict(l="info", a="xmlClipPath", clip_id=channelname,
                       rid=time())
        res = urlget(self.APIURL, params=options)

        dom = res_xml(res)
        rtmpurl = dom.getElementsByTagName("url")
        rtmp = None

        if len(rtmpurl) > 0:
            rtmp = get_node_text(rtmpurl[0])
        else:
            raise PluginError(("No RTMP Streams found on URL {0}").format(self.url))

        rtmplist = {}
        rtmplist["live"] = RTMPStream(self.session, {
            "rtmp": rtmp,
            "swfVfy": self.SWFURL,
            "live": True
        })

        return rtmplist
예제 #23
0
    def _get_metadata(self):
        url = self.MetadataURL.format(self.channelname)

        cookies = {}

        for cookie in self.options.get("cookie").split(";"):
            try:
                name, value = cookie.split("=")
            except ValueError:
                continue

            cookies[name.strip()] = value.strip()

        res = urlget(url, cookies=cookies)
        meta = res_xml(res, "metadata XML")

        metadata = {}
        metadata["access_guid"] = meta.findtext("access_guid")
        metadata["login"] = meta.findtext("login")
        metadata["title"] = meta.findtext("title")

        return metadata
예제 #24
0
    def _parse_smil(self, url):
        res = urlget(url)
        smil = res_xml(res, "SMIL config")

        streams = {}
        httpbase = smil.find("{http://www.w3.org/2001/SMIL20/Language}head/"
                             "{http://www.w3.org/2001/SMIL20/Language}meta[@name='httpBase']")

        if not (httpbase is not None and httpbase.attrib.get("content")):
            raise PluginError("Missing HTTP base in SMIL")

        httpbase = httpbase.attrib.get("content")

        videos = smil.findall("{http://www.w3.org/2001/SMIL20/Language}body/"
                              "{http://www.w3.org/2001/SMIL20/Language}switch/"
                              "{http://www.w3.org/2001/SMIL20/Language}video")

        for video in videos:
            url = urljoin(httpbase, video.attrib.get("src"))
            bitrate = int(video.attrib.get("system-bitrate"))
            streams[bitrate] = AkamaiHDStream(self.session, url)

        return streams
예제 #25
0
 def _get_live_cubeid(self):
     res = urlget(API_URL_APP, params=dict(mode="get_live"))
     root = res_xml(res)
     return root.findtext("./cube/cubeid")
예제 #26
0
파일: gomexp.py 프로젝트: Am2k/livestreamer
 def _get_live_cubeid(self):
     res = urlget(API_URL_APP, params=dict(mode="get_live"))
     root = res_xml(res)
     return root.findtext("./cube/cubeid")