Zum Inhalt

tvOS Top Shelf Hero Video (Design)

Datum: 2026-06-21 Status: Spec — zur Review Plattform: tvOS only (Top Shelf ist eine Apple-TV-Home-Screen-Fläche).

1. Kontext & Ziel

Wenn der Nutzer Physarum in die oberste Reihe des Apple-TV-Home-Screens legt und fokussiert, zeigt das Top Shelf (der große Banner oben) statt eines statischen Bilds einen kinematischen Hero-Loop: ~2 Min lebendes Physarum, das weich durch die kuratierten Presets gleitet, full-screen direkt auf dem Home-Screen. Geparkt war's als „tvOS UI Polish (Hero/Visual Brand)".

Verifiziert (WWDC19 Session 211 + Apple-Docs): seit tvOS 13 spielt das Top-Shelf-Carousel Video ab — TVTopShelfCarouselItem.previewVideoURL. Bilder 1920×1080 (×2 = 3840×2160 fürs 4K-ATV), empfohlene Videolänge ~2-5 Min, Audio von Apple gesteuert. Braucht ein eigenes Top-Shelf-Extension-Target mit einem TVTopShelfContentProvider.

2. Scope-Entscheidung (ratifiziert 2026-06-21)

Ein kinematischer Hero-Loop (1 Carousel-Item, 1 langes Video, weiche Überblendungen durch die Presets) — nicht ein Multi-Item-Carousel, nicht die 28-s-Montage. Frisch gerendert, ~2 Min.

3. Architektur / Komponenten

① Hero-Video-Asset (Skript)

scripts/shoot-topshelf-hero.sh — baut auf der bestehenden Kette auf: - Nutzt den schon gebauten PHYSARUM_BOOT_PRESET-DEBUG-Hook, um jedes der 7 kuratierten Presets deterministisch auf dem tvOS-Sim zu booten. - Nimmt pro Preset ~18 s auf (Recorder-Validate+Retry-Logik aus dem Montage-Skript wiederverwenden — der tvOS-Sim-Recorder ist flaky). - ffmpeg xfade (Cross-Dissolve, ~2 s Overlap) verkettet die 7 Clips zu einem durchgehenden ~2-Min-Loop ohne harte Schnitte; das Ende blendet zurück auf den Anfang → nahtlose Schleife. Master = 3840×2160 (4K-ATV). - Rein additiv; berührt keinen Produktionscode.

② Hosting (Codeberg Pages)

Das Top-Shelf-Video muss gehostet sein (Apple liefert per URL aus). Output nach public/topshelf/ → Vite kopiert es nach dist/ → der bestehende deploy.yml-Workflow serviert es auf Codeberg Pages: - https://pages.jkaindl.de/physarum/topshelf/hero.mp4 (progressive .mp4, primär — simpel) - https://pages.jkaindl.de/physarum/topshelf/poster.png (3840×2160 Standbild, das Carousel-Bild) - Risiko/Fallback: Apple empfiehlt HLS. Erster Wurf = progressive .mp4 (kein Segmentieren, kein Content-Type-Risiko). Falls die echte ATV das .mp4 im Top-Shelf nicht autoplayt → auf HLS (.m3u8 + .ts) umstellen (ffmpeg -f hls); dann auch den .m3u8-Content-Type (application/vnd.apple.mpegurl) auf Codeberg Pages prüfen. Geräte-Verifikationspunkt.

③ Top-Shelf-Extension-Target (project.yml)

Neues tvOS-only App-Extension-Target PhysarumTopShelf: - XcodeGen type = tvOS-Top-Shelf-Extension (Produkt-Typ com.apple.product-type.tv-app-extension); platform/supportedDestinations: tvOS. - Info.plist NSExtension: NSExtensionPointIdentifier = com.apple.tv-top-shelf, NSExtensionPrincipalClass = $(PRODUCT_MODULE_NAME).TopShelfProvider. - Bundle-ID de.jkaindl.physarum.topshelf; eingebettet in die tvOS-App (App-Target bekommt eine dependency: { target: PhysarumTopShelf, embed: true } nur für tvOS). - macOS/iOS-Builds bleiben unberührt (Extension nur tvOS).

④ Content-Provider (TopShelfProvider.swift)

TopShelfProvider: TVTopShelfContentProvider (im Extension-Target): - loadTopShelfContent(completionHandler:) liefert TVTopShelfCarouselContent(style: .details, items: [heroItem]). - heroItem = TVTopShelfCarouselItem(identifier: "physarum-hero") mit: imageShape = .HDTV, setImageURL(posterURL, traits: []), previewVideoURL = heroVideoURL, und einer displayAction/playAction, die die App öffnet. - Testbar: eine pure Helper-Funktion TopShelfContent.heroItem(posterURL:videoURL:) baut das Item; host-getestet (Identifier/URLs/imageShape gesetzt) ohne UI. - URLs als Konstanten (die Codeberg-Pages-URLs); ein #if DEBUG-Override für lokale Tests optional.

⑤ Verifikation

  • Headless/host-testbar: der Item-Builder (④); Extension + App bauen für tvOS-Sim; der Hero-Master hat die Zielmaße/Dauer (ffprobe); ein Frame-Sichtcheck der Überblendung.
  • Geräte-Sign-off (Johannes): das echte Top-Shelf zeigt sich nur auf echter ATV (Sim rendert es nicht realistisch) und nur wenn Physarum in der obersten Reihe liegt + fokussiert ist. Johannes: Physarum nach oben links schieben → fokussieren → Hero-Loop spielt + sieht edel aus. Diese Schritte kommen in die [[Handover-AppStore]]-Note (deine Aufgabe, in der Note verankert).

4. Was NICHT in Scope (YAGNI)

  • Kein Multi-Item-Carousel (1 Hero-Item).
  • Keine dynamische/per-Nutzer-Personalisierung (statischer Hero).
  • Kein In-App-Overlay-Redesign (separate Sache).
  • Kein macOS/iOS-Touch (Extension tvOS-only).
  • Audio: Apple steuert die Wiedergabe selbst — wir liefern Video (stumm reicht; optional Tonspur später).

5. Ehrliche Caveats

  • Conditional-Sichtbarkeit: zeigt sich nur in der obersten Home-Reihe + fokussiert. Es ist Lieblings-App-Politur, kein Dauer-Schaufenster.
  • .mp4 vs HLS: progressive .mp4 ist der einfache erste Wurf; falls die ATV streikt → HLS (Geräte-Verifikation). Apple empfiehlt HLS.
  • Nur Geräte-Verifikation fürs echte Top-Shelf-Erlebnis (Sim zeigt's nicht).

6. Verifikation / DoD

  • [ ] scripts/shoot-topshelf-hero.sh erzeugt einen nahtlosen ~2-Min-Cross-Dissolve-Loop (4K-Master), ffprobe-bestätigt.
  • [ ] HLS/.mp4 + Poster in public/topshelf/; Deploy serviert sie (URL erreichbar).
  • [ ] PhysarumTopShelf-Extension-Target gebaut + in die tvOS-App eingebettet; macOS/iOS/tvOS-Builds grün.
  • [ ] TopShelfProvider liefert das Hero-Carousel-Item; pure-Helper host-getestet.
  • [ ] Voller Regressions-Check: bestehende Suiten + 3-Plattform-Build grün.
  • [ ] Geräte-Sign-off-Schritt in [[Handover-AppStore]] ergänzt (Johannes prüft auf echter ATV).

7. Offene Annahmen / für den Plan

  • Exakter XcodeGen-type/Embed-Syntax fürs tvOS-Top-Shelf-Extension-Target (im Plan verifizieren — XcodeGen-Extension-Embedding ist fummelig).
  • Genauer TVTopShelfCarouselItem-API-Aufruf (imageShape-Enum, setImageURL-Traits, displayAction) gegen die tvOS-17-SDK prüfen.
  • Hero-Render-Detail: gleichmäßige Preset-Reihenfolge + Cross-Dissolve-Timing fürs „weich" — im Plan/iterativ am Output tunen.