Playback of Video from Web Download In Plugin

If I have a downloaded video and want to play it back from within the plugin.  Example, I want to play an error video from local file within the Plugin and using URL Services and you have to use the URLPatterns.  How do I tell it to playback from local file lets say from the Plug-in Support Data directory so you will not get the following error:  FrameworkException: No route found matching.
 

Thanks for your help as always!!!!! B)

If you put the video in the plugin's resource folder with the artwork, then you should be able to pass R('my_video.mp4') as the key to the part object of the VideoClipObject. I haven't tested this but I believe it should work.

Thanks Mike as always,

I will test your idea and report back.  ^_^

One other question related if you put multiple videos there would it trigger an update from the Unsupported app store?

Is there a way to get the framework to talk to the Data folder like the python scripts do for pulling data files?


UPDATE:  I tried the R('video.mp4')  however, it stopped giving the FrameworkException: No route found matching but it would not play the video. 


 

Updates from the UAS are only triggered by changes being pushed to GitHub by the author. The update logic is essentially this:

- check for updates
  - are there any new commits on the GitHub repo since the last time an update for this channel was downloaded?
    - if yes, update
    - otherwise, nothing

To clarify your desired scenario...

You plan to include the video file within the plugin, so that new installs or updates will automatically have the video included? or, is this a video that the plugin itself downloads for later playback?

I'm curious to see the code you used to test with.

Cat out of the bag -- Working on using threading and downloading video files to playback at a later date.   The Files at the time are being downloaded to a video folder within the Plugin's Data Folder setup by  Plex Media Center and this does work.

(Plex Media Server\Plug-in Support\Data\com.plexapp.plugins.movie2k\MyVideos).  And thought to use Python alias code and create an alias to the file with in the Services/Resources folder.  If I could get your idea to work using R('my_video.mp4') with the aliased file.....  Would aliased files being added trigger an update by the Unsupported App Store?  Unless you have a better idea for the http server to see the MyVideos folder to access the video files.

If I were you, I would look at how Mike W handles that in the code for SSPlex. The code is on GitHub and works pretty well from what I understand.

This is way beyond my knowledge, but I do use SSPlex. It uses cURL and Mike W has it programmed so the videos are saved in the default TV and Movie folder the user already has set up for their local media. Then it just uses PMS to produce all the metadata and play the video.

Thanks for the good comments as always! ^_^

If you put the video in the plugin's resource folder with the artwork, then you should be able to pass R('my_video.mp4') as the key to the part object of the VideoClipObject. I haven't tested this but I believe it should work.

Update I was able to make it playback using R('my_video.mp4").  This time it was an mp4 instead of an FLV.  Might try the FLV again just to make sure it was not a typo or something.

Update I was able to make it playback using R('my_video.mp4").  This time it was an mp4 instead of an FLV.  Might try the FLV again just to make sure it was not a typo or something.

Hey there Joe,

What a coincidence... Working on exactly the same thing at the moment for the IceFilms and, by default, LMWT plugins. By the looks of it, we're pretty much going for the same implementation style as well, with downloaded items preferably staying within and being accessed via the plugin and not contaminating the user's library.

Just spent the last three days tearing my hair out on this. Found this thread whilst trying to think up of yet a different way I could get this working on all clients....

Just a heads up from what I went through.... Using R() worked fine for me until items got to about 100MB or so. After that, due to the way the PMS's web server (on port 32400) talks to the plug-in's dynamically instantiated web server, things go rapidly downhill, with the clients buffering, missing frames, etc... that is when they even start playing!

Just something you may want to test for.

I've also got a long list of other things that won't work or will only work for some clients. But nobody wants to hear about those. :lol:

In the end I gave up fighting Plex and decided to just abuse it instead. So, when a user wants to watch a downloaded item, I create a tmp dir in which I put a hardlink back to the downloaded item and create a temporary "Home Movie" library for that tmp folder. I then manually look up the item's URL in the library and return that to the client. Shortly after the video starts playing, a thread goes off and deletes the Library.

It's far from an ideal solution, but it's the only one that I've been able to make work on all the clients I've got access to. So far, it seems to work pretty solidly except for what appears to be a small bug in Plex/Web where it receives the new library notification  and adds it to its library list, but doesn't seem to do the same for library deletions. As a result, it's library listing shows the temp library which have since been deleted. At this point, that's good enough for me.

Update I was able to make it playback using R('my_video.mp4").  This time it was an mp4 instead of an FLV.  Might try the FLV again just to make sure it was not a typo or something.

Haven't looked at your code to see what you currently use but the fact that it is working for mp4 and not flv made me wonder if Redirect might be the issue.

Many clients do not like when you use Redirect in the PlayVideo function of your URL service due to transcoding issues. It has been explained to me that you should always use @indirect with IndirectResponse instead. 

Redirect will work if you are only returning mp4s because they are native to all clients, but it is just better practice to use @indirect just in case.

I would like to get this to work too.  I am however now going to use it for errors R('Host_Down.mp4')   I am working on 4 maybe 5 small 30 second spots to playback for errors.  So if Host has changed their code it will playback Host_Down.mp4, if does't like the IP plays Worng_IP.mp4, Sites like Streamcloud that do geolocation lockout if not in their region which is one reason I added Tor network tie in if you want to use it and play Geolocation_Lockout.mp4, Video removed play Video_Removed.mp4 and maybe bad upload but may lump this under Video_Removed.mp4.

Not sure if you want anything like that for Icefilms I can create you some.  I need a graphic for background designed to match your plugin make it for 1080p.  I have a minute spot created but I am going to see if plex will play a 15 or 30 second spot ok.  So I can get the file smaller so the plugin will not be so huge to download.

Here is what Plex Media Server generates when using R('Host_Down.mp4') == /:/plugins/com.plexapp.plugins.movie2k/resources/Host_Down.mp4?t=1384922516

Am with you ReallyFuzzy I wanted to keep it simple for users too just store the download in the data folder for the plugin in a sub folder.  This is how I do my favorites and Captcha hosts storing my Json files in the Plugins Data folder since that's where Plex Media Server dumps the plugins data files to.  I have an idea I know you can use Python go creating a symbolic link:
 

if not os.path.lexists(destFile):
    os.symlink(sourceFile, destFile)

Maybe have a temp file that's always there when you update to github in your Services\Resource folder that will be reused to point to the current file that wants to be played back by the user?  How could we use this with what shopgirl284 stated: @indirect with IndirectResponse instead of R()???  So we can playback any video file downloaded from the Host sites....

Just FYI I am using URL Services with this plugin...

I think there may be a little confusion about what R() does. It's just a short-form reference for Resources. That is, a way to reference files, such as thumbnails and artwork, which are stored in the plugin's Resources folder. It's not the same as using a Redirect() for returning media. I would agree with shopgirl that using an @indirect/IndirectResponse will likely provide better cross-platform compatibility but that doesn't necessarily rule out the possibility of referencing resource files with R().

FWIW, there may be some snippets of code in the Unsupported Appstore could prove useful for you. I make use of some unpublished framework functions for dealing with data storage that might help with your project(s).

Oops. Sorry about that. I was thinking about the downloading of the file, not when he was playing it through R(), but the download would not going through the channel's URL service PlayVideo function. Duh!!!

But, I would like to play back the downloaded file via  the URL Service in the plugin.  That's why I was thinking if I could use a symbolic link to the file in the Resources folder to the file stored in the Data folder so the HTTP server can see it.  If it is not an MP4 as shopgirl284 pointed out it will not play on the set top box using R().  Need it to kick up the transcoder.  So trying to figure out how to play a stored FLV, AVI, ect. back.

The R() is working great for the Error Vids which are MP4.

 

Ok, after a little digging I found this thread on playing local files:
https://forums.plexapp.com/index.php/topic/36020-problem-using-local-media-in-a-plug-in/

I am trying to figure out the path variable.  Meaning if I just stick path="mymoviename.flv"
Will it look with in the plugins local path set up by Plex Media Server?  Meaning playing back files that are dumped into the ....\Plex Media Server\Plug-in Support\Data\com.plexapp.plugins.movie2k directory?  Just like when you read and write to a local file that's where Python dumps it.
 

Also, since my Plugin does have URL Sevice Setup the Dev said you don't have to call it.  So I can create a local function within __init__.py should work?
 ...
oc.add(MovieObject(
     title = title,
     summary = summary,
     thumb = Callback(Thumb, url=thumbImg),
     items = [
          MediaObject(
               parts = [PartObject(key = Callback(PlayVideo, path=path)]
          )
     ]

...


def PlayVideo(path):
     return Stream.LocalFile(path)

I also updated the plugins Info.plst file to include: 
 
PlexPluginCodePolicy
Elevated

I updated that thread yesterday to note that it has been confirmed that Stream.LocalFile() is deprecated and won’t work.

HMMM.....,  So there is nothing in the Framework like Stream.localFile() to playback local media supported by the transcoder within a plugin?  Besides R() which we have established is only good for short MP4 files but still takes the Player a bit to kick up even a 30 second file around 3 megs.

I did a little snooping through Plex Media Server python files.   What about this StreamKit.LocalFile(path)  found in streamkit.py?  :huh:

I went back to Plex Media Server v0.9.0.21 and looked at the elevatedpolicy.py and Stream =  Framework.api.StreamKit

So StreamKit.LocalFile(Path) is the same thing as Stream.LocalFile(Path).... 

So that being said can we use StreamKit.localFile(path)

 

You can try. What I was told is that Stream.LocalFile() died and there is not any other type of support for passing local files through a channel to PMS and it’s clients. If you can figure out a way, I’m sure there are others who would be interested.

A trick that may work for you error messages is to host them on Dropbox or something similar and reference the “public” URL in the plugin. For other stuff, something more robust may need to be developed.

Please refer to this forum link for fix:  ^_^

https://forums.plexapp.com/index.php/topic/88740-play-local-mpegts/?p=522911