Symptoms: Page Unresponsive on poster grid, posters missing then black backdrops, 'Abspielen' German Play button surviving Traefik+force-english chases, video black-screen on play. Root causes (different from initial guesses): - Browser hangs: deployed index.html drifted ahead of repo; uncommitted forceEnglishUI() text-walker MutationObserver froze main thread on poster lazy-load. Reverted to repo HEAD. - 'Abspielen': Cineplex theme HARDCODES German via 'content:' ::after rule -- not a Jellyfin locale issue. Doc 25 already proved per-user UICulture is theatre. Override CSS with content: 'Play'. - Backdrops black: BLACK-PASS CustomCss block paints #000 !important on .layout-desktop / .pageContainer -- occludes backdrop layer (z-index:-1). Existing transparent-scope rule used body.itemDetailPage selector that doesn't match in 10.10.3 (body class is libraryDocument). Replaced with :has(.itemDetailPage) ancestor scoping. - HLS 499: encoding.xml had EnableThrottling+EnableSegmentDeletion=true, segments reaped before browser re-request. Disabled both. Verified via new bin/headless-test.py (playwright Chromium login + screenshot + computed-style probe). Fixes idempotent and re-runnable via new bin/apply-26-incident-fixes.sh. Open: AV1+Opus items still black-screen in Chrome due to DirectStream codec-tag mislabel bug. Tracked for 10.11.8 migration.
80 lines
3 KiB
Bash
Executable file
80 lines
3 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# apply-26-incident-fixes.sh
|
|
#
|
|
# Re-applies the three server-state fixes from docs/26 if branding.xml /
|
|
# encoding.xml drift back to broken state (e.g. after a Jellyfin restore).
|
|
#
|
|
# 1. CustomCss: Cineplex hardcoded "Abspielen" → "Play"
|
|
# 2. CustomCss: Backdrop transparent-scope using :has() (BLACK-PASS occluded backdrop layer)
|
|
# 3. encoding.xml: EnableThrottling=false + EnableSegmentDeletion=false (kills HLS 499)
|
|
#
|
|
# Usage: ssh user@nullstone "$(cat bin/apply-26-incident-fixes.sh)"
|
|
# Idempotent: re-running is safe.
|
|
|
|
set -euo pipefail
|
|
|
|
# 3. encoding.xml — disable throttling + segment deletion (both containers if present)
|
|
for cfg in /home/docker/jellyfin/config/config/encoding.xml \
|
|
/home/docker/jellyfin-dev/config/config/encoding.xml; do
|
|
[ -f "$cfg" ] || continue
|
|
cp -n "$cfg" "$cfg.bak.pre-doc26" || true
|
|
sed -i \
|
|
-e 's|<EnableThrottling>true</EnableThrottling>|<EnableThrottling>false</EnableThrottling>|' \
|
|
-e 's|<EnableSegmentDeletion>true</EnableSegmentDeletion>|<EnableSegmentDeletion>false</EnableSegmentDeletion>|' \
|
|
"$cfg"
|
|
echo "[+] patched $cfg"
|
|
done
|
|
|
|
# 1+2. branding.xml CustomCss — Abspielen + backdrop transparent-scope
|
|
patch_branding() {
|
|
local cfg="$1"
|
|
[ -f "$cfg" ] || return 0
|
|
if grep -q "ARRFLIX 2026-05-09" "$cfg"; then
|
|
echo "[=] $cfg already has doc-26 patch"
|
|
return 0
|
|
fi
|
|
cp -n "$cfg" "$cfg.bak.pre-doc26" || true
|
|
python3 - <<PY
|
|
p = "$cfg"
|
|
s = open(p).read()
|
|
patch = """
|
|
|
|
/* ARRFLIX 2026-05-09 — incident fixes (see docs/26-incident-2026-05-09-...).
|
|
1. Cineplex theme hardcodes German "Abspielen" via ::after on .play_arrow.
|
|
Override with English. The German text was in CSS, not Jellyfin locale —
|
|
so all Traefik Accept-Language rewrites + force-english-all-users.sh
|
|
chases never fixed it.
|
|
2. The BLACK-PASS block paints #000 !important on .layout-desktop,
|
|
.pageContainer, .padded-bottom-page etc — these wrap the backdrop layer
|
|
(z-index:-1) and occlude it. Use :has() to scope only when an
|
|
.itemDetailPage descendant exists, so backdrop renders only on detail
|
|
pages. */
|
|
.mainDetailButtons .material-icons.play_arrow::after {
|
|
content: "Play" !important;
|
|
}
|
|
.itemDetailPage,
|
|
.layout-desktop:has(.itemDetailPage),
|
|
.layout-mobile:has(.itemDetailPage),
|
|
.layout-tv:has(.itemDetailPage),
|
|
.mainAnimatedPages:has(.itemDetailPage),
|
|
.pageContainer:has(.itemDetailPage),
|
|
.padded-bottom-page:has(.itemDetailPage),
|
|
.libraryPage:has(.itemDetailPage),
|
|
.absolutePageTabContent:has(.itemDetailPage) {
|
|
background-color: transparent !important;
|
|
background: transparent !important;
|
|
}
|
|
"""
|
|
s = s.replace("</CustomCss>", patch + "</CustomCss>")
|
|
open(p, "w").write(s)
|
|
PY
|
|
echo "[+] patched $cfg"
|
|
}
|
|
|
|
patch_branding /home/docker/jellyfin/config/config/branding.xml
|
|
patch_branding /home/docker/jellyfin-dev/config/config/branding.xml
|
|
|
|
# Restart so changes take effect
|
|
docker restart jellyfin jellyfin-dev 2>/dev/null || docker restart jellyfin
|
|
|
|
echo "[*] Done. Verify with bin/headless-test.py."
|