Example #1
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,
                               additionalHeaders=item.HttpHeaders)
        json = JsonHelper(data)
        videoInfo = json.GetValue("content", "videoInfos")

        part = item.CreateNewEmptyMediaPart()
        if "HLSurlHD" in videoInfo:
            # HLSurlHD=http://srfvodhd-vh.akamaihd.net/i/vod/potzmusig/2015/03/potzmusig_20150307_184438_v_webcast_h264_,q10,q20,q30,q40,q50,q60,.mp4.csmil/master.m3u8
            for s, b in M3u8.GetStreamsFromM3u8(videoInfo["HLSurlHD"],
                                                self.proxy):
                item.complete = True
                # s = self.GetVerifiableVideoUrl(s)
                part.AppendMediaStream(s, b)
        elif "HLSurl" in videoInfo:
            # HLSurl=http://srfvodhd-vh.akamaihd.net/i/vod/potzmusig/2015/03/potzmusig_20150307_184438_v_webcast_h264_,q10,q20,q30,q40,.mp4.csmil/master.m3u8
            for s, b in M3u8.GetStreamsFromM3u8(videoInfo["HLSurl"],
                                                self.proxy):
                item.complete = True
                # s = self.GetVerifiableVideoUrl(s)
                part.AppendMediaStream(s, b)

        if "downloadLink" in videoInfo:
            # downloadLink=http://podcastsource.sf.tv/nps/podcast/10vor10/2015/03/10vor10_20150304_215030_v_podcast_h264_q10.mp4
            part.AppendMediaStream(videoInfo["downloadLink"], 1000)

        return item
Example #2
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 #3
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 #4
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
Example #5
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
    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 #7
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 #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("Updating a (Live) video item")

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

        return item
Example #9
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 #10
0
    def __UpdateItemFromVideoReferences(self, item, videos, subtitles=None):
        item.MediaItemParts = []
        part = item.CreateNewEmptyMediaPart()
        if self.localIP:
            part.HttpHeaders.update(self.localIP)

        for video in videos:
            videoFormat = video.get("format", "")
            if not videoFormat:
                videoFormat = video.get("playerType", "")
            videoFormat = videoFormat.lower()

            if "dash" in videoFormat or "hds" in videoFormat:
                Logger.Debug("Skipping video format: %s", videoFormat)
                continue
            Logger.Debug("Found video item for format: %s", videoFormat)

            url = video['url']
            if len(filter(lambda s: s.Url == url, part.MediaStreams)) > 0:
                Logger.Debug("Skippping duplicate Stream url: %s", url)
                continue

            if "m3u8" in url:
                altIndex = url.find("m3u8?")
                # altIndex = videoUrl.find("~uri")
                if altIndex > 0:
                    url = url[0:altIndex + 4]

                for s, b in M3u8.GetStreamsFromM3u8(url, proxy=self.proxy, headers=part.HttpHeaders):
                    part.AppendMediaStream(s, b)

            elif video["url"].startswith("rtmp"):
                # just replace some data in the URL
                part.AppendMediaStream(self.GetVerifiableVideoUrl(video["url"]).replace("_definst_", "?slist="), video[1])
            else:
                part.AppendMediaStream(url, 0)

        if subtitles:
            Logger.Info("Found subtitles to play")
            for sub in subtitles:
                subFormat = sub["format"].lower()
                url = sub["url"]
                if subFormat == "websrt":
                    subUrl = url
                # elif subFormat == "webvtt":
                #     Logger.Info("Found M3u8 subtitle, replacing with WSRT")
                #     start, name, index = sub[-1].rsplit("/", 2)
                #     subUrl = "%s/%s/%s.wsrt" % (start, name, name)
                else:
                    # look for more
                    continue

                part.Subtitle = subtitlehelper.SubtitleHelper.DownloadSubtitle(subUrl, format="srt", proxy=self.proxy)
                # stop when finding one
                break

        item.complete = True
        return item
Example #11
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)

        videoId = item.url[item.url.rfind("/") + 1:]

        url = "http://embed.kijk.nl/?width=868&height=491&video=%s" % (
            videoId, )
        referer = "http://www.kijk.nl/video/%s" % (videoId, )

        # now the mediaurl is derived. First we try WMV
        data = UriHandler.Open(url, proxy=self.proxy, referer=referer)
        Logger.Trace(self.mediaUrlRegex)
        objectData = Regexer.DoRegex(self.mediaUrlRegex, data)[0]
        Logger.Trace(objectData)

        # seed = "61773bc7479ab4e69a5214f17fd4afd21fe1987a"
        # seed = "0a2b91ec0fdb48c5dd5239d3e796d6f543974c33"
        seed = "0b0234fa8e2435244cdb1603d224bb8a129de5c1"
        amfHelper = BrightCove(Logger.Instance(), objectData[0], objectData[1],
                               url,
                               seed)  # , proxy=ProxyInfo("localhost", 8888)
        item.description = amfHelper.GetDescription()

        part = item.CreateNewEmptyMediaPart()
        for stream, bitrate in amfHelper.GetStreamInfo():
            if "m3u8" in stream:
                for s, b in M3u8.GetStreamsFromM3u8(stream, self.proxy):
                    item.complete = True
                    # s = self.GetVerifiableVideoUrl(s)
                    part.AppendMediaStream(s, b)
            part.AppendMediaStream(stream.replace("&mp4:", ""), bitrate)

        item.complete = True
        return item
Example #12
0
    def UpdateLiveItem(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 UpdateLiveItem for %s (%s)', item.name,
                     self.channelName)

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

        spoofIp = self._GetSetting("spoof_ip", "0.0.0.0")
        if spoofIp:
            for s, b in M3u8.GetStreamsFromM3u8(
                    item.url, self.proxy, headers={"X-Forwarded-For":
                                                   spoofIp}):
                part.AppendMediaStream(s, b)
            # data = UriHandler.Open(item.url, proxy=self.proxy, additionalHeaders={"X-Forwarded-For": spoofIp})
        else:
            for s, b in M3u8.GetStreamsFromM3u8(item.url, self.proxy):
                part.AppendMediaStream(s, b)
            # data = UriHandler.Open(item.url, proxy=self.proxy)

        item.complete = True
        return item
Example #13
0
    def UpdateLiveVideo(self, item):
        if "m3u8" not in item.url:
            Logger.Error("Cannot update live stream that is not an M3u8: %s", item.url)

        part = item.CreateNewEmptyMediaPart()
        for s, b in M3u8.GetStreamsFromM3u8(item.url, self.proxy):
            item.complete = True
            # apparently they split up M3u8 streams and audio streams, so we need to fix that here
            # this is an ugly fix, but it will work!
            s = s.replace(".m3u8", "-audio_track=96000.m3u8")
            part.AppendMediaStream(s, b)
        return item
Example #14
0
    def __GetVideoStreams(self, videoId, part):
        """ Fetches the video stream for a given videoId

        @param videoId: (integer) the videoId
        @param part:    (MediaPart) the mediapart to add the streams to
        @return:        (bool) indicating a successfull retrieval

        """

        # hardcoded for now as it does not seem top matter
        dscgeo = '{"countryCode":"%s","expiry":1446917369986}' % (
            self.language.upper(), )
        dscgeo = HtmlEntityHelper.UrlEncode(dscgeo)
        headers = {"Cookie": "dsc-geo=%s" % (dscgeo, )}

        # send the data
        http, nothing, host, other = self.baseUrl.split("/", 3)
        subdomain, domain = host.split(".", 1)
        url = "https://secure.%s/secure/api/v2/user/authorization/stream/%s?stream_type=hls" \
              % (domain, videoId,)
        data = UriHandler.Open(url,
                               proxy=self.proxy,
                               additionalHeaders=headers,
                               noCache=True)
        json = JsonHelper(data)
        url = json.GetValue("hls")

        if url is None:
            return False

        streamsFound = False
        if "?" in url:
            qs = url.split("?")[-1]
        else:
            qs = None
        for s, b in M3u8.GetStreamsFromM3u8(url, self.proxy):
            # and we need to append the original QueryString
            if "X-I-FRAME-STREAM" in s:
                continue

            streamsFound = True
            if qs is not None:
                if "?" in s:
                    s = "%s&%s" % (s, qs)
                else:
                    s = "%s?%s" % (s, qs)

            part.AppendMediaStream(s, b)

        return streamsFound
    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 #16
0
    def UpdateVideoItemFeeds(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', item)

        # rtmpt://vrt.flash.streampower.be/een//2011/07/1000_110723_getipt_neefs_wiels_Website_EEN.flv
        # http://www.een.be/sites/een.be/modules/custom/vrt_video/player/player_4.3.swf

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

        if item.MediaItemParts == 1:
            part = item.MediaItemParts[0]
        else:
            part = item.CreateNewEmptyMediaPart()

        streamItems = json.GetValue("channel", "items")
        if not streamItems:
            return item

        mediaUrlMedium = streamItems[0]["item"].get("ipad_url", "")
        mediaUrlLow = streamItems[0]["item"].get("iphone_url", "")

        if mediaUrlLow == mediaUrlMedium and "m3u8" in mediaUrlLow:
            Logger.Debug("Found M3u8 playlists for streams: %s", mediaUrlLow)

            for s, b in M3u8.GetStreamsFromM3u8(mediaUrlLow, self.proxy):
                item.complete = True
                # s = self.GetVerifiableVideoUrl(s)
                part.AppendMediaStream(s, b)
        else:
            if mediaUrlMedium != "":
                # not all have seperate bitrates, so these are estimates
                part.AppendMediaStream(
                    self.GetVerifiableVideoUrl(
                        mediaUrlMedium.replace("mp4:", "/mp4:")), 960)
            if mediaUrlLow != "":
                # not all have seperate bitrates, so these are estimates
                part.AppendMediaStream(
                    self.GetVerifiableVideoUrl(
                        mediaUrlLow.replace("mp4:", "/mp4:")), 696)
        item.complete = True
        return item
Example #17
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)

        xmlData = UriHandler.Open(item.url, proxy=self.proxy)
        # <ref type='adaptive' device='pc' host='http://manifest.us.rtl.nl' href='/rtlxl/network/pc/adaptive/components/videorecorder/27/278629/278630/d009c025-6e8c-3d11-8aba-dc8579373134.ssm/d009c025-6e8c-3d11-8aba-dc8579373134.m3u8' />
        m3u8Urls = Regexer.DoRegex("<ref type='adaptive' device='pc' host='([^']+)' href='/([^']+)' />", xmlData)
        if not m3u8Urls:
            Logger.Warning("No m3u8 data found for: %s", item)
            return item
        m3u8Url = "%s/%s" % (m3u8Urls[0][0], m3u8Urls[0][1])

        part = item.CreateNewEmptyMediaPart()
        # prevent the "418 I'm a teapot" error
        part.HttpHeaders["user-agent"] = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
        # Remove the Range header to make all streams start at the beginning.
        Logger.Debug("Setting an empty 'Range' http header to force playback at the start of a stream")
        part.HttpHeaders["Range"] = ''

        for s, b in M3u8.GetStreamsFromM3u8(m3u8Url, self.proxy):
            item.complete = True
            part.AppendMediaStream(s, b)

        return item
Example #18
0
    def UpdateLiveItem(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)
        part = item.CreateNewEmptyMediaPart()

        hlsUrl = mediaInfo.GetValue("streamUrl")
        if hlsUrl is not None and "m3u8" in hlsUrl:
            Logger.Debug("Found HLS url for %s: %s",
                         mediaInfo.json["streamName"], hlsUrl)
            # from debug.router import Router
            # data = Router.GetVia("be", hlsUrl, proxy=self.proxy)
            for s, b in M3u8.GetStreamsFromM3u8(hlsUrl, self.proxy):
                part.AppendMediaStream(s, b)
                item.complete = True
        else:
            Logger.Debug("No HLS url found for %s. Fetching RTMP Token.",
                         mediaInfo.json["streamName"])
            # fetch the token:
            tokenUrl = "%s/api/media/streaming?streamname=%s" % (
                self.baseUrl, mediaInfo.json["streamName"])
            tokenData = UriHandler.Open(tokenUrl,
                                        proxy=self.proxy,
                                        additionalHeaders=item.HttpHeaders,
                                        noCache=True)
            tokenData = JsonHelper(tokenData)
            token = tokenData.GetValue("token")
            Logger.Debug("Found token '%s' for '%s'", token,
                         mediaInfo.json["streamName"])

            rtmpUrl = "rtmp://rtmp.rtbf.be/livecast/%s?%s pageUrl=%s tcUrl=rtmp://rtmp.rtbf.be/livecast" % (
                mediaInfo.json["streamName"], token, self.baseUrl)
            rtmpUrl = self.GetVerifiableVideoUrl(rtmpUrl)
            part.AppendMediaStream(rtmpUrl, 0)
            item.complete = True

        item.isGeoLocked = not mediaInfo.GetValue("geoLocRestriction",
                                                  fallback="world") == "world"
        return item
Example #19
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)

        # rtmpt://vrt.flash.streampower.be/een//2011/07/1000_110723_getipt_neefs_wiels_Website_EEN.flv
        # http://www.een.be/sites/een.be/modules/custom/vrt_video/player/player_4.3.swf

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

        urls = Regexer.DoRegex(self.mediaUrlRegex, data)
        part = item.CreateNewEmptyMediaPart()
        for url in urls:
            if not url[1] == "":
                mediaurl = "%s//%s" % (
                    url[0], url[1]
                )  # the extra slash in the url causes the application name in the RTMP stream to be "een" instead of "een/2011"
            else:
                mediaurl = url[0]

            mediaurl = mediaurl.replace(" ", "%20")

            if "rtmp" in mediaurl:
                mediaurl = self.GetVerifiableVideoUrl(mediaurl)
                # In some cases the RTMPT does not work. Let's just try the RTMP first and then add the original if the RTMP version fails.
                part.AppendMediaStream(mediaurl.replace("rtmpt://", "rtmp://"),
                                       650)
            elif "rtsp" in mediaurl:
                part.AppendMediaStream(mediaurl, 600)
            elif mediaurl.startswith("http") and "m3u8" in mediaurl:
                # http://iphone.streampower.be/een_nogeo/_definst_/2013/08/1000_130830_placetobe_marjolein_Website_Een_M4V.m4v/playlist.m3u8
                mediaurl = mediaurl.rstrip()
                for s, b in M3u8.GetStreamsFromM3u8(mediaurl, self.proxy):
                    part.AppendMediaStream(s, b)
            else:
                Logger.Warning("Media url was not recognised: %s", mediaurl)

        item.complete = True
        return item
Example #20
0
    def __UpdateVideo(self, item, data):
        regex = 'data-file="([^"]+)'
        m3u8Url = Regexer.DoRegex(regex, data)[-1]

        if ".m3u8" not in m3u8Url:
            Logger.Info("Not a direct M3u8 file. Need to log in")
            url = "https://api.viervijfzes.be/content/%s" % (m3u8Url, )

            # We need to log in
            if not self.loggedOn:
                self.LogOn()

            # add authorization header
            authenticationHeader = {
                "authorization": self.__idToken,
                "content-type": "application/json"
            }
            data = UriHandler.Open(url,
                                   proxy=self.proxy,
                                   additionalHeaders=authenticationHeader)
            jsonData = JsonHelper(data)
            m3u8Url = jsonData.GetValue("video", "S")

        # Geo Locked?
        if "geo" in m3u8Url.lower():
            # set it for the error statistics
            item.isGeoLocked = True

        part = item.CreateNewEmptyMediaPart()
        for s, b in M3u8.GetStreamsFromM3u8(m3u8Url, self.proxy):
            if int(b) < 200:
                Logger.Info("Skipping stream of quality '%s' kbps", b)
                continue

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

        item.complete = True
        return item
Example #21
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)

        # load the details.
        part = item.CreateNewEmptyMediaPart()
        # prevent the "418 I'm a teapot" error
        part.HttpHeaders[
            "user-agent"] = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"

        for s, b in M3u8.GetStreamsFromM3u8(item.url, self.proxy):
            part.AppendMediaStream(s, b)

        item.complete = True
        return item
Example #22
0
    def UpdateLiveItem(self, item):
        # http://services.vrt.be/videoplayer/r/live.json?_1466364209811=
        channelData = UriHandler.Open(
            "http://services.vrt.be/videoplayer/r/live.json", proxy=self.proxy)
        channelData = JsonHelper(channelData)
        url = None
        for channelId in channelData.json:
            if channelId not in item.url:
                continue
            else:
                url = channelData.json[channelId].get("hls")

        if url is None:
            Logger.Error("Could not find stream for live channel: %s",
                         item.url)
            return item

        Logger.Debug("Found stream url for %s: %s", item, url)
        part = item.CreateNewEmptyMediaPart()
        for s, b in M3u8.GetStreamsFromM3u8(url, self.proxy):
            item.complete = True
            # s = self.GetVerifiableVideoUrl(s)
            part.AppendMediaStream(s, b)
        return item
Example #23
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)

        # noinspection PyStatementEffect
        """
        data-video-id="1613274"
        data-video-type="video"
        data-video-src="http://media.vrtnieuws.net/2013/04/135132051ONL1304255866693.urlFLVLong.flv"
        data-video-title="Het journaal 1 - 25/04/13"
        data-video-rtmp-server="rtmp://vrt.flash.streampower.be/vrtnieuws"
        data-video-rtmp-path="2013/04/135132051ONL1304255866693.urlFLVLong.flv"
        data-video-rtmpt-server="rtmpt://vrt.flash.streampower.be/vrtnieuws"
        data-video-rtmpt-path="2013/04/135132051ONL1304255866693.urlFLVLong.flv"
        data-video-iphone-server="http://iphone.streampower.be/vrtnieuws_nogeo/_definst_"
        data-video-iphone-path="2013/04/135132051ONL1304255866693.urlMP4_H.264.m4v"
        data-video-mobile-server="rtsp://mp4.streampower.be/vrt/vrt_mobile/vrtnieuws_nogeo"
        data-video-mobile-path="2013/04/135132051ONL1304255866693.url3GP_MPEG4.3gp"
        data-video-sitestat-program="het_journaal_1_-_250413_id_1-1613274"
        """

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

        descriptions = Regexer.DoRegex('<div class="longdesc"><p>([^<]+)</',
                                       data)
        Logger.Trace(descriptions)
        for desc in descriptions:
            item.description = desc

        data = data.replace("\\/", "/")
        urls = Regexer.DoRegex(self.mediaUrlRegex, data)
        part = item.CreateNewEmptyMediaPart()
        for url in urls:
            Logger.Trace(url)
            if url[0] == "src":
                flv = url[1]
                bitrate = 750
            else:
                flvServer = url[1]
                flvPath = url[2]

                if url[0] == "rtmp-server":
                    flv = "%s//%s" % (flvServer, flvPath)
                    bitrate = 750

                elif url[0] == "rtmpt-server":
                    continue
                    #flv = "%s//%s" % (flvServer, flvPath)
                    #flv = self.GetVerifiableVideoUrl(flv)
                    #bitrate = 1500

                elif url[0] == "iphone-server":
                    flv = "%s/%s" % (flvServer, flvPath)
                    if not flv.endswith("playlist.m3u8"):
                        flv = "%s/playlist.m3u8" % (flv, )

                    for s, b in M3u8.GetStreamsFromM3u8(flv, self.proxy):
                        item.complete = True
                        part.AppendMediaStream(s, b)
                    # no need to continue adding the streams
                    continue

                elif url[0] == "mobile-server":
                    flv = "%s/%s" % (flvServer, flvPath)
                    bitrate = 250

                else:
                    flv = "%s/%s" % (flvServer, flvPath)
                    bitrate = 0

            part.AppendMediaStream(flv, bitrate)

        item.complete = True
        return item
Example #24
0
    def __UpdateVideoItem(self, item, videoId):
        # we need a token:
        token = self.__GetToken()

        # deviceId = AddonSettings.GetClientId()
        mediaUrl = "https://vod.medialaan.io/vod/v2/videos/" \
                   "%s" \
                   "/watch?deviceId=%s" % (
                       videoId,
                       uuid.uuid4()
                   )

        auth = "apikey=%s&access_token=%s" % (self.__apiKey, token)
        headers = {"Authorization": auth}
        data = UriHandler.Open(mediaUrl, proxy=self.proxy, additionalHeaders=headers)

        jsonData = JsonHelper(data)
        dashInfo = jsonData.GetValue("response", "dash-cenc")
        if self.__dashStreamsSupported and dashInfo:
            Logger.Debug("Using Dash streams to playback")
            dashInfo = jsonData.GetValue("response", "dash-cenc")
            licenseUrl = dashInfo["widevineLicenseServerURL"]
            streamUrl = dashInfo["url"]
            sessionId = jsonData.GetValue("request", "access_token")

            licenseHeader = {
                "merchant": "medialaan",
                "userId": self.__userId,
                "sessionId": sessionId
            }
            licenseHeader = JsonHelper.Dump(licenseHeader, False)
            licenseHeaders = "x-dt-custom-data={0}&Content-Type=application/octstream".format(base64.b64encode(licenseHeader))

            kodiProps = {
                "inputstreamaddon": "inputstream.adaptive",
                "inputstream.adaptive.manifest_type": "mpd",
                "inputstream.adaptive.license_type": "com.widevine.alpha",
                "inputstream.adaptive.license_key": "{0}?specConform=true|{1}|R{{SSM}}|".format(licenseUrl, licenseHeaders or "")
            }

            part = item.CreateNewEmptyMediaPart()
            stream = part.AppendMediaStream(streamUrl, 0)
            # noinspection PyTypeChecker
            for k, v in kodiProps.iteritems():
                stream.AddProperty(k, v)
        else:
            Logger.Debug("No Dash streams supported or no Dash streams available. Using M3u8 streams")

            m3u8Url = jsonData.GetValue("response", "hls-encrypted", "url")
            if not m3u8Url:
                m3u8Url = jsonData.GetValue("response", "uri")
                # m3u8Url = jsonData.GetValue("response", "hls-drm-uri")  # not supported by Kodi

            part = item.CreateNewEmptyMediaPart()
            # Set the Range header to a proper value to make all streams start at the beginning. Make
            # sure that a complete TS part comes in a single call otherwise we get stuttering.
            byteRange = 10 * 1024 * 1024
            Logger.Debug("Setting an 'Range' http header of bytes=0-%d to force playback at the start "
                         "of a stream and to include a full .ts part.", byteRange)
            part.HttpHeaders["Range"] = 'bytes=0-%d' % (byteRange, )

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

        return item
Example #25
0
    def GetStreamsFromNpo(url, episodeId, proxy=None, headers=None):
        """ Retrieve NPO Player Live streams from a different number of stream urls.

        @param url:               (String) The url to download
        @param episodeId:         (String) The NPO episode ID
        @param headers:           (dict) Possible HTTP Headers
        @param proxy:             (Proxy) The proxy to use for opening

        Can be used like this:

            part = item.CreateNewEmptyMediaPart()
            for s, b in NpoStream.GetStreamsFromNpo(m3u8Url, self.proxy):
                item.complete = True
                # s = self.GetVerifiableVideoUrl(s)
                part.AppendMediaStream(s, b)

        """

        if url:
            Logger.Info("Determining streams for url: %s", url)
            episodeId = url.split("/")[-1]
        elif episodeId:
            Logger.Info("Determining streams for VideoId: %s", episodeId)
        else:
            Logger.Error("No url or streamId specified!")
            return []

        # we need an hash code
        tokenJsonData = UriHandler.Open("http://ida.omroep.nl/app.php/auth",
                                        noCache=True,
                                        proxy=proxy,
                                        additionalHeaders=headers)
        tokenJson = JsonHelper(tokenJsonData)
        token = tokenJson.GetValue("token")

        url = "http://ida.omroep.nl/app.php/%s?adaptive=yes&token=%s" % (
            episodeId, token)
        streamData = UriHandler.Open(url,
                                     proxy=proxy,
                                     additionalHeaders=headers)
        if not streamData:
            return []

        streamJson = JsonHelper(streamData, logger=Logger.Instance())
        streamInfos = streamJson.GetValue("items")[0]
        Logger.Trace(streamInfos)
        streams = []
        for streamInfo in streamInfos:
            Logger.Debug("Found stream info: %s", streamInfo)
            if streamInfo["format"] == "mp3":
                streams.append((streamInfo["url"], 0))
                continue

            elif streamInfo["contentType"] == "live":
                Logger.Debug("Found live stream")
                url = streamInfo["url"]
                url = url.replace("jsonp", "json")
                liveUrlData = UriHandler.Open(url,
                                              proxy=proxy,
                                              additionalHeaders=headers)
                liveUrl = liveUrlData.strip("\"").replace("\\", "")
                Logger.Trace(liveUrl)
                streams += M3u8.GetStreamsFromM3u8(liveUrl,
                                                   proxy,
                                                   headers=headers)

            elif streamInfo["format"] == "hls":
                m3u8InfoUrl = streamInfo["url"]
                m3u8InfoData = UriHandler.Open(m3u8InfoUrl,
                                               proxy=proxy,
                                               additionalHeaders=headers)
                m3u8InfoJson = JsonHelper(m3u8InfoData,
                                          logger=Logger.Instance())
                m3u8Url = m3u8InfoJson.GetValue("url")
                streams += M3u8.GetStreamsFromM3u8(m3u8Url,
                                                   proxy,
                                                   headers=headers)

            elif streamInfo["format"] == "mp4":
                bitrates = {"hoog": 1000, "normaal": 500}
                url = streamInfo["url"]
                if "contentType" in streamInfo and streamInfo[
                        "contentType"] == "url":
                    mp4Url = url
                else:
                    url = url.replace("jsonp", "json")
                    mp4UrlData = UriHandler.Open(url,
                                                 proxy=proxy,
                                                 additionalHeaders=headers)
                    mp4InfoJson = JsonHelper(mp4UrlData,
                                             logger=Logger.Instance())
                    mp4Url = mp4InfoJson.GetValue("url")
                bitrate = bitrates.get(streamInfo["label"].lower(), 0)
                if bitrate == 0 and "/ipod/" in mp4Url:
                    bitrate = 200
                elif bitrate == 0 and "/mp4/" in mp4Url:
                    bitrate = 500
                streams.append((mp4Url, bitrate))

        return streams
Example #26
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)
        Logger.Trace(data)

        if 'livestart":-' in data:
            Logger.Debug("Live item that has not yet begun.")
            json = JsonHelper(data, Logger.Instance())
            secondsToStart = json.GetValue("video", "livestart")
            if secondsToStart:
                secondsToStart = -int(secondsToStart)
                Logger.Debug("Seconds till livestream: %s", secondsToStart)
                timeLeft = "%s:%02d:%02d" % (secondsToStart / 3600, (secondsToStart % 3600) / 60, secondsToStart % 60)
                Logger.Debug("Live items starts at %s", timeLeft)
                lines = list(LanguageHelper.GetLocalizedString(LanguageHelper.NoLiveStreamId))
                lines[-1] = "%s ETA: %s" % (lines[-1], timeLeft)
                XbmcWrapper.ShowDialog(LanguageHelper.GetLocalizedString(LanguageHelper.NoLiveStreamTitleId),
                                       lines)
            else:
                XbmcWrapper.ShowDialog(LanguageHelper.GetLocalizedString(LanguageHelper.NoLiveStreamTitleId),
                                       LanguageHelper.GetLocalizedString(LanguageHelper.NoLiveStreamId))
            return item

        item.MediaItemParts = []
        mediaPart = item.CreateNewEmptyMediaPart()
        spoofIp = self._GetSetting("spoof_ip", "0.0.0.0")
        if spoofIp is not None:
            mediaPart.HttpHeaders["X-Forwarded-For"] = spoofIp

        # mediaPart.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0"

        # isLive = False
        if '"live":true' in data or "/live/" in item.url:
            mediaPart.AddProperty("IsLive", "true")
            Logger.Debug("Live video item found.")
            # isLive = True
        else:
            Logger.Debug("Normal (not live, or possible was live) video item found")

        # replace items
        #videos = map(lambda v: self.__ReplaceClist(v), videos)

        jsonVideoData = JsonHelper(data)
        videos = jsonVideoData.GetValue("video", "videoReferences")
        # videos = Regexer.DoRegex(self.mediaUrlRegex, data)
        for video in videos:
            playerType = video.get("playerType", "")
            if "dash" in playerType:
                continue

            if video["url"].startswith("rtmp"):
                # just replace some data in the URL
                mediaPart.AppendMediaStream(self.GetVerifiableVideoUrl(video["url"]).replace("_definst_", "?slist="),
                                            video[1])

            elif "m3u8" in video["url"]:
                Logger.Info("SVTPlay.se m3u8 stream found: %s", video["url"])

                # apparently the m3u8 do not work well for server www0.c91001.dna.qbrick.com
                if "www0.c91001.dna.qbrick.com" in video["url"]:
                    continue

                # m3u8 we need to parse. Get more streams from this file.
                videoUrl = video["url"]
                altIndex = videoUrl.find("m3u8?")
                # altIndex = videoUrl.find("~uri")
                if altIndex > 0:
                    videoUrl = videoUrl[0:altIndex + 4]
                for s, b in M3u8.GetStreamsFromM3u8(videoUrl, self.proxy, headers=mediaPart.HttpHeaders):
                    item.complete = True
                    mediaPart.AppendMediaStream(s, b)

            elif "f4m" in video["url"]:
                Logger.Info("SVTPlay.se manifest.f4m stream found: %s", video["url"])

                #if "manifest.f4m?start=" in video["url"]:
                #    # this was a live stream, convert it to M3u8
                #    # http://svt06-lh.akamaihd.net/z/svt06_0@77501/manifest.f4m?start=1386566700&end=1386579600
                #    # to
                #    # http://svt06hls-lh.akamaihd.net/i/svt06_0@77501/master.m3u8?__b__=563&start=1386566700&end=1386579600
                #    m3u8Url = video["url"].replace("-lh.akamaihd.net/z", "hls-lh.akamaihd.net/i").replace("manifest.f4m?", "master.m3u8?__b__=563&")
                #    Logger.Info("Found f4m stream for an old Live stream. Converting to M3U8:\n%s -to -\n%s", video["url"], m3u8Url)
                #    videos.append((m3u8Url, 0))
                #    continue

                # for now we skip these as they do not yet work with XBMC
                continue
                # http://svtplay8m-f.akamaihd.net/z/se/krypterat/20120830/254218/LILYHAMMER-003A-mp4-,c,d,b,e,-v1-4bc7ecc090b19c82.mp4.csmil/manifest.f4m?hdcore=2.8.0&g=TZOMVRTEILSE
                #videoDataUrl = video["url"]
                # videoUrl = "%s?hdcore=2.8.0&g=TZOMVRTEILSE" % (videoDataUrl,)
                #videoUrl = "%s?hdcore=2.10.3&g=IJGTWSVWPPKH" % (videoDataUrl,)

                # metaData = UriHandler.Open(videoUrl, proxy=self.proxy, referer=self.swfUrl)
                # Logger.Debug(metaData)

                # The referer seems to be unimportant
                # header = "referer=%s" % (urllib.quote(self.swfUrl),)
                # videoUrl = "%s|%s" % (videoUrl, header)
                #mediaPart.AppendMediaStream(videoUrl, video[1])

            else:
                Logger.Info("SVTPlay.se standard HTTP stream found.")
                # else just use the URL
                mediaPart.AppendMediaStream(video["url"], video["bitrate"])

        subtitle = Regexer.DoRegex('"url":"([^"]+.wsrt)"|"url":"(http://media.svt.se/download/[^"]+.m3u8)', data)
        for sub in subtitle:
            if sub[-1]:
                Logger.Info("Found M3u8 subtitle, replacing with WSRT")
                start, name, index = sub[-1].rsplit("/", 2)
                subUrl = "%s/%s/%s.wsrt" % (start, name, name)
            else:
                subUrl = sub[0]
            mediaPart.Subtitle = subtitlehelper.SubtitleHelper.DownloadSubtitle(subUrl, format="srt", proxy=self.proxy)

        item.complete = True
        return item
Example #27
0
    def UpdateChannelItem(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")
        Logger.Trace(videos)

        item.MediaItemParts = []
        part = item.CreateNewEmptyMediaPart()
        spoofIp = self._GetSetting("spoof_ip", "0.0.0.0")
        if spoofIp is not None:
            part.HttpHeaders["X-Forwarded-For"] = spoofIp

        for video in videos:
            # bitrate = video['bitrate']
            url = video['url']
            # player = video['playerType']
            # if "ios" in player:
            #     bitrate += 1

            if "akamaihd" in url and "f4m" in url:
                continue
                # these are not supported as they return a 503 error
                #noinspection PyUnreachableCode
                #url = url.replace("/z/", "/i/").replace("/manifest.f4m", "/master.m3u8")

            if len(filter(lambda s: s.Url == url, part.MediaStreams)) > 0:
                Logger.Debug("Skippping duplicate Stream url: %s", url)
                continue

            if "m3u8" in url:
                for s, b in M3u8.GetStreamsFromM3u8(url, proxy=self.proxy, headers=part.HttpHeaders):
                    part.AppendMediaStream(s, b)
            else:
                part.AppendMediaStream(url, 0)

        item.complete = True
        return item
Example #28
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,
                               additionalHeaders=item.HttpHeaders)
        videoId = Regexer.DoRegex('data-video="([^"]+)"', data)[-1]
        url = "https://mediazone.vrt.be/api/v1/canvas/assets/%s" % (videoId, )
        data = UriHandler.Open(url,
                               proxy=self.proxy,
                               additionalHeaders=item.HttpHeaders)
        json = JsonHelper(data)

        geoLocked = str(json.GetValue("metaInfo", "allowedRegion").lower())
        hideGeoLocked = AddonSettings.HideGeoLockedItemsForLocation(geoLocked)
        if hideGeoLocked:
            geoRegion = AddonSettings.HideGeoLockedItemsForLocation(
                geoLocked, True)
            Logger.Warning(
                "Found GEO Locked item for region '%s'. Current region is '%s'",
                geoLocked, geoRegion)
            return item

        part = item.CreateNewEmptyMediaPart()
        for video in json.GetValue("targetUrls"):
            videoType = video["type"].lower()
            url = video["url"]
            if videoType == "progressive_download":
                bitrate = 1000
            elif videoType == "hls":
                for s, b in M3u8.GetStreamsFromM3u8(url, self.proxy):
                    # s = self.GetVerifiableVideoUrl(s)
                    part.AppendMediaStream(s, b)
                continue
            elif videoType == "rtmp":
                # url=rtmp://vod.stream.vrt.be/mediazone_canvas/_definst_/mp4:2015/11/mz-ast-79a551d6-2621-4a0f-9af0-a272fb0954db-1/video_1296.mp4
                url = url.replace("_definst_/mp4:", "?slist=")
                bitrate = 1100
            else:
                Logger.Debug("Found unhandled stream type '%s':%s", videoType,
                             url)
                continue
            part.AppendMediaStream(url, bitrate)

        item.complete = True
        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:
        * 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)
        # User-agent (and possible other headers), should be consistent over all M3u8 requests (See #864)
        headers = {
            # "User-Agent": AddonSettings.GetUserAgent(),
            "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)",
            # "Origin": "https://www.viafree.se"
        }
        if self.localIP:
            headers.update(self.localIP)

        if True:
            data = UriHandler.Open(item.url,
                                   proxy=self.proxy,
                                   additionalHeaders=headers or None)
        else:
            from debug.router import Router
            data = Router.GetVia("se", item.url, self.proxy)

        json = JsonHelper(data)

        # see if there was an srt already
        if item.MediaItemParts:
            part = item.MediaItemParts[0]
            if part.Subtitle and part.Subtitle.endswith(".vtt"):
                part.Subtitle = SubtitleHelper.DownloadSubtitle(
                    part.Subtitle, format="webvtt", proxy=self.proxy)
            else:
                part.Subtitle = SubtitleHelper.DownloadSubtitle(
                    part.Subtitle, format="dcsubtitle", proxy=self.proxy)
        else:
            part = item.CreateNewEmptyMediaPart()

        for q in ("high", 3500), ("hls", 2700), ("medium", 2100):
            url = json.GetValue("streams", q[0])
            Logger.Trace(url)
            if not url:
                continue

            if ".f4m" in url:
                # Kodi does not like the f4m streams
                continue

            if url.startswith("http") and ".m3u8" in url:
                for s, b in M3u8.GetStreamsFromM3u8(url,
                                                    self.proxy,
                                                    headers=headers):
                    part.AppendMediaStream(s, b)

                if not part.MediaStreams and "manifest.m3u8":
                    Logger.Warning(
                        "No streams found in %s, trying alternative with 'master.m3u8'",
                        url)
                    url = url.replace("manifest.m3u8", "master.m3u8")
                    for s, b in M3u8.GetStreamsFromM3u8(url,
                                                        self.proxy,
                                                        headers=headers):
                        part.AppendMediaStream(s, b)

                # check for subs
                # https://mtgxse01-vh.akamaihd.net/i/201703/13/DCjOLN_1489416462884_427ff3d3_,48,260,460,900,1800,2800,.mp4.csmil/master.m3u8?__b__=300&hdnts=st=1489687185~exp=3637170832~acl=/*~hmac=d0e12e62c219d96798e5b5ef31b11fa848724516b255897efe9808c8a499308b&cc1=name=Svenska%20f%C3%B6r%20h%C3%B6rselskadade~default=no~forced=no~lang=sv~uri=https%3A%2F%2Fsubstitch.play.mtgx.tv%2Fsubtitle%2Fconvert%2Fxml%3Fsource%3Dhttps%3A%2F%2Fcdn-subtitles-mtgx-tv.akamaized.net%2Fpitcher%2F20xxxxxx%2F2039xxxx%2F203969xx%2F20396967%2F20396967-swt.xml%26output%3Dm3u8
                # https://cdn-subtitles-mtgx-tv.akamaized.net/pitcher/20xxxxxx/2039xxxx/203969xx/20396967/20396967-swt.xml&output=m3u8
                if "uri=" in url and not part.Subtitle:
                    Logger.Debug("Extracting subs from M3u8")
                    subUrl = url.rsplit("uri=")[-1]
                    subUrl = HtmlEntityHelper.UrlDecode(subUrl)
                    subData = UriHandler.Open(subUrl, proxy=self.proxy)
                    # subUrl = None
                    subs = filter(lambda line: line.startswith("http"),
                                  subData.split("\n"))
                    # for line in subData.split("\n"):
                    #     if line.startswith("http"):
                    #         subUrl = line
                    #         break
                    if subs:
                        part.Subtitle = SubtitleHelper.DownloadSubtitle(
                            subs[0], format='webvtt', proxy=self.proxy)

            elif url.startswith("rtmp"):
                # rtmp://mtgfs.fplive.net/mtg/mp4:flash/sweden/tv3/Esport/Esport/swe_skillcompetition.mp4.mp4
                oldUrl = url
                if not url.endswith(".flv") and not url.endswith(".mp4"):
                    url += '.mp4'

                if "/mp4:" in url:
                    # in this case we need to specifically set the path
                    # url = url.replace('/mp4:', '//') -> don't do this, but specify the path
                    server, path = url.split("mp4:", 1)
                    url = "%s playpath=mp4:%s" % (server, path)

                if oldUrl != url:
                    Logger.Debug("Updated URL from - to:\n%s\n%s", oldUrl, url)

                url = self.GetVerifiableVideoUrl(url)
                part.AppendMediaStream(url, q[1])

            else:
                part.AppendMediaStream(url, q[1])

        part.HttpHeaders.update(headers)
        if part.MediaStreams:
            item.complete = True
        Logger.Trace("Found mediaurl: %s", item)
        return item
Example #30
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)

        # rtmpt://vrt.flash.streampower.be/een//2011/07/1000_110723_getipt_neefs_wiels_Website_EEN.flv
        # http://www.een.be/sites/een.be/modules/custom/vrt_video/player/player_4.3.swf

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

        part = item.CreateNewEmptyMediaPart()
        if "mediazone.vrt.be" not in item.url:
            # Extract actual media data
            videoId = Regexer.DoRegex('data-video=[\'"]([^"\']+)[\'"]',
                                      data)[0]
            # if videoId.startswith("http"):
            #     Logger.Info("Found direct stream. Not processing any further.")
            #     part.AppendMediaStream(videoId, 0)
            #     item.complete = True
            #     return item

            url = "https://mediazone.vrt.be/api/v1/een/assets/%s" % (videoId, )
            data = UriHandler.Open(url, proxy=self.proxy)

        json = JsonHelper(data)
        urls = json.GetValue("targetUrls")
        for urlInfo in urls:
            Logger.Trace(urlInfo)
            if urlInfo["type"].lower() != "hls":
                continue

            hlsUrl = urlInfo["url"]
            for s, b in M3u8.GetStreamsFromM3u8(hlsUrl, self.proxy):
                part.AppendMediaStream(s, b)

        # urls = Regexer.DoRegex(self.mediaUrlRegex, data)
        # Logger.Trace(urls)
        # part = item.CreateNewEmptyMediaPart()
        # for url in urls:
        #     if not url[1] == "":
        #         mediaurl = "%s//%s" % (url[0], url[1])  # the extra slash in the url causes the application name in the RTMP stream to be "een" instead of "een/2011"
        #     else:
        #         mediaurl = url[0]
        #
        #     mediaurl = mediaurl.replace(" ", "%20")
        #
        #     if "rtmp" in mediaurl:
        #         mediaurl = self.GetVerifiableVideoUrl(mediaurl)
        #         # In some cases the RTMPT does not work. Let's just try the RTMP first and then add the original if the RTMP version fails.
        #         part.AppendMediaStream(mediaurl.replace("rtmpt://", "rtmp://"), 650)
        #     elif "rtsp" in mediaurl:
        #         part.AppendMediaStream(mediaurl, 600)
        #     elif mediaurl.startswith("http") and "m3u8" in mediaurl:
        #         # http://iphone.streampower.be/een_nogeo/_definst_/2013/08/1000_130830_placetobe_marjolein_Website_Een_M4V.m4v/playlist.m3u8
        #         mediaurl = mediaurl.rstrip()
        #         for s, b in M3u8.GetStreamsFromM3u8(mediaurl, self.proxy):
        #             part.AppendMediaStream(s, b)
        #     else:
        #         Logger.Warning("Media url was not recognised: %s", mediaurl)

        item.complete = True
        return item