fix: video stuck on still frame after long pause

close #536
This commit is contained in:
edde746
2026-02-25 08:17:14 +01:00
parent cb39945a9d
commit b193a23524
4 changed files with 26 additions and 2 deletions
+1 -2
View File
@@ -282,8 +282,7 @@ class PlayerNative extends PlayerBase {
Future<void> updateFrame() async {
checkDisposed();
if (!initialized) return;
// Only iOS and macOS use Metal layer that needs frame updates
if (Platform.isIOS || Platform.isMacOS) {
if (Platform.isIOS || Platform.isMacOS || Platform.isLinux) {
await methodChannel.invokeMethod('updateFrame');
}
}
+4
View File
@@ -1698,6 +1698,10 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> with WidgetsBindin
// Toggle wakelock based on playback state
if (isPlaying) {
WakelockPlus.enable();
// Force a texture refresh on resume to unstick stale frames
// (Linux/macOS texture registrars can miss frame-available
// notifications after extended pause periods)
player?.updateFrame();
} else {
WakelockPlus.disable();
}
@@ -43,6 +43,9 @@ class PlaybackProgressTracker {
/// Timer ticks to skip before retrying after failures (exponential backoff).
int _ticksToSkip = 0;
/// Counts timer ticks while paused to send periodic "paused" heartbeats.
int _pausedTickCounter = 0;
PlaybackProgressTracker({
required this.client,
required this.metadata,
@@ -70,6 +73,7 @@ class PlaybackProgressTracker {
_progressTimer = Timer.periodic(updateInterval, (timer) {
if (player.state.playing) {
_pausedTickCounter = 0;
// Skip ticks when backing off after consecutive failures to avoid
// flooding the network with doomed requests during an outage.
if (_ticksToSkip > 0) {
@@ -77,6 +81,18 @@ class PlaybackProgressTracker {
return;
}
_sendProgress('playing');
} else {
// Send periodic "paused" updates to keep the Plex session alive
// (~60s with default 10s interval)
_pausedTickCounter++;
if (_pausedTickCounter >= 6) {
_pausedTickCounter = 0;
if (_ticksToSkip > 0) {
_ticksToSkip--;
return;
}
_sendProgress('paused');
}
}
});
+5
View File
@@ -324,6 +324,11 @@ static void mpv_plugin_handle_method_call(FlMethodChannel* channel,
response = FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
}
} else if (strcmp(method, "updateFrame") == 0) {
if (self->visible && self->texture) {
mpv_texture_mark_frame_available(self->texture);
}
response = FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
} else if (strcmp(method, "isInitialized") == 0) {
gboolean initialized = self->player && self->initialized;
response = FL_METHOD_RESPONSE(