From 7d679c9d7848050429eac73735a9a6d4837ec64d Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Sun, 10 May 2026 22:17:00 +0200 Subject: [PATCH] fix(player): gate frame-rate refresh on mpv playback-restart --- .../video_player/parts/display_matching.dart | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/screens/video_player/parts/display_matching.dart b/lib/screens/video_player/parts/display_matching.dart index d3873ab3..f18f3afa 100644 --- a/lib/screens/video_player/parts/display_matching.dart +++ b/lib/screens/video_player/parts/display_matching.dart @@ -79,11 +79,25 @@ extension _VideoPlayerDisplayMatchingMethods on VideoPlayerScreenState { final positionMs = p.state.position.inMilliseconds; final fallbackMs = fallbackPosition?.inMilliseconds ?? 0; final targetMs = positionMs > 0 ? positionMs : (fallbackMs > 0 ? fallbackMs : 1); + // Subscribe before the seek so the broadcast event isn't dropped when + // the restart fires synchronously fast. + var timedOut = false; + final restartFuture = p.streams.playbackRestart.first.timeout( + const Duration(milliseconds: 2500), + onTimeout: () { + timedOut = true; + }, + ); + final sw = Stopwatch()..start(); try { appLogger.d('Frame rate matching: refreshing Android MPV decoder ($reason, target=${targetMs}ms)'); await p.command(['seek', (targetMs / 1000.0).toStringAsFixed(3), 'absolute+exact']); - await Future.delayed(const Duration(milliseconds: 150)); - appLogger.d('Frame rate matching: refreshed Android MPV decoder ($reason, target=${targetMs}ms)'); + await restartFuture; + appLogger.d( + 'Frame rate matching: refreshed Android MPV decoder ' + '($reason, target=${targetMs}ms, waited=${sw.elapsedMilliseconds}ms, ' + 'gate=${timedOut ? 'timeout' : 'playback-restart'})', + ); } catch (e) { appLogger.w('Failed to refresh Android MPV decoder after frame rate switch ($reason)', error: e); }