-
-
Save Hellowlol/ee47b6534410b1880e19 to your computer and use it in GitHub Desktop.
""" | |
This is a simple script showing how you can used plexpys notifications system to kill a stream | |
Possible plexpyargs: -tk {transcode_key} -u {username} -td {transcode_decision} -t 20:20 -ln Secret_tash | |
Instructions: | |
1. Save the script somewhere on your computer as kill_a_stream.py. | |
2. Edit the variables at the top of the script: | |
The host, port, token, and ssl, can be the same as in the PlexPy settings | |
Edit the list of blocked_users, separated by a comma. | |
3. PlexPy > Settings > Notification Agents > Scripts > Bell icon: | |
[X] Notify on playback start | |
[X] Notify on playback resume | |
4. PlexPy > Settings > Notification Agents > Scripts > Gear icon: | |
Enter the "Script folder" where you save the script from step 1. | |
Playback Start: kill_a_stream.py | |
Playback Resume: kill_a_stream.py | |
Save | |
5. PlexPy > Settings > Notifications > Script > Script Arguments: | |
-tk {transcode_key} -u {username} -td {transcode_decision} | |
Any time one of the blocked_users starts a transcoded session, the script will stop the stream. | |
You can also supply a -t 20:30 and the script will only kill a stream after 20:30 or disallow transcode from a library with -ln | |
""" | |
import argparse | |
import requests | |
from uuid import getnode | |
import platform | |
from datetime import datetime | |
### Edit me ### | |
host = '10.0.0.97' | |
port = 32400 | |
token = '<token>' | |
ssl = '' # s or '' | |
kill_time = '' # time for date in 20:00 format | |
blocked_users = 'Hellowlol' # 'username1, username2' | |
blocked_librarys = '' # 'PG-18, adult' | |
### stop ### | |
def tcomp(kill_time): | |
zz = False | |
if kill_time: | |
tk = kill_time.split(':') | |
h = int(tk[0]) | |
m = int(tk[1]) | |
zz = datetime(2009, 12, 2, h, m).time() | |
return zz | |
def fetch(path, t='GET'): | |
url = 'http%s://%s:%s/' % (ssl, host, port) | |
headers = {'X-Plex-Token': 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): | |
print fetch('video/:/transcode/universal/stop?session=' + transcode_key) | |
def now(): | |
return datetime.now().time() | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser() | |
parser.add_argument('-tk', '--transcode_key', action='store', default='', | |
help='Transcode key of the the current stream to kill') | |
parser.add_argument('-u', '--user', action='store', default=None, | |
help='username of the person watching a stream') | |
parser.add_argument('-td', '--transcode_decision', action='store', default=None, | |
help='transcode decision') | |
parser.add_argument('-ln', '--library_name', action='store', default=blocked_librarys, | |
help='What library was this played from') | |
parser.add_argument('-t', '--time', action='store', default=kill_time, | |
help='Kill only streams if clock is above t') | |
p = parser.parse_args() | |
if p.user in [bu.strip() for bu in blocked_users.split(',')] and p.transcode_decision.lower() == 'transcode' and not p.time: | |
kill_transcode(p.transcode_key) | |
# You can also kill any transcodes based on time by passing the -t parameter or editing the kill_tme | |
elif p.time and now() > tcomp(p.time) and p.transcode_decision.lower() == 'transcode' and p.user in [bu.strip() for bu in blocked_users.split(',')]: | |
kill_transcode(p.transcode_key) | |
elif p.library_name in [bln.strip() for bln in blocked_librarys.split(',')] and p.user in [bu.strip() for bu in blocked_users.split(',')] and p.transcode_decision.lower() == 'transcode': | |
kill_transcode(p.transcode_key) |
It seems that when I enter an IP and force SSL, the requests library throws an error because by default it will verify SSL certificates. Because we're connecting directly to the plex server and not via the FQDN that the SSL certificate is issued to, it will fail.
Suggested fix is is to change:
r = requests.get(url + path, headers=headers)
elif t == 'POST':
r = requests.post(url + path, headers=headers)
elif t == 'DELETE':
r = requests.delete(url + path, headers=headers)
into:
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)
I'm testing out this method, but via Postman and I'm receiving a 404 status error. I know it's only been a month since this was posted, but does this method still work?
@jrudio if get 404 you need to check your token.
@Hellowlol I believe the token should be fine, I took it from a browser session. The transcode key I am getting is from /transcode/sessions
.
I just checked the pms logs and it's showing that the colon in video/:/transcode/universal/stop
is missing. So it looks like that's the reason. Why it's getting stripped idk.
@Hellowlol Is there another method to kill direct play streams?
@Hellowlol am also interest in killing direct play streams..
script is being sent, but isnt killing the stream
not sure whats wrong.
@iscmarkiemark I kind of have it working, if you revoke library access to a user, it will stop downloading more data. The downside is that the user can still play what they buffered.
Sorry for not responsive before. There is no way to stop a non transcode except revoke access as @jrudio explained.
@Hellowlol
i'm wondering about transcodes though
i'm checking the logs and the script does get activated, but it doesn't seem to do anything to the transcode
is this still in development?
Is there a way to simply run this script on demand to stop all or SOME of the current streams? Like, if I have x ammount of streams from remote users and I want to kick them all w/o restarting PMS, or brining down my LAN?
I'm also wondering if this still in development also. I want to be able to limit certain users to 1 stream.
SO, just so I'm clear, this will "auto kill" the stream based on the user? Is there any way to kill a stream say, ON DEMAND?
So, I have this working, but it is canceling on all transcodes. I would not mind when it transcodes audio, so I changed transcode_decision to video_decision, but now I get this issue where sometimes it responds as copy altho its transcode. This happens when user decides to start with Original, but changes to lower quality later, any ideas how to avoid that?
I have separate VMs hosting Plex Media Server and PlexPy, when the stream is getting killed - which server is killing the stream? is it PlexPy or is it Plex Media Server? Just curious which machine requires all pre-requisite modules to be installed.
Am currently getting the following error (shown in PlexPy logs) -
PlexPy Notifiers :: Script error:
Traceback (most recent call last):
File "/opt/plexpy/PlexPy_Scripts/Kill_A_Stream.py", line 26, in
import requests
ImportError: No module named requests
However, running it in CLI I do not get the error when attempting to run python /opt/plexpy/PlexPy_Scripts/Kill_A_Stream.py.
I can also confirm the necessary modules are installed, any helps or a more simple guide would be much appreciated. Or even a sample configuration someone has setup.
Currently running both Plex Media Server and PlexPy on Ubuntu Server 16.04.
Thanks.
Sorry for not responding before. I don't get notified when some adds a comment to this gist. I'll respond when I have access to a computer
@seanvree This script isnt in development anymore. I cant remember why i added it i think it was a request on reddit. (I have loads of fun with it)
@rembomy Check for both transcode and copy in https://gist.github.com/Hellowlol/ee47b6534410b1880e19#file-kill_a_stream-py-L120
Fx if p.user in [bu.strip() for bu in blocked_users.split(',')] and p.transcode_decision.lower() in ['copy', 'transcode'] and not p.time:
@mescon I know is a really long time since you asked but in answering out of posterinty. The -t variable is intended if you want to block a user after a set amount of time. Say you dont want the kid use plex on the ipad after 2200
Hello friend, I am new to the plexpy script for a long time ago I am trying to make a script that allows me to have multiple users and some 2 to 3 transcodes, I want to close their transcodes if they are more than 2 and let them use only 1, it is possible???
@neuroryuu .. that functionality is built into the plex server. If you access server settings under Network there is:
Remote streams allowed per user xxx
Maximum number of simultaneous streams each user is allowed when not on the local network.
Hi, first off all, thank you so much for this script :D after i updated plex to Version 1.7.5.4035. the script doesn't kill streams anymore. Can anyone comfirm this, or is it just me.
(trying to figure out if kill_time = '20:20' is something i'm supposed to change... )
I always want transcodes for banned users to be killed, so what's the point of a kill_time variable?