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
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 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
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
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
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=([^&]+)&[^"]+" />', data) #<param name="flashvars" value="id=dj0xMDEzNzQyJmM9MTAwMDAwNA&tags=source%253Dfreecaster&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
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
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
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
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
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)
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)
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)
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
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
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
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
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
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
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)
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
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
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
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)
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
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
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