What is the right way to use HTTPLiveStreamURL without URL services?

Lets say I have a simple channel plug-in:

NAME = 'HLSTest'
PREFIX = '/video/hlstest'
URL = 'http://abclive.abcnews.com/i/abc_live4@136330/index_1200_av-b.m3u8'

def Start():
    pass

@handler(PREFIX, NAME)
def MainMenu():
    oc = ObjectContainer(title1 = NAME)
    oc.add(CreateVideoClipObject(url = URL, title = NAME, include_container = False))
    return oc

@route(PREFIX + '/createvideoclipobject')
def CreateVideoClipObject(url, title, include_container):
    vco = VideoClipObject(
        key = Callback(CreateVideoClipObject, url = url, title = title, include_container = True),
        rating_key = url,
        title = title,
        items = [
            MediaObject(
                parts = [
                    PartObject(
                        key = Callback(PlayVideo, url = url)
                    )
                ],
            )
        ]
    )
    return ObjectContainer(objects = [vco]) if include_container else vco

@indirect
@route(PREFIX + '/playvideo')
def PlayVideo(url):
    return IndirectResponse(VideoClipObject, key = url)

What is the right way to incorporate HTTPLiveStreamURL() in here?

@Cigaras: same reason for your post?


/R

@rols1 said:
@Cigaras: same reason for your post?
https://forums.plex.tv/discussion/260454/no-directplay-with-httplivestreamurl-in-the-latest-web-players/p1?new=1
/R

Something not working in a specific client and asking how to create the VideoClipObject are 2 different things.

@Cigaras: a couple of things:
If you’re sending variables other then text to a function with a route, you have to specify the type of variable. In this case the variable include_container is a boolean:

@route(PREFIX + '/createvideoclipobject', include_container=bool)

Some Plex clients send more variables if they request a function. To catch this problem add **kwargs at the end here to catch (and ignore) those:

def CreateVideoClipObject(url, title, include_container, **kwargs):

Add the “shortcut” function HTTPLiveStreamURL to your key. This will set most of the MediaObject details (like codecs) automatically. Drop the PlayVideo callback function, it is not needed in your code:

PartObject(key=HTTPLiveStreamURL(url))

Thank You @sander1, but my final PlayVideo function does some stuff before playing the video, to be precise it sets http header, like HTTP.SetHeader('User-Agent', Prefs['user_agent']). Alternatively I guess I could set the header in CreateVideoClipObject but as preferences can be changed after creating the VideoClipObject it wont have effect until I “restart” the main menu if I understand how this works correctly…

In that case you can leave the PlayVideo callback in there, that’s exactly what it’s used for :slight_smile:

By the way, from the comments in the Plex framework: The HTTP.SetHeader() function is deprecated. Use HTTP.Headers to get and set headers instead.

But what about HTTPLiveStreamURL() then, if I do

PartObject(key=HTTPLiveStreamURL(Callback(PlayVideo, url = url)))

I get FrameworkException: No route found matching ‘/video/hlstest/playvideo.m3u8’

@Cigaras said:
But what about HTTPLiveStreamURL() then, if I do

PartObject(key=HTTPLiveStreamURL(Callback(PlayVideo, url = url)))

I get FrameworkException: No route found matching ‘/video/hlstest/playvideo.m3u8’

my tests shows that pms in this cases needs .m3u8 as appendix to the route, if the url ends with m3u8. The function itself doesn’t need it:
@route(PREFIX + ‘/playvideo.m3u8’)
def playvideo(url):
/R

needs .m3u8 as appendix to the route
Or I can drop the route decoration and it will work, but what is the right way intended to be used by Plex?

@Cigaras said:
Or I can drop the route decoration and it will work, but what is the right way intended to be used by Plex?
I don’t know, but I assume sander1 has the right answer (I’m also waiting for it)
/R

@rols1 said:

@Cigaras said:
Or I can drop the route decoration and it will work, but what is the right way intended to be used by Plex?
I don’t know, but I assume sander1 has the right answer (I’m also waiting for it)
/R

I forgot about that :slight_smile: You can just name your route to what PMS is expecting:

@route(PREFIX + '/playvideo.m3u8')

Routes are not required, but they give cleaner URLs in your PMS log files and are easier to read.