If you have not already, we suggest setting your Plex username to something else rather than email which is displayed on your posts in forum. You can change the username at https://app.plex.tv/desktop#!/account
Welcome to our forums! Please take a few moments to read through our Community Guidelines (also conveniently linked in the header at the top of each page). There, you'll find guidelines on conduct, tips on getting the help you may be searching for, and more!

Individual request headers for streaming requests

realriotrealriot Posts: 334Members, Plex Pass Plex Pass

Hi,

 

is it possible to define explicit request headers to fetch streaming content?

I know that adding custom header informations within the channel plugin works. So I can auth against any webservice.

 

The webservice I'm talking to awaits an extra header information 'Authorization: Bearer <token>' to get the content. Problem is that the streaming request doesn't come from the plex server. The client starts the streaming, just like a download as a plain web request...

 

Perhaps someone has a hint for me...

 

Greets

Sascha

Please, support my development work:

 

Donate now via Paypal

 

My channels:

Comments

  • sander1sander1 Channel Developer/Admin Posts: 3,716Members, Plex Pass, Plex Ninja Plex Ninja
    edited February 2014

    A bit of a guess, and I'm not sure if this works on all Plex apps, but you can set "http_headers" like this (@indirect is required):

    ####################################################################################################
    def MediaObjectsForURL(url):
    
        return [
            MediaObject(
                parts = [
                    PartObject(
                        key = Callback(PlayVideo, url=url)
                    )
                ],
                video_resolution = '480',
                container = Container.MP4,
                video_codec = VideoCodec.H264,
                audio_codec = AudioCodec.AAC,
                audio_channels = 2,
                optimized_for_streaming = True
            )
        ]
    
    ####################################################################################################
    @indirect
    def PlayVideo(url):
    
        # Process stuff and find final video url.
        final_url = 'http://www.example.com/video.mp4'
    
        oc = ObjectContainer(http_headers={'Authorization': 'Bearer <token>'})
    
        oc.add(VideoClipObject(
            items = [
                MediaObject(
                    parts = [PartObject(key=final_url)]
                )
            ]
        ))
    
        return oc
    

    If this does not work, you can try it with leaving out the codec information, which makes the app ask for a transcode from PMS (which in its turn sends the http headers):

    ####################################################################################################
    def MediaObjectsForURL(url):
    
        return [
            MediaObject(
                parts = [
                    PartObject(
                        key = Callback(PlayVideo, url=url)
                    )
                ]
            )
        ]
    

  • realriotrealriot Posts: 334Members, Plex Pass Plex Pass

    Thanks, I'll give it a try...

    Please, support my development work:

     

    Donate now via Paypal

     

    My channels:

  • realriotrealriot Posts: 334Members, Plex Pass Plex Pass

    Adding the headers to the PlayVideo() function was the best solution for me... But does not seem to work. The channel displays an error (not available). But cannot see any errors within the channel log...

    Please, support my development work:

     

    Donate now via Paypal

     

    My channels:

  • realriotrealriot Posts: 334Members, Plex Pass Plex Pass

    Ok, there was missing a ":" within your example code :-) 

    But the problem is still that the header is not set... A tcpdump on the destination host shows me still no change within the header informations...

    Please, support my development work:

     

    Donate now via Paypal

     

    My channels:

  • realriotrealriot Posts: 334Members, Plex Pass Plex Pass

    I'm cannot get it work... Still no luck after testing several ways. A tcpdump shows me the old (original) Useragent or other header...

    [...]
            vco = VideoClipObject(
                    key = Callback(createOnlineTvChannelObject, channel = channel, container = True),
                    rating_key = uniqid,
                    title = name,
                    summary = summary,
                    duration = epg_length,
                    thumb = thumb,
                    items = [
                            MediaObject(
    
                                    video_codec = VideoCodec.H264,
                                    audio_codec = AudioCodec.AAC,
                                    audio_channels = 2,
                                    optimized_for_streaming = True,
                                    parts = [PartObject(key = Callback(PlayVideo, url=url))]
                            )
                    ]
            )
    
            if container:
                    return ObjectContainer(objects = [vco])
            else:
                    return vco
            return vco
    
    @indirect
    def PlayVideo(url):
            headers = { 'User-Agent' : 'MyTest Agent 1.0' }
            oc = ObjectContainer(http_headers=headers)
            oc.user_agent = 'MyTest Agent 1.0'
    
            oc.add(VideoClipObject(
                    items = [
                            MediaObject(
                                    parts = [PartObject(key=HTTPLiveStreamURL(url))]
                            )
                    ]
            ))
    
            return oc
    

    I hope someone can give me a hit into the right direction :-)

    Please, support my development work:

     

    Donate now via Paypal

     

    My channels:

  • realriotrealriot Posts: 334Members, Plex Pass Plex Pass

    It's me again :-)

    1 year later this point is still open and I couldn't find a working solution. The only thing I need to do is to give the "client" which requests the streaming-url an additional header. Without the header the client cannot fetch the stream.

    So, could you please investigate how I can solve this problem for my channel users? So that it works on ALL supported plex client platforms.

    Thx
    Sascha

    Please, support my development work:

     

    Donate now via Paypal

     

    My channels:

  • realriotrealriot Posts: 334Members, Plex Pass Plex Pass

    And again, 1 more year without a solution for this kind of problem. Is it possible that a "Ninja" helps me so get these "request" headers working?

    Please, support my development work:

     

    Donate now via Paypal

     

    My channels:

  • realriotrealriot Posts: 334Members, Plex Pass Plex Pass
    def Start():
            ObjectContainer.art = R(ART_DEFAULT)
    
    ####################################################################################################
    @handler(PLUGIN_PREFIX, TEXT_TITLE, ICON_DEFAULT, ART_DEFAULT)
    def MainMenu():
            mediaList = ObjectContainer(no_cache=True)
            mediaList.add(CreateVideoObject())
            return mediaList
    
    def CreateVideoObject(container = False):
            url = "http://localhost/test.mp4"
    
            vo = VideoClipObject(
                    key = Callback(CreateVideoObject, container = True),
                    title = 'TEST - Title',
                    rating_key = 'abc123',
                    items = []
            )
            mo = MediaObject(
                    parts = [PartObject(key = Callback(GetVideoURL, url = url))]
            )
            vo.items.append(mo)
    
            if container:
                    #headers = { 'X-Forwarded-For' : '1.2.3.4' }
                    headers = { 'User-Agent' : 'FooAgent 1.0', 'X-User-Agent' : 'FooAgent 1.0', }
                    return ObjectContainer(objects = [vo], http_headers=headers)
            else:
                    return vo
            return vo
    
    def GetVideoURL(url):
            return Redirect(url)
    

    After playing around with objects and header settings I noticed that I can change the User-Agent this way... But another header (like X-User-Agent) cannot be set...

    Any hint?

    Please, support my development work:

     

    Donate now via Paypal

     

    My channels:

  • coryo123coryo123 Posts: 158Members, Plex Pass Plex Pass

    @realriot
    So you need to send a specific header to the server in order to get the Master Playlist of an HLS stream?

    It might be possible that in your url service you could HTTP.Request (with the header) to get the playlist file, then parse out the url's from that file which point to the specific video stream.

  • realriotrealriot Posts: 334Members, Plex Pass Plex Pass

    I need to request the stream by giving additional headers. Like X-Forwarded-For or a "Bearer" token... (Dropbox)

    Please, support my development work:

     

    Donate now via Paypal

     

    My channels:

  • coryo123coryo123 Posts: 158Members, Plex Pass Plex Pass

    I tested the http_headers property on an object container

    oc = ObjectContainer(http_headers={"a:": "b", "user-agent": "test", "TEST": "TEST"})
        oc.add(VideoClipObject(
            items = [
                    MediaObject(parts = [PartObject(key="http://127.0.0.1:8085")])
            ]))
    return oc
    

    the key url is a server that prints out the headers for any request. Here's the output.

    Plex Home Theater

    { range: 'bytes=0-',
      'user-agent': 'test',
      host: '127.0.0.1:8085',
      accept: '*/*',
      connection: 'keep-alive',
      test: 'TEST',
      a: ': b' }
    

    iOS

    { 'user-agent': 'Lavf/56.15.103',
      accept: '*/*',
      range: 'bytes=0-',
      connection: 'close',
      host: '127.0.0.1:8085',
      'icy-metadata': '1' }
    

    Android

    { 'accept-encoding': 'gzip',
      connection: 'Keep-Alive',
      'user-agent': 'ExoPlayer',
      host: '127.0.0.1:8085' }
    

    Only PHT actually included them.

  • realriotrealriot Posts: 334Members, Plex Pass Plex Pass

    Hm, this is really bad. So there's actually no chance to complete some ideas of plugins.

    Is there a bug tracker to open a bug report?

    Please, support my development work:

     

    Donate now via Paypal

     

    My channels:

  • ginobeanginobean Posts: 1Members

    Yes. Please add this custom headers feature to the Apple TV Plex client. One plugin that I'm using, requires the 'Referer' field to be a custom value, in order for the video url to be accessed.

    Interestingly, the Plex Home Theater client, on both Linux and macOS, are able to handle the custom Referer field, and are therefore able to play the requested video.

    On my Apple TV Plex client, it fails to play, even though it is talking to the same server.

    As a comparison, Kodi can play .strm files that have arbitrary custom headers appended to the end of the url. http://video-url-link-goes-here.mp4|Referer=http://www.site-origin-goes-here

    It would see that this is a fairly simple fix to make -- you could probably look at the Plex Home Theater code to see how it's handling custom http headers as a starting point..

Sign In or Register to comment.