Commit Graph
125 Commits
Author SHA1 Message Date
edde746 744e72d76b fix(player): stop continuous Dolby Direct Play judder via MPVKit 1.0.23
Direct Play of any (E-)AC-3 track on Apple TV developed persistent
micro-stutter: mpv's audio clock was derived from es_pts on the
compressed path, which is credited a whole 32 ms burst the moment a
payload lands, sawtoothing the clock on a ~0.8 s cycle that video
retires as visible skip/hold pairs. AAC content was unaffected, which
is why the symptom tracked Dolby audio and survived every VO-side fix.

MPVKit 1.0.23 measures the clock from IEC samples actually handed to
ao_read_data instead. Verified with an HDMI capture rig against the
CI-built binary: EAC3 display cadence is now statistically identical
to AAC (was 47.6 skips/min plus 453 multi-frame holds over 38 min).

close #1776
2026-08-19 12:57:15 +02:00
edde746 35eef09f72 fix(tvos): present video on the host clock instead of the media timebase
Direct Play on Apple TV develops recurring micro-stutter that worsens
the longer playback runs and clears temporarily on pause/play
(issue #1776). Since 2.4 the avfoundation VO has presented frames
against a media-time CMTimebase anchored and rate-servoed to follow
mpv's audio-slaved schedule; clock skew between the two domains can
only be retired by rate slewing or a re-anchor snap that retimes every
queued frame at once. The media timebase exists for PiP, which tvOS
does not have.

Bump MPVKit to 1.0.22 and opt tvOS into its new
avfoundation-presentation=host mode: samples carry mpv's scheduled
display time against a free-running host-clock timebase, so drift is
absorbed per frame inside mpv and no timing state accumulates in the
VO. The queue lead returns to 128ms; 500ms only dampened media-mode
snaps and quadrupled their blast radius. 1.0.22 also paces the
compressed-passthrough feed off the most-advanced playhead reading,
fixing the periodic audio dropouts passthrough users reported on 2.14.
2026-08-18 08:38:46 +02:00
edde746 e47b4e0a73 fix(macos): fall back to AVFoundation audio when CoreAudio fails to open
On macOS 27 beta, CoreAudio rejects ao_coreaudio's channel-layout setup
with paramErr (-50), and since 2.14.0 pinned ao=coreaudio as the only
output, the failed init left every video playing with no audio and no
selectable audio track. Append avfoundation as the fallback, mirroring
upstream mpv's macOS probe order: every format still opens through the
HAL-backed CoreAudio path when it works, and the fallback only engages
when CoreAudio's init fails outright.

close #1964
2026-08-16 22:40:53 +02:00
edde746 ea528b5213 fix(macos): use CoreAudio for every audio format
The AVFoundation/CoreAudio split still left PCM on AVFoundation and maintained two macOS timing paths. Select CoreAudio as the sole macOS audio output so PCM and compressed streams share the HAL-backed implementation. This intentionally drops macOS AVFoundation spatialization; iOS and tvOS remain unchanged.
2026-08-15 20:09:35 +02:00
edde746 35b3e97730 fix(macos): route compressed audio through CoreAudio
AC3/EAC3 playback could stutter after AVFoundation began handling compressed streams. Decline compressed formats in macOS AVFoundation so mpv falls through to CoreAudio, while retaining AVFoundation for PCM and the tvOS Dolby path.

close #1940
2026-08-15 17:52:51 +02:00
Aldo BarrerasandGitHub 8383c7b73b chore: bump go server version, run formatter & regenerate podfile lock file checksum (#1944)
* Bump go server and run formatter.

* Regenerate Podfile lock file checksum.
2026-08-15 13:44:56 +02:00
edde746 9769c4e092 chore: bump MPVKit to 1.0.20 2026-08-12 08:56:33 +02:00
edde746 69fadc220d chore: clean up code comments 2026-08-10 20:28:41 +02:00
edde746 3177290083 chore: bump MPVKit to 1.0.19
Picks up two vo_avfoundation fixes: keep the displayed frame across
seek resets, and refuse Core Image geometry rendering for Dolby
Vision passthrough frames (defense in depth - the app already keeps
mpv video-zoom at 0 on iOS/tvOS and zooms the display layer instead).
2026-08-10 14:50:05 +02:00
edde746 8ad13e94cf chore(mpv): bump MPVKit to 1.0.17 2026-08-09 12:31:48 +02:00
edde746 0a6865fa18 fix(macos): unbound the AVFoundation AO's PCM lookahead
MPVKit 1.0.15 bounded how far ahead ao_avfoundation enqueues PCM on macOS —
about 450ms of queue against the renderer's own ~1.7s — and disarms the feed
between refills, re-arming from a half-bound timer. 2.10 is the first release
to carry it: the AO pin went 1.0.12 to 1.0.16 over that release. #1711 reports
macOS audio skipping roughly every half second on 2.10 that 2.9.1 does not
have, and that bound is the only change to this path in the window, so restore
the renderer-owned depth 2.9.1 shipped. The option documents 0 as exactly that.

The AO itself stays. allowedAudioSpatializationFormats is a property of
AVSampleBufferAudioRenderer, and the compressed E-AC3 JOC sink lives there
too, while ao_coreaudio drives the HAL device and exposes no spatialization
control at all — CoreAudio is the fallback, not an alternative.

The cost is the latency the bound was added to remove: mpv multiplies --volume
into the samples as it hands them over, so a volume change stays inaudible
until the renderer queue drains. That is 2.9.1's behaviour, and the fix for it
belongs to the AO's gain domain rather than to how far ahead it may buffer.

Verified against the pinned MPVKit 1.0.16 libmpv on macOS: both option writes
are accepted, playback lands on ao_avfoundation and advances at 0.997x real
time. Runner's native suite passes.
2026-07-30 02:54:36 +02:00
edde746 31b3689740 fix(settings): list external players only when they are installed
Detection now runs off the UI isolate and covers every platform where
the answer can be trusted.

Availability was a plain platform check, so Linux always listed VLC, mpv
and Celluloid, macOS always listed VLC and IINA, and Windows always
listed VLC and PotPlayer whether or not any of them existed. Each player
now has a detector that asks exactly the question its launcher asks:
`sh -c 'command -v'` for PATH launches so the kernel performs the
executable check, NSWorkspace/Launch Services for `open -a`, `where.exe`
plus the concrete install paths for Windows VLC, and the registered URL
handler for PotPlayer and the iOS players.

Detection is asynchronous and memoised behind KnownPlayers.probe rather
than a Process.runSync in a static initialiser, which forked three
shells on the UI isolate during ExternalPlayerScreen.build. It is
prewarmed from startup, fails open when a probe throws, and keeps the
selected player listed when a detector misses it so a false negative
cannot leave the list with nothing selected.

iOS and tvOS gained LSApplicationQueriesSchemes entries for vlc and
infuse. Without them canOpenURL returns false for both schemes, so
_launchUrlScheme was already refusing to hand off to either player.

Android keeps the platform check: package visibility needs native
declarations, and a wrong answer there hides a working player.
2026-07-28 04:38:33 +02:00
edde746 bae6055123 fix(macos): drop the dangling MpvMetalLayerTests reference
The Xcode project wired macos/RunnerTests/MpvMetalLayerTests.swift into
the RunnerTests target, but the file was never committed alongside it,
so the macOS test target failed to build from a clean checkout:

  error: Build input file cannot be found: .../MpvMetalLayerTests.swift
         (in target 'RunnerTests' from project 'Runner')

Remove the reference. The test it belonged to is parked on
wip/macos-drawable-size-sync together with the change it covers.
2026-07-27 05:27:57 +02:00
edde746 3515eaf9b4 chore(mpv): bump MPVKit to 1.0.16
Brings in the AVFoundation audio output's bounded PCM lookahead, which
is compiled in on macOS only. AVSampleBufferAudioRenderer holds roughly
1.7s of audio there, and mpv multiplies --volume into the samples as it
hands them over, so a volume change stayed inaudible until that backlog
drained. The bound cuts the queue to about 450ms, measured; tvOS and
iOS preprocess to the source they had before the patch, so the deep
buffering their AirPlay path relies on is untouched.

Also carries the Dolby-conformant compressed EAC3 sink from 1.0.15.
2026-07-27 04:57:13 +02:00
edde746 a893e1859c fix(macos): restore the CocoaPods version the runners regenerate
The lockfile was last written by CocoaPods 1.16.2 while the macOS runner
ships 1.17.0, so `flutter build macos --config-only` ran pod install,
rewrote the marker, and tripped the guard that asserts Flutter
configuration leaves the committed lockfile untouched. ios/Podfile.lock
already records 1.17.0, which is why only macOS failed.
2026-07-26 23:05:16 +02:00
edde746 6c14049e95 fix(tvos): make EAC3 playback conform to Dolby's guidance
Groundwork for #1300. Establishes the session, buffering and route
handling Dolby's application guide prescribes, and adds the diagnostic
arm needed to find out whether Apple's sample-buffer renderer can carry
Atmos objects at all.

Audio session, per the guide's sequence:

- Adopt the long-form playback profile in one atomic call at app launch
  and activate the session there. The SDK only accepts that policy with
  category Playback, a Default/MoviePlayback/SpokenAudio mode and no
  options, so it cannot be assembled from separate calls.
- Report the resolved rendering mode in the player, hidden unless the
  system resolves it. Apple only resolves it for CarPlay and AirPlay, so
  an unresolved value means unknown, never "not Dolby".

Diagnostics (Apple TV only, Settings > Video Playback > Atmos Output Test):

- Add a sample-buffer arm. It reads the asset with AVAssetReader at
  outputSettings nil and hands the untouched compressed buffers and the
  untouched format description straight to the renderer, with a variant
  that rebuilds the description the way playback builds it. Every
  existing mode went through AVPlayer, so nothing exercised the path
  playback actually uses; this is what tells us whether the renderer or
  our construction is at fault.
- Add an AirPlay route picker. AirPlay is the only route where the system
  resolves the rendering mode and the supported channel layouts, so it is
  what makes those observations reachable at all, and the AVPlayer arms
  now allow external playback so every arm can be compared on the same
  destination.
- Add a session-mode toggle for the one profile difference between the
  guide and previous playback behaviour.
- Report the session profile, supported layouts, both format
  descriptions, the magic cookie and the renderer status, and release the
  session on stop so a failed run cannot contaminate the next one.

Also bumps MPVKit to 1.0.14, which carries the matching audio output
work: the channel layout AVFoundation itself uses for Dolby content, a
renderer-failure observer so the fallback to PCM can actually run, the
prescribed feed ordering and preroll, flush recovery that re-supplies the
discarded audio instead of shifting later audio into its place, and
capability-driven fallback on route and capability changes.

This does not yet fix #1300. Whether the sample-buffer renderer can carry
JOC is still unknown; it removes every difference from the documented
setup that could explain the failure, and gives us the arm to answer it
on real hardware.
2026-07-26 20:42:58 +02:00
edde746 f8f366a513 fix(native): harden player teardown and shelf recovery 2026-07-25 16:16:24 +02:00
edde746 40833e65ec fix(ci): align toolchains and isolate platform tests 2026-07-24 10:06:50 +02:00
edde746 0c6dab01b3 build(deps): upgrade Flutter package dependencies 2026-07-24 03:56:40 +02:00
edde746 9f2e050797 fix(native): bound cross-platform lifecycle ownership 2026-07-24 03:56:40 +02:00
edde746 e0bf66eea8 fix(runtime): harden application service boundaries 2026-07-24 03:46:46 +02:00
edde746 658da37b48 build: make toolchain inputs reproducible 2026-07-24 03:40:06 +02:00
edde746 0a3e9d9e89 build(apple): bump MPVKit to 1.0.13 2026-07-13 23:37:30 +02:00
edde746 e6e7d8cdfd test: remove redundant coverage and shorten timers 2026-07-13 02:15:03 +02:00
edde746 4a81246986 build(libass): bump fork to 0.18.3 2026-07-12 00:44:08 +02:00
edde746 71d644c4ae fix(macos): stop CPU spin when display sleeps with video paused
When the display/system sleeps with a video paused, the window server
stops completing CAMetalLayer presents and mpv's MoltenVK swapchain wedges,
pinning one core at 100% until the app exits. occlusionState does not
reliably change on display sleep, so observe NSWorkspace screensDidSleep/
Wake to hide the metal layer (and drop the playback activity) while dark,
restoring on wake with a forced redraw when paused to avoid a stale frame.

Pairs with MPVKit v1.0.10, which gates libmpv presentation on the layer's
hidden state (check_visible) so presents actually stop while hidden.
2026-07-09 11:56:13 +02:00
edde746 422db75b5b feat(music): mpv audio playback engine with gapless queue service
Audio-only mpv core on every platform (dedicated
com.plezy/mpv_audio_player channels): parameterized android/windows/
linux mpv plugins and a new apple MpvAudioPlayerCore, all skipping
video/window paths (vid=no, audio-display=no, gapless-audio=weak).
MusicPlaybackService drives an in-memory queue with shuffle/repeat,
file-loaded-event gapless arming (property edges coalesce and the
android bridge drops them), per-track progress reporting, OS media
controls, audio focus, sleep timer, and error auto-skip.
PlaybackCoordinator enforces one live native player: starting video
disposes the audio core first.
2026-07-05 19:26:28 +02:00
edde746 87eaafe3c4 chore(deps): update MPVKit to v1.0.9
close #1420, close #1457, close #1484
2026-07-05 08:15:00 +02:00
edde746 8fa91fe444 chore(apple): pin MPVKit 1.0.8
AV1 perf: NEON dav1d (upstream prebuilt shipped C-only) + fused
software-frame upload in the avfoundation VO (patch 0009).
2026-07-03 08:51:19 +02:00
edde746 d5df426ab6 build(libass): bump to 0.18.2 2026-07-02 11:41:24 +02:00
edde746 d333ac2382 fix(apple): pin MPVKit 1.0.6 2026-06-27 06:03:07 +02:00
edde746 9ff3099a9d fix(player): update MPVKit and stream buffering 2026-06-13 20:51:14 +02:00
edde746 3c43874342 fix(tvos): update mpvkit audio passthrough 2026-06-13 10:24:15 +02:00
edde746 1292d7ac34 fix(dovi): bump MPVKit to v1.0.2 for profile 8 DV hardware decode
close #1262
2026-06-10 20:26:11 +02:00
edde746 cd9498abb8 refactor(player): centralize playback opening
close #1280
2026-06-10 02:26:26 +02:00
edde746 3cca29512d fix: bump MPVKit to v1.0.1 for profile 8 Dolby Vision decode
Routes all single-layer DV profile 8 (incl. compat 0) through the Apple
DV decode path, so VideoToolbox decodes it in hardware as true Dolby
Vision instead of failing over to software HDR10. Refs #1262.
2026-06-06 16:06:31 +02:00
edde746 6b3e49d410 fix(ios): recover frozen video after Control Center
close #1232
2026-06-06 00:49:19 +02:00
edde746 e6ca5f254d fix(ios): correct anamorphic video aspect ratio
close #1244
2026-06-05 10:15:03 +02:00
edde746 eba553413c fix(macos): allow LuaJIT under hardened runtime
close #1214
2026-06-01 02:46:37 +02:00
edde746 869b4fe230 chore: bump MPVKit 2026-05-28 00:14:06 +02:00
edde746 7b4e399013 chore: bump MPVKit 2026-05-27 06:52:03 +02:00
edde746 e98d7febdd chore: upgrade Flutter to 3.44 2026-05-18 22:52:51 +02:00
edde746 db2a2c34d2 fix(apple): update MPVKit release 2026-05-15 18:14:13 +02:00
edde746 9b248a7a5b fix(macos): restore video layer on focus 2026-05-11 10:13:05 +02:00
edde746 bfb6aa01b9 fix(apple): use platform-specific mpv rendering 2026-05-10 13:33:02 +02:00
edde746 6f273b0aa8 fix(apple): align local network permissions 2026-05-10 09:39:43 +02:00
edde746 3a612df3d3 chore: remove in-app review 2026-05-09 11:47:37 +02:00
edde746 afda61119e fix(macos): sync restored fullscreen chrome 2026-05-09 11:35:36 +02:00
edde746 d38f7cf78f perf(player): reduce playback UI churn 2026-05-09 09:38:25 +02:00
edde746 633ce11c88 chore(deps): update MPVKit 2026-05-09 09:17:03 +02:00