From 9088869ccd6c85087594e624c773937328680a4f Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 10 Jan 2014 07:03:22 +1100 Subject: [PATCH 1/8] start on rewrite and URL service --- ABCiView.bundle/Contents/Code/__init__.py | 55 ++++++++++++------- ABCiView.bundle/Contents/Code/iview_class.py | 22 +++++--- ABCiView.bundle/Contents/Info.plist | 2 +- .../Contents/Services/ServiceInfo.plist | 18 ++++++ .../Services/URL/iview/ServiceCode.pys | 47 ++++++++++++++++ 5 files changed, 117 insertions(+), 27 deletions(-) create mode 100644 ABCiView.bundle/Contents/Services/ServiceInfo.plist create mode 100644 ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys diff --git a/ABCiView.bundle/Contents/Code/__init__.py b/ABCiView.bundle/Contents/Code/__init__.py index df4fc0b..66930f3 100644 --- a/ABCiView.bundle/Contents/Code/__init__.py +++ b/ABCiView.bundle/Contents/Code/__init__.py @@ -3,17 +3,14 @@ ART = 'art-default.jpg' ICON = 'icon-default.jpg' - def Start(): + HTTP.RandomizeUserAgent(browser='Safari') Plugin.AddViewGroup('List', viewMode='List', mediaType='items') Plugin.AddViewGroup('InfoList', viewMode='InfoList', mediaType='items') - -@handler('/video/aubciview', 'Australian ABC iView', art=ART, thumb=ICON) +@handler('/video/iview', 'ABC iView', art=ART, thumb=ICON) def MainMenu(): oc = ObjectContainer(view_group='List', title2='ABC iView') - - #oc.add(VideoClipObject(key = RTMPVideoURL(url = 'rtmp://203.18.195.10/ondemand' + '?auth=7B8F0402DD370FF9299E', clip = 'mp4:comedy/madashell_02_08', swf_url = 'http://www.abc.net.au/iview/images/iview.jpg'), rating_key = '123',title = 'TEST')) cats = iView_Config.List_Categories() @@ -29,7 +26,7 @@ def MainMenu(): return oc -@route('/video/aubciview/category/{category}') +@route('/video/iview/category/{category}') def GetSeriesByCaegory(category): cat = iView_Category(category) @@ -42,19 +39,23 @@ def GetSeriesByCaegory(category): key=Callback(GetEpisodesBySeries, series=item[0]), title=item[1] )) + Log('Adding series key:' + item[0]) oc.objects.sort(key=lambda obj: obj.title) return oc -@route('/video/aubciview/series/{series}') +@route('/video/abciview/series/{series}') def GetEpisodesBySeries(series): show = iView_Series(series) oc = ObjectContainer(view_group='InfoList', title2=show.title, no_cache=True) episodes = show.episodes - + Log('>>>>>>>>>>Got Episodes<<<<<<<<<<<<<<') + Log(str(episodes)) + rtmp_url = iView_Config.RTMP_URL() + Log('Got rtmp url for TPG IP with: ' + rtmp_url) for item in episodes: dur = item[5] * 1000 @@ -65,7 +66,7 @@ def GetEpisodesBySeries(series): return oc -@route('/video/aubciview/episode/play') +@route('/video/iview/episode/play') def Play_iView(iView_Title, iView_Summary, iView_Path, iView_Thumb, iView_Duration, video_url, iView_live=0, include_container=False): HTTP.ClearCache() @@ -83,27 +84,43 @@ def Play_iView(iView_Title, iView_Summary, iView_Path, iView_Thumb, iView_Durati "include_container": True, } + Log('==== Video ====') + Log('Title: ' + iView_Title) + Log('RTMP Path: ' + video_url) + Log('Clip Path: ' + iView_Config.CLIP_PATH()) + Log('Video Path: ' + iView_Path) + Log('==== End Video ====') + if iView_live == 1: rtmpVid = RTMPVideoURL(url=video_url, clip=iView_Path, swf_url=iView_Config.SWF_URL, live=True) else: rtmpVid = RTMPVideoURL(url=video_url, clip=iView_Config.CLIP_PATH() + iView_Path, swf_url=iView_Config.SWF_URL) + #vco = VideoClipObject( + # key=Callback(Play_iView, **call_args), + # rating_key=iView_Path, + # title=iView_Title, + # summary=iView_Summary, + # thumb=iView_Thumb, + # duration=int(iView_Duration), + # items=[ + # MediaObject( + # parts=[ + # PartObject( + # key=rtmpVid + # ) + # ] + # ) + # ] + #) + vco = VideoClipObject( - key=Callback(Play_iView, **call_args), + url= 'something', #Callback(Play_iView, **call_args), rating_key=iView_Path, title=iView_Title, summary=iView_Summary, thumb=iView_Thumb, duration=int(iView_Duration), - items=[ - MediaObject( - parts=[ - PartObject( - key=rtmpVid - ) - ] - ) - ] ) if include_container: diff --git a/ABCiView.bundle/Contents/Code/iview_class.py b/ABCiView.bundle/Contents/Code/iview_class.py index e271c4c..0b3d437 100644 --- a/ABCiView.bundle/Contents/Code/iview_class.py +++ b/ABCiView.bundle/Contents/Code/iview_class.py @@ -16,19 +16,27 @@ class iView_Config(): SERIES_URL = API_URL + 'seriesIndex' SERIES_JSON = JSON.ObjectFromURL(SERIES_URL) category_list = {} + + FALLBACK_PATH = 'rtmp://cp53909.edgefcs.net/ondemand' @classmethod def RTMP_URL(self): - xml = XML.ElementFromURL(url=self.AUTH_URL) - token = xml.xpath('//a:token/text()', namespaces={'a': 'http://www.abc.net.au/iView/Services/iViewHandshaker'})[ - 0] - return xml.xpath('//a:server/text()', namespaces={'a': 'http://www.abc.net.au/iView/Services/iViewHandshaker'})[ - 0] + '?auth=' + token - + xml = XML.ElementFromURL(url=self.AUTH_URL) + token = xml.xpath('//a:token/text()', namespaces={'a': 'http://www.abc.net.au/iView/Services/iViewHandshaker'})[0] + server = xml.xpath('//a:server/text()', namespaces={'a': 'http://www.abc.net.au/iView/Services/iViewHandshaker'})[0] + + if 'http' in server: + return self.FALLBACK_PATH + '?auth=' + token + else: + return server + '?auth=' + token + + @classmethod def CLIP_PATH(self): - xml = XML.ElementFromURL(self.AUTH_URL) + return 'mp4:flash/playback/_definst_/' + + xml = XML.ElementFromURL(self.AUTH_URL) path = xml.xpath('//a:path/text()', namespaces={'a': 'http://www.abc.net.au/iView/Services/iViewHandshaker'}) if not path: return 'mp4:' diff --git a/ABCiView.bundle/Contents/Info.plist b/ABCiView.bundle/Contents/Info.plist index 76a0a73..dfa823e 100644 --- a/ABCiView.bundle/Contents/Info.plist +++ b/ABCiView.bundle/Contents/Info.plist @@ -3,7 +3,7 @@ CFBundleIdentifier - com.plexapp.plugins.aubciview + com.plexapp.plugins.iview PlexClientPlatforms * PlexFrameworkVersion diff --git a/ABCiView.bundle/Contents/Services/ServiceInfo.plist b/ABCiView.bundle/Contents/Services/ServiceInfo.plist new file mode 100644 index 0000000..057e8c3 --- /dev/null +++ b/ABCiView.bundle/Contents/Services/ServiceInfo.plist @@ -0,0 +1,18 @@ + + + + + URL + + iview + + Identifier + com.plexapp.plugins.iview + URLPatterns + + http://abc.net.au/iview/.+ + + + + + \ No newline at end of file diff --git a/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys b/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys new file mode 100644 index 0000000..c22ae55 --- /dev/null +++ b/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys @@ -0,0 +1,47 @@ +# getSeries: http://iview.abc.net.au/api/legacy/flash/?series=$ID +# getAllSeries: http://iview.abc.net.au/api/legacy/flash/?series=all + +def MetadataObjectForURL(url): + + #if CHECKURL + # + data = JSON.ObjectFromURL(url) + Log('>>>>>>>>SERVICE: MetadataObjectForURL: ' + url) + #title = data['name'] + #summary = data['shortDescription'] + #thumb = data['thumbnailURL'] + #duration = data['length'] + #originally_available_at = Datetime.FromTimestamp(int(data['publishedDate'])/1000) + # + #return VideoClipObject( + # title=title, + # summary=summary, + # thumb=thumb, + # duration=duration, + # originally_available_at=originally_available_at, + #) + + +def MediaObjectsForURL(url): + + container = Container.MP4 + video_codec = VideoCodec.H264 + audio_codec = AudioCodec.AAC + audio_channels = 2 + + return [ + MediaObject( + protocol='rtmp', + video_resolution='576', + audio_channels=2, + parts=[PartObject(key=Callback(PlayVideo, url=url))], + ), + ] + +@indirect +def PlayVideo(url): + #do the work to return get the RTMP URL + + return IndirectResponse(VideoClipObject, key=RTMPVideoURL(url=rtmp_base, clip=rtmp_clip)) + #data = JSON.ObjectFromURL(url) + #return Redirect(data['FLVURL']) \ No newline at end of file From 56bd53dca6e5b9448101a9d10fd1542a8d770a77 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 10 Jan 2014 08:21:37 +1100 Subject: [PATCH 2/8] URL service now working bar playback --- ABCiView.bundle/Contents/Code/__init__.py | 20 +++++++--- ABCiView.bundle/Contents/Code/iview_class.py | 36 +++++++---------- .../Services/URL/iview/ServiceCode.pys | 40 ++++++++++++------- 3 files changed, 55 insertions(+), 41 deletions(-) diff --git a/ABCiView.bundle/Contents/Code/__init__.py b/ABCiView.bundle/Contents/Code/__init__.py index 66930f3..ce011d1 100644 --- a/ABCiView.bundle/Contents/Code/__init__.py +++ b/ABCiView.bundle/Contents/Code/__init__.py @@ -45,9 +45,19 @@ def GetSeriesByCaegory(category): return oc -@route('/video/abciview/series/{series}') +@route('/video/iview/series/{series}') def GetEpisodesBySeries(series): show = iView_Series(series) + json = JSON.ObjectFromURL('http://iview.abc.net.au/api/legacy/flash/?series=' + series) + Log('Got series info back>>>>>' + str(json)) + Log('Got show back>>>>>') + Log(str(show)) + #self.title = json[0]['b'] + #self.description = json[0]['c'] + #self.category = json[0]['e'] + #self.img = json[0]['d'] + #self.episode_count = len(json[0]['f']) + #self.episodes = self.Episodes(json[0]['f']) oc = ObjectContainer(view_group='InfoList', title2=show.title, no_cache=True) episodes = show.episodes @@ -58,8 +68,7 @@ def GetEpisodesBySeries(series): Log('Got rtmp url for TPG IP with: ' + rtmp_url) for item in episodes: - dur = item[5] * 1000 - oc.add(Play_iView(item[1], item[2], item[3], item[4], dur, rtmp_url, item[6])) + oc.add(Play_iView(item['id'], item['title'], item['description'], item['url'], item['thumb'], item['duration'], rtmp_url, item['live'])) oc.objects.sort(key=lambda obj: obj.title) @@ -67,13 +76,14 @@ def GetEpisodesBySeries(series): @route('/video/iview/episode/play') -def Play_iView(iView_Title, iView_Summary, iView_Path, iView_Thumb, iView_Duration, video_url, iView_live=0, +def Play_iView(video_id, iView_Title, iView_Summary, iView_Path, iView_Thumb, iView_Duration, video_url, iView_live=0, include_container=False): HTTP.ClearCache() iView_live = int(iView_live) call_args = { + "video_id": video_id, "iView_Title": iView_Title, "iView_Summary": iView_Summary, "iView_Path": iView_Path, @@ -115,7 +125,7 @@ def Play_iView(iView_Title, iView_Summary, iView_Path, iView_Thumb, iView_Durati #) vco = VideoClipObject( - url= 'something', #Callback(Play_iView, **call_args), + url= 'http://abc.net.au/iview/#/view/' + video_id, #Callback(Play_iView, **call_args), rating_key=iView_Path, title=iView_Title, summary=iView_Summary, diff --git a/ABCiView.bundle/Contents/Code/iview_class.py b/ABCiView.bundle/Contents/Code/iview_class.py index 0b3d437..e59bc07 100644 --- a/ABCiView.bundle/Contents/Code/iview_class.py +++ b/ABCiView.bundle/Contents/Code/iview_class.py @@ -59,7 +59,8 @@ def List_Categories(self): class iView_Series(object): def __init__(self, key): self.id = key - json = JSON.ObjectFromURL(iView_Config.API_URL + 'series=' + key) + Log('Getting iView series info for:' + iView_Config.API_URL + 'series=' + key) + json = JSON.ObjectFromURL(iView_Config.API_URL + 'series=' + key) self.title = json[0]['b'] self.description = json[0]['c'] @@ -71,33 +72,26 @@ def __init__(self, key): def Episodes(self, json): eps = [] for ep in json: - id = ep['a'] - title = ep['b'] - description = ep['d'] + episode = {} + episode['id'] = ep['a'] + episode['title'] = ep['b'] + episode['description'] = ep['d'] - live = 0 + episode['live'] = 0 if 'n' in ep: - url = ep['n'][:-4] + episode['url'] = ep['n'][:-4] else: - url = ep['r'] - live = 1 + episode['url'] = ep['r'] + episode['live'] = 1 - thumb = ep['s'] + episode['thumb'] = ep['s'] if 'j' in ep: - duration = int(ep['j']) + episode['duration'] = int(ep['j']) * 1000 else: - duration = 0 - - tmp = [] - tmp.append(id) - tmp.append(title) - tmp.append(description) - tmp.append(url) - tmp.append(thumb) - tmp.append(duration) - tmp.append(live) - eps.append(tmp) + episode['duration'] = 0 + + eps.append(episode) return eps diff --git a/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys b/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys index c22ae55..beccd57 100644 --- a/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys +++ b/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys @@ -5,21 +5,28 @@ def MetadataObjectForURL(url): #if CHECKURL # - data = JSON.ObjectFromURL(url) + RE_PLAYLIST = Regex('([0-9]+)$', Regex.DOTALL) + ID = RE_PLAYLIST.search(url).group(0) + Log('Got ID:' + ID) + + data = JSON.ObjectFromURL('http://iview.abc.net.au/api/legacy/flash/?series='+ID) Log('>>>>>>>>SERVICE: MetadataObjectForURL: ' + url) - #title = data['name'] - #summary = data['shortDescription'] - #thumb = data['thumbnailURL'] - #duration = data['length'] - #originally_available_at = Datetime.FromTimestamp(int(data['publishedDate'])/1000) - # - #return VideoClipObject( - # title=title, - # summary=summary, - # thumb=thumb, - # duration=duration, - # originally_available_at=originally_available_at, - #) + episodes = data[0]['f'] + for episode in episodes: + if episode['a'] == ID: + title = episode['b'] + summary = episode['d'] + thumb = episode['s'] + duration = int(episode['j'])*1000 + #originally_available_at + + + return VideoClipObject( + title=title, + summary=summary, + thumb=thumb, + duration=duration, + ) def MediaObjectsForURL(url): @@ -42,6 +49,9 @@ def MediaObjectsForURL(url): def PlayVideo(url): #do the work to return get the RTMP URL - return IndirectResponse(VideoClipObject, key=RTMPVideoURL(url=rtmp_base, clip=rtmp_clip)) + rtmpVid = RTMPVideoURL(url='rtmp://cp53909.edgefcs.net/ondemand?auth=daEdQbtbJd7dPaMbjcFb4b_cGbybNaLaDdi-bsZWG.-8-llu_wHAqG&aifp=v001' + , clip='kids/backyardscience_01_20', swf_url='http://www.abc.net.au/iview/images/iview.jpg' + ) + return IndirectResponse(VideoClipObject, key=rtmpVid) #data = JSON.ObjectFromURL(url) #return Redirect(data['FLVURL']) \ No newline at end of file From 372b02501ba72439a7a6e661314c33ce51d2479f Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 10 Jan 2014 18:35:02 +1100 Subject: [PATCH 3/8] RTMP not playing but REAL support now included --- .../Contents/Services/ServiceInfo.plist | 6 +++++- .../Contents/Services/URL/iview/ServiceCode.pys | 14 ++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/ABCiView.bundle/Contents/Services/ServiceInfo.plist b/ABCiView.bundle/Contents/Services/ServiceInfo.plist index 057e8c3..918fd52 100644 --- a/ABCiView.bundle/Contents/Services/ServiceInfo.plist +++ b/ABCiView.bundle/Contents/Services/ServiceInfo.plist @@ -12,7 +12,11 @@ http://abc.net.au/iview/.+ - + + PlexFrameworkFlags + + UseRealRTMP + \ No newline at end of file diff --git a/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys b/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys index beccd57..d127477 100644 --- a/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys +++ b/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys @@ -49,9 +49,11 @@ def MediaObjectsForURL(url): def PlayVideo(url): #do the work to return get the RTMP URL - rtmpVid = RTMPVideoURL(url='rtmp://cp53909.edgefcs.net/ondemand?auth=daEdQbtbJd7dPaMbjcFb4b_cGbybNaLaDdi-bsZWG.-8-llu_wHAqG&aifp=v001' - , clip='kids/backyardscience_01_20', swf_url='http://www.abc.net.au/iview/images/iview.jpg' - ) - return IndirectResponse(VideoClipObject, key=rtmpVid) - #data = JSON.ObjectFromURL(url) - #return Redirect(data['FLVURL']) \ No newline at end of file + #rtmpVid = RTMPVideoURL(url='rtmp://cp53909.edgefcs.net/ondemand?auth=daEdQbtbJd7dPaMbjcFb4b_cGbybNaLaDdi-bsZWG.-8-llu_wHAqG&aifp=v001' + # , clip='kids/backyardscience_01_20', swf_url='http://www.abc.net.au/iview/images/iview.jpg' + # ) + rtmpVid = RTMPVideoURL(url='rtmp://cp53909.edgefcs.net/ondemand?auth=daEdQbtbJd7dPaMbjcFb4b_cGbybNaLaDdi-bsZWG.-8-llu_wHAqG&aifp=v001', clip='mp4:flash/playback/_definst_/kids/backyardscience_01_20', swf_url='http://www.abc.net.au/iview/images/iview.jpg') + + Log('attempting to play video') + + return IndirectResponse(VideoClipObject, key=RTMPVideoURL(url='rtmp://cp53909.edgefcs.net/ondemand?auth=daEdQbtbJd7dPaMbjcFb4b_cGbybNaLaDdi-bsZWG.-8-llu_wHAqG&aifp=v001', clip='mp4:flash/playback/_definst_/kids/backyardscience_01_20', swf_url='http://www.abc.net.au/iview/images/iview.jpg')) \ No newline at end of file From a4db0a53b70097a691aa07bf2cdd6f68f20da33d Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 10 Jan 2014 22:37:58 +1100 Subject: [PATCH 4/8] now streaming --- .../Services/URL/iview/ServiceCode.pys | 45 +++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys b/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys index d127477..001458d 100644 --- a/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys +++ b/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys @@ -51,9 +51,48 @@ def PlayVideo(url): #rtmpVid = RTMPVideoURL(url='rtmp://cp53909.edgefcs.net/ondemand?auth=daEdQbtbJd7dPaMbjcFb4b_cGbybNaLaDdi-bsZWG.-8-llu_wHAqG&aifp=v001' # , clip='kids/backyardscience_01_20', swf_url='http://www.abc.net.au/iview/images/iview.jpg' - # ) - rtmpVid = RTMPVideoURL(url='rtmp://cp53909.edgefcs.net/ondemand?auth=daEdQbtbJd7dPaMbjcFb4b_cGbybNaLaDdi-bsZWG.-8-llu_wHAqG&aifp=v001', clip='mp4:flash/playback/_definst_/kids/backyardscience_01_20', swf_url='http://www.abc.net.au/iview/images/iview.jpg') + #) + BASE_URL = 'http://www.abc.net.au/iview/' + CFG_URL = BASE_URL + 'xml/config.xml' + CFG_XML = XML.ElementFromURL(CFG_URL) + AUTH_URL = CFG_XML.xpath('/config/param[@name="auth"]')[0].get("value") + FALLBACK_PATH = 'rtmp://cp53909.edgefcs.net/ondemand' + xml = XML.ElementFromURL(url=AUTH_URL) + token = xml.xpath('//a:token/text()', namespaces={'a': 'http://www.abc.net.au/iView/Services/iViewHandshaker'})[0] + server = xml.xpath('//a:server/text()', namespaces={'a': 'http://www.abc.net.au/iView/Services/iViewHandshaker'})[0] + + if 'http' in server: + rtmpURL = FALLBACK_PATH + '?auth=' + token + else: + rtmpURL = server + '?auth=' + token + + RE_ID = Regex('([0-9]+)$', Regex.DOTALL) + ID = RE_ID.search(url).group(0) + Log('Got ID:' + ID) + API_URL = CFG_XML.xpath('/config/param[@name="api"]')[0].get("value") + + data = JSON.ObjectFromURL(API_URL + 'series=' + str(ID)) + Log('>>>>>>>>SERVICE: MetadataObjectForURL: ' + url) + episodes = data[0]['f'] + for episode in episodes: + if episode['a'] == ID: + live = 0 + if 'n' in episode: + video_url = episode['n'][:-4] + else: + video_url = episode['r'] + live = 1 + + SWF_URL = 'http://www.abc.net.au/iview/images/iview.jpg' + CLIP = 'mp4:flash/playback/_definst_/' + if live == 1: + rtmpVid = RTMPVideoURL(url=rtmpURL, clip=video_url, swf_url=SWF_URL, live=True) + else: + rtmpVid = RTMPVideoURL(url=rtmpURL, clip=CLIP + video_url, swf_url=SWF_URL) + + #rtmpVid = RTMPVideoURL(url='rtmp://cp53909.edgefcs.net/ondemand?auth=daEdQbtbJd7dPaMbjcFb4b_cGbybNaLaDdi-bsZWG.-8-llu_wHAqG&aifp=v001', clip='mp4:flash/playback/_definst_/kids/backyardscience_01_20', swf_url='http://www.abc.net.au/iview/images/iview.jpg') Log('attempting to play video') - return IndirectResponse(VideoClipObject, key=RTMPVideoURL(url='rtmp://cp53909.edgefcs.net/ondemand?auth=daEdQbtbJd7dPaMbjcFb4b_cGbybNaLaDdi-bsZWG.-8-llu_wHAqG&aifp=v001', clip='mp4:flash/playback/_definst_/kids/backyardscience_01_20', swf_url='http://www.abc.net.au/iview/images/iview.jpg')) \ No newline at end of file + #return IndirectResponse(VideoClipObject, key=RTMPVideoURL(url='rtmp://cp53909.edgefcs.net/ondemand?auth=daEdQbtbJd7dPaMbjcFb4b_cGbybNaLaDdi-bsZWG.-8-llu_wHAqG&aifp=v001', clip='mp4:flash/playback/_definst_/kids/backyardscience_01_20', swf_url='http://www.abc.net.au/iview/images/iview.jpg')) + return IndirectResponse(VideoClipObject, key=rtmpVid) \ No newline at end of file From 8c909b0a2491b4c2cc212639ad01a1526838ba25 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 11 Jan 2014 07:45:56 +1100 Subject: [PATCH 5/8] clean up - start on populating all EpisodeObject fields --- ABCiView.bundle/Contents/Code/__init__.py | 50 ++----------------- .../Services/URL/iview/ServiceCode.pys | 29 ++++------- 2 files changed, 13 insertions(+), 66 deletions(-) diff --git a/ABCiView.bundle/Contents/Code/__init__.py b/ABCiView.bundle/Contents/Code/__init__.py index ce011d1..d5b9809 100644 --- a/ABCiView.bundle/Contents/Code/__init__.py +++ b/ABCiView.bundle/Contents/Code/__init__.py @@ -10,9 +10,8 @@ def Start(): @handler('/video/iview', 'ABC iView', art=ART, thumb=ICON) def MainMenu(): + oc = ObjectContainer(view_group='List', title2='ABC iView') - #oc.add(VideoClipObject(key = RTMPVideoURL(url = 'rtmp://203.18.195.10/ondemand' + '?auth=7B8F0402DD370FF9299E', clip = 'mp4:comedy/madashell_02_08', swf_url = 'http://www.abc.net.au/iview/images/iview.jpg'), rating_key = '123',title = 'TEST')) - cats = iView_Config.List_Categories() for key in cats: @@ -22,16 +21,14 @@ def MainMenu(): )) oc.objects.sort(key=lambda obj: obj.title) - return oc @route('/video/iview/category/{category}') def GetSeriesByCaegory(category): + cat = iView_Category(category) - oc = ObjectContainer(view_group='List', title2=cat.title) - series = cat.series_list for item in series: @@ -39,9 +36,8 @@ def GetSeriesByCaegory(category): key=Callback(GetEpisodesBySeries, series=item[0]), title=item[1] )) - Log('Adding series key:' + item[0]) + oc.objects.sort(key=lambda obj: obj.title) - return oc @@ -49,24 +45,10 @@ def GetSeriesByCaegory(category): def GetEpisodesBySeries(series): show = iView_Series(series) json = JSON.ObjectFromURL('http://iview.abc.net.au/api/legacy/flash/?series=' + series) - Log('Got series info back>>>>>' + str(json)) - Log('Got show back>>>>>') - Log(str(show)) - #self.title = json[0]['b'] - #self.description = json[0]['c'] - #self.category = json[0]['e'] - #self.img = json[0]['d'] - #self.episode_count = len(json[0]['f']) - #self.episodes = self.Episodes(json[0]['f']) oc = ObjectContainer(view_group='InfoList', title2=show.title, no_cache=True) - episodes = show.episodes - Log('>>>>>>>>>>Got Episodes<<<<<<<<<<<<<<') - Log(str(episodes)) - rtmp_url = iView_Config.RTMP_URL() - Log('Got rtmp url for TPG IP with: ' + rtmp_url) - + for item in episodes: oc.add(Play_iView(item['id'], item['title'], item['description'], item['url'], item['thumb'], item['duration'], rtmp_url, item['live'])) @@ -79,7 +61,6 @@ def GetEpisodesBySeries(series): def Play_iView(video_id, iView_Title, iView_Summary, iView_Path, iView_Thumb, iView_Duration, video_url, iView_live=0, include_container=False): HTTP.ClearCache() - iView_live = int(iView_live) call_args = { @@ -101,29 +82,6 @@ def Play_iView(video_id, iView_Title, iView_Summary, iView_Path, iView_Thumb, iV Log('Video Path: ' + iView_Path) Log('==== End Video ====') - if iView_live == 1: - rtmpVid = RTMPVideoURL(url=video_url, clip=iView_Path, swf_url=iView_Config.SWF_URL, live=True) - else: - rtmpVid = RTMPVideoURL(url=video_url, clip=iView_Config.CLIP_PATH() + iView_Path, swf_url=iView_Config.SWF_URL) - - #vco = VideoClipObject( - # key=Callback(Play_iView, **call_args), - # rating_key=iView_Path, - # title=iView_Title, - # summary=iView_Summary, - # thumb=iView_Thumb, - # duration=int(iView_Duration), - # items=[ - # MediaObject( - # parts=[ - # PartObject( - # key=rtmpVid - # ) - # ] - # ) - # ] - #) - vco = VideoClipObject( url= 'http://abc.net.au/iview/#/view/' + video_id, #Callback(Play_iView, **call_args), rating_key=iView_Path, diff --git a/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys b/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys index 001458d..50117a0 100644 --- a/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys +++ b/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys @@ -3,14 +3,10 @@ def MetadataObjectForURL(url): - #if CHECKURL - # + #TODO get normalised url RE_PLAYLIST = Regex('([0-9]+)$', Regex.DOTALL) ID = RE_PLAYLIST.search(url).group(0) - Log('Got ID:' + ID) - data = JSON.ObjectFromURL('http://iview.abc.net.au/api/legacy/flash/?series='+ID) - Log('>>>>>>>>SERVICE: MetadataObjectForURL: ' + url) episodes = data[0]['f'] for episode in episodes: if episode['a'] == ID: @@ -19,8 +15,11 @@ def MetadataObjectForURL(url): thumb = episode['s'] duration = int(episode['j'])*1000 #originally_available_at - - + #content_rating = episode['m'] + #season = episode['u'] + #absolute_index = episode['v'] + + return VideoClipObject( title=title, summary=summary, @@ -47,11 +46,6 @@ def MediaObjectsForURL(url): @indirect def PlayVideo(url): - #do the work to return get the RTMP URL - - #rtmpVid = RTMPVideoURL(url='rtmp://cp53909.edgefcs.net/ondemand?auth=daEdQbtbJd7dPaMbjcFb4b_cGbybNaLaDdi-bsZWG.-8-llu_wHAqG&aifp=v001' - # , clip='kids/backyardscience_01_20', swf_url='http://www.abc.net.au/iview/images/iview.jpg' - #) BASE_URL = 'http://www.abc.net.au/iview/' CFG_URL = BASE_URL + 'xml/config.xml' CFG_XML = XML.ElementFromURL(CFG_URL) @@ -68,11 +62,11 @@ def PlayVideo(url): RE_ID = Regex('([0-9]+)$', Regex.DOTALL) ID = RE_ID.search(url).group(0) - Log('Got ID:' + ID) + #TODO: handle if URL is of different format (ie .scrape page and get same share liknk) API_URL = CFG_XML.xpath('/config/param[@name="api"]')[0].get("value") - + + #API returns series even if querying with episode ID data = JSON.ObjectFromURL(API_URL + 'series=' + str(ID)) - Log('>>>>>>>>SERVICE: MetadataObjectForURL: ' + url) episodes = data[0]['f'] for episode in episodes: if episode['a'] == ID: @@ -90,9 +84,4 @@ def PlayVideo(url): else: rtmpVid = RTMPVideoURL(url=rtmpURL, clip=CLIP + video_url, swf_url=SWF_URL) - #rtmpVid = RTMPVideoURL(url='rtmp://cp53909.edgefcs.net/ondemand?auth=daEdQbtbJd7dPaMbjcFb4b_cGbybNaLaDdi-bsZWG.-8-llu_wHAqG&aifp=v001', clip='mp4:flash/playback/_definst_/kids/backyardscience_01_20', swf_url='http://www.abc.net.au/iview/images/iview.jpg') - - Log('attempting to play video') - - #return IndirectResponse(VideoClipObject, key=RTMPVideoURL(url='rtmp://cp53909.edgefcs.net/ondemand?auth=daEdQbtbJd7dPaMbjcFb4b_cGbybNaLaDdi-bsZWG.-8-llu_wHAqG&aifp=v001', clip='mp4:flash/playback/_definst_/kids/backyardscience_01_20', swf_url='http://www.abc.net.au/iview/images/iview.jpg')) return IndirectResponse(VideoClipObject, key=rtmpVid) \ No newline at end of file From 3343c04caf00d3604f3d554a585d71067fb74f32 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 11 Jan 2014 14:28:27 +1100 Subject: [PATCH 6/8] Improved metadata for EpisodeObject --- .../Services/URL/iview/ServiceCode.pys | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys b/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys index 50117a0..5a16b1d 100644 --- a/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys +++ b/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys @@ -8,23 +8,39 @@ def MetadataObjectForURL(url): ID = RE_PLAYLIST.search(url).group(0) data = JSON.ObjectFromURL('http://iview.abc.net.au/api/legacy/flash/?series='+ID) episodes = data[0]['f'] + show = data[0]['b'] + RE_EPISODE = Regex('^'+show+' (.*)$') + for episode in episodes: if episode['a'] == ID: - title = episode['b'] + title = RE_EPISODE.search(episode['b']).group(1) summary = episode['d'] thumb = episode['s'] duration = int(episode['j'])*1000 - #originally_available_at - #content_rating = episode['m'] - #season = episode['u'] - #absolute_index = episode['v'] + content_rating = episode['m'] + try: + season = int(episode['u']) + except: + season = None + + try: + absolute_index = int(episode['v']) + except: + absolute_index = None + expires_on = episode['g'] + aired = Datetime.ParseDate(episode['f']) + summary = summary + '\n\nExpires: ' + expires_on - return VideoClipObject( + return EpisodeObject( title=title, summary=summary, thumb=thumb, duration=duration, + show = show, + season = season, + absolute_index = absolute_index, + originally_available_at = aired ) From bd874bb529e345e2955181fd8b95ba9c25b528c6 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 11 Jan 2014 14:40:56 +1100 Subject: [PATCH 7/8] Simplified main plugin code --- ABCiView.bundle/Contents/Code/__init__.py | 34 +++++------------------ 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/ABCiView.bundle/Contents/Code/__init__.py b/ABCiView.bundle/Contents/Code/__init__.py index d5b9809..ac022ec 100644 --- a/ABCiView.bundle/Contents/Code/__init__.py +++ b/ABCiView.bundle/Contents/Code/__init__.py @@ -47,10 +47,9 @@ def GetEpisodesBySeries(series): json = JSON.ObjectFromURL('http://iview.abc.net.au/api/legacy/flash/?series=' + series) oc = ObjectContainer(view_group='InfoList', title2=show.title, no_cache=True) episodes = show.episodes - rtmp_url = iView_Config.RTMP_URL() - + for item in episodes: - oc.add(Play_iView(item['id'], item['title'], item['description'], item['url'], item['thumb'], item['duration'], rtmp_url, item['live'])) + oc.add(Play_iView(item['id'], item['title'], item['description'], item['url'], item['thumb'], item['duration'] )) oc.objects.sort(key=lambda obj: obj.title) @@ -58,40 +57,21 @@ def GetEpisodesBySeries(series): @route('/video/iview/episode/play') -def Play_iView(video_id, iView_Title, iView_Summary, iView_Path, iView_Thumb, iView_Duration, video_url, iView_live=0, - include_container=False): +def Play_iView(video_id, iView_Title, iView_Summary, iView_Path, iView_Thumb, iView_Duration): + HTTP.ClearCache() - iView_live = int(iView_live) - - call_args = { - "video_id": video_id, - "iView_Title": iView_Title, - "iView_Summary": iView_Summary, - "iView_Path": iView_Path, - "iView_Thumb": iView_Thumb, - "iView_Duration": int(iView_Duration), - "video_url": video_url, - "iView_live": iView_live, - "include_container": True, - } - Log('==== Video ====') Log('Title: ' + iView_Title) - Log('RTMP Path: ' + video_url) - Log('Clip Path: ' + iView_Config.CLIP_PATH()) Log('Video Path: ' + iView_Path) Log('==== End Video ====') vco = VideoClipObject( - url= 'http://abc.net.au/iview/#/view/' + video_id, #Callback(Play_iView, **call_args), + url= 'http://abc.net.au/iview/#/view/' + video_id, rating_key=iView_Path, title=iView_Title, summary=iView_Summary, thumb=iView_Thumb, - duration=int(iView_Duration), + duration=iView_Duration, ) - if include_container: - return ObjectContainer(objects=[vco]) - else: - return vco + return vco From ef0b96db9e051badb83da82dbcbd9e2072a46a94 Mon Sep 17 00:00:00 2001 From: adamrumbold Date: Sun, 19 Jan 2014 18:08:25 +1100 Subject: [PATCH 8/8] resolve API which now always returns ABC News24 live stream - so needs to be excluded --- ABCiView.bundle/Contents/Code/__init__.py | 8 +- ABCiView.bundle/Contents/Code/iview_class.py | 19 +-- .../Services/URL/iview/ServiceCode.pys | 108 +++++++++--------- 3 files changed, 74 insertions(+), 61 deletions(-) diff --git a/ABCiView.bundle/Contents/Code/__init__.py b/ABCiView.bundle/Contents/Code/__init__.py index ac022ec..a2021a7 100644 --- a/ABCiView.bundle/Contents/Code/__init__.py +++ b/ABCiView.bundle/Contents/Code/__init__.py @@ -34,17 +34,21 @@ def GetSeriesByCaegory(category): for item in series: oc.add(DirectoryObject( key=Callback(GetEpisodesBySeries, series=item[0]), - title=item[1] + title=item[1], + thumb=Callback(GetSeriesThumb, seriesID=item[0]) )) oc.objects.sort(key=lambda obj: obj.title) return oc +def GetSeriesThumb(seriesID): + show = iView_Series(seriesID) + return show.img + @route('/video/iview/series/{series}') def GetEpisodesBySeries(series): show = iView_Series(series) - json = JSON.ObjectFromURL('http://iview.abc.net.au/api/legacy/flash/?series=' + series) oc = ObjectContainer(view_group='InfoList', title2=show.title, no_cache=True) episodes = show.episodes diff --git a/ABCiView.bundle/Contents/Code/iview_class.py b/ABCiView.bundle/Contents/Code/iview_class.py index e59bc07..6546888 100644 --- a/ABCiView.bundle/Contents/Code/iview_class.py +++ b/ABCiView.bundle/Contents/Code/iview_class.py @@ -61,13 +61,18 @@ def __init__(self, key): self.id = key Log('Getting iView series info for:' + iView_Config.API_URL + 'series=' + key) json = JSON.ObjectFromURL(iView_Config.API_URL + 'series=' + key) - - self.title = json[0]['b'] - self.description = json[0]['c'] - self.category = json[0]['e'] - self.img = json[0]['d'] - self.episode_count = len(json[0]['f']) - self.episodes = self.Episodes(json[0]['f']) + for result in json: + Log('Checking series ID ' + str(key) + ' against results ' + str(result['a']) ) + if str(result['a']) == str(key): + Log('Got match for series ID') + self.title = result['b'] + self.description = result['c'] + self.category = result['e'] + self.img = result['d'] + self.episode_count = len(result['f']) + self.episodes = self.Episodes(result['f']) + else: + Log('rejected series ID match') def Episodes(self, json): eps = [] diff --git a/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys b/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys index 5a16b1d..0f94041 100644 --- a/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys +++ b/ABCiView.bundle/Contents/Services/URL/iview/ServiceCode.pys @@ -7,43 +7,45 @@ def MetadataObjectForURL(url): RE_PLAYLIST = Regex('([0-9]+)$', Regex.DOTALL) ID = RE_PLAYLIST.search(url).group(0) data = JSON.ObjectFromURL('http://iview.abc.net.au/api/legacy/flash/?series='+ID) - episodes = data[0]['f'] - show = data[0]['b'] - RE_EPISODE = Regex('^'+show+' (.*)$') - for episode in episodes: - if episode['a'] == ID: - title = RE_EPISODE.search(episode['b']).group(1) - summary = episode['d'] - thumb = episode['s'] - duration = int(episode['j'])*1000 - content_rating = episode['m'] - try: - season = int(episode['u']) - except: - season = None - - try: - absolute_index = int(episode['v']) - except: - absolute_index = None - expires_on = episode['g'] - aired = Datetime.ParseDate(episode['f']) - summary = summary + '\n\nExpires: ' + expires_on + for result in data: + Log('Checking for ID:' + str(ID) + ' and got ' + str(result['a']) ) + Log('matched ID so getting episodes data') + episodes = result['f'] + show = result['b'] + RE_EPISODE = Regex('^'+show+' (.*)$') + + for episode in episodes: + if episode['a'] == ID: + title = RE_EPISODE.search(episode['b']).group(1) + summary = episode['d'] + thumb = episode['s'] + duration = int(episode['j'])*1000 + content_rating = episode['m'] + try: + season = int(episode['u']) + except: + season = None + + try: + absolute_index = int(episode['v']) + except: + absolute_index = None + expires_on = episode['g'] + aired = Datetime.ParseDate(episode['f']) + summary = summary + '\n\nExpires: ' + expires_on - - return EpisodeObject( - title=title, - summary=summary, - thumb=thumb, - duration=duration, - show = show, - season = season, - absolute_index = absolute_index, - originally_available_at = aired - ) - - + return EpisodeObject( + title=title, + summary=summary, + thumb=thumb, + duration=duration, + show = show, + season = season, + absolute_index = absolute_index, + originally_available_at = aired + ) + def MediaObjectsForURL(url): container = Container.MP4 @@ -83,21 +85,23 @@ def PlayVideo(url): #API returns series even if querying with episode ID data = JSON.ObjectFromURL(API_URL + 'series=' + str(ID)) - episodes = data[0]['f'] - for episode in episodes: - if episode['a'] == ID: - live = 0 - if 'n' in episode: - video_url = episode['n'][:-4] - else: - video_url = episode['r'] - live = 1 + + for results in data: + episodes = results['f'] + for episode in episodes: + if episode['a'] == ID: + live = 0 + if 'n' in episode: + video_url = episode['n'][:-4] + else: + video_url = episode['r'] + live = 1 + + SWF_URL = 'http://www.abc.net.au/iview/images/iview.jpg' + CLIP = 'mp4:flash/playback/_definst_/' + if live == 1: + rtmpVid = RTMPVideoURL(url=rtmpURL, clip=video_url, swf_url=SWF_URL, live=True) + else: + rtmpVid = RTMPVideoURL(url=rtmpURL, clip=CLIP + video_url, swf_url=SWF_URL) - SWF_URL = 'http://www.abc.net.au/iview/images/iview.jpg' - CLIP = 'mp4:flash/playback/_definst_/' - if live == 1: - rtmpVid = RTMPVideoURL(url=rtmpURL, clip=video_url, swf_url=SWF_URL, live=True) - else: - rtmpVid = RTMPVideoURL(url=rtmpURL, clip=CLIP + video_url, swf_url=SWF_URL) - - return IndirectResponse(VideoClipObject, key=rtmpVid) \ No newline at end of file + return IndirectResponse(VideoClipObject, key=rtmpVid) \ No newline at end of file