Pluto On-Demand Playback Experiments

Anybody had any luck getting Pluto On-Demand content to play back within Channels? They have a decent amount of free content and nice APIs to browse it. My content discovery and prep is done outside of Channels. I am simply trying to create an "On-Demand" channel (9999) to playback previously staged content.

Pluto On-Demand and TV content streams are quite similar. On-Demand includes the #EXT-X-PLAYLIST-TYPE:VOD in the m3u8 header, #EXT-X-ENDLIS at m3u8 end and downloads all the hls metadata in one chunk. The TV content excludes those headers and uses the windows chunking delivery. All other hls directives appear identical.

Things I have tried that all failed with Apple TV Channels (but #2-#5 work with Apple TV VLC):

#1- Place the Pluto stitched m3u master url in the custom channel m3u.
#2- Reference a "dummy channel" (demand9999.m3u) from the custom channel and 302 Redirect the former to the Pluto master m3u.
#3- Return the actual contents of the Pluto master m3u as the dummy channel payload (after converting all the URLs from relative to absolute).
#4- Return the contents of the Pluto playlist m3u (the actual hls metadata layer) as the dummy channel payload (after converting all the URLs from relative to absolute).
#5- Same as #4 but remove the #EXT-X-PLAYLIST-TYPE:VOD as well.

For #4, the DVR accesses the playlist.m3u twice, first logging "parseMasterPlaylist" and then "fetchMediaPlaylist" both with 200 success. My pseudo web server never sees an access from the Apple TV.

Obviously having native Channels support for Import path .m3u with VOD playback would be optimal (and leave all the content discovery external), but faking a on-demand custom channel seems like a reasonable interim solution that keeps the entire viewing experience within channels. (Apple TV VLC does not support deeplinks so using it is not optimal.)

Appreciate any ideas as this has me stumped at the moment. Thanks.

Interested in seeing if you or someone else can get this working. Agreed on the nice amount of VOD content. I've pulled some of this using youtube-dl but that does require storing the content rather than streaming it the way you are proposing.

tldr; can't help but interested.

I was playing around with this earlier today, but am not that familiar with youtube-dl.
Right now I can get a show to download to a file named master.mp4
Have you managed to either have it download to a file with the show name, or get an entire season to download in one go?

Impressive effort, but it's going to be very hard to make this work since everything about the DVR streamer assumes a live never-ending stream.

What you're trying to achieve fits in more with the .strmlnk concept, except you want to point to the stream directly and not link to another app. I believe other media apps use .strm for this and that's something we might be able to add support for into the DVR.

3 Likes

What you're trying to achieve fits in more with the .strmlnk concept, except you want to point to the stream directly and not link to another app. I believe other media apps use .strm for this and that's something we might be able to add support for into the DVR.

Totally agree and would happily abandon this line of exploration if .strm is viable in the next couple months. My existing Channels->VLC approach is short-term serviceable though not elegant. Only quirk is ensuring the .strm supports 302 redirect as robust implementations will refresh the m3u links at playtime to ensure valid link credentials.

Impressive effort, but it's going to be very hard to make this work since everything about the DVR streamer assumes a live never-ending stream.

For fun, tried #6: strip both #EXT-X-PLAYLIST-TYPE:VOD AND #EXT-X-ENDLIST. The video played a Pluto lead-in sequence for ~10 seconds likely due to dumb timing luck. VLC would not play the same stream. Even though the playlist contains EXT-X-PROGRAM-DATE-TIME (that should synchronize the stream to current time), something odd happening. Only playing the lead-in was likely related to a DISCONNECT that I failed to handle.

I've pulled some of this using youtube-dl but that does require storing the content

youtube-dl -g is your friend (sort of) in that it provides a URL rather than the content. If .strm existed, saving the -g provided link into the .strm file provides on-demand.

Have you managed to either have it download to a file with the show name, or get an entire season to download in one go?

https://api.pluto.tv/v3/vod/slugs/$slug?appName=web&sid=$random&deviceMake=unknown&deviceModel=web&deviceType=web

Be smart with the link above and cache data appropriately. The $slug variable is the Pluto URL simplified version of the movie/series/episode name (i.e., krull-1983-1-1). Returns all details for a movie or the episodic list (every season/episode). For my on-demand, I save the slug identifiers and use the call above to get the stitched URL immediately prior to playback.

(Edited to fix formatting/readability of the API call)

2 Likes

Given the results from #6, experimented further and found the answer. What I hastily assumed was a lead-in sequence was lead-out. Tried to verify via pluto.tv website, but their site is an onslaught of video diarrhea. Moving to VLC (which ironically seems to bypass the commercials) confirmed the "pluto star sequence" was the lead-out.

Realizing the player was jumping to the final #EXT-X-DISCONTINUOUS: sequence provided the hint. A super crude mod to return the m3u playlist in small increments (divided at http segments) made the Channels (iOS HLS?) decoder happy.

Native ".strm" support is the right long-term answer and enables so many amazing use cases. Look forward to turning that into a rich content ecosystem. Thanks.

5 Likes

Thanks!

The streams I used with youtube-dl also produced programs/movies without ads. It seems that those are injected in real time. Adding stream link capabilities for Pluto TV would certainly be beneficial to me as I have been recording some of these tv series mainly for the comskip.

During normal youtube-dl operation (downloading/saving the actual media), it analyzes the hls stream and removes commercials if the stream has obvious markers. It comes down to how obvious the provider made the commercial injection. If using youtube-dl -g (get the URL only), then any commercial stripping (if possible) must be performed at playback.

I am no longer certain if VLC was suppressing commercials or not. The big difference between VOD playback via VLC and custom channel injection is random access. With VLC playback, you can jump around the media at will and thus I might have simply skipped over any ads. (By contrast, the Pluto TV web player will not seek across a advertising segment.) Looking at the VLC TvOS source code, I see no obvious commercial suppression logic so guessing I was mistaken.

By contrast, my VOD custom channel injection results in a pure linear playback experience. Because channels believes is it playing linear TV content, it cannot seeks past the current play point. Just like a normal channel, it will buffer the playback history on the local device and normal tricks like pause to buffer followed by fast-forward work. Removing commercials requires editing them out of the hls stream prior to injecting into Channels for playback.

If the .strm link feature discussed above happens, that would bring random access playback and make it superior to custom channel injection for VOD. However, by itself, it would not remove commercials.

1 Like