HTTPLiveStreamURL

Here is a question for you guys.

 

Since it is not currently in the documentation, what exactly is HTTPLiveStreamURL() and how can it be used?

 

I know it can be used in the MediaObject to automatically set the attributes with:

MediaObject(
       parts = [PartObject(key = HTTPLiveStreamURL(url))]
     )

Is it only for use within the MediaObject()?  And does it automatically set all the attributes for MediaObject()? Are there any other attributes you may or may not want to add?

HTTPLiveStreamURL will set the following attributes and values for you:
protocol = 'hls'
container = 'mpegts'
video_codec = VideoCodec.H264
audio_codec = AudioCodec.AAC

Other attributes you can set: 

video_resolution = '480'
audio_channels = 2
optimized_for_streaming = True

Trying to make a channel work with HTTPLiveStreamURL and get errors if I include anything else apart from the URL argument. Is the above still valid?

Also is there anything else that you can put in container?

Trying to make a channel work with HTTPLiveStreamURL and get errors if I include anything else apart from the URL argument. Is the above still valid?

Also is there anything else that you can put in container?

Yes, it is still valid. HTTPLiveStreamURL takes the url for an m3u8 playlist as the key argument. Alternatively, you can call a function to execute some code and return the m3u8 playlist url using a Callback() as the key parameter.

MediaObject(
       parts = [PartObject(key = HTTPLiveStreamURL(Callback(PlayVideo, url)))]
     )

where PlayVideo() is defined something like this:

@indirect
def PlayVideo(url):
''' take the given url and execute necessary requests/manipulation to return a valid video url'''
  ...
  return IndirectResponse(VideoClipObject, key=m3u8_url)

What else are you trying to add to the container?

I've basically picked up my RTMP streaming plugin again, and then realised in a proper 'doh' moment that the site works on iOS as well so therefore must have HLS streams, which it does.

I've successfully converted my code to use the HLS streams, but I'm still getting an error when trying to play on iOS/Apple TV etc. Weirdly, I get the same error in Chrome as well, but the stream plays (although it pauses and then plays back like it's on fast forward, pauses, plays back like ff, whilst the audio is fine). PHT works as expected, and I can play streams directly in VLC and Quicktime via my constructed URL (for reference the site uses a randomised pool of IP addresses, I assume to spread load).

I've currently got this:

CHANNEL_OBJECT              = VideoClipObject(
        key                     = Callback(CreateChannelEpisodeObject,QUALITY=QUALITY,TITLE=TITLE,SUMMARY=SUMMARY,NUMBER=NUMBER,THUMB=THUMB,INCLUDE_CONTAINER=True),
        rating_key              = NUMBER,
        title                   = TITLE,
        summary                 = SUMMARY,
        thumb                   = R(THUMB),
        items                   = [
            MediaObject(
                video_codec             = VideoCodec.H264,
                video_resolution        = HEIGHT,
                audio_codec             = AudioCodec.AAC,
                audio_channels          = 2,
                protocol                = 'HTTPLiveStreaming',
                optimized_for_streaming = True,
                height                  = HEIGHT,
                width                   = WIDTH,
                parts                   =   [
                    PartObject(
                        key             = HTTPLiveStreamURL(
                            url                     = URL   
                        )
                    )
                ]
            )
        ]
    )
if INCLUDE_CONTAINER:
  return ObjectContainer(objects=[CHANNEL_OBJECT])
else:
  return CHANNEL_OBJECT

And was just about to hack that down a bit to see if less detail made it work on iOS

The error I get (via iOS devices, and Chrome, despite it playing the url) is:

ERROR - [Transcoder] Failed to open bitstream filter h264_mp4toannexb for stream 0 with codec cop
ERROR - [Transcoder] : Invalid argument

And it basically constantly spits that out for the duration of the time you try to access the stream on an iOS device.

Just to update – i removed the audio_codec, video_codec and protocol attributes from the MediaObject and it now works across all the devices I have to test it on (iPad, iPhone, Apple TV, PHT, both Chrome and Safari.

It seems like the extra details, or duplication of detail in this case as defaults were okay, seems to force other clients to into thinking they need to transcode the streams.

This, I assume, is probably _not_ news to some of you.  ;)

If you're using HTTPLiveStreamURL some attributes are set automatically. In this case, this should be enough:

        items                   = [
            MediaObject(
                video_resolution        = HEIGHT,
                audio_channels          = 2,
                optimized_for_streaming = True,
                height                  = HEIGHT,
                width                   = WIDTH,
                parts                   = [
                    PartObject(
                        key             = HTTPLiveStreamURL(url=URL)
                    )
                ]
            )
        ]

If you want to set values manually, you can leave out the HTTPLiveStreamURL and do this:

        items                   = [
            MediaObject(
                protocol                = 'hls', # protocol = 'HTTPLiveStreaming' is incorrect, 'hls' is the correct value.
                container               = 'mpegts',
                video_codec             = VideoCodec.H264,
                video_resolution        = HEIGHT,
                audio_codec             = AudioCodec.AAC,
                audio_channels          = 2,
                optimized_for_streaming = True,
                height                  = HEIGHT,
                width                   = WIDTH,
                parts                   = [
                    PartObject(
                        key             = URL
                    )
                ]
            )
        ]
 

I've gone with the first solution you've posted sander1, but might try the second one as it's not working on my Nexus 7 (original one) on Android 4.4.3 (though it works on Galaxy Nexus with Android 4.3).

Also wondering if the @indirect method has any effect on it playing on more devices?

Once again revisiting this as I’m updating a plugin.

I’ve got this working on everything but iOS/Apple TV 4. So it works on PHT, Plex Web, Android AND Apple TV 3 via PlexConnect, but refuses to work via the iOS or Apple TV 4 apps.

The code I’m using is:

CHANNEL_OBJECT = VideoClipObject( key = Callback( CreateChannelEpisodeObject, TITLE = TITLE, URL = URL, SUMMARY = SUMMARY, THUMB = THUMB, INCLUDE_CONTAINER = True ), rating_key = URL, title = TITLE, summary = SUMMARY, thumb = R(THUMB), items = [ MediaObject( video_resolution = RESOLUTION, width = WIDTH, height = HEIGHT, audio_channels = 2, optimized_for_streaming = True, video_frame_rate = 25, parts = [ PartObject( key = HTTPLiveStreamURL( url = URL ) ) ] ) ] )

(WIDTH, HEIGHT and RESOLUTION are calculated based on whether the stream is HD or not)

The logs look exactly the same whether it’s attempting to play back on say Plex Web (or PHT) or in the iOS/Apple TV apps.

I can also play the streams, using the generated URLs, directly in VLC on Mac, or via Infuse on iOS.

It seems like HLS is always trying to be transcoded for iOS.

HLS isn’t in the ‘DirectPlayProfiles’ of the iOS Profile in Program Files (x86)\Plex Media Server\Resources\Profiles\iOS.xml or usr/local/plexmediaserver/Resources/Profiles/iOS.xml.

I removed the HLS entry from TranscodeTargets in that file, and put in DirectPlayProfiles:

<VideoProfile protocol="hls" container="mpegts" codec="h264" audioCodec="aac,mp3" context="streaming" />

so Plex Media Server\Resources\Profiles\iOS.xml now looks like:

<?xml version="1.0" encoding="utf-8"?>
<Client name="iOS">
  <!-- Author: Plex Inc. -->
  <!-- This profile is used by A5 and higher devices (starting with iPhone 4S and iPad 3) -->
  <TranscodeTargets>
    <VideoProfile container="mp4" codec="h264" audioCodec="aac" context="static">
      <Setting name="VideoEncodeFlags" value="-x264opts bframes=3:cabac=1" />
    </VideoProfile>
    <MusicProfile container="mp3" codec="mp3" />
    <PhotoProfile container="jpeg" />
    <SubtitleProfile protocol="hls" container="webvtt" subtitleCodec="webvtt"/>
  </TranscodeTargets>
  <DirectPlayProfiles>
    <VideoProfile container="mp4" codec="h264,mpeg4" audioCodec="aac,mp3" subtitleCodec="ttxt,tx3g" />
    <VideoProfile protocol="hls" container="mpegts" codec="h264" audioCodec="aac,mp3" context="streaming" />
    <!-- Since iOS may have issues direct playing mov/*/mp3 it has its own profile  -->
    <VideoProfile container="mov" codec="h264,mpeg4" audioCodec="aac" subtitleCodec="ttxt,tx3g,mov_text" />
    <MusicProfile container="mp3" codec="mp3" />
    <MusicProfile container="mp4" codec="aac" />
    <PhotoProfile container="jpeg" />
  </DirectPlayProfiles>
  <CodecProfiles>
    <VideoCodec name="h264">
      <Limitations>
        <UpperBound name="video.width" value="1920" />
        <UpperBound name="video.height" value="1080" />
        <UpperBound name="video.bitDepth" value="8" isRequired="false" />
      </Limitations>
    </VideoCodec>
    <VideoAudioCodec name="aac">
      <Limitations>
        <UpperBound name="audio.channels" value="2" />
      </Limitations>
    </VideoAudioCodec>
  </CodecProfiles>
</Client>

After restarting my server, HLS content from my Twitch TV channel was able to play on iPad.

Hmm, I followed your instructions to a T and now rather than the endless spinning circle and no stream ever loading, I instantly get a popup box that says “Uh-oh! Couldn’t create the playback session for this time” with an Ok box or x to get rid of. I feel like I’m so close… any other ideas?

Can confirm this works for me! Great work coryo123! Such an easy fix too. I updated all of the iOS profiles because I have many different iOS devices. You might want to try the same thing volcom45.

For Mac users: Right click on the Plex Media Server application and choose “Show Package Contents”. Then choose “Contents”. From there you can follow coryo123’s instructions.

@volcom45
I think there’s more to the issue.

my Twitch.tv channel gives HTTPLiveStreamURL for both live streams and vod content, and after my fix, the live streams work but the vods don’t.

Also YouTubeTV gives HTTPLiveStreamURL from youtube, and that also doesn’t work.

At least we got some content to load though.

Cant get my own media to play with this fix, channels great tho…

Haha, even weirder, I decided to change it back to the way it was before and saved, but haven’t restarted server yet, and just tried again and now it’s working fine for first time ever… :stuck_out_tongue:

@volcom45 said:
Haha, even weirder, I decided to change it back to the way it was before and saved, but haven’t restarted server yet, and just tried again and now it’s working fine for first time ever… :stuck_out_tongue:

Can you play your own media and channels, everything works?

Is this a recent change to PMS?

My plugin/Channel used to work, with the same HLS URLs, on iOS devices.

@Phatland said:

@krisvenden said:
Haha, even weirder, I decided to change it back to the way it was before and saved, but haven’t restarted server yet, and just tried again and now it’s working fine for first time ever… :stuck_out_tongue:

Can you play your own media and channels, everything works?

Hmm, nope my own media seems broken now… which is real weird because file should be back to the way it was originally now yet channels continue to work and my media doesn’t.

There is a known issue with playing HTTP Live Stream videos on iOS and tvOS in Plex clients. Devs are aware of it.