From b99ba68b4bead2a1e3be74a41d264897b7dd08d8 Mon Sep 17 00:00:00 2001 From: Timothy Date: Sun, 26 Jul 2026 22:23:24 +0200 Subject: [PATCH] docs(ersatztv skill): record the #510 no-logo-no-bug policy and deco seeding recipe The skill's Logo System section documented the #502/#525 chain but stopped before #510, so it described a behavior that no longer holds and omitted the one fact someone consulting it would most likely need: a channel with a watermark configured but no usable logo now renders NO on-screen bug, from every attachment point, and says so in the log. Adds, all discovered while working #510: - The unified policy plus the log strings to grep ("has no logo artwork", "no longer exists") before suspecting the ffmpeg pipeline. - That the deco path alone used to render the generated-initials nameplate and that it genuinely worked, with #652 as the revival path -- otherwise a future reader finds the nameplate in the code history and assumes it was dead. - The #653 carve-out: the song-progress overlay bypasses the resolver and is still unchecked, so "no usable logo means no bug" is a property of the selector, not of the whole app. - That /iptv/logos/gen is unauthenticated while the rest of /iptv is not, because ConditionalIptvAuthorizeFilter is a class attribute on IptvController and that route lives on ArtworkController. - The fully API-driven deco-watermark seeding recipe (watermarks -> decos/groups -> decos -> PUT decos/{id} -> PUT playouts/{id}/deco), which cost real discovery time this session, plus the reminder that branding is not testable through the troubleshooting-playback API. Docs-only leaf change to one skill file; no code, no server-state effect. Verified the YAML frontmatter still parses (name + description intact) since an unquoted ": " there silently disables a skill. refs #510 #652 #653 --- .claude/skills/ersatztv/SKILL.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.claude/skills/ersatztv/SKILL.md b/.claude/skills/ersatztv/SKILL.md index 6c5f8f7c2..68fc57c6a 100644 --- a/.claude/skills/ersatztv/SKILL.md +++ b/.claude/skills/ersatztv/SKILL.md @@ -433,6 +433,27 @@ Consumers reach ETV **only through Dispatcharr** (`ErsatzTV → Dispatcharr → `GET`/`PUT /api/v1/settings/iptv` (`iptv.base_url`, ersatztv#340, `iptv.base-url`) — to pin them to a fixed public origin; unset falls back byte-identical to the old behavior. The base64-upload workaround in `docs/Docker/ErsatzTV.md` is only needed if that setting is left unset. +- **No usable logo ⇒ no on-screen bug, from every attachment point** (ersatztv#510, 2026-07-26, + `ffmpeg.watermark-resolution-unified`). A `ChannelLogo` watermark resolves through one shared + `WatermarkSelector.ResolveWatermark` whether it came from a playout item, the channel, the global + setting, **or a deco**. A missing cached file, an un-migrated external URL, and a channel with no logo + artwork each render *without* a bug and log a warning. So when debugging "this channel has a watermark + configured but no bug appears", grep the log for `has no logo artwork` / `no longer exists` before + suspecting the ffmpeg pipeline. + - Before #510 the **deco** path alone was unchecked and returned the generated-initials nameplate + (`/iptv/logos/gen`) for a logoless channel — it genuinely rendered. That fallback is now off + everywhere; reviving it via the image cache is ersatztv#652. + - **Not covered:** the song-progress overlay is built as a `WatermarkOptions` directly by the + streaming/troubleshooting handlers, bypassing the resolver, and is still unchecked — ersatztv#653. +- **`/iptv/logos/gen` is unauthenticated**, unlike the rest of `/iptv`: `ConditionalIptvAuthorizeFilter` + is a class-level attribute on `IptvController` only, and that route lives on `ArtworkController`. + Handy for probing, and the reason a container-internal self-fetch of a generated logo succeeds. +- **Seeding a deco watermark for testing is fully API-driven** (no SQLite needed): `POST /api/v1/watermarks` + (needs the full required field set — check `v1.json`), `POST /api/v1/decos/groups`, `POST /api/v1/decos`, + `PUT /api/v1/decos/{id}` (set `watermarkMode` + `watermarkIds`), then `PUT /api/v1/playouts/{id}/deco`. + Use `watermarkMode: "Override"` to make the deco watermark the only one selected. Note branding is + **not** testable through the troubleshooting-playback API (`testing.troubleshoot-path-cannot-test-branding`) + — drive a real channel playout and capture a frame. - `logo_XX.png` files in the logos root dir are HTML garbage (broken downloads), not actual logos — ignore them ### Other