Skip to content

Instantly share code, notes, and snippets.

@chazlarson
Forked from tobiasglen/stop_4k_transcodes.py
Created May 6, 2025 04:04
Show Gist options
  • Select an option

  • Save chazlarson/95bc809a40a0ababd828e9de7b3ad913 to your computer and use it in GitHub Desktop.

Select an option

Save chazlarson/95bc809a40a0ababd828e9de7b3ad913 to your computer and use it in GitHub Desktop.
Stop-Emby-transcodes-automatically
# 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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment