Skip to content

fix(HTMLVideo): recover from hls.js errors to prevent silent audio#142

Open
Aqu1tain wants to merge 1 commit intoStremio:masterfrom
Aqu1tain:fix/hls-audio-error-recovery
Open

fix(HTMLVideo): recover from hls.js errors to prevent silent audio#142
Aqu1tain wants to merge 1 commit intoStremio:masterfrom
Aqu1tain:fix/hls-audio-error-recovery

Conversation

@Aqu1tain
Copy link
Copy Markdown

Summary

Adds an Hls.Events.ERROR listener in HTMLVideo so a small set of stalling conditions that hls.js does not recover from on its own no longer leave audio silent while video keeps playing.

Why

HTMLVideo.js constructs an Hls instance with no error listener and never calls recoverMediaError, swapAudioCodec, or startLoad. When hls.js exhausts retries on bufferStalledError, bufferAppendingError, audioTrackLoadError, audioTrackLoadTimeOut, or hits a fatal NETWORK_ERROR/MEDIA_ERROR, the audio source buffer can stall while the video element keeps decoding video. The host UI shows normal, non-muted state because nothing toggles videoElement.muted or videoElement.volume. Users see silent playback until they reload. Only HTMLVideo is affected; ShellVideo and external players bypass hls.js.

Behavior

  • Non-fatal error: startLoad() only for the four known stalling details. All other non-fatal errors are left to hls.js's own state machine.
  • Fatal NETWORK_ERROR: startLoad().
  • Fatal MEDIA_ERROR: first occurrence calls recoverMediaError(); a second within 3s adds swapAudioCodec() before recovery. Capped at 3 attempts; counter resets on FRAG_BUFFERED.
  • Other fatal types: untouched. The existing videoElement.onerror path continues to map decode errors as before.

Test plan

  • Play an HLS stream that triggers BUFFER_STALLED_ERROR and verify audio resumes without reload.
  • Play an HLS stream that triggers a fatal MEDIA_ERROR and verify audio recovers; force a second within 3s and verify codec swap kicks in.
  • Force repeated unrecoverable MEDIA_ERRORs and verify the listener stops intervening after 3 attempts so the video error path takes over.
  • Switch streams and verify per-load state resets cleanly (no cross-load codec-swap or attempt-counter behavior).
  • npm run lint passes.

@Aqu1tain Aqu1tain force-pushed the fix/hls-audio-error-recovery branch from ab322b8 to 7a2ce33 Compare April 30, 2026 13:25
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