Skip to content

Instantly share code, notes, and snippets.

@blacktwin
Last active December 19, 2018 03:08
Show Gist options
  • Save blacktwin/d5fbf1568fcd3b32c7083d6124fdc7a4 to your computer and use it in GitHub Desktop.
Save blacktwin/d5fbf1568fcd3b32c7083d6124fdc7a4 to your computer and use it in GitHub Desktop.
Receive transcode key from PlexPy when paused. Send key to sub-script to wait for X time then check if still paused. If paused kill.
'''
kill_transcode function from https://gist.github.com/Hellowlol/ee47b6534410b1880e19
PlexPy > Settings > Notification Agents > Scripts > Bell icon:
[X] Notify on pause
PlexPy > Settings > Notification Agents > Scripts > Gear icon:
Playback Pause: create_wait_kill.py
PlexPy > Settings > Notifications > Script > Script Arguments:
{transcode_key}
create_wait_kill.py creates a new file with the transcode_key (sub_script) as it's name.
PlexPy will timeout kill_trans_pause_wait.py after 30 seconds (default) but sub_script.py will continue.
sub_script will check if the transcode stream is still pause or if playing as restarted.
If playback is restarted then sub_script will stop and delete itself.
If stream remains paused then it will be killed and sub_script will stop and delete itself.
Set TIMEOUT to max time before killing stream
Set INTERVAL to how often you want to check the stream status
'''
import requests
import sys
import platform
from uuid import getnode
import subprocess
import os
## EDIT THESE SETTINGS ##
PLEX_HOST = ''
PLEX_PORT = 32400
PLEX_SSL = '' # s or ''
PLEX_TOKEN = '<token>'
PLEXPY_APIKEY = 'XXXXXXX' # Your PlexPy API key
PLEXPY_URL = 'http://localhost:8181/' # Your PlexPy URL
TIMEOUT = 120
INTERVAL = 20
ignore_lst = ('')
class Activity(object):
def __init__(self, data=None):
d = data or {}
self.rating_key = d['rating_key']
self.title = d['full_title']
self.user = d['user']
self.user_id = d['user_id']
self.video_decision = d['video_decision']
self.transcode_decision = d['transcode_decision']
self.transcode_key = d['transcode_key']
self.state = d['state']
def get_get_activity():
# Get the user IP list from PlexPy
payload = {'apikey': PLEXPY_APIKEY,
'cmd': 'get_activity'}
try:
r = requests.get(PLEXPY_URL.rstrip('/') + '/api/v2', params=payload)
response = r.json()
res_data = response['response']['data']['sessions']
return [Activity(data=d) for d in res_data]
except Exception as e:
sys.stderr.write("PlexPy API 'get_get_users_tables' request failed: {0}.".format(e))
def fetch(path, t='GET'):
url = 'http%s://%s:%s/' % (PLEX_SSL, PLEX_HOST, PLEX_PORT)
headers = {'X-Plex-Token': PLEX_TOKEN,
'Accept': 'application/json',
'X-Plex-Provides': 'controller',
'X-Plex-Platform': platform.uname()[0],
'X-Plex-Platform-Version': platform.uname()[2],
'X-Plex-Product': 'Plexpy script',
'X-Plex-Version': '0.9.5',
'X-Plex-Device': platform.platform(),
'X-Plex-Client-Identifier': str(hex(getnode()))
}
try:
if t == 'GET':
r = requests.get(url + path, headers=headers, verify=False)
elif t == 'POST':
r = requests.post(url + path, headers=headers, verify=False)
elif t == 'DELETE':
r = requests.delete(url + path, headers=headers, verify=False)
if r and len(r.content): # incase it dont return anything
return r.json()
else:
return r.content
except Exception as e:
print e
def kill_transcode(transcode_key, xtime, ntime):
activity = get_get_activity()
for a in activity:
if a.state == 'paused' and a.user not in ignore_lst and a.transcode_key == transcode_key\
and xtime == ntime:
sys.stdout.write("Killing {a.user}'s transcode stream of {a.title}".format(a=a))
print fetch('video/:/transcode/universal/stop?session=' + transcode_key)
return ntime
elif a.state == 'playing' and a.transcode_key == transcode_key:
sys.stdout.write("{a.user}'s transcode stream of {a.title} restarted".format(a=a))
return ntime
else:
return xtime
if __name__ == '__main__':
startupinfo = None
if os.name == 'nt':
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
transcode_key = ''
if len(sys.argv) > 1:
if 'transcode' and 'sessions' in sys.argv[1].split('/'):
transcode_key = sys.argv[1].split('/')[3]
else:
transcode_key = sys.argv[1]
try:
if transcode_key:
file_name = "{}.py".format(transcode_key)
file = "from time import sleep\n" \
"import sys, os\n" \
"from create_wait_kill import fetch, kill_transcode \n" \
"\n" \
"transcode_key = os.path.basename(sys.argv[0])[:-3]\n" \
"x = 0\n" \
"n = {ntime}\n" \
"while x < n:\n" \
" sleep({xtime})\n" \
" x += kill_transcode(transcode_key, {xtime}, n)\n" \
"kill_transcode(transcode_key, {ntime}, n)\n" \
"os.remove(sys.argv[0])".format(ntime=TIMEOUT, xtime=INTERVAL)
with open(file_name, "w+") as output:
output.write(file)
subprocess.Popen([sys.executable, file_name], startupinfo=startupinfo)
exit(0)
except Exception:
pass
@msh100
Copy link

msh100 commented Apr 17, 2017

I am not sure how this is supposed to work considering PlexPy does not pass arguments.

Also OS is not defined (at least not on Linux)

@blacktwin
Copy link
Author

@msh100 You need to set PlexPy to pass the {transcode_key} argument. OS check has been added.

@csy7550
Copy link

csy7550 commented Jun 9, 2017

Edit: Just saw the discussion on reddit and hoping for a new version of this one :)

I've managed to get this to run, but it doesn't actually kill the stream (?).

Running PMS 1.5.5.3634 and PlexPy 1.4.19 with Python 2.7 and requests module.

  • Pause playback and randomtranscodekey.py is created
  • After 120sek randomtranscodekey.py deletes itself
  • No killing stream

Settings:

PLEX_HOST = '127.0.0.1'
PLEX_PORT = 32400
PLEX_SSL = 's' # s or ''
PLEX_TOKEN = 'ExtractedFromXML'
PLEXPY_APIKEY = 'APIKEYFROMPLEXPY' # Your PlexPy API key
PLEXPY_URL = 'http://192.168.1.2:4007/' # Your PlexPy URL

TIMEOUT = 120
INTERVAL = 20

Log (Replaced plexypy api key):

2017-06-09 13:24:30 INFO PlexPy Notifiers :: Script notification sent.
2017-06-09 13:24:30 DEBUG PlexPy APIv2 :: Cleaned kwargs: {}
2017-06-09 13:24:30 DEBUG PlexPy APIv2 :: API called with kwargs: {'apikey': u'XXX', 'cmd': u'get_activity'}
2017-06-09 13:24:30 DEBUG PlexPy APIv2 :: Cleaned kwargs: {}
2017-06-09 13:24:30 DEBUG PlexPy APIv2 :: API called with kwargs: {'apikey': u'XXX', 'cmd': u'get_activity'}
2017-06-09 13:24:10 DEBUG PlexPy APIv2 :: Cleaned kwargs: {}
2017-06-09 13:24:10 DEBUG PlexPy APIv2 :: API called with kwargs: {'apikey': u'XXX', 'cmd': u'get_activity'}
2017-06-09 13:23:50 DEBUG PlexPy APIv2 :: Cleaned kwargs: {}
2017-06-09 13:23:50 DEBUG PlexPy APIv2 :: API called with kwargs: {'apikey': u'XXX', 'cmd': u'get_activity'}
2017-06-09 13:23:30 DEBUG PlexPy APIv2 :: Cleaned kwargs: {}
2017-06-09 13:23:30 DEBUG PlexPy APIv2 :: API called with kwargs: {'apikey': u'XXX', 'cmd': u'get_activity'}
2017-06-09 13:23:10 DEBUG PlexPy APIv2 :: Cleaned kwargs: {}
2017-06-09 13:23:10 DEBUG PlexPy APIv2 :: API called with kwargs: {'apikey': u'XXX', 'cmd': u'get_activity'}
2017-06-09 13:22:50 DEBUG PlexPy APIv2 :: Cleaned kwargs: {}
2017-06-09 13:22:50 DEBUG PlexPy APIv2 :: API called with kwargs: {'apikey': u'XXX', 'cmd': u'get_activity'}
2017-06-09 13:22:29 DEBUG PlexPy Notifiers :: Executing script in a new thread.
2017-06-09 13:22:29 DEBUG PlexPy Notifiers :: Full script is: ['python', 'C:\drzoidberg33-plexpy-786a374\scripts\create_wait_kill.py', '3eq3z2qangadxcydx8xrwu8z']
2017-06-09 13:22:29 DEBUG PlexPy Notifiers :: Trying to run notify script, action: pause, arguments: [u'3eq3z2qangadxcydx8xrwu8z']
2017-06-09 13:22:29 DEBUG PlexPy Monitor :: Session 1480 has been paused.

@blacktwin
Copy link
Author

blacktwin commented Jun 12, 2017

@csy7550 Looks like a Plex update made this obsolete. Here is a similar script that uses Plex's new kill stream.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment