0.2.56 - Reliable trailer playback

This commit is contained in:
ponzischeme89
2026-08-12 11:05:07 +12:00
parent 9777eb0952
commit f2d052dbf6
22 changed files with 1438 additions and 55 deletions
+21
View File
@@ -745,6 +745,27 @@ network answered. Things to preserve:
- **An episode is keyed on its series**, not on itself — that is what its own page will ask
for, and it is what makes one warm serve a whole row of Continue Watching.
**Trailers are a provider chain, not ordinary title playback.** `GET /v1/items/{id}/trailers`
is the cheap availability answer used while a detail page is warmed; the Play press opens
`PlayerActivity` immediately and `POST /v1/items/{id}/trailers/resolve` selects one native
stream from `internal/trailer`. Official Apple and labelled official YouTube sources come
first, followed by local Emby media and then the remaining recognised remote trailers. The server validates direct
media before returning it and caches only successful mappings. The player keeps the subject
and rejected candidate ids: an error or an eight-second stall before the first frame asks for
the next provider behind the same loading surface. Exhausting the chain closes the player and
returns to the still-composed detail page; it never shows the ordinary playback error pane.
Keep these boundaries:
- Metadata discovery may be warmed and cached, but local `PlaybackInfo` and remote stream
resolution begin only after the viewer presses Trailer.
- Provider details stay behind the resolver interface. Compose knows only whether a trailer
exists, and the player knows only how to ask for the next candidate.
- A trailer never uses the Memby pre-roll. Back and natural completion return to the screen
that launched it, while the normal native controls and aspect-ratio handling remain intact.
- Direct-to-Emby mode retains local trailers. Remote Apple and YouTube resolution belongs to
the gateway, which is the only surface that can validate and cache those mappings without
putting provider scraping or expiring URLs on every television.
**A detail overlay seeds its settings from `repository.currentSettings`**, never
`Settings.EMPTY`. Collecting a flow with an empty initial value draws the first frame under
default preferences and then recomposes the entire page — and restarts the effects keyed on