I preface this by saying I am not great with the playing media from the __init__.py. I tend to use a URL service when possible and stick to the always used "CreateObject" function format you see in all the ones that do not have a URL service.
But looking at the code you posted, it looks like you are missing the if/else for the include container that is shown in that seinfeild example and others.
if include_container:
return ObjectContainer(objects=[videoclip_obj])
else:
return videoclip_obj
I think it has to be able to run through that function twice, once to get the metadata and then a second time to get the media. And different Plex players pull the metadata and media different ways, so that is why it may work on some players and not others. For example, the Roku app does not even require a separate CreateObject function to play media.
This is the reason you tend to see people use the "CreateObject" named function so often. They have copied it and then just made changes to the existing copy where they need to make sure it is structured right.
Another tip: I have also spent way too much time debugging because I did not make sure the rating key was picking up a unique identifier for each item.
Thanks for the tip but sadly I think that's not the reason. Look that I'm using a DirectoryObject and that's why I don't need that pattern.
I'm going to put another example to understand that pattern you refer to.
# -*- coding: utf-8 -*-
TITLE = u'Test Channel'
PREFIX = '/video/testchannel'
################################################################################
def Start():
ObjectContainer.title1 = TITLE
HTTP.CacheTime = CACHE_1HOUR
################################################################################
@handler(PREFIX, TITLE)
def testchannel_main_menu():
oc = ObjectContainer()
oc.add(DirectoryObject(
# key = Callback(testchannel_amovie, container = True),
# title = 'A Movie'
))
Here we are directly adding a MovieObject to the ObjectContainer
So the container is not needed
oc.add(
testchannel_amovie()
)
return oc
################################################################################
@route(PREFIX + ‘/movie’)
def testchannel_amovie(container = False):
mo = MovieObject(
key = Callback(testchannel_amovie, container = True),
rating_key = ‘TestChannel_AMovie’,
genres = [ “genre1”, “genre2” ],
tags = [ “tag1”, “tag2” ],
duration = 5000,
title = ‘A Movie’,
original_title = ‘A Movie’,
year = 2015,
studio = “Vetro Polding Meier”,
thumb = Resource.ContentsOfURLWithFallback(‘https://image.tmdb.org/t/p/w396/9O7gLzmreU0nGkIB6K3BsJbzvNv.jpg’),
art = Resource.ContentsOfURLWithFallback(‘https://image.tmdb.org/t/p/w780/xBKGJQsAIeweesB79KC89FpBrVr.jpg’),
tagline = “Amazing Clip”,
summary = “Beep, beep, beep, beep”,
content_rating = ‘NC-17’,
content_rating_age = 17,
rating = 9.9,
writers = [ “George R. R. King” ],
directors = [ “Francis Ford Kubrik” ],
producers = [ “Walt de Laurentiis” ],
countries = [ “Orbis Alia” ],
roles = [
{ ‘role’: ‘Harrison Cage’ },
{ ‘role’: ‘Mary-Louise Hepburn’ }
],
items = [
MediaObject(
parts = [
PartObject( key = ‘http://techslides.com/demos/sample-videos/small.mp4’ )
],
container = Container.MP4,
video_codec = VideoCodec.H264,
audio_codec = AudioCodec.AAC
)
]
)
if container:
return ObjectContainer( objects = [ mo ] )
else:
return mo
This is the code using that pattern you refer to. It is used when you want to create a list of MovieObjects (or VideoClipObjects). On the list you need to have the Movie/VideoClipObject without container and that's why you need the if/else pattern in the function that creates the object (we can call it CreateObject. In my case I called it testchannel_amovie).
But anyone can test this new example to see it is not working in Plex Home Theater either. When you reach the full details preplay page you don't have a play button to actually play the media. But it works in other clients.
And once again if you just change the MovieObject to VideoClipObject it works in Plex Home Theater and the rest of clients.
Well just to see it clear I repeat the code with that minor change:
# -*- coding: utf-8 -*-
TITLE = u'Test Channel'
PREFIX = '/video/testchannel'
################################################################################
def Start():
ObjectContainer.title1 = TITLE
HTTP.CacheTime = CACHE_1HOUR
################################################################################
@handler(PREFIX, TITLE)
def testchannel_main_menu():
oc = ObjectContainer()
oc.add(DirectoryObject(
# key = Callback(testchannel_amovie, container = True),
# title = 'A Movie'
))
Here we are directly adding a MovieObject to the ObjectContainer
So the container is not needed
oc.add(
testchannel_amovie()
)
return oc
################################################################################
@route(PREFIX + ‘/movie’)
def testchannel_amovie(container = False):
mo = VideoClipObject(
key = Callback(testchannel_amovie, container = True),
rating_key = ‘TestChannel_AMovie’,
genres = [ “genre1”, “genre2” ],
tags = [ “tag1”, “tag2” ],
duration = 5000,
title = ‘A Movie’,
original_title = ‘A Movie’,
year = 2015,
studio = “Vetro Polding Meier”,
thumb = Resource.ContentsOfURLWithFallback(‘https://image.tmdb.org/t/p/w396/9O7gLzmreU0nGkIB6K3BsJbzvNv.jpg’),
art = Resource.ContentsOfURLWithFallback(‘https://image.tmdb.org/t/p/w780/xBKGJQsAIeweesB79KC89FpBrVr.jpg’),
tagline = “Amazing Clip”,
summary = “Beep, beep, beep, beep”,
content_rating = ‘NC-17’,
content_rating_age = 17,
rating = 9.9,
writers = [ “George R. R. King” ],
directors = [ “Francis Ford Kubrik” ],
producers = [ “Walt de Laurentiis” ],
countries = [ “Orbis Alia” ],
roles = [
{ ‘role’: ‘Harrison Cage’ },
{ ‘role’: ‘Mary-Louise Hepburn’ }
],
items = [
MediaObject(
parts = [
PartObject( key = ‘http://techslides.com/demos/sample-videos/small.mp4’ )
],
container = Container.MP4,
video_codec = VideoCodec.H264,
audio_codec = AudioCodec.AAC
)
]
)
if container:
return ObjectContainer( objects = [ mo ] )
else:
return mo
-------------------------
When that pattern is used sometimes (or all of the times not sure) the createObject function receives as parameters some or all of the metadata to create the object. And this must be for whatever reason, for example because they only can gather the metadata from the list of clips page but they don't have specific pages to gather the metadata and media for each clip to be able to create a URL Service.
-------------------------
Maybe I'm missing something that I'm not able to find but it all indicates this is a bug in Plex Home Theater.