Hello.
Got a really strange issue.
I'm re-codiig a channel and the two URL Services that is needed (one on the channel for live, and one in Serviecs.bundle for on demand).
I've got two sources
1. live HTTP streaming MP4 HLS, that works fine.
2. Ondemand HTTP MP4 HLS, that plays fine on web, but when playing in PHT, it looks like extreme field interpolation (looks like the video plays for 20 frames, and then skips 5 frames back).
All content is on Akamai CDN, and i just call the manifest file, with several quality streams.
I'm able to see the manifest for the live feeds, but not for on-demand, but i have codec matrix from the content provider, saying that it's H264/ACC
Code isn't on github, but i should be able to copy/paste it here ;)
__init__.py
TITLE = 'DR TV'
PREFIX_VIDEO = '/video/drdk'
PREFIX_AUDIO = '/audio/drdk'
API_URL = 'http://www.dr.dk/mu-online/api/1.0/'
ART = 'art-default.jpg'
ICON = 'icon-default.png'
WebsiteURL = 'http://www.dr.dk'
WebsiteTVURL = 'http://www.dr.dk/tv'
menuTitles = {'TopSpots':'Anbefalede', 'PopularList':'Populære','Live':'Se live TV', 'News':'Nyheder', 'SelectedList':'Udvalgte','LastChance':'Sidste chance'}
def Start():
pass
@handler(PREFIX_VIDEO, TITLE, art = ART, thumb=ICON)
def MainMenu():
oc = ObjectContainer()
frontJSON = JSON.ObjectFromURL(‘http://www.dr.dk/mu-online/api/1.0/page/tv/front’)
# ToCarusel
for TopSpots in frontJSON[‘TopSpots’][‘Items’]:
oc.add(VideoClipObject(title = TopSpots['Title'], tagline = TopSpots['Subtitle'], thumb = TopSpots['PrimaryImageUri'], url = 'http://www.dr.dk/tv/se/' + TopSpots['SeriesSlug'] + '/' + TopSpots['Slug']))
# Themes
for Themes in frontJSON['Themes']:
oc.add(DirectoryObject(title = Themes['Title'], thumb = R(ICON), key = Callback(submenu, json = Themes['Items'], mediatype = 'Themes')))
#Live
oc.add(DirectoryObject(title = 'Live', thumb = R(ICON), key = Callback(submenu, json = frontJSON['Live'], mediatype = 'Live')))
#remaining frontpage
for FrontpageViewModel in frontJSON:
if FrontpageViewModel != 'Themes' and FrontpageViewModel != 'TopSpots' and FrontpageViewModel != 'Live':
oc.add(DirectoryObject(title = unicode(L(FrontpageViewModel)), thumb = R(ICON), key = Callback(submenu, json = frontJSON[FrontpageViewModel], mediatype='TV') ))
return oc
@route(PREFIX_VIDEO + ‘/submenu’, json = JSON, mediatype = String)
def submenu(json, mediatype):
oc = ObjectContainer()
livejson = JSON.ObjectFromURL(‘http://www.dr.dk/mu-online/api/1.0/channel/all-active-dr-tv-channels’)
for drlive in json:
for drjson in livejson:
if drlive[‘ChannelSlug’] == drjson[‘Slug’]:
oc.add(VideoClipObject(title = drjson[‘Title’], url = WebsiteTVURL + ‘/live/’ + drjson[‘Slug’], thumb = drjson[‘PrimaryImageUri’]))
Log.Debug(drjson[‘Title’])
break
return oc
Channel Servicecode.py
BASE_URL = "http://www.dr.dk/tv" API_URL = "http://www.dr.dk/mu-online/api/1.0/"def MetadataObjectForURL(url):
slug = url.rsplit(’/’,1)[1]programcard = JSON.ObjectFromURL(API_URL + 'programcard/' + slug) title = programcard['Title'] summary = programcard['Description'] source_title = "Danmarks Radio" year = programcard['PrimaryBroadcast']['ProductionYear'] originally_available_at = Datetime.ParseDate(programcard['PrimaryBroadcastStartTime']) tagline = programcard['Subtitle'] countries = [programcard['PrimaryBroadcast']['ProductionCountry']] thumb = programcard['PrimaryImageUri'] art = programcard['PrimaryImageUri'] return VideoClipObject(title = title, summary = summary, source_title = source_title, year = year, originally_available_at = originally_available_at, tagline = tagline, countries = countries, thumb = thumb, art = art )def MediaObjectsForURL(url):
slug = url.rsplit(’/’,1)[1]
return [MediaObject(container = Container.MP4, parts = [PartObject(key = Callback(PlayMedia, slug = slug))])]
#return MediaObject(duration = programcard[‘PrimaryAsset’][‘DurationInMilliseconds’], k)@indirect
def PlayMedia(slug):
client = ‘plexapp.’ + Client.Product.replace(’ ', ‘’) + ‘.’ + Client.Version
ProgramCard = JSON.ObjectFromURL(API_URL + ‘programcard/’ + slug)
PrimaryAsset = JSON.ObjectFromURL(ProgramCard[‘PrimaryAsset’][‘Uri’])
for Links in PrimaryAsset[‘Links’]:
if Links[‘Target’] == ‘HLS’:
url = Links[‘Uri’]
#HTTP.Request(‘http://www.dr.dk/mu-online/api/1.0/reporting/viewed’, values = {‘Id’:slug, ‘Client’:client})
return IndirectResponse(VideoClipObject, key=url)def TestURLs():
passdef NormalizeURL(url):
return url.rsplit(’!#’,1)[0]
Services.bundle ServiceCode.py
BASE_URL_TV = "http://www.dr.dk/tv/"
BASE_URL_RADIO = "http://www.dr.dk/radio/"
BASE_API_URL = "http://www.dr.dk/mu-online/api/1.0/"
#PROFILES = {'1700': {'Frames':25,"Keyframes":2,'Pixelwidth': 1024, 'Pixelheight':576}}
def MetadataObjectForURL(url):
slug = url.rsplit(’/’,1)[1]
drjson = JSON.ObjectFromURL(BASE_API_URL + ‘channel/’ + slug)
if ‘Message’ in drjson:
Ex.MediaNotAvailable
else:
title = drjson[‘Title’]
thumb = drjson[‘PrimaryImageUri’]
drnownext = JSON.ObjectFromURL('http://www.dr.dk/mu-online/api/1.0/schedule/nownext/' + slug)
drnow = drnownext['Now']
drnext = drnownext['Next']
summary = "Nu: " + drnow['Title'] + '
’ + drnow[‘Description’]
return VideoClipObject(title = title, summary = summary, thumb = thumb, source_title = "Danmarks Radio")
def MediaObjectsForURL(url):
slug = url.rsplit(’/’,1)[1]
return [MediaObject(video_codec = VideoCodec.H264, audio_codec = AudioCodec.AAC, video_resolution = ‘720’, parts = [PartObject(key = HTTPLiveStreamURL(Callback(PlayMedia, slug = slug)))])]
@indirect
def PlayMedia(slug):
# Gemius
client = ‘plexapp.’ + Client.Product.replace(’ ', ‘’) + ‘.’ + Client.Version
drjson = JSON.ObjectFromURL(BASE_API_URL + ‘channel/’ + slug)
for StreamingServers in drjson[‘StreamingServers’]:
if StreamingServers[‘LinkType’] == ‘HLS’:
uri = StreamingServers[‘Server’] + ‘/’ + StreamingServers[‘Qualities’][0][‘Streams’][0][‘Stream’]
#HTTP.Request(‘http://www.dr.dk/mu-online/api/1.0/reporting/viewed’, values = {‘Id’:slug,‘Client’:client})
return IndirectResponse(VideoClipObject, key = uri)
And finally, heres a grab of one of the videos with info turned on PHT attached.
/HuX