#!/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+5. encoding.xml — disable throttling + segment deletion (HLS 499)
# AND disable software tonemapping (CPU-only nullstone
# cannot sustain real-time 4K HDR tonemap+x264, ffmpeg
# runs at ~0.5x → 18s wait time before video starts;
# R&M is fake-HDR per doc 21 anyway, so no visual loss)
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|true|false|' \
-e 's|true|false|' \
-e 's|true|false|' \
-e 's|true|false|' \
"$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 - < *,
.detailPageContent,
.detailPagePrimaryContainer,
.detailPageWrapperContainer,
.detailPageContent > *,
.detailVerticalSection,
.detailVerticalSection-extrabottompadding,
.detailSection,
.detailSectionContent,
.itemsContainer,
.scrollSlider,
.scrollSliderContainer,
.padded-bottom-page,
.detailPagePrimaryContent,
.sectionTitleContainer,
.detailRibbon,
.subtitleAudioContainer,
.detailPageRoot {
background-color: transparent !important;
background: transparent !important;
}
/* INC4: 2026-05-08 home-page "kill gray band" rule paints .emby-scroller
#000 unscoped — that's the OPAQUE wrapper around every carousel inside
.itemDetailPage. Override back to transparent on detail page only. */
.itemDetailPage .emby-scroller,
.itemDetailPage .emby-scroller-container,
.itemDetailPage .verticalSection,
.itemDetailPage .padded-top-focusscale,
.itemDetailPage .padded-bottom-focusscale,
.itemDetailPage .moreFromSeasonSection,
.itemDetailPage .moreFromArtistSection,
.itemDetailPage .scrollSliderContainer,
.itemDetailPage .scrollButtonContainer {
background-color: transparent !important;
background: transparent !important;
}
/* INC7 2026-05-09: BLACK-PASS paints .libraryPage #000; #videoOsdPage uses
that class so the OSD page covers