player icon indicating copy to clipboard operation
player copied to clipboard

Chromium: Play not working after pause and programmatically seek

Open KammererTob opened this issue 10 months ago • 3 comments

Current Behavior:

If you programmatically pause and seek (by setting currentTime) you can not resume the playback. I think this happens because the paused state is not set correctly in this instance.

This only happens in Chromium based Browsers. Firefox works fine.

Expected Behavior:

To be able to resume playback after pausing and seeking

Steps To Reproduce:

  1. Use Google Chrome (or any Chromium Browser)
  2. Pause the playback and immediately seek like this:
  await player.pause();
  player.currentTime = 8;
  1. Try to resume playback like this: await player.play();

Reproduction Link:

https://codesandbox.io/p/devbox/crazy-wing-yf9j4f?file=%2Fpackage.json&workspaceId=ws_JF2zkipFRqmiNRc3h9Njkn

Start playback by either the Play Button or "Play/Resume" Button. Press the "Pause" Button. Notice how it seeks to 8 seconds, but the play button stays as if it was still playing. You cannot resume playback by either button.

Environment:

  • Framework: Vue/Web-Components
  • OS: Windows 10 64 bit
  • Browser: [email protected]
  • Vidstack: latest

KammererTob avatar Mar 12 '25 18:03 KammererTob

Has this been solved yet? It's causing some major problems for our application, unfortunately.

JudahMantell avatar Jun 03 '25 14:06 JudahMantell

Third this bug. Crazy to me that it was not priority fixed. I was able to work around it by commenting out the checks for peek(paused) in play/pause in media-request-manager.ts as a temp fix. Looking forward to a real fix. Seems like some code is setting paused to false but not actually playing the media after seeking, but I didn't dive in that far.

flagoworld avatar Jul 15 '25 17:07 flagoworld

Setting a 0ms timeout after the pausing prevents the issue..

player.paused = true

setTimeout(() => {
  player.currentTime = 8
}, 0);

or if you want to avoid timeouts, listen for the pause completing before seeking, example..

await player.pause();

await new Promise(resolve => {
  const onPause = () => {
    player.removeEventListener('pause', onPause);
    resolve();
  };
  player.addEventListener('pause', onPause);
});
player.currentTime = 8;

either way, you'd need to wait for the pause to complete, rather than potentially interrupting it.

wplit avatar Jul 16 '25 01:07 wplit