I have multiple Youtube video that I would like to combine into a single item. So if someone were to click the object in plex it would play both the videos back to back. How do I do this.
All I have is the URL for each of the video.
I have multiple Youtube video that I would like to combine into a single item. So if someone were to click the object in plex it would play both the videos back to back. How do I do this.
All I have is the URL for each of the video.
The channel system is not ideally suited to creating a sequential playlist like that. When multiple segments are used to make up a video, you can add them as "parts" of the MediaObject and most clients will play them back to back. The url service for the Colbert Report is one example of how you can achieve that.
Intresting ...
I have implemented a URL service for a site that has video links to Dailymotion/Youtube. I am trying to add multiple parts of a video.
Once I have the URLs of the parts can I use the existing Dailymotion URL service ?
.
def MediaObjectsForURL(url):videoParts = [] Log("### Getting media for URL %s", url) return [ MediaObject( parts = [ PartObject(key=Callback(PlayVideo, url= 'http://www.dailymotion.com/video/xz06f0/', fmt='sd')), PartObject(key=Callback(PlayVideo, url= 'http://www.dailymotion.com/video/xz06nf/', fmt='sd')), PartObject(key=Callback(PlayVideo, url= 'http://www.dailymotion.com/video/xz06xk/', fmt='sd')), PartObject(key=Callback(PlayVideo, url= 'http://www.dailymotion.com/video/xz0748/', fmt='sd')) ], container = Container.MP4, bitrate = '400', video_resolution = 'sd', video_codec = VideoCodec.H264, audio_codec = AudioCodec.AAC, audio_channels = 2, optimized_for_streaming = True ) ]
I have tried hardcoding the parts with little success. The first video in the list plays fine but I don't see the other parts being played.
From com.plexapp.system.log, I see the first video being invoked.
2013-04-16 19:32:22,588 (21a4) : INFO (logkit:16) - ### PlayVideo http://www.dailymotion.com/video/xz06f0/ 2013-04-16 19:32:22,588 (21a4) : INFO (logkit:16) - ### Processing dailymotion video http://www.dailymotion.com/video/xz06f0/ 2013-04-16 19:32:22,591 (21a4) : DEBUG (networking:172) - Requesting 'http://www.dailymotion.com/json/video/xz06f0?fields=video_id,title,thumbnail_large_url,url,stream_h264_sd_url,stream_h264_url,stream_h264_hd_url,rating,duration,description' 2013-04-16 19:32:23,003 (21a4) : DEBUG (runtime:897) - Response: [200] MediaContainer, 971 bytes
From system log
Apr 16, 2013 19:32:22:563 [4420] DEBUG - [com.plexapp.system] Sending command over HTTP (GET): /:/plugins/com.plexapp.system/serviceFunction/url/com.plexapp.plugins.xxxx
Apr 16, 2013 19:32:22:564 [4420] DEBUG - (Capabilties) Passing down capabilities of 'protocols=http-streaming-video;videoDecoders=h264{profile:high&resolution:1080&level:41};audioDecoders=aac' to plug-in.
Apr 16, 2013 19:32:22:564 [4420] DEBUG - HTTP requesting to: http://127.0.0.1:2226/:/plugins/com.plexapp.system/serviceFunction/url/com.plexapp.plugins.xxxxx
Apr 16, 2013 19:32:22:615 [9348] DEBUG - WebSocket: client initiated close
Apr 16, 2013 19:32:22:615 [9348] DEBUG - WebSocket: processed 0 frame(s)
Apr 16, 2013 19:32:22:622 [9348] DEBUG - Removing notification stream because of close.
Apr 16, 2013 19:32:22:622 [10456] ERROR - handle_stream_read error 2 End of file
Apr 16, 2013 19:32:23:006 [4420] DEBUG - [com.plexapp.system] HTTP reply status 200, with 971 bytes of content.
Apr 16, 2013 19:32:23:006 [11852] DEBUG - Caching document http://127.0.0.1:32400/:/plugins/com.plexapp.system/serviceFunction/url/com.plexapp.plugins.xxxxx as 89c73f6bf8181d4889563a3706dffbea4c61afd1
Apr 16, 2013 19:32:23:007 [11852] DEBUG - Remuxing to hls/mpegts/h264/mp3
Apr 16, 2013 19:32:23:007 [11852] DEBUG - Found session GUID of globihjsybu in session start.
Apr 16, 2013 19:32:23:007 [11852] DEBUG - Using session GUID globihjsybu for new transcode session.
Apr 16, 2013 19:32:23:007 [11852] DEBUG - Using existing transcode session.
Apr 16, 2013 19:32:23:065 [8136] DEBUG - Request: GET /video/:/transcode/universal/session/globihjsybu/base/index.m3u8 [127.0.0.1:2572] (5 live)
Apr 16, 2013 19:32:23:065 [8136] DEBUG - Building an M3U8 for 261 total seconds.
Apr 16, 2013 19:32:23:236 [11952] DEBUG - Request: GET /video/:/transcode/universal/session/globihjsybu/base/00000.ts [127.0.0.1:2576] (5 live)
Apr 16, 2013 19:32:23:236 [11952] DEBUG - Asked for segment 0 from session.
Apr 16, 2013 19:32:23:238 [11952] DEBUG - We're in a seek: asked for 0, min/max available was 21/26
Apr 16, 2013 19:32:23:239 [11952] DEBUG - Segment #0 WON.
Apr 16, 2013 19:32:23:239 [11952] DEBUG - Stopping transcode session globihjsybu
Apr 16, 2013 19:32:23:239 [11952] DEBUG - Killing job.
Apr 16, 2013 19:32:23:239 [11952] DEBUG - Cleaning directory for session globihjsybu
Any help would be appreciated
That scenario is a little outside the intended use case for the PartObjects of a MediaObject. You could try passing a direct call to another URL Service as part of your PlayVideo() function. It's generally frowned upon but, in some situations it's the only way to get things working. It would probably look something like this:
def MediaObjectsForURL(url):
Log("### Getting media for URL %s", url)
return [
MediaObject(
parts = [
PartObject(key=Callback(PlayVideo, url= 'http://www.dailymotion.com/video/xz06f0/')),
PartObject(key=Callback(PlayVideo, url= 'http://www.dailymotion.com/video/xz06nf/')),
PartObject(key=Callback(PlayVideo, url= 'http://www.dailymotion.com/video/xz06xk/')),
PartObject(key=Callback(PlayVideo, url= 'http://www.dailymotion.com/video/xz0748/'))
],
container = Container.MP4,
video_codec = VideoCodec.H264,
audio_codec = AudioCodec.AAC,
audio_channels = 2,
optimized_for_streaming = True
)
]
@indirect
def PlayVideo(url):
return IndirectResponse(VideoClipObject, key=URLService.MediaObjectsForURL(url))
Then, as long as an URL Service exists for the url that is passed in, a new set of media objects will be returned for the part object from that service. Theoretically, most clients *should* be able to follow the chain of ObjectContainers until they get the playable media. Honestly, it's a complicated setup and using stacked parts in combination with extra Callbacks has proven particularly tricky in my experience. Don't be surprised if some clients react in differently.
Thanks Mike,
I tried redirecting to another URL service and that works great even though you have put a caveat.
Alternatively, does any of the media container have an option to set 'Play All' to true by default. In my plugin I have video objects under a directory container.
I'm not aware of any "Play All" flag for Media Objects. I recall some discussion of creating some kind of playlist capability via the channel framework but, I have no idea if/when that will be implemented.
What would be the suggest approach to put multi part video content for a single episode together?
The question is mostly inclined towards best practice as I see there is no straight forward approach.
The general best practice is to use multiple PartObjects within one MediaObject although that really works best for cases where both parts are accessible via the same webpage.
If you’re building episodes/movies from a list of parts, it might work better to handle it without an URL Service and still use multiple PartObjects.
I guess the real decision comes down to whether or not to use an URL service with the implementation.
Since I was still on the learning curve I used URL service, now which I think is an incorrect usage.
As with the PartObjects, I will try to build the MovieObject in the plugin code it self.
I will update this thread once I finish testing the code.
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.