Ejemplo n.º 1
0
    def CreateVideoItem(self, resultSet):
        """Creates a MediaItem of type 'video' using the resultSet from the regex.

        Arguments:
        resultSet : tuple (string) - the resultSet of the self.videoItemRegex

        Returns:
        A new MediaItem of type 'video' or 'audio' (despite the method's name)

        This method creates a new MediaItem from the Regular Expression or Json
        results <resultSet>. The method should be implemented by derived classes
        and are specific to the channel.

        If the item is completely processed an no further data needs to be fetched
        the self.complete property should be set to True. If not set to True, the
        self.UpdateVideoItem method is called if the item is focussed or selected
        for playback.

        """

        # Logger.Trace(resultSet)

        xmlData = XmlHelper(resultSet)
        title = xmlData.GetSingleNodeContent("title")
        url = xmlData.GetSingleNodeContent("link")
        description = xmlData.GetSingleNodeContent("description")
        description = description.replace("<![CDATA[ ",
                                          "").replace("]]>", "").replace(
                                              "<p>", "").replace("</p>", "\n")

        item = mediaitem.MediaItem(title, url)
        item.type = 'video'
        item.complete = False
        item.description = description
        item.thumb = self.noImage
        item.icon = self.icon

        date = xmlData.GetSingleNodeContent("pubDate")
        dateResult = Regexer.DoRegex("\w+, (\d+) (\w+) (\d+)", date)[-1]
        day = dateResult[0]
        monthPart = dateResult[1].lower()
        year = dateResult[2]

        try:
            monthLookup = [
                "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep",
                "oct", "nov", "dec"
            ]
            month = monthLookup.index(monthPart) + 1
            item.SetDate(year, month, day)
        except:
            Logger.Error("Error matching month: %s",
                         resultSet[4].lower(),
                         exc_info=True)

        return item
    def create_video_item(self, result_set):
        """ Creates a MediaItem of type 'video' using the result_set from the regex.

        This method creates a new MediaItem from the Regular Expression or Json
        results <result_set>. The method should be implemented by derived classes
        and are specific to the channel.

        If the item is completely processed an no further data needs to be fetched
        the self.complete property should be set to True. If not set to True, the
        self.update_video_item method is called if the item is focussed or selected
        for playback.

        :param list[str]|dict[str,str] result_set: The result_set of the self.episodeItemRegex

        :return: A new MediaItem of type 'video' or 'audio' (despite the method's name).
        :rtype: MediaItem|None

        """

        # Logger.Trace(result_set)

        xml_data = XmlHelper(result_set)
        title = xml_data.get_single_node_content("title")
        url = xml_data.get_single_node_content("link")
        description = xml_data.get_single_node_content("description")
        description = description.replace("<![CDATA[ ",
                                          "").replace("]]>", "").replace(
                                              "<p>", "").replace("</p>", "\n")

        item = MediaItem(title, url)
        item.type = 'video'
        item.complete = False
        item.description = description
        item.thumb = self.noImage
        item.icon = self.icon

        date = xml_data.get_single_node_content("pubDate")
        date_result = Regexer.do_regex(r"\w+, (\d+) (\w+) (\d+)", date)[-1]
        day = date_result[0]
        month_part = date_result[1].lower()
        year = date_result[2]

        try:
            month_lookup = [
                "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep",
                "oct", "nov", "dec"
            ]
            month = month_lookup.index(month_part) + 1
            item.set_date(year, month, day)
        except:
            Logger.error("Error matching month: %s",
                         result_set[4].lower(),
                         exc_info=True)

        return item
Ejemplo n.º 3
0
    def CreateVideoItemXml(self, resultSet):
        """Creates a MediaItem of type 'video' using the resultSet from the regex.

        Arguments:
        resultSet : tuple (string) - the resultSet of the self.videoItemRegex

        Returns:
        A new MediaItem of type 'video' or 'audio' (despite the method's name)

        This method creates a new MediaItem from the Regular Expression or Json
        results <resultSet>. The method should be implemented by derived classes
        and are specific to the channel.

        If the item is completely processed an no further data needs to be fetched
        the self.complete property should be set to True. If not set to True, the
        self.UpdateVideoItem method is called if the item is focussed or selected
        for playback.

        """
        Logger.Trace(resultSet)

        xmlData = XmlHelper(resultSet)
        title = xmlData.GetSingleNodeContent("title")
        url = xmlData.GetTagAttribute("link", {"rel": "alternate"}, {"href": None})
        description = xmlData.GetSingleNodeContent("description")
        date = xmlData.GetSingleNodeContent("updated")

        item = mediaitem.MediaItem(title, url)
        item.type = 'video'
        item.description = description
        thumbUrl = xmlData.GetTagAttribute("link", {"rel": "enclosure"}, {"href": None})
        if thumbUrl:
            thumbUrl = thumbUrl.replace("/medium/", "/large/")  # or extralarge
            if thumbUrl.startswith("//"):
                thumbUrl = "http:%s" % (thumbUrl, )
            item.thumb = thumbUrl
        else:
            item.thumb = self.noImage

        item.complete = False
        Logger.Trace("%s - %s - %s - %s - %s", title, description, date, thumbUrl, url)
        return item
Ejemplo n.º 4
0
    def ParseXmlData(self, data):
        """ Parses the xml data entry of the mainlist

        Arguments:
        data : string - the retrieve data that was loaded for the current item and URL.

        Returns:
        A tuple of the data and a list of MediaItems that were generated.


        Accepts an data from the ProcessFolderList method, BEFORE the items are
        processed. Allows setting of parameters (like title etc) for the channel.
        Inside this method the <data> could be changed and additional items can
        be created.

        The return values should always be instantiated in at least ("", []).

        """

        items = []
        data = UriHandler.Open(
            "http://www.omroepflevoland.nl/Mobile/FeedV3/programmas.aspx?t=a&wifi=1&v=14",
            proxy=self.proxy)
        programs = Regexer.DoRegex("<item[\w\W]{0,5000}?</item>", data)

        liveItem = mediaitem.MediaItem(
            "\a.: Live TV :.",
            "http://edge02.streamgate.nl/live/omroepflevoland/"
            "smil:flevo_livestream.smil/playlist.m3u8")
        liveItem.icon = self.icon
        liveItem.thumb = self.noImage
        liveItem.type = 'video'
        liveItem.dontGroup = True
        now = datetime.datetime.now()
        liveItem.SetDate(now.year, now.month, now.day, now.hour, now.minute,
                         now.second)
        items.append(liveItem)

        for program in programs:
            xmlData = XmlHelper(program)
            name = xmlData.GetTagAttribute("item", {"title": None})
            Logger.Debug("Processing: '%s'", name)

            thumb = xmlData.GetTagAttribute("thumb", {"url": None})
            thumb = "http://www.omroepflevoland.nl/SiteFiles/%s" % (thumb, )

            date = xmlData.GetTagAttribute("item", {"date": None})
            day, month, year = date.split("-")

            showItem = mediaitem.MediaItem(name, None)
            showItem.thumb = thumb
            showItem.icon = self.icon
            showItem.SetDate(year, month, day)
            items.append(showItem)

            episodes = Regexer.DoRegex("<show[\w\W]{0,1000}?</show>", program)
            for episode in episodes:
                xmlData = XmlHelper(episode)
                url = xmlData.GetTagAttribute("show", {"url": None})
                description = xmlData.GetSingleNodeContent("content",
                                                           stripCData=True)
                name = "%s - %s" % (name, date)

                date = xmlData.GetTagAttribute("show", {"date": None})
                day, month, year = date.split("-")
                time = xmlData.GetTagAttribute("show", {"time": None})
                hours, minutes = time.split(":")

                episodeItem = mediaitem.MediaItem(name, None)
                episodeItem.type = 'video'
                episodeItem.thumb = thumb
                episodeItem.description = description
                episodeItem.icon = self.icon
                episodeItem.SetDate(year, month, day, hours, minutes, 0)
                episodeItem.complete = True
                showItem.items.append(episodeItem)

                part = episodeItem.CreateNewEmptyMediaPart()
                part.AppendMediaStream(url, 1225)
                # we guess the other streams
                part.AppendMediaStream(url.replace("/middel/", "/hoog/"), 1825)
                part.AppendMediaStream(url.replace("/middel/", "/laag/"), 630)

        return data, items
Ejemplo n.º 5
0
    def update_video_item(self, item):
        """ Updates an existing MediaItem with more data.

        Used to update none complete MediaItems (self.complete = False). This
        could include opening the item's URL to fetch more data and then process that
        data or retrieve it's real media-URL.

        The method should at least:
        * cache the thumbnail to disk (use self.noImage if no thumb is available).
        * set at least one MediaItemPart with a single MediaStream.
        * set self.complete = True.

        if the returned item does not have a MediaItemPart then the self.complete flag
        will automatically be set back to False.

        :param MediaItem item: the original MediaItem that needs updating.

        :return: The original item with more data added to it's properties.
        :rtype: MediaItem

        """

        Logger.debug('Starting update_video_item for %s (%s)', item.name,
                     self.channelName)

        data = UriHandler.open(item.url, proxy=self.proxy)
        json_data, _ = self.extract_json(data)
        video_id = json_data.get_value("versions", 0, "id")
        stream_data_url = "http://open.live.bbc.co.uk/mediaselector/5/select/version/2.0/mediaset/iptv-all/vpid/{}".format(
            video_id)

        # this URL is one from the webbrowser but requires a security part. So NOT:
        # streamDataUrl = "http://open.live.bbc.co.uk/mediaselector/5/select/version
        # /2.0/mediaset/pc/vpid/%s" % (vid,)
        #
        # but:
        # streamDataUrl = "http://open.live.bbc.co.uk/mediaselector/5/select/version
        # /2.0/mediaset/pc/vpid/%s/atk/2214e42b5729dcdd012dfb61a3054d39309ccd31/asn/1/
        # And I don't know where that one comes from

        part = item.create_new_empty_media_part()

        stream_data = UriHandler.open(stream_data_url, proxy=self.proxy)
        # Reroute for debugging
        # from debug.router import Router
        # streamData = Router.get_via("uk", streamDataUrl, self.proxy)

        connection_datas = Regexer.do_regex(
            r'<media bitrate="(\d+)"[^>]+>\W*'
            r'(<connection[^>]+>\W*)'
            r'(<connection[^>]+>\W*)?'
            r'(<connection[^>]+>\W*)?'
            r'(<connection[^>]+>\W*)?'
            r'(<connection[^>]+>\W*)?'
            r'(<connection[^>]+>\W*)?'
            r'(<connection[^>]+>\W*)?'
            r'(<connection[^>]+>\W*)?'
            r'(<connection[^>]+>\W*)?'
            r'(<connection[^>]+>\W*)?'
            r'(<connection[^>]+>\W*)?'
            r'(<connection[^>]+>\W*)?</media>', stream_data)

        for connection_data in connection_datas:
            # first the bitrate
            bitrate = int(connection_data[0])
            Logger.trace("Found Media: %s", connection_data)

            # go through the available connections
            for connection in connection_data[1:]:
                if not connection:
                    continue

                connection_xml = XmlHelper(connection)
                stream_bitrate = bitrate
                Logger.trace("Analyzing Connection: %s", connection)
                supplier = connection_xml.get_tag_attribute(
                    "connection", {"supplier": None})
                protocol = connection_xml.get_tag_attribute(
                    "connection", {"protocol": None})
                transfer_format = connection_xml.get_tag_attribute(
                    "connection", {"transferFormat": None})
                Logger.debug(
                    "Found connection information:\n"
                    "Protocol:       %s\n"
                    "TransferFormat: %s\n"
                    "Supplier:       %s\n"
                    "Bitrate:        %s", protocol, transfer_format, supplier,
                    bitrate)

                if protocol.startswith("http"):
                    if transfer_format != "hls":  # and transfer_format != "dash":
                        Logger.debug("Ignoring TransferFormat: %s",
                                     transfer_format)
                        continue
                    if "lime" in supplier or "mf_akamai_uk" in supplier:
                        # Prefer others
                        stream_bitrate -= 1
                        # Logger.debug("Ignoring Supplier: %s", supplier)
                        # continue
                    url = connection_xml.get_tag_attribute(
                        "connection", {"href": None})

                elif protocol.startswith("rtmp"):
                    Logger.warning("Ignoring RTMP for now")
                    continue
                else:
                    Logger.warning("Unknown protocol: %s", protocol)
                    continue

                if transfer_format == "hls":
                    item.complete = M3u8.update_part_with_m3u8_streams(
                        part, url, proxy=self.proxy, bitrate=stream_bitrate)
                elif transfer_format == "dash":
                    strm = part.append_media_stream(url, bitrate)
                    Mpd.set_input_stream_addon_input(strm, self.proxy)

        # get the subtitle
        subtitles = Regexer.do_regex(
            '<connection href="(http://www.bbc.co.uk/iplayer/subtitles/[^"]+/)([^/]+.xml)"',
            stream_data)
        if len(subtitles) > 0:
            subtitle = subtitles[0]
            subtitle_url = "%s%s" % (subtitle[0], subtitle[1])
            part.Subtitle = subtitlehelper.SubtitleHelper.download_subtitle(
                subtitle_url, subtitle[1], "ttml", proxy=self.proxy)

        item.complete = True
        Logger.trace('finishing update_video_item: %s.', item)
        return item
Ejemplo n.º 6
0
    def UpdateVideoItem(self, item):
        """
        Accepts an item. It returns an updated item.
        """
        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name, self.channelName)

        Logger.Trace(item.url)
        if not item.url.startswith("http://www.bbc.co.uk/mediaselector/"):
            Logger.Debug("Determining the stream URL")
            data = UriHandler.Open(item.url, proxy=self.proxy)
            needle = '"vpid"\W*"([^"]+)"'
            vid = Regexer.DoRegex(needle, data)[-1]
            # streamDataUrl = "http://open.live.bbc.co.uk/mediaselector/4/mtis/stream/%s/" % (vid,)
            streamDataUrl = "http://open.live.bbc.co.uk/mediaselector/5/select/version/2.0/mediaset/iptv-all/vpid/%s" % (vid,)
            # streamDataUrl = "http://open.live.bbc.co.uk/mediaselector/5/select/version/2.0/mediaset/pc/vpid/%s" % (vid,)
        else:
            streamDataUrl = item.url

        # this URL is one from the webbrowser but requires a security part. So NOT:
        # streamDataUrl = "http://open.live.bbc.co.uk/mediaselector/5/select/version
        # /2.0/mediaset/pc/vpid/%s" % (vid,)
        #
        # but:
        # streamDataUrl = "http://open.live.bbc.co.uk/mediaselector/5/select/version
        # /2.0/mediaset/pc/vpid/%s/atk/2214e42b5729dcdd012dfb61a3054d39309ccd31/asn/1/
        # And I don't know where that one comes from

        part = item.CreateNewEmptyMediaPart()

        if True:
            streamData = UriHandler.Open(streamDataUrl, proxy=self.proxy)
        else:
            from debug.router import Router
            streamData = Router.GetVia("uk", streamDataUrl, self.proxy)

        connectionDatas = Regexer.DoRegex(
            '<media bitrate="(\d+)"[^>]+>\W*'
            '(<connection[^>]+>\W*)'
            '(<connection[^>]+>\W*)?'
            '(<connection[^>]+>\W*)?'
            '(<connection[^>]+>\W*)?</media>', streamData)

        for connectionData in connectionDatas:
            # first the bitrate
            bitrate = connectionData[0]
            Logger.Trace("Found Media: %s", connectionData)

            # go through the available connections
            for connection in connectionData[1:]:
                if not connection:
                    continue

                connectionXml = XmlHelper(connection)
                Logger.Trace("Analyzing Connection: %s", connection)
                supplier = connectionXml.GetTagAttribute("connection", {"supplier": None})
                protocol = connectionXml.GetTagAttribute("connection", {"protocol": None})
                transferFormat = connectionXml.GetTagAttribute("connection", {"transferFormat": None})
                Logger.Debug("Found connection information:\n"
                             "Protocol:       %s\n"
                             "TransferFormat: %s\n"
                             "Supplier:       %s\n"
                             "Bitrate:        %s",
                             protocol, transferFormat, supplier, bitrate)

                if protocol.startswith("http"):
                    if transferFormat != "hls":
                        Logger.Debug("Ignoring TransferFormat: %s", transferFormat)
                        continue
                    if "lime" in supplier or "mf_akamai_uk" in supplier:
                        Logger.Debug("Ignoring Supplier: %s", supplier)
                        continue
                    url = connectionXml.GetTagAttribute("connection", {"href": None})
                elif protocol.startswith("rtmp"):
                    Logger.Warning("Ignoring RTMP for now")
                    continue
                else:
                    Logger.Warning("Unknown protocol: %s", protocol)
                    continue

                #
                # # port: we take the default one
                # # determine protocol
                # protocol = connectionXml.GetTagAttribute("connection", {"protocol": None})
                # if protocol == "http":
                #     Logger.Debug("Http stream found, skipping for now.")
                #     continue
                #
                # elif protocol == "":
                #     protocol = "rtmp"
                # Logger.Debug("Found protocol      : %s", protocol)
                #
                # # now for the non-http version, we need application, authentication, server, file and kind
                # application = connectionXml.GetTagAttribute("connection", {"application": None})
                # if application == "":
                #     application = "ondemand"
                # Logger.Debug("Found application   : %s", application)
                #
                # authentication = connectionXml.GetTagAttribute("connection", {"authString": None})
                # authentication = htmlentityhelper.HtmlEntityHelper.ConvertHTMLEntities(authentication)
                # Logger.Debug("Found authentication: %s", authentication)
                #
                # server = connectionXml.GetTagAttribute("connection", {"server": None})
                # Logger.Debug("Found server        : %s", server)
                #
                # fileName = connectionXml.GetTagAttribute("connection", {"identifier": None})
                # Logger.Debug("Found identifier    : %s", fileName)
                #
                # kind = connectionXml.GetTagAttribute("connection", {"kind": None})
                # Logger.Debug("Found kind          : %s", kind)
                #
                # Logger.Trace("XML: %s\nProtocol: %s, Server: %s, Application: %s, Authentication: %s, File: %s , Kind: %s", connection, protocol, server, application, authentication, fileName, kind)
                # if "akamai" in kind:
                #     Logger.Debug("Not including AKAMAI streams")
                #     continue
                #     # url = "%s://%s/%s?%s playpath=%s?%s" % (protocol, server, application, authentication, fileName, authentication)
                #     # Logger.Debug("Creating RTMP for Akamai type\n%s", url)
                #
                # elif kind == "limelight":
                #     # for limelight we need to be more specific on what to play
                #     url = "%s://%s/ app=%s?%s tcurl=%s://%s/%s?%s playpath=%s" % (
                #         protocol, server, application, authentication, protocol, server, application, authentication,
                #         fileName)
                #     Logger.Debug("Creating RTMP for LimeLight type\n%s", url)
                # else:
                #     # for a none-limelight we just compose a RTMP stream
                #     url = "%s://%s/%s?%s playpath=%s" % (protocol, server, application, authentication, fileName)
                #     Logger.Debug("Creating RTMP for a None-LimeLight type\n%s", url)
                # url = self.GetVerifiableVideoUrl(url)

                # if liveStream:
                #     url = "%s live=1" % (url, )
                part.AppendMediaStream(url, bitrate)

        # get the subtitle
        subtitles = Regexer.DoRegex('<connection href="(http://www.bbc.co.uk/iplayer/subtitles/[^"]+/)([^/]+.xml)"',
                                    streamData)
        if len(subtitles) > 0:
            subtitle = subtitles[0]
            subtitleUrl = "%s%s" % (subtitle[0], subtitle[1])
            part.Subtitle = subtitlehelper.SubtitleHelper.DownloadSubtitle(subtitleUrl, subtitle[1], "ttml",
                                                                           proxy=self.proxy)

        item.complete = True
        Logger.Trace('finishing UpdateVideoItem: %s.', item)
        return item