0.2.57 - Traliers bug fixes

This commit is contained in:
ponzischeme89
2026-08-12 13:08:53 +12:00
parent f2d052dbf6
commit 64f19aeef2
45 changed files with 1215 additions and 681 deletions
+47 -10
View File
@@ -25,6 +25,24 @@ in Emby's dashboard read as the same build and there was no way to tell which se
behind. A request the gateway makes for itself (library sync, health probe, device cleanup)
carries no session, and reports the gateway's own `buildinfo.Version()` instead.
**The header is not the only thing Emby writes down.** The **device profile** sent with
`PlaybackInfo` is named in Emby's playback device list too, and it read `Memby Android TV`
on both paths — the product name, in the one place it must never be. It is now `MbyATV`
(`deviceProfileName` in `internal/emby/device_profile.go`, the literal in
`DeviceProfile.embyAndroidTv`), and like the header the two must agree or one television
playing both ways appears as two clients.
**And the gateway is not a television.** `Credentials.Gateway` marks a request the server
makes on its own behalf, and Emby records those under `MEMBY_GATEWAY_CLIENT_NAME`
(**`MbyGateway`**, `emby.DefaultGatewayClientName`) with a device name to match, so the
sync, the health probe, device cleanup and an operator signing into the admin console or
the web installer are separable from the sets in the house. Two things to preserve: the
flag is **stated, never inferred** from a missing token or version — an old APK reports
neither, and reading one as the server would file a television under the wrong name — and
a gateway request with no device name falls back to the gateway's name rather than to
`store.DefaultDeviceName`, the placeholder that made the server read as somebody's unnamed
TV.
`Emby*` class names (`EmbyRepository`, `EmbyApi`, `EmbyServiceFactory`, `EmbyModels`) are
kept on purpose: those types model *Emby's* API, and renaming them would make the code
lie about what it talks to. App-identity types are `Memby*`.
@@ -747,24 +765,31 @@ network answered. Things to preserve:
**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.
`PlayerActivity` immediately and `POST /v1/items/{id}/trailers/resolve` selects a candidate.
Official Apple and labelled official YouTube sources come first, followed by local Emby media
and then the remaining recognised remote trailers. Local media is returned directly; Apple
and YouTube pages are resolved and validated on the television, then played natively. That
boundary is deliberate: provider requests and any IP-bound media URL must originate from the
viewer's real client address, never the gateway. 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.
exists, and the player knows only how to ask for the next candidate. The client resolver
caches only mappings that passed a media probe; a failed player source is evicted before
fallback.
- 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.
The player's title treatment receives the subject's logo URL, with text only as its fallback.
- 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.
the gateway-assisted path because it owns metadata discovery and candidate ordering, but
provider resolution itself stays on the television. `POST /v1/items/{id}/trailers/report`
records started, failed and completed attempts with the forwarded client address; successful
candidates become the gateway's next first choice only after a real first frame.
**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
@@ -1317,6 +1342,18 @@ inside the running player instead of relaunching the activity, so `itemId`/`play
/`stopReported` must all be reset together or the outgoing episode is never reported
stopped; and a movie simply resolves to null, which is why nothing special-cases item type.
The optional **next-episode recap or preview** extends that same auto-advance path. Once the
next episode is known, the television searches YouTube in the background using series name,
episode code and title, ranks official previews and recaps above reactions, reviews and
breakdowns, resolves the best playable native stream, and caches the result. Playback never
waits for this work. If the setting is on and the playhead naturally crosses two minutes
remaining, the preview replaces the closing credits and then advances to the episode. Seeking
straight into that window does not trigger it. A failure before the first preview frame
silently restores the current episode at its saved position; a failure after that frame moves
on to the next episode, because the outgoing episode has already been closed. Preview time is
never reported to Emby as episode progress, and no YouTube account or embedded web player is
involved.
**Skipping is Left and Right, and it does not open anything.** `ui/player/SeekControls.kt`
holds the arithmetic and the wording; `PlayerActivity.dispatchKeyEvent` owns the keys and
`player_seek_indicator.xml` is the centred chip that says what just happened. How far one