0.2.70 - Cold start improvements

This commit is contained in:
ponzischeme89
2026-08-16 22:08:43 +12:00
parent 845fa349e4
commit 93fb0fd728
15 changed files with 402 additions and 80 deletions
+19 -6
View File
@@ -1280,8 +1280,11 @@ decoded. Four things exist to hold it down, and each is easy to give back:
construction is on the critical path of every launch. It pulls media bytes through
`HttpStack` rather than media3's own HttpURLConnection client, so the header, index and
offset requests a resume makes reuse one connection instead of repeating the handshake
three times; and it enables constant-bitrate seeking, so a container with no usable seek
table computes the offset instead of reading its way there. Both are borrowed from
three times. PlaybackInfo and media bytes use a dedicated dispatcher, so a launcher full
of queued artwork cannot occupy the stream's per-host slots; it still shares the same
connection pool, retaining the warm connection. It also enables constant-bitrate seeking,
so a container with no usable seek table computes the offset instead of reading its way
there. The connection reuse and seeking choices are borrowed from
[Wholphin](https://github.com/damontecres/Wholphin), a Jellyfin TV client under the same
GPL-2.0 licence.
- **`PlayerActivity.onCreate` is ordered as critical path then decoration**, with the
@@ -1312,11 +1315,19 @@ decoded. Four things exist to hold it down, and each is easy to give back:
places: the `Playable`, the intent's parameter list, its `putExtra`, and `onCreate`'s
`getBooleanExtra`. `subtitleDownloadAvailable` is the worked example of all four.
- **`ui/player/PlaybackTrace.kt` says where the time went.** "Playback is slow" is not
actionable; `event=first_frame … activity=…(+…) player=… stream=… prepared=… ready=…
first_frame=…` is. Marks are cumulative from the Play press, a repeated stage keeps the
actionable; `event=first_frame … play_clicked=0 … source_resolved=… player_prepared=…
ready=… first_frame=…` is. Marks are cumulative from the Play press, a repeated stage keeps the
first time it was reached, and a stage that never happened is absent rather than zero.
`PlaybackTraceSections.kt` names the same two spans for a systrace so `:benchmark` can
measure what the log can only report — see "Benchmarks" below.
- **Startup is bounded even when Media3 never throws.** Source resolution has a 15-second
deadline and one fresh foreground retry. After `prepare()`, first frame has a 20-second
deadline; the first expiry stops the player, clears its media items, negotiates a fresh
playback session and prepares again. A second expiry becomes the ordinary retry/exit
error screen. The foreground resolution discards a stale focus-prefetch after a short
grace period rather than awaiting a process-scoped deferred indefinitely. These bounds
are cancelled while the activity is stopped and reinstated on return, so backgrounding
the app is not itself treated as a playback failure.
Measured on a Chromecast with Google TV against the NAS gateway, the shape is:
`prepare()` → first frame is **over 90%** of a resume, the stream negotiation is ~120 ms
@@ -1422,8 +1433,10 @@ gateway's catalogue. Things to preserve:
unreachable. A stream that is not seekable falls through to media3 instead: nothing
errors and nothing claims to have skipped.
- **Only discrete presses count.** A held key repeats at the platform's rate, which is fast
enough to throw somebody minutes down a film they meant to nudge — the repeats are
consumed rather than acted on, so letting go does not open the transport either.
enough to throw somebody minutes down a film they meant to nudge. `DiscreteSeekPresses`
remembers the physical DOWN until its matching UP because some remotes report every held
repeat with `repeatCount == 0`; all repeats are consumed rather than acted on, so letting
go does not open the transport either.
- **A pending skip is committed in `onStop`** and dropped by `resetSeekControls` when the
episode underneath changes, or the position reported to Emby — and so where the title
resumes from — is one the viewer had already skipped past.