Skip to content

Playback diagnostics events and error handling#103

Open
ghenry22 wants to merge 3 commits intodoublesymmetry:mainfrom
ghenry22:pr/playback-diagnostics
Open

Playback diagnostics events and error handling#103
ghenry22 wants to merge 3 commits intodoublesymmetry:mainfrom
ghenry22:pr/playback-diagnostics

Conversation

@ghenry22
Copy link

I am also submitting a corresponding PR to the React-Native-Track-Player repo that integrates these new features.

Add playback diagnostic events: stalled, error log, buffer empty/full
Fix empty AVWrapperItemPlaybackStalled handler to emit playbackStalled event
Add AVPlayerItemNewErrorLogEntry notification observer with error log data extraction
Add isPlaybackBufferEmpty and isPlaybackBufferFull KVO observers
Propagate all new events through delegate chain (Observer -> AVPlayerWrapper -> AudioPlayer -> EventHolder)
Add PlaybackStalledEventData, NewErrorLogEntryEventData, BufferEmptyEventData, BufferFullEventData type aliases
These events enable consuming applications to detect and respond to:
Playback stalls (buffer underruns during streaming)
Transient streaming errors that don't stop playback
Buffer state changes for fine-grained monitoring

Add lastPosition to preserve playback position across reload/failure cycles
Track last known-good position in AVPlayerWrapper via periodic time observer and seek completions
Fix reload() to use lastPosition instead of reading from potentially broken AVPlayerItem
Fix playWhenReady setter to always preserve position on both .failed and .stopped states
Fall back to lastPosition when AVPlayer.currentTime() returns NaN
Reset lastPosition only on unload() or when loading a new URL

fix: decouple bufferDuration from automaticallyWaitsToMinimizeStalling
Previously, setting bufferDuration > 0 automatically set automaticallyWaitsToMinimizeStalling to false, which caused the first play on a fresh AVPlayer to report "playing" state while position stayed at 0 (no actual audio output). After ~5 seconds the player would fail with itemFailedToPlayToEndTime.
The recreated AVPlayer (from retry) would then have the default automaticallyWaitsToMinimizeStalling=true and work correctly.
Now bufferDuration only controls preferredForwardBufferDuration (how aggressively to buffer) and automaticallyWaitsToMinimizeStalling is an independent setting that defaults to true.

ghenry22 and others added 3 commits February 14, 2026 16:03
- Fix empty AVWrapperItemPlaybackStalled handler to emit playbackStalled event
- Add AVPlayerItemNewErrorLogEntry notification observer with error log data extraction
- Add isPlaybackBufferEmpty and isPlaybackBufferFull KVO observers
- Propagate all new events through delegate chain (Observer -> AVPlayerWrapper -> AudioPlayer -> EventHolder)
- Add PlaybackStalledEventData, NewErrorLogEntryEventData, BufferEmptyEventData, BufferFullEventData type aliases

These events enable consuming applications to detect and respond to:
- Playback stalls (buffer underruns during streaming)
- Transient streaming errors that don't stop playback
- Buffer state changes for fine-grained monitoring

Co-authored-by: Cursor <cursoragent@cursor.com>
…cycles

- Track last known-good position in AVPlayerWrapper via periodic time
  observer and seek completions
- Fix reload() to use lastPosition instead of reading from potentially
  broken AVPlayerItem
- Fix playWhenReady setter to always preserve position on both .failed
  and .stopped states
- Fall back to lastPosition when AVPlayer.currentTime() returns NaN
- Reset lastPosition only on unload() or when loading a new URL

Co-authored-by: Cursor <cursoragent@cursor.com>
Previously, setting bufferDuration > 0 automatically set
automaticallyWaitsToMinimizeStalling to false, which caused the
first play on a fresh AVPlayer to report "playing" state while
position stayed at 0 (no actual audio output). After ~5 seconds
the player would fail with itemFailedToPlayToEndTime.

The recreated AVPlayer (from retry) would then have the default
automaticallyWaitsToMinimizeStalling=true and work correctly.

Now bufferDuration only controls preferredForwardBufferDuration
(how aggressively to buffer) and automaticallyWaitsToMinimizeStalling
is an independent setting that defaults to true.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant