Example #1
0
    def LoadChannelData(self, data):
        """ Adds the channel items to the listing.

        @param data:    The data to use.

        Returns a list of MediaItems that were retrieved.

        """

        items = []
        # data = UriHandler.Open("https://www.svtplay.se/api/channel_page", proxy=self.proxy, noCache=True)

        now = datetime.datetime.now()
        try:
            serverTime = UriHandler.Open("https://www.svtplay.se/api/server_time",
                                         proxy=self.proxy, noCache=True)
            serverTimeJson = JsonHelper(serverTime)
            serverTime = serverTimeJson.GetValue("time")
        except:
            Logger.Error("Error determining server time", exc_info=True)
            serverTime = "%04d-%02d-%02dT%02d:%02d:%02d" % (now.year, now.month, now.day, now.hour, now.minute, now.second)

        data = UriHandler.Open(
            "https://www.svtplay.se/api/channel_page?now=%s" % (serverTime, ),
            proxy=self.proxy)
        return data, items
Example #2
0
    def UpdateVideoItem(self, item):
        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name, self.channelName)

        # we need to fetch the actual url as it might differ for single video items
        data, secureUrl = UriHandler.Header(item.url, proxy=self.proxy)

        secureUrl = secureUrl.rstrip("/")
        secureUrl = "%s.mssecurevideo.json" % (secureUrl, )
        data = UriHandler.Open(secureUrl, proxy=self.proxy, additionalHeaders=item.HttpHeaders)
        secureData = JsonHelper(data, logger=Logger.Instance())
        mzid = secureData.GetValue(secureData.json.keys()[0], "videoid")
        assetUrl = "https://mediazone.vrt.be/api/v1/vrtvideo/assets/%s" % (mzid, )
        data = UriHandler.Open(assetUrl, proxy=self.proxy)
        assetData = JsonHelper(data, logger=Logger.Instance())

        for streamData in assetData.GetValue("targetUrls"):
            if streamData["type"] != "HLS":
                continue

            part = item.CreateNewEmptyMediaPart()
            for s, b, a in M3u8.GetStreamsFromM3u8(streamData["url"], self.proxy, mapAudio=True):
                item.complete = True
                if a:
                    audioPart = a.rsplit("-", 1)[-1]
                    audioPart = "-%s" % (audioPart, )
                    s = s.replace(".m3u8", audioPart)
                # s = self.GetVerifiableVideoUrl(s)
                part.AppendMediaStream(s, b)
        return item
Example #3
0
    def UpdateVideoItem(self, item):
        """Updates an existing MediaItem with more data.

        Arguments:
        item : MediaItem - the MediaItem that needs to be updated

        Returns:
        The original item with more data added to it's properties.

        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.

        """

        videoData = UriHandler.Open(item.url, proxy=self.proxy)

        if not videoData:
            return item

        videoData = JsonHelper(videoData)
        videoInfo = videoData.GetValue("data", "attributes")

        part = item.CreateNewEmptyMediaPart()
        # Somehow only this specific user-agent works (dunno why)!
        part.HttpHeaders[
            "user-agent"] = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 (.NET CLR 3.5.30729)"

        m3u8url = videoInfo["streaming"]["hls"]["url"]
        m3u8data = UriHandler.Open(m3u8url, self.proxy)

        for s, b, a in M3u8.GetStreamsFromM3u8(m3u8url,
                                               self.proxy,
                                               appendQueryString=False,
                                               mapAudio=True,
                                               playListData=m3u8data):
            item.complete = True
            if a:
                audioPart = a.split("-prog_index.m3u8", 1)[0]
                audioId = audioPart.rsplit("/", 1)[-1]
                s = s.replace("-prog_index.m3u8",
                              "-{0}-prog_index.m3u8".format(audioId))
            part.AppendMediaStream(s, b)

        vttUrl = M3u8.GetSubtitle(m3u8url, self.proxy, m3u8data)
        # https://dplaynordics-vod-80.akamaized.net/dplaydni/259/0/hls/243241001/1112635959-prog_index.m3u8?version_hash=bb753129&hdnts=st=1518218118~exp=1518304518~acl=/*~hmac=bdeefe0ec880f8614e14af4d4a5ca4d3260bf2eaa8559e1eb8ba788645f2087a
        vttUrl = vttUrl.replace("-prog_index.m3u8", "-0.vtt")
        part.Subtitle = SubtitleHelper.DownloadSubtitle(vttUrl,
                                                        format='srt',
                                                        proxy=self.proxy)
        return item
Example #4
0
    def UpdateVideoItem(self, item):
        """Updates an existing MediaItem with more data.

        Arguments:
        item : MediaItem - the MediaItem that needs to be updated

        Returns:
        The original item with more data added to it's properties.

        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.

        """

        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name, self.channelName)

        data = UriHandler.Open(item.url, proxy=self.proxy)

        # get the playlist GUID
        playlistGuids = Regexer.DoRegex("<div[^>]+data-playlist-id='([^']+)'[^>]+></div>", data)
        if not playlistGuids:
            # let's try the alternative then (for the new channels)
            playlistGuids = Regexer.DoRegex('local_playlist[", -]+([a-f0-9]{20})"', data)
        playlistGuid = playlistGuids[0]
        # Logger.Trace(playlistGuid)

        # now we can get the playlist meta data
        # http://api.mtvnn.com/v2/mrss.xml?uri=mgid%3Asensei%3Avideo%3Amtvnn.com%3Alocal_playlist-39ce0652b0b3c09258d9-SE-uma_site--ad_site-nickelodeon.se-ad_site_referer-video/9764-barjakt&adSite=nickelodeon.se&umaSite={umaSite}&show_images=true&url=http%3A//www.nickelodeon.se/video/9764-barjakt
        # but this seems to work.
        # http://api.mtvnn.com/v2/mrss.xml?uri=mgid%3Asensei%3Avideo%3Amtvnn.com%3Alocal_playlist-39ce0652b0b3c09258d9
        playListUrl = "http://api.mtvnn.com/v2/mrss.xml?uri=mgid%3Asensei%3Avideo%3Amtvnn.com%3Alocal_playlist-" + playlistGuid
        playListData = UriHandler.Open(playListUrl, proxy=self.proxy)

        # now get the real RTMP data
        rtmpMetaData = Regexer.DoRegex("<media:content [^>]+url='([^']+)'", playListData)[0]
        rtmpData = UriHandler.Open(rtmpMetaData, proxy=self.proxy)

        rtmpUrls = Regexer.DoRegex('<rendition[^>]+bitrate="(\d+)"[^>]*>\W+<src>([^<]+ondemand)/([^<]+)</src>', rtmpData)

        part = item.CreateNewEmptyMediaPart()
        for rtmpUrl in rtmpUrls:
            url = "%s/%s" % (rtmpUrl[1], rtmpUrl[2])
            bitrate = rtmpUrl[0]
            # convertedUrl = url.replace("ondemand/","ondemand?slist=")
            convertedUrl = self.GetVerifiableVideoUrl(url)
            part.AppendMediaStream(convertedUrl, bitrate)

        item.complete = True
        Logger.Trace("Media url: %s", item)
        return item
Example #5
0
    def UpdateVideoItem(self, item):
        """Updates an existing MediaItem with more data.

        Arguments:
        item : MediaItem - the MediaItem that needs to be updated

        Returns:
        The original item with more data added to it's properties.

        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.

        """

        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name,
                     self.channelName)

        metaData = UriHandler.Open(item.url,
                                   proxy=self.proxy,
                                   referer=self.baseUrl)
        meta = JsonHelper(metaData)
        streamParts = meta.GetValue("feed", "items")
        for streamPart in streamParts:
            streamUrl = streamPart["group"]["content"]
            # streamUrl = streamUrl.replace("{device}", "ipad")
            streamUrl = streamUrl.replace("{device}", "html5")
            streamUrl = "%s&format=json" % (streamUrl, )
            streamData = UriHandler.Open(streamUrl, proxy=self.proxy)
            stream = JsonHelper(streamData)

            # subUrls = stream.GetValue("package", "video", "item", 0, "transcript", 0, "typographic")
            part = item.CreateNewEmptyMediaPart()

            # m3u8Url = stream.GetValue("package", "video", "item", 0, "rendition", 0, "src")
            # for s, b in M3u8.GetStreamsFromM3u8(m3u8Url, self.proxy):
            #     item.complete = True
            #     part.AppendMediaStream(s, b)

            rtmpDatas = stream.GetValue("package", "video", "item", 0,
                                        "rendition")
            for rtmpData in rtmpDatas:
                rtmpUrl = rtmpData["src"]
                rtmpUrl = rtmpUrl.replace("rtmpe://", "rtmp://")
                bitrate = rtmpData["bitrate"]
                part.AppendMediaStream(rtmpUrl, bitrate)

        item.complete = True
        Logger.Trace("Media url: %s", item)
        return item
Example #6
0
    def UpdateVideoItem(self, item):
        """
        Accepts an item. It returns an updated item. Usually retrieves the MediaURL 
        and the Thumb! It should return a completed item. 
        """
        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name, self.channelName)
        
        # get additional info
        data = UriHandler.Open(item.url, proxy=self.proxy)
        guid = Regexer.DoRegex('<meta property="og:video" content="http://player.extreme.com/FCPlayer.swf\?id=([^&]+)&amp[^"]+" />', data)

        #<param name="flashvars" value="id=dj0xMDEzNzQyJmM9MTAwMDAwNA&amp;tags=source%253Dfreecaster&amp;autoplay=1" />
        # http://freecaster.tv/player/smil/dj0xMDEzNzQyJmM9MTAwMDAwNA -> playlist with bitrate
        # http://freecaster.tv/player/smil/dj0xMDEzNzQyJmM9MTAwMDAwNA -> info (not needed, get description from main page.

        if len(guid) > 0:
            url = '%s/player/smil/%s' % (self.baseUrl, guid[0],) 
            data = UriHandler.Open(url)

            smiller = Smil(data)
            baseUrl = smiller.GetBaseUrl()
            urls = smiller.GetVideosAndBitrates()

            part = item.CreateNewEmptyMediaPart()
            for url in urls:
                if "youtube" in url[0]:
                    for s, b in YouTube.GetStreamsFromYouTube(url[0], self.proxy):
                        item.complete = True
                        part.AppendMediaStream(s, b)
                else:
                    part.AppendMediaStream("%s%s" % (baseUrl, url[0]), bitrate=int(int(url[1]) / 1000))
                item.complete = True

            Logger.Trace("UpdateVideoItem complete: %s", item)
            return item

        # Try the brightcove
        brightCoveRegex = '<object id="myExperience[\w\W]+?videoPlayer" value="(\d+)"[\w\W]{0,1000}?playerKey" value="([^"]+)'
        brightCoveData = Regexer.DoRegex(brightCoveRegex, data)
        Logger.Trace(brightCoveData)
        if len(brightCoveData) > 0:
            seed = "c5f9ae8729f7054d43187989ef3421531ee8678d"
            objectData = brightCoveData[0]
            # from proxyinfo import ProxyInfo
            playerKey = str(objectData[1])
            videoId = int(objectData[0])

            part = item.CreateNewEmptyMediaPart()
            # But we need the IOS streams!
            amfHelper = BrightCove(Logger.Instance(), playerKey, videoId, str(item.url), seed, proxy=self.proxy)
            for stream, bitrate in amfHelper.GetStreamInfo(renditions="IOSRenditions"):
                part.AppendMediaStream(stream, bitrate)

        # Logger.Error("Cannot find GUID in url: %s", item.url)
        return item
Example #7
0
    def UpdateJsonVideoItem(self, item):
        data = UriHandler.Open(item.url, proxy=self.proxy)
        json = JsonHelper(data)
        m3u8Url = json.GetValue("playlist")

        if m3u8Url != "https://embed.kijk.nl/api/playlist/.m3u8":
            part = item.CreateNewEmptyMediaPart()
            for s, b in M3u8.GetStreamsFromM3u8(m3u8Url,
                                                self.proxy,
                                                appendQueryString=True):
                if "_enc_" in s:
                    Logger.Warning("Found encrypted stream. Skipping %s", s)
                    continue

                item.complete = True
                # s = self.GetVerifiableVideoUrl(s)
                part.AppendMediaStream(s, b)
            return item

        Logger.Warning("No M3u8 data found. Falling back to BrightCove")
        videoId = json.GetValue("vpakey")
        # videoId = json.GetValue("videoId") -> Not all items have a videoId
        url = "https://embed.kijk.nl/video/%s?width=868&height=491" % (
            videoId, )
        referer = "https://embed.kijk.nl/video/%s" % (videoId, )
        part = item.CreateNewEmptyMediaPart()

        # First try the new BrightCove JSON
        data = UriHandler.Open(url, proxy=self.proxy, referer=referer)
        brightCoveRegex = '<video[^>]+data-video-id="(?<videoId>[^"]+)[^>]+data-account="(?<videoAccount>[^"]+)'
        brightCoveData = Regexer.DoRegex(Regexer.FromExpresso(brightCoveRegex),
                                         data)
        if brightCoveData:
            Logger.Info("Found new BrightCove JSON data")
            brightCoveUrl = 'https://edge.api.brightcove.com/playback/v1/accounts/%(videoAccount)s/videos/%(videoId)s' % \
                            brightCoveData[0]
            headers = {
                "Accept":
                "application/json;pk=BCpkADawqM3ve1c3k3HcmzaxBvD8lXCl89K7XEHiKutxZArg2c5RhwJHJANOwPwS_4o7UsC4RhIzXG8Y69mrwKCPlRkIxNgPQVY9qG78SJ1TJop4JoDDcgdsNrg"
            }
            brightCoveData = UriHandler.Open(brightCoveUrl,
                                             proxy=self.proxy,
                                             additionalHeaders=headers)
            brightCoveJson = JsonHelper(brightCoveData)
            streams = filter(lambda d: d["container"] == "M2TS",
                             brightCoveJson.GetValue("sources"))
            if streams:
                # noinspection PyTypeChecker
                streamUrl = streams[0]["src"]
                for s, b in M3u8.GetStreamsFromM3u8(streamUrl, self.proxy):
                    item.complete = True
                    part.AppendMediaStream(s, b)
                return item
Example #8
0
    def UpdateVideoItem(self, item):
        """Updates an existing MediaItem with more data.

        Arguments:
        item : MediaItem - the MediaItem that needs to be updated

        Returns:
        The original item with more data added to it's properties.

        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.

        """

        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name,
                     self.channelName)

        url = item.url
        data = UriHandler.Open(url)

        if "json" in self.mainListUri:
            metaData = data
        else:
            mgid = Regexer.DoRegex("mgid:[^ ]+playlist-[abcdef0-9]+", data)[0]
            mgidUrlEncoded = htmlentityhelper.HtmlEntityHelper.UrlEncode(mgid)
            metaData = UriHandler.Open(
                "http://api.mtvnn.com/v2/mrss.xml?uri=%s" % (mgidUrlEncoded, ))

        videoUrl = Regexer.DoRegex("<media:content[^>]+url='([^']+)'>",
                                   metaData)[0]
        Logger.Trace(videoUrl)
        videoData = UriHandler.Open(videoUrl)
        videoItems = Regexer.DoRegex(
            '<rendition[^>]+bitrate="(\d+)"[^>]*>\W+<src>([^<]+)<', videoData)

        item.MediaItemParts = []
        part = item.CreateNewEmptyMediaPart()
        for videoItem in videoItems:
            mediaUrl = self.GetVerifiableVideoUrl(videoItem[1])
            part.AppendMediaStream(mediaUrl, videoItem[0])

        item.complete = True
        return item
Example #9
0
    def UpdateVideoItemLive(self, item):
        """Updates an existing MediaItem with more data.

        Arguments:
        item : MediaItem - the MediaItem that needs to be updated

        Returns:
        The original item with more data added to it's properties.

        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.

        """

        Logger.Debug('Starting UpdateVideoItem: %s', item.name)

        item.MediaItemParts = []
        part = item.CreateNewEmptyMediaPart()

        referer = {"referer": self.baseUrlLive}
        streams = NpoStream.GetLiveStreamsFromNpo(item.url, Config.cacheDir, proxy=self.proxy, headers=referer)
        if streams:
            Logger.Debug("Found live stream urls from item url")
            for s, b in streams:
                item.complete = True
                part.AppendMediaStream(s, b)
        else:
            # we need to determine radio or live tv
            Logger.Debug("Fetching live stream data from item url")
            htmlData = UriHandler.Open(item.url, proxy=self.proxy)

            mp3Urls = Regexer.DoRegex("""data-streams='{"url":"([^"]+)","codec":"[^"]+"}'""", htmlData)
            if len(mp3Urls) > 0:
                Logger.Debug("Found MP3 URL")
                part.AppendMediaStream(mp3Urls[0], 192)
            else:
                jsonUrl = item.url
                if not item.url.startswith("http://e.omroep.nl/metadata/"):
                    Logger.Debug("Finding the actual metadata url from %s", item.url)
                    jsonUrls = Regexer.DoRegex('<div class="video-player-container"[^>]+data-prid="([^"]+)"', htmlData)
                    jsonUrl = None
                    for url in jsonUrls:
                        jsonUrl = "http://e.omroep.nl/metadata/%s" % (url,)

                for s, b in NpoStream.GetLiveStreamsFromNpo(jsonUrl, Config.cacheDir, proxy=self.proxy, headers=referer):
                    item.complete = True
                    part.AppendMediaStream(s, b)

        item.complete = True
        # Logger.Trace(item)
        return item
    def UpdateVideoItem(self, item):
        """
        Accepts an item. It returns an updated item. Usually retrieves the MediaURL
        and the Thumb! It should return a completed item.
        """
        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name,
                     self.channelName)

        # now the mediaurl is derived. First we try WMV
        data = UriHandler.Open(item.url)

        urls = Regexer.DoRegex(
            '<a href="([^"]+.(?:wmv|mp4))">(High|Medium|Mid|Low|MP4)', data)
        mediaPart = mediaitem.MediaItemPart(item.name)
        for url in urls:
            if url[1].lower() == "high":
                bitrate = 2000
            elif url[1].lower() == "medium" or url[1].lower() == "mid":
                bitrate = 1200
            elif url[1].lower() == "low" or url[1].lower() == "mp4":
                bitrate = 200
            else:
                bitrate = 0
            mediaPart.AppendMediaStream(
                HtmlEntityHelper.ConvertHTMLEntities(url[0]), bitrate)

        item.MediaItemParts.append(mediaPart)

        #images = Regexer.DoRegex('<link type="image/jpeg" rel="videothumbnail" href="([^"]+)"/>', data)
        #for image in images:
        #    thumbUrl = htmlentityhelper.HtmlEntityHelper.ConvertHTMLEntities(image)
        #    break

        item.complete = True
        return item
Example #11
0
    def UpdateVideoItem(self, item):
        data = UriHandler.Open(item.url,
                               proxy=self.proxy,
                               additionalHeaders=item.HttpHeaders)
        mediaRegex = 'data-media="([^"]+)"'
        mediaInfo = Regexer.DoRegex(mediaRegex, data)[0]
        mediaInfo = HtmlEntityHelper.ConvertHTMLEntities(mediaInfo)
        mediaInfo = JsonHelper(mediaInfo)
        Logger.Trace(mediaInfo)

        # sources
        part = item.CreateNewEmptyMediaPart()
        # high, web, mobile, url
        mediaSources = mediaInfo.json.get("sources", {})
        for quality in mediaSources:
            url = mediaSources[quality]
            if quality == "high":
                bitrate = 2000
            elif quality == "web":
                bitrate = 800
            elif quality == "mobile":
                bitrate = 400
            else:
                bitrate = 0
            part.AppendMediaStream(url, bitrate)

        # geoLocRestriction
        item.isGeoLocked = not mediaInfo.GetValue("geoLocRestriction",
                                                  fallback="world") == "world"
        item.complete = True
        return item
Example #12
0
    def UpdateVideoItem(self, item):
        """Updates an existing MediaItem with more data.

        Arguments:
        item : MediaItem - the MediaItem that needs to be updated

        Returns:
        The original item with more data added to it's properties.

        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.

        """

        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name,
                     self.channelName)

        if not self.loggedOn:
            Logger.Warning("Cannot log on")
            return None

        data = UriHandler.Open(item.url, proxy=self.proxy)
        videoIdRegex = '"vodId":"([^"]+)"'
        videoId = Regexer.DoRegex(videoIdRegex, data)[0]
        return self.__UpdateVideoItem(item, videoId)
Example #13
0
 def UpdateVideoEpgItemJson(self, item):
     data = UriHandler.Open(item.url,
                            proxy=self.proxy,
                            additionalHeaders=self.httpHeaders)
     jsonData = JsonHelper(data)
     videoId = jsonData.GetValue("response", "videos", 0, "id")
     return self.__UpdateVideoItem(item, videoId)
Example #14
0
    def UpdateVideoApiItem(self, item):
        """ Updates an existing MediaItem with more data.

        Arguments:
        item : MediaItem - the MediaItem that needs to be updated
        date : String    - the json content of the item's URL

        Returns:
        The original item with more data added to it's properties.

        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.

        """
        Logger.Debug('Starting UpdateChannelItem for %s (%s)', item.name, self.channelName)

        data = UriHandler.Open(item.url, proxy=self.proxy)

        json = JsonHelper(data, logger=Logger.Instance())
        videos = json.GetValue("videoReferences")
        subtitles = json.GetValue("subtitleReferences")
        Logger.Trace(videos)
        return self.__UpdateItemFromVideoReferences(item, videos, subtitles)
Example #15
0
    def UpdateVideoItem(self, item):
        """
        Accepts an item. It returns an updated item. Usually retrieves the MediaURL
        and the Thumb! It should return a completed item.
        """
        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name,
                     self.channelName)

        if not item.url.endswith("m3u8"):
            data = UriHandler.Open(item.url, proxy=self.proxy)
            jsonData = Regexer.DoRegex(self.mediaUrlRegex, data)
            if not jsonData:
                Logger.Error("Cannot find JSON stream info.")
                return item

            json = JsonHelper(jsonData[0])
            Logger.Trace(json.json)
            stream = json.GetValue("source", "hls")
            Logger.Debug("Found HLS: %s", stream)
        else:
            stream = item.url

        part = item.CreateNewEmptyMediaPart()
        for s, b in M3u8.GetStreamsFromM3u8(stream, self.proxy):
            item.complete = True
            # s = self.GetVerifiableVideoUrl(s)
            part.AppendMediaStream(s, b)

        # var playerConfig = {"id":"mediaplayer","width":"100%","height":"100%","autostart":"false","image":"http:\/\/www.ketnet.be\/sites\/default\/files\/thumb_5667ea22632bc.jpg","brand":"ketnet","source":{"hls":"http:\/\/vod.stream.vrt.be\/ketnet\/_definst_\/mp4:ketnet\/2015\/12\/Ben_ik_familie_van_R001_A0023_20151208_143112_864.mp4\/playlist.m3u8"},"analytics":{"type_stream":"vod","playlist":"Ben ik familie van?","program":"Ben ik familie van?","episode":"Ben ik familie van?: Warre - Aflevering 3","parts":"1","whatson":"270157835527"},"title":"Ben ik familie van?: Warre - Aflevering 3","description":"Ben ik familie van?: Warre - Aflevering 3"}
        return item
Example #16
0
    def AddEpisodePaging(self, data):
        """Performs pre-process actions for data processing/

        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 = []

        # we need to create page items. So let's just spoof the paging. Youtube has
        # a 50 max results per query limit.
        itemsPerPage = 50
        data = UriHandler.Open(self.mainListUri, proxy=self.proxy)
        xml = xmlhelper.XmlHelper(data)
        nrItems = xml.GetSingleNodeContent("openSearch:totalResults")

        for index in range(1, int(nrItems), itemsPerPage):
            items.append(self.CreateEpisodeItem([index, itemsPerPage]))
            pass
        # Continue working normal!

        return data, items
Example #17
0
    def UpdateLiveItem(self, item):
        """
        Accepts an item. It returns an updated item. Usually retrieves the MediaURL
        and the Thumb! It should return a completed item.
        """
        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name,
                     self.channelName)

        data = UriHandler.Open(item.url, proxy=self.proxy)
        data = data[data.index('{'):]
        json = JsonHelper(data)

        sid = json.GetValue("sid")
        # The i= is the same as the one from the RTMP stream at the page of ATV.sr:
        # http://edge1.tikilive.com:1935/rtmp_tikilive/34967/amlst:mainstream/jwplayer.smil?id=dIzAVAVL2dirCfJgAPEb&i=YXBwTmFtZT1QbGF5ZXImY0lEPTM0OTY3JmNOYW1lPUFUViUyME5ldHdvcmtzJm9JRD0xMzY1NTUmb05hbWU9YXR2bmV0d29ya3Mmc0lkPWJwaHR2bXR2OXI4M2N1Mm9sZ2Q5dWx1aWs2JnVJRD0wJnVOYW1lPUd1ZXN0OWFmYTE=

        # videoUrl = "http://edge2.tikilive.com:1935/html5_tikilive/34967/amlst:mainstream/playlist.m3u8" \
        #            "?i=8xbrQERMXS2dTUKuAPbW&i=YXBwTmFtZT1QbGF5ZXImY0lEPTM0OTY3JmNOYW1lPUFUViUyME5ldHdvcm" \
        #            "tzJm9JRD0xMzY1NTUmb05hbWU9YXR2bmV0d29ya3Mmc0lkPWJwaHR2bXR2OXI4M2N1Mm9sZ2Q5dWx1aWs2JnVJRD0wJnVOYW1lPUd1ZXN0YzExZmE=&id=%s" \
        #            % (sid,)
        videoUrl = "http://edge2.tikilive.com:1935/html5_tikilive/34967/amlst:mainstream/playlist.m3u8" \
                   "?i=YXBwTmFtZT1QbGF5ZXImY0lEPTM0OTY3JmNOYW1lPUFUViUyME5ldHdvcmtzJm9JRD0xMzY1NTUmb05hbW" \
                   "U9YXR2bmV0d29ya3Mmc0lkPWZvODRpbDNlN3FzNjh1ZXQycWwyZWF2MDgxJnVJRD0wJnVOYW1lPUd1ZXN0MTNiNjk=&id=%s" \
                   % (sid,)
        part = item.CreateNewEmptyMediaPart()
        for s, b in M3u8.GetStreamsFromM3u8(videoUrl, self.proxy):
            item.complete = True
            # s = self.GetVerifiableVideoUrl(s)
            part.AppendMediaStream(s, b)

        item.complete = True
        return item
    def UpdateVideoItem(self, item):
        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name,
                     self.channelName)

        data = UriHandler.Open(item.url,
                               proxy=self.proxy,
                               additionalHeaders=item.HttpHeaders)
        json = JsonHelper(data)

        part = item.CreateNewEmptyMediaPart()
        part.Subtitle = NpoStream.GetSubtitle(json.GetValue("mid"),
                                              proxy=self.proxy)

        for stream in json.GetValue("videoStreams"):
            if not stream["url"].startswith("odi"):
                part.AppendMediaStream(stream["url"], stream["bitrate"] / 1000)
                item.complete = True

        if item.HasMediaItemParts():
            return item

        for s, b in NpoStream.GetStreamsFromNpo(None,
                                                json.GetValue("mid"),
                                                proxy=self.proxy):
            item.complete = True
            part.AppendMediaStream(s, b)

        return item
Example #19
0
    def UpdateLiveItem(self, item):
        """
        Accepts an item. It returns an updated item. Usually retrieves the MediaURL
        and the Thumb! It should return a completed item.
        """
        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name,
                     self.channelName)

        data = UriHandler.Open(item.url, proxy=self.proxy)
        data = data[data.index('{'):]
        json = JsonHelper(data)

        sid = json.GetValue("sid")
        videoUrl = "http://edge2.tikilive.com:1935/html5_tikilive/34967/amlst:mainstream/playlist.m3u8" \
                   "?i=YXBwTmFtZT1QbGF5ZXImY0lEPTM0OTY3JmNOYW1lPUFUViUyME5ldHdvcmtzJm9JRD0xMzY1NTUmb05hbW" \
                   "U9YXR2bmV0d29ya3Mmc0lkPWZvODRpbDNlN3FzNjh1ZXQycWwyZWF2MDgxJnVJRD0wJnVOYW1lPUd1ZXN0MTNiNjk=&id=%s" \
                   % (sid,)
        part = item.CreateNewEmptyMediaPart()
        for s, b in M3u8.GetStreamsFromM3u8(videoUrl, self.proxy):
            item.complete = True
            # s = self.GetVerifiableVideoUrl(s)
            part.AppendMediaStream(s, b)

        item.complete = True
        return item
Example #20
0
    def UpdateLiveStream(self, item):
        Logger.Debug("Updating Live stream")
        # let's request a token
        token = self.__GetToken()

        # What is the channel name to play
        channel = self.channelCode
        if self.channelCode == "q2":
            channel = "2be"
        elif self.channelCode == "stievie":
            channel = item.metaData["channelId"]

        url = "https://stream-live.medialaan.io/stream-live/v1/channels/%s/broadcasts/current/video/?deviceId=%s" % (
            channel,
            uuid.uuid4()  # Could be a random int
        )

        auth = {"Authorization": "apikey=%s&access_token=%s" % (self.__apiKey, token)}
        data = UriHandler.Open(url, proxy=self.proxy, noCache=True, additionalHeaders=auth)
        jsonData = JsonHelper(data)
        hls = jsonData.GetValue("response", "url", "hls")
        if not hls:
            return item

        part = item.CreateNewEmptyMediaPart()
        for s, b in M3u8.GetStreamsFromM3u8(hls, self.proxy):
            item.complete = True
            # s = self.GetVerifiableVideoUrl(s)
            part.AppendMediaStream(s, b)
        return item
Example #21
0
    def __IsNewVersionAvailable(self):
        """ Verifies that there is a new version available. It compares the addons.xml.md5 with the stored one.

        @return: True or False
        """

        # first check if there is a "channel" folder
        channelPath = os.path.join(Config.rootDir, "channels")
        if not os.path.isdir(channelPath):
            Logger.Warning(
                "No Channels found at '%s', skipping updates for now.",
                channelPath)
            return False

        onlineData = UriHandler.Open(Config.UpdateUrl)
        self.__NewMd5 = onlineData.strip()
        self.__OldMd5 = AddonSettings.GetCurrentAddonXmlMd5()

        updated = self.__OldMd5 != self.__NewMd5
        if updated:
            Logger.Info("New updates are available ('%s' vs '%s')",
                        self.__OldMd5, self.__NewMd5)
        else:
            Logger.Info("No new updates available, MD5 hashes match")
        return updated
Example #22
0
    def UpdateVideoItem(self, item):
        """Updates an existing MediaItem with more data.

        Arguments:
        item : MediaItem - the MediaItem that needs to be updated

        Returns:
        The original item with more data added to it's properties.

        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.

        """

        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name,
                     self.channelName)

        # https://api.viervijfzes.be/content/c58996a6-9e3d-4195-9ecf-9931194c00bf
        # videoId = item.url.split("/")[-1]
        # url = "%s/video/v3/embed/%s" % (self.baseUrl, videoId,)
        url = item.url
        data = UriHandler.Open(url, proxy=self.proxy)
        return self.__UpdateVideo(item, data)
Example #23
0
    def AddClips(self, data):
        Logger.Info("Adding Clips Pre-Processing")
        items = []

        # if the main list was retrieve using json, are the current data is json, just determine
        # the clip URL
        clipUrl = None
        if data.lstrip().startswith("{"):
            if self.parentItem.url.endswith("type=program"):
                # http://playapi.mtgx.tv/v3/videos?format=6723&order=-airdate&type=program
                # http://playapi.mtgx.tv/v3/videos?format=6723&order=-updated&type=clip" % (dataId,)
                clipUrl = self.parentItem.url.replace("type=program",
                                                      "type=clip")
        else:
            # now we determine the ID and load the json data
            dataId = Regexer.DoRegex('data-format-id="(\d+)"', data)[-1]
            Logger.Debug("Found FormatId = %s", dataId)
            programUrl = "http://playapi.mtgx.tv/v3/videos?format=%s&order=-airdate&type=program" % (
                dataId, )
            data = UriHandler.Open(programUrl, proxy=self.proxy)
            clipUrl = "http://playapi.mtgx.tv/v3/videos?format=%s&order=-updated&type=clip" % (
                dataId, )

        if clipUrl is not None:
            clipTitle = LanguageHelper.GetLocalizedString(LanguageHelper.Clips)
            clipItem = mediaitem.MediaItem("\a.: %s :." % (clipTitle, ),
                                           clipUrl)
            clipItem.thumb = self.noImage
            items.append(clipItem)

        Logger.Debug("Pre-Processing finished")
        return data, items
Example #24
0
    def UpdateVideoItem(self, item):
        """
        Updates the item
        """

        data = UriHandler.Open(item.url, proxy=self.proxy)

        baseEncode = Regexer.DoRegex(self.mediaUrlRegex, data)[-1]
        jsonData = EncodingHelper().DecodeBase64(baseEncode)
        json = JsonHelper(jsonData, logger=Logger.Instance())
        Logger.Trace(json)

        # "flv": "http://media.dumpert.nl/flv/e2a926ff_10307954_804223649588516_151552487_n.mp4.flv",
        # "tablet": "http://media.dumpert.nl/tablet/e2a926ff_10307954_804223649588516_151552487_n.mp4.mp4",
        # "mobile": "http://media.dumpert.nl/mobile/e2a926ff_10307954_804223649588516_151552487_n.mp4.mp4",

        item.MediaItemParts = []
        part = item.CreateNewEmptyMediaPart()
        streams = json.GetValue()
        for key in streams:
            if key == "flv":
                part.AppendMediaStream(streams[key], 1000)
            elif key == "tablet":
                part.AppendMediaStream(streams[key], 800)
            elif key == "mobile":
                part.AppendMediaStream(streams[key], 450)
            else:
                Logger.Debug("Key '%s' was not used", key)

        item.complete = True
        Logger.Trace("VideoItem updated: %s", item)
        return item
Example #25
0
    def UpdateVideoItem(self, item):
        """
        Accepts an item. It returns an updated item. Usually retrieves the MediaURL
        and the Thumb! It should return a completed item.
        """
        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name,
                     self.channelName)

        data = UriHandler.Open(item.url,
                               proxy=self.proxy).decode('unicode_escape')
        streams = Regexer.DoRegex("file:\W+'([^']+)'", data)
        part = item.CreateNewEmptyMediaPart()
        for s in streams:
            if "anifest" in s:
                continue
            s = JsonHelper.ConvertSpecialChars(s)
            if s.startswith("rtmp"):
                s = self.GetVerifiableVideoUrl(s)
                part.AppendMediaStream(s, 1001)
                part.AppendMediaStream(s.replace("_medium.mp4", "_low.mp4"),
                                       301)
            else:
                part.AppendMediaStream(s, 1002)
                part.AppendMediaStream(s.replace("_medium.mp4", "_low.mp4"),
                                       302)

        item.complete = True
        return item
Example #26
0
    def LogOn(self):
        signatureSettings = "mediaan_signature"
        signatureSetting = AddonSettings.GetSetting(signatureSettings)
        # apiKey = "3_HZ0FtkMW_gOyKlqQzW5_0FHRC7Nd5XpXJZcDdXY4pk5eES2ZWmejRW5egwVm4ug-"  # from VTM
        apiKey = "3_OEz9nzakKMkhPdUnz41EqSRfhJg5z9JXvS4wUORkqNf2M2c1wS81ilBgCewkot97"  # from Stievie
        if signatureSetting and "|" not in signatureSetting:
            url = "https://accounts.eu1.gigya.com/accounts.getAccountInfo"
            data = "APIKey=%s" \
                   "&sdk=js_7.4.30" \
                   "&login_token=%s" % (apiKey, signatureSetting, )
            logonData = UriHandler.Open(url,
                                        params=data,
                                        proxy=self.proxy,
                                        noCache=True)
            if self.__ExtractSessionData(logonData, signatureSettings):
                return True
            Logger.Warning("Failed to extend the VTM.be session.")

        Logger.Info("Logging onto VTM.be")
        v = Vault()
        password = v.GetSetting("mediaan_password")
        username = AddonSettings.GetSetting("mediaan_username")
        if not username or not password:
            XbmcWrapper.ShowDialog(
                title=None,
                lines=LanguageHelper.GetLocalizedString(
                    LanguageHelper.MissingCredentials),
                # notificationType=XbmcWrapper.Error,
                # displayTime=5000
            )
            return False

        Logger.Debug("Using: %s / %s", username, "*" * len(password))
        url = "https://accounts.eu1.gigya.com/accounts.login"
        data = "loginID=%s" \
               "&password=%s" \
               "&targetEnv=jssdk" \
               "&APIKey=%s" \
               "&includeSSOToken=true" \
               "&authMode=cookie" % \
               (HtmlEntityHelper.UrlEncode(username), HtmlEntityHelper.UrlEncode(password), apiKey)

        logonData = UriHandler.Open(url,
                                    params=data,
                                    proxy=self.proxy,
                                    noCache=True)
        return self.__ExtractSessionData(logonData, signatureSettings)
Example #27
0
    def UpdateVideoItem(self, item):
        """Updates an existing MediaItem with more data.

        Arguments:
        item : MediaItem - the MediaItem that needs to be updated

        Returns:
        The original item with more data added to it's properties.

        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.

        """

        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name, self.channelName)

        rssUrl, htmlUrl = item.url.split("|", 1)

        # now the mediaurl is derived. First we try WMV
        data = UriHandler.Open(rssUrl, proxy=self.proxy)
        item.MediaItemParts = []
        i = 1
        found = False
        for part in Regexer.DoRegex(self.mediaUrlRegex, data):
            found = True
            name = "%s - Deel %s" % (item.name, i)
            mediaPart = mediaitem.MediaItemPart(name, part, 128)
            item.MediaItemParts.append(mediaPart)
            i += 1

        if not found:
            data = UriHandler.Open(htmlUrl, proxy=self.proxy)
            for mediaUrl in Regexer.DoRegex('<meta property="og:video"[^>]+content="([^"]+)" />', data):
                item.AppendSingleStream(mediaUrl, 128)

        item.complete = True
        return item
    def UpdateVideoItem(self, item):
        """Updates an existing MediaItem with more data.

        Arguments:
        item : MediaItem - the MediaItem that needs to be updated

        Returns:
        The original item with more data added to it's properties.

        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.

        """

        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name, self.channelName)

        # http://www.foxsports.nl/divadata/Output/VideoData/564939.xml
        # http://www.foxsports.nl/divadata/Output/VideoData/604652.xml
        data = UriHandler.Open(item.url, proxy=self.proxy, additionalHeaders=item.HttpHeaders)
        videoId = Regexer.DoRegex('data-videoid="(\d+)" ', data)[-1]
        data = UriHandler.Open("http://www.foxsports.nl/divadata/Output/VideoData/%s.xml" % (videoId,),
                               proxy=self.proxy, additionalHeaders=item.HttpHeaders)
        streams = Regexer.DoRegex('<uri>([^>]+)</uri>', data)

        part = item.CreateNewEmptyMediaPart()
        for stream in streams:
            if stream.endswith("m3u8"):
                for s, b in M3u8.GetStreamsFromM3u8(stream, self.proxy):
                    item.complete = True
                    # s = self.GetVerifiableVideoUrl(s)
                    part.AppendMediaStream(s, b)
            # elif stream.endswith("mp4"):
            #     part.AppendMediaStream(stream, 4000)
            else:
                Logger.Debug("Not using: %s", stream)

        return item
Example #29
0
    def UpdateVideoItem(self, item):
        """Updates an existing MediaItem with more data.

        Arguments:
        item : MediaItem - the MediaItem that needs to be updated

        Returns:
        The original item with more data added to it's properties.

        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.

        """

        Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name,
                     self.channelName)

        url = item.url
        data = UriHandler.Open(url, proxy=self.proxy)

        renditionsUrl = Regexer.DoRegex('<media:content[^>]+url=\W([^\'"]+)\W',
                                        data)[0]
        renditionsUrl = HtmlEntityHelper.StripAmp(renditionsUrl)
        renditionData = UriHandler.Open(renditionsUrl, proxy=self.proxy)
        videoItems = Regexer.DoRegex(
            '<rendition[^>]+bitrate="(\d+)"[^>]*>\W+<src>([^<]+)<',
            renditionData)

        item.MediaItemParts = []
        part = item.CreateNewEmptyMediaPart()
        for videoItem in videoItems:
            mediaUrl = self.GetVerifiableVideoUrl(videoItem[1].replace(
                "rtmpe", "rtmp"))
            part.AppendMediaStream(mediaUrl, videoItem[0])

        item.complete = True
        return item
Example #30
0
    def ParseMainList(self, returnData=False):
        """Parses the mainlist of the channel and returns a list of MediaItems

        This method creates a list of MediaItems that represent all the different
        programs that are available in the online source. The list is used to fill
        the ProgWindow.

        Keyword parameters:
        returnData : [opt] boolean - If set to true, it will return the retrieved
                                     data as well

        Returns a list of MediaItems that were retrieved.

        """

        items = []
        if len(self.mainListItems) > 1:
            if returnData:
                return self.mainListItems, ""
            else:
                return self.mainListItems

        data = UriHandler.Open(self.mainListUri, proxy=self.proxy, additionalHeaders=self.httpHeaders)
        Logger.Trace("Retrieved %s chars as mainlist data", len(data))

        # first process folder items.
        watch = stopwatch.StopWatch('Mainlist', Logger.Instance())

        episodeItems = []
        if not self.episodeItemRegex == "" and self.episodeItemRegex is not None:
            Logger.Trace("Using Regexer for episodes")
            episodeItems = Regexer.DoRegex(self.episodeItemRegex, data)
            watch.Lap("Mainlist Regex complete")

        elif self.episodeItemJson is not None:
            Logger.Trace("Using JsonHelper for episodes")
            json = JsonHelper(data, Logger.Instance())
            episodeItems = json.GetValue(*self.episodeItemJson)
            watch.Lap("Mainlist Json complete")

        Logger.Debug('Starting CreateEpisodeItem for %s items', len(episodeItems))
        for episodeItem in episodeItems:
            Logger.Trace('Starting CreateEpisodeItem for %s', self.channelName)
            tmpItem = self.CreateEpisodeItem(episodeItem)
            # catch the return of None
            if tmpItem:
                items.append(tmpItem)

        # Filter out the duplicates using the HASH power of a set
        items = list(set(items))

        watch.Lap("MediaItem creation complete")
        self.mainListItems = items

        if returnData:
            return items, data
        else:
            return items