-
-
Save tobiasglen/445d90bddc0e1caf78630b5b47eba638 to your computer and use it in GitHub Desktop.
# this requires your content naming scheme includes the resolution in the file name | |
# --> (Show Title - s01e02 - Episode Name - WEBDL-2160p - (h265 EAC3 Atmos) - GROUP.mkv) | |
# the script will then first check locally to make sure the ffmpeg transcode process is transcoding video (audio and container is allowed) | |
# and makes sure "2160p" is in the file name, if both cases are true then the script will kill the process and show the user an error message | |
import os | |
import re | |
import requests | |
import time | |
import logging | |
# Emby API info | |
EmbyURL = 'http://EMBY_URL/IP_HERE:8096' | |
API_key = 'EMBY_API_KEY' | |
headers = { | |
'content-type': 'application/json', | |
'accept': 'application/json' | |
} | |
logging.basicConfig(filename="caught-4k-transcodes.txt", | |
filemode='a', | |
format='%(asctime)s %(levelname)-8s %(message)s', | |
datefmt='%Y-%m-%d %H:%M:%S', | |
level=logging.INFO) | |
def stop_4k_transcode(process_pid, original_path): | |
os.popen("/bin/kill 9 {}".format(process_pid)) | |
for i in range(50): | |
time.sleep(0.5) | |
active_sessions = '{}/emby/Sessions?api_key={}'.format(EmbyURL, API_key) | |
sessions_response = requests.get(active_sessions, headers=headers).json() | |
for session in sessions_response: | |
if 'NowPlayingItem' in session: | |
if 'Path' in session['NowPlayingItem']: | |
if original_path in session['NowPlayingItem']['Path']: | |
session_id = session["Id"] | |
print("kill this session ID: {}".format(session_id)) | |
# First kill the stream, then we'll show the user a message explaining why | |
params = ( | |
('api_key', API_key), | |
) | |
data = '{"Command":"Stop"}' | |
kill_response = requests.post(EmbyURL + '/emby/Sessions/' + session_id + '/Playing/Stop', headers=headers, params=params, data=data) | |
if kill_response.ok: | |
logging.info("Stopped '" + session["UserName"] + "' from transcoding the file '" + session["NowPlayingItem"]["Path"] + "'") | |
# Show the user a message explaining why their stream was killed | |
params_message = ( | |
('Text', 'Transcoding 4K video is not allowed, Play the 1080p version instead or update your settings to Direct Play 4K'), | |
('Header', '4K Error'), | |
('api_key', API_key), | |
) | |
response = requests.post(EmbyURL + '/emby/Sessions/' + session_id + '/Message', headers=headers, params=params_message) | |
if response.ok: | |
execution_time = (time.time() - startTime) | |
print('Execution time in seconds: ' + str(execution_time)) | |
quit() | |
hevc_ffmpeg_process = os.popen("/bin/ps aux | grep '[h]evc'").read().strip() | |
if hevc_ffmpeg_process != "": | |
for process in hevc_ffmpeg_process.split('\n'): | |
pid = process.split(' ')[4] | |
if "2160p" in process: | |
if not re.search(r'\b.-sn.-c:v:0 copy\b', process): | |
startTime = time.time() | |
get_path = re.compile(r'(?<=-i.)(.*)(?=.mkv|mp4)') | |
path = get_path.search(process).group() | |
print("killing PID: '{}'".format(pid)) | |
stop_4k_transcode(pid, path) |
Hello
How does this script get triggered? Can we run it via the webhook settings on Emby maybe?
Thanks
Firstly the script is run using python3, each time its triggered it first checks local ffmpeg transcode processes for 4K transcodes, this means that this script needs to be run on the same server that Emby is using. If a ffmpeg transcode process is found with "2160p" in the filename (This is how I rename my files, I always include the resolution in the filename) then the script makes an API request to your Emby server to try and kill the stream
It's done in this order to minimize API requests to Emby and to kill the transcode more quickly to ease the load on your system.
I personally trigger this python script every 2 seconds using a bash script (Note that it checks local system processes every 2 seconds, the API requests are more spread apart), I've included my bash script below (pastebin link)
#!/bin/bash
while (sleep 2 && /usr/bin/python3 ~/scripts/stop_4k_transcodes.py) &
do
wait $!
done
Then chmod +x your .sh script so you can execute it and I personally just open up a screen session and trigger the bash script from it and keep it running
Hello
How does this script get triggered? Can we run it via the webhook settings on Emby maybe?
Thanks