This repository has been archived on 2026-04-18. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
server-config/services/jellyfin/jellyfin-set-defaults.py
Simon Gardling 735603deb8
All checks were successful
Build and Deploy / deploy (push) Successful in 2m41s
jellyfin: Prefer fMP4-HLS Media Container for all users
2026-04-16 01:11:59 -04:00

98 lines
2.4 KiB
Python

"""Enforce default Jellyfin user preferences via the API.
Iterates all users and sets preferFmp4HlsContainer in their
DisplayPreferences if not already enabled. Idempotent.
"""
import json
import os
import sys
import time
import urllib.request
from pathlib import Path
JELLYFIN_URL = os.environ.get("JELLYFIN_URL", "http://127.0.0.1:8096")
def get_api_key():
cred_dir = os.environ["CREDENTIALS_DIRECTORY"]
return Path(cred_dir, "jellyfin-api-key").read_text().strip()
def api(method, path, data=None):
url = f"{JELLYFIN_URL}{path}"
sep = "&" if "?" in url else "?"
url += f"{sep}api_key={get_api_key()}"
body = json.dumps(data).encode() if data else None
req = urllib.request.Request(url, data=body, method=method)
if body:
req.add_header("Content-Type", "application/json")
with urllib.request.urlopen(req) as resp:
if resp.status == 204:
return None
return json.loads(resp.read())
def wait_healthy(timeout=120):
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:
try:
req = urllib.request.Request(f"{JELLYFIN_URL}/health")
with urllib.request.urlopen(req, timeout=5) as resp:
if resp.read().decode().strip() == "Healthy":
return
except Exception:
pass
time.sleep(2)
print("Jellyfin did not become healthy in time", file=sys.stderr)
sys.exit(1)
# Preferences to enforce: (key, desired_value)
DEFAULTS = [
("preferFmp4HlsContainer", "true"),
]
def main():
wait_healthy()
users = api("GET", "/Users")
if not users:
print("No users found, nothing to do")
return
for user in users:
user_id = user["Id"]
name = user["Name"]
prefs = api(
"GET",
f"/DisplayPreferences/usersettings?userId={user_id}&client=emby",
)
custom = prefs.get("CustomPrefs", {})
changed = False
for key, value in DEFAULTS:
if custom.get(key) != value:
custom[key] = value
changed = True
if not changed:
print(f"{name}: already up to date")
continue
prefs["CustomPrefs"] = custom
api(
"POST",
f"/DisplayPreferences/usersettings?userId={user_id}&client=emby",
prefs,
)
print(f"{name}: updated preferences")
if __name__ == "__main__":
main()