Python Subprocess call from Plex Channel (modified HDHR Viewer)

Hey Everyone!
I’m trying to run an FFMPEG subprocess from a Plex Channel modified from HDHRViewer. The script below transcodes a channel (only testing one right now) and hosts it using FFServer (already started as a service). I was able to run the call fine manually, but it appears to crash when run locally.

import subprocess
...
subprocess.call(['ffmpeg','-i','http://sonnytv.local:5004/auto/v1007','http://127.0.0.1:8090/720.ffm'])
...

From this, I get the following error in the channel’s error log:

2016-08-07 12:40:44,736 (80879d000) : CRITICAL (runtime:889) - Exception (most recent call last):
File “/usr/local/share/plexmediaserver/Resources/Plug-ins-35f0caa/Framework.bundle/Contents/Resources/Versions/2/Python/Framework/components/runtime.py”, line 843, in handle_request
result = f(**d)
File “/usr/local/plexdata/Plex Media Server/Plug-ins/HDHRViewerV2.bundle/Contents/Code/init.py”, line 140, in FavoriteChannelsMenu
return BuildChannelObjectContainer(favorite.name,channelList)
File “/usr/local/plexdata/Plex Media Server/Plug-ins/HDHRViewerV2.bundle/Contents/Code/init.py”, line 192, in BuildChannelObjectContainer
oc.add(CreateVO(url=channel.streamUrl,title=GetVcoTitle(channel), year=GetVcoYear(program), tagline=GetVcoTagline(program), summary=GetVcoSummary(program), starRating=GetVcoStarRating(program), thumb=GetVcoIcon(channel,program)))
File “/usr/local/plexdata/Plex Media Server/Plug-ins/HDHRViewerV2.bundle/Contents/Code/init.py”, line 605, in CreateVO
subprocess.call([‘ffmpeg’,‘-i’,‘http://sonnytv.local:5004/auto/v1007’,'http://127.0.0.1:8090/720.ffm’])
File “/usr/home/plex/jenkins/pms-deps-universal-v2/BUILD_TAG/freebsd-x86_64/output/pms-depends-freebsd-x86_64-release-c0dbc55/lib/python2.7/subprocess.py”, line 524, in call
File “/usr/home/plex/jenkins/pms-deps-universal-v2/BUILD_TAG/freebsd-x86_64/output/pms-depends-freebsd-x86_64-release-c0dbc55/lib/python2.7/subprocess.py”, line 711, in init
File “/usr/home/plex/jenkins/pms-deps-universal-v2/BUILD_TAG/freebsd-x86_64/output/pms-depends-freebsd-x86_64-release-c0dbc55/lib/python2.7/subprocess.py”, line 1308, in _execute_child
OSError: [Errno 2] No such file or directory

2016-08-07 12:40:44,738 (80879d000) : DEBUG (runtime:924) - Response: [500] 1760 bytes

I’ve tested the subprocess natively in the system python so I know it works. If I’m reading the error above correctly, the version of python within Plex has stripped out subprocess? I’ve run several searches and cannot seem to find any part of the mentioned path after ‘/usr/’

If that is the case, does anyone know how to import system python so that this can run properly?
Before anyone asks, I have already talked with @zynine . It sounds like both of us are pretty amateur at python, but when this is done, I’m offering it back to wrap into HDHRViewer.

I think I may have found an alternative: WSGI
Given that it is build into python, that keeps the code stack the same. I’ve written a python script to host a listener. If this is an elegant solution, these are the remaining tasks before it can get baked into any solution:

  1. Connect my constructed syntax to FFMPEG on the host.
  2. Test for available tuners on HD HomeRun
  3. Display the file generated by FFServer. (requires multithreading and proxy functions)
  4. Check for clients connected to streams and terminate FFMPEG when they disconnect.

This would appear to be a more efficient and simple solution than what is currently out there for PRIME (…particularly tvheadend, wallop, and HDHRSurfer) if all you want is for Plex to play your channels. From there, HDHRViewer just needs to support alternative URL paths for FFServer Transcoding. Furthermore, this can unshackle transcoding from the Plex Server.

My WSGI script is attached (updated 8/12). Anyone care to help?

Hey everyone! I’m moving this over to my github repo. Feel free to check it out there! I hope to have something figured out soon.

@lordcantide

Yes, the Python bundled with Plex is somewhat limited. But you’re free to add any Python library to your Plex channel, but in order for it to use it, your channel has to run with ‘elevated’ code policy (set in Info.plist):

<key>PlexPluginCodePolicy</key>
<string>Elevated</string>

I suppose this is to control the execution of the potentially harmful code by the 3rd party channels, but I’m not aware of any real implications if you use this in your own channel.

Edit:

These Shared Libraries cannot be run from the URL Services code though, because they are being executed from the system sandbox. Using it from the Shared Code is okay as long as it’s the channel code that makes the call. If Shared Code that imports your Shared Library is called from the URL Service, it’ll fail with a very obscure error message.

Thanks @czukowski !!! I’ll look into that. However, I think I’m going to abandon a completely native solution for the time being. I’m still using Python so I can consolidate it down the road if so desired. My big road block right now is running the FFMPEG and relaying the feed to the browser simultaneously.

Oh by the way, there is one thing about bundling custom libraries to a channel that may not be immediately obvious and I didn’t realize it when posting my comment: these libraries can’t be run from the URL Services code, because they are being executed from the system sandbox. Using it from the Shared Code is okay as long as it’s the channel code that makes the call. If Shared Code that imports your Shared Library is called from the URL Service, it’ll fail with a very obscure error message.

(I also added this info to my comment above in case anybody finds and uses it)