Skip to content

Conversation

Zaggy1024
Copy link

@Zaggy1024 Zaggy1024 commented Oct 15, 2025

This fixes a few inconsistencies between the spec and browsers' implementations of a few behaviors:

  1. Media elements' seek steps do not set the official playback position before parallel steps begin #11773: A script is not immediately guaranteed to receive a playback position on the media timeline after setting currentTime:

    console.log(video.duration); // 10
    let x = video.currentTime = 100;
    console.log(x); // 100
    console.log(video.currentTime); // spec: 100, implementations: 10

    The fix for this issue is to specify that the currentTime setter returns the value passed to it, and that the seek steps should synchronously set the official playback position to the chosen new playback position after clamping it to the earliest possible position, the duration, and the seekable ranges. This also ensures that currentTime reflects the new playback time after calling fastSeek(), which matches Firefox and Safari behavior.

  2. Media elements can loop if they reach the end of media playback while paused #11774: Seeking to the end of a video while paused loops to the start:

    video.loop = true;
    video.currentTime = video.duration;
    setTimeout(() => console.log(video.currentTime), 250); // spec: 0, implementations: 10

    In order to fix this, when reaching the end of playback while the loop attribute is set, the seek to the earliest position is only run when not paused. In order to allow playback to restart when that condition does not pass, the internal play steps must then seek to the start if looping was skipped due to being paused the last time they were run.

  3. Media element is not considered to have ended playback if loop is enabled after reaching the end #11775: Finally, if the loop attribute is set after playback has ended:

    video.loop = false;
    video.play();
    video.currentTime = video.duration;
    setTimeout(() => {
        console.log(video.ended); // true
        video.loop = true;
        console.log(video.ended); // spec: false, implementations: true
    }, 250);

    This is solved by specifying that playback has ended when the loop attribute was specified the last time that the end of playback was reached, meaning that modifying it before playback ends again does not affect the value of the ended attribute. This also allows playback to restart from the beginning even after specifying loop while playback is ended.


  • At least two implementers are interested (and none opposed):
  • Tests are written and can be reviewed and commented upon at:
  • Implementation bugs are filed:
    • Chromium: …
    • Gecko: …
    • WebKit: …
    • Deno (only for timers, structured clone, base64 utils, channel messaging, module resolution, web workers, and web storage): …
    • Node.js (only for timers, structured clone, base64 utils, channel messaging, and module resolution): …
  • Corresponding HTML AAM & ARIA in HTML issues & PRs:
  • MDN issue is filed: …
  • The top of this comment includes a clear commit message to use.

(See WHATWG Working Mode: Changes for more details.)

This change ensures that the new playback position on the valid media timeline is observable immediately following an assignment to a media element's currentTime attribute. It will also be immediately observable after calling fastSeek().

Fixes whatwg#11773
@annevk annevk requested a review from a team October 15, 2025 12:42
The existing steps cause a seek to the end of the media resource while
paused to seek to the start immediately after. This differs from
implementations in Chrome, Firefox and Safari.

Fixes whatwg#11774
Before this change, allowing playback to end, then subsequently setting the loop attribute to true, would result in the ended attribute being false, and playback not restarting when the play steps are run.

Fixes whatwg#11775
@Zaggy1024 Zaggy1024 force-pushed the media-element-fixes branch from 54fe603 to efca938 Compare October 15, 2025 18:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant