name: Bug Report — video.play() overridden by Vidstack state machine causing autoplay failure
about: Bug
Related Problem:
When calling hls.on(Hls.Events.MANIFEST_PARSED, () => { video.play() }) on the native video element inside onProviderChange / provider.onInstance(), Vidstack resets the video back to paused state after its internal initialization completes, cancelling the autoplay call.
Describe:
Vidstack wraps the native <video> element in its own state machine that tracks paused/playing internally. When HLS.js fires MANIFEST_PARSED and we call video.play() directly on the native element, Vidstack's internal state still says paused: true. Vidstack then calls video.pause() to sync the real element back to its internal state, immediately cancelling our autoplay.
Why it is inconsistent:
- Fast-loading content —
MANIFEST_PARSED fires after Vidstack finishes initializing, so there is no conflict and autoplay works.
- Slow-loading content —
MANIFEST_PARSED fires while Vidstack is still mid-initialization. Its state machine is in a transitional state and actively resets the video to paused after our play() call.
The autoPlay prop does not reliably prevent this either — the same race condition applies.
Alternatives:
We tried the following workarounds, none of which consistently solved the issue:
- Using the
onCanPlay prop instead of MANIFEST_PARSED
- Mute →
play() → unmute trick to bypass browser autoplay policy
- Delaying
play() with setTimeout
- Listening to Vidstack's own
onProviderChange and canPlay events
All of these still failed for slow-loading content because Vidstack's state machine fires after MANIFEST_PARSED regardless of when play() is called.
Anything Else?
This issue forced us to remove Vidstack entirely and replace it with raw HLS.js + a plain <video> element, which removed the conflict completely and fixed autoplay 100% of the time. We would prefer to use Vidstack but cannot until this state machine conflict is resolved.
Expected behavior: If autoPlay is set, or if video.play() is called during MANIFEST_PARSED, Vidstack should not override the playing state during or after its own initialization.
name: Bug Report — video.play() overridden by Vidstack state machine causing autoplay failure
about: Bug
Related Problem:
When calling
hls.on(Hls.Events.MANIFEST_PARSED, () => { video.play() })on the native video element insideonProviderChange/provider.onInstance(), Vidstack resets the video back to paused state after its internal initialization completes, cancelling the autoplay call.Describe:
Vidstack wraps the native
<video>element in its own state machine that trackspaused/playinginternally. When HLS.js firesMANIFEST_PARSEDand we callvideo.play()directly on the native element, Vidstack's internal state still sayspaused: true. Vidstack then callsvideo.pause()to sync the real element back to its internal state, immediately cancelling our autoplay.Why it is inconsistent:
MANIFEST_PARSEDfires after Vidstack finishes initializing, so there is no conflict and autoplay works.MANIFEST_PARSEDfires while Vidstack is still mid-initialization. Its state machine is in a transitional state and actively resets the video to paused after ourplay()call.The
autoPlayprop does not reliably prevent this either — the same race condition applies.Alternatives:
We tried the following workarounds, none of which consistently solved the issue:
onCanPlayprop instead ofMANIFEST_PARSEDplay()→ unmute trick to bypass browser autoplay policyplay()withsetTimeoutonProviderChangeandcanPlayeventsAll of these still failed for slow-loading content because Vidstack's state machine fires after
MANIFEST_PARSEDregardless of whenplay()is called.Anything Else?
This issue forced us to remove Vidstack entirely and replace it with raw HLS.js + a plain
<video>element, which removed the conflict completely and fixed autoplay 100% of the time. We would prefer to use Vidstack but cannot until this state machine conflict is resolved.Expected behavior: If
autoPlayis set, or ifvideo.play()is called duringMANIFEST_PARSED, Vidstack should not override the playing state during or after its own initialization.