perf(player): cut wasted per-frame rebuilds during playback#2
Closed
JenteJan wants to merge 1 commit into
Closed
Conversation
Profiling steady-state playback on macOS (libmpv path, shared with Windows) showed the Flutter layer doing needless work while watching, even though the video itself is composited cheaply by mpv. - Unmount the overlay controls once their hide animation finishes, so their position-driven Consumers stop rebuilding while the overlay is hidden (the common 'just watching' case). Remount before fading back in. Steady-state UI work drops to ~3 idle frames/sec. - Only build the progress-bar scrub-preview card while it is actually visible; it was building and laying out its image/trickplay subtree on every frame behind opacity 0 (the dominant LAYOUT cost when controls are shown). - Narrow the audio queue / queue-dialog watches to repeatMode via select() instead of watching the whole playback model, so they no longer rebuild and re-map the entire queue on every position tick. No behavioural change; pure rebuild-scope reduction.
Owner
Author
|
Superseded by DonutWare#1019 (opened upstream). |
JenteJan
added a commit
that referenced
this pull request
Jun 16, 2026
…can-f#3 DonutWare#10 DonutWare#4) - DonutWare#9 connect() tears down the active session before switching, so e.g. AirPlay is actually stopped before Chromecast starts. - #2 DlnaPlayer sends UPnP Stop on dispose so the TV session closes on disconnect. - irican-f#3 DLNA play/pause are optimistic (snappy UI) behind a short command guard, after which the poll is authoritative again — so play/seek done on the TV itself is reflected on the client. - DonutWare#10 external-end handling generalized: DLNA poll detects STOPPED/NO_MEDIA or an unreachable renderer; a native Chromecast session-disconnect listener (guarded to chromecast sessions) restores local playback when the receiver is taken over or turned off. (web SESSION_ENDED already covered.) - Responsiveness: connecting/disconnecting states with the target name; picker shows progress and disables tiles during transitions. - DonutWare#4 device tiles keyed by id so the tap ripple lands on the tapped row.
JenteJan
added a commit
that referenced
this pull request
Jun 16, 2026
…utWare#4) - #2 AirPlay now shows the item's backdrop behind the cast badge (fullscreen + mini), like the other cast targets — the video plays on the Apple TV, so we show the shared CastingPlaceholder instead of the local AVPlayer texture. - DonutWare#4 Chromecast devices publish live via GoogleCastDiscoveryManager.devicesStream instead of only being snapshotted within the scan window, so they appear as the SDK finds them (notably on iOS, where the first scan often finished before the SDK had them — no more manual reload). Discovery now merges a persistent cast-device list with the per-scan DLNA renderers.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Three rebuild-scope cleanups in the video player. No behaviour change — purely doing less redundant work.
opacity: 0when auto-hidden, so their position-driven Consumers kept rebuilding (~1–2×/sec from position ticks) the whole time you're just watching. Now dropped from the tree once the hide animation finishes, remounted before fading back in.chapterCardbuilt and laid out its image / TrickPlayImage subtree on every frame behindopacity: 0. For content with trickplay this means decoding/laying out a preview tile every frame even when the preview isn't shown. Now gated on actual hover/drag.mediaPlaybackModeland re-.map()-ed the entire queue on every position tick; they only needrepeatMode, so they nowselect()just that.Profiling notes (honest)
Profiled in profile mode on macOS (the libmpv/
media_kitdesktop path, shared with Windows). Findings:opacity: 0is a clear anti-pattern worth removing.No fabricated metrics: the case for these is the code itself (don't rebuild offscreen widgets; don't watch a whole model for one field) plus lighter idle CPU/battery, especially on weaker hardware.
Draft — opened against my fork's develop for review before sending upstream.