Skip to content

[Android] Seeks silently dropped around FirstFrameReady; Pause commands dropped while state reads playing=False paused=False #2492

Description

@dashcambike

Unity version

6000.5.2f1

Unity editor platform

macOS

AVPro Video edition

Core

AVPro Video version

3.4.1

Device hardware

Google Pixel 6a

Which Android OS version are you using?

16

Unity Graphics API

OpenGLES 3

Video API

MediaPlayer

Texture format

BGRA

Audio output

System Direct

Any other Media Player component configuration required to reproduce the issue.

No response

Which output component(s) are you using?

Display uGUI

Any other component configuration required to reproduce the issue.

No response

The issue

I see a few issues when a user is trying to scrub around my timeline. Sometimes I get stuck in a bad state, where the video is playing but AVProVideo thinks it's not, sometimes seeks fail. I've tried to distill this down to concrete issues, and found four concrete underlying causes.

[AI Disclosure: I used Claude to analyze logs and generate the text below, but A Real Human encountered and debugged the issue]

  1. A seek issued at/near FirstFrameReady is silently dropped. IsSeeking() never becomes true, no error is raised, the clock stays at 0. Re-issuing the same SeekWithTolerance ~100ms later succeeds.
  2. If playback starts while a seek is in flight (e.g. deferred autoplay firing mid-seek), the state machine enters a persistent limbo: IsPlaying()=false, IsPaused()=false while the decoder is actively playing (clock advancing). The limbo persists for seconds, well past the transition.
  3. Pause() commands issued while in that limbo are dropped (clock keeps advancing); Play() commands from the same limbo are accepted. Once flags are settled (IsPlaying()=true), Pause() works normally.
  4. Status flags are unreliable during transitions: FirstFrameReady fires before the pipeline accepts commands; IsSeeking() stays false during an in-flight seek. (On 3.4.0 I also saw IsPlaying()=false while the video was actually playing, but I have not seen this since upgrading to 3.4.1 so I think it's fixed.)

Issue 3 is the most user-visible: the user pauses, the app calls Pause(), and the video keeps playing.

To Reproduce

Minimal flow that reproduces it

// 1. Open a local clip, autoplay=true
mediaPlayer.OpenMedia(new MediaPath(path, MediaPathType.AbsolutePathOrURL), autoPlay: true);

// 2. On MediaPlayerEvent.EventType.FirstFrameReady, seek:
mediaPlayer.Control.SeekWithTolerance(target, 0.05, 0.05);
// Issue 1: this seek is silently dropped. IsSeeking() never goes true, no error,
// GetCurrentTime() stays 0.

// 3. Workaround for Issue 1: re-issue the same SeekWithTolerance every ~100ms until
// GetCurrentTime() is observed near the target. A retry ~100-200ms after
// FirstFrameReady succeeds. While this retried seek is in flight, OpenMedia's
// deferred autoplay starts playback:
// Issue 2: the flags are now stuck at playing=False paused=False (limbo), and stay
// there even after the seek completes and the decoder is running.

// 4. The retried seek from step 3 lands (GetCurrentTime() ~= target). Now pause:
mediaPlayer.Control.Pause();
// Issue 3: dropped -- the clock keeps advancing. A Play() issued from this same
// limbo state IS honored; only Pause() is lost.

Workarounds

  1. Open with autoPlay:false always; issue a single Play() only after the seek has landed (avoids Issue 2).
  2. Keep a queued seek "pending" and re-issue it every 100ms until GetCurrentTime() is observed near the target (works around Issue 1).
  3. Track play/pause intent app-side and re-issue Pause() whenever the clock advances >0.3s past a pause (works around Issue 3).
  4. Drive all UI state from app-side intent instead of Control.IsPlaying() (works around Issue 4).

Media information

No response

Logcat output

Metadata

Metadata

Assignees

Labels

triageNeeds triage

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions