Skip to content

html: Track the script/UA initiated media seek request#40981

Merged
mrobinson merged 1 commit intoservo:mainfrom
tharkum:html-media-track-seek-request
Dec 2, 2025
Merged

html: Track the script/UA initiated media seek request#40981
mrobinson merged 1 commit intoservo:mainfrom
tharkum:html-media-track-seek-request

Conversation

@tharkum
Copy link
Copy Markdown
Contributor

@tharkum tharkum commented Dec 1, 2025

The low-level media seek request could be initiated by script (DOM method call or setting of an IDL attribute), by the user agent (seeking data) or by the media engine itself (e.g. gst_play_set_rate()).
And to distinguish between them we will use the latest seek position (in seconds) to be able abort processing the seek algorithm steps (13-17) for a seek request initiated by the media engine.

See https://html.spec.whatwg.org/multipage/#dom-media-seek

If the seeking is in progress, any callback which affects the current playback position (position changed, end of the playback) shouldn't be processed (event marshalling over IPC router is non-state conditional).

Testing: Regression in the following test causes by gstreamer issue when the gst_play_set_rate() overrides the latest seek requested position unconditionally and the user agent receives the seek completion event with the unexpected seek position (0.5+ instead of 0.0).

  • html/semantics/embedded-content/media-elements/preserves-pitch.html

See https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4762

Fixes: #37057

@tharkum tharkum added the T-linux-wpt Do a try run of the WPT label Dec 1, 2025
@github-actions github-actions bot removed the T-linux-wpt Do a try run of the WPT label Dec 1, 2025
@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 1, 2025

🔨 Triggering try run (#19822168393) for Linux (WPT)

@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 1, 2025

Test results for linux-wpt from try job (#19822168393):

Flaky unexpected result (35)
  • TIMEOUT /FileAPI/url/url-in-tags-revoke.window.html (#19978)
    • TIMEOUT [expected PASS] subtest: Fetching a blob URL immediately before revoking it works in <script> tags.

      Test timed out
      

  • OK /IndexedDB/idbfactory_open.any.html
    • FAIL [expected PASS] subtest: Calling open() with version argument 1.5 should not throw.

      assert_equals: version expected 1 but got 9007199254740991
      

  • PASS [expected FAIL] /_mozilla/css/linear_gradients_reverse_a.html
  • OK /_mozilla/css/offset_properties_inline.html (#40543)
    • FAIL [expected PASS] subtest: offsetTop

      assert_equals: offsetTop of #inline-1 should be 0. expected 0 but got -1
      

    • FAIL [expected PASS] subtest: offsetLeft

      assert_equals: offsetLeft of #inline-2 should be 40. expected 40 but got 25
      

  • OK /_mozilla/webxr/create_session.https.html
    • FAIL [expected PASS] subtest: create_session

      can't access property "simulateDeviceConnection", navigator.xr.test is undefined
      

  • ERROR [expected TIMEOUT] /_mozilla/webxr/sessionavailable.https.html
  • CRASH [expected ERROR] /_webgl/conformance/extensions/oes-texture-float-with-canvas.html
  • CRASH [expected OK] /_webgl/conformance2/rendering/out-of-bounds-index-buffers-after-copying.html
  • TIMEOUT /content-security-policy/inheritance/location-reload.html (#38983)
    • FAIL [expected PASS] subtest: location.reload() of empty iframe.

      assert_equals: Image should be blocked by CSP after reload. expected "img blocked" but got "img loaded"
      

  • FAIL [expected PASS] /css/css-backgrounds/background-size-041.html
  • TIMEOUT [expected FAIL] /css/css-content/element-replacement-image-no-src.tentative.html
  • ERROR /fetch/metadata/generated/serviceworker.https.sub.html (#36247)
    • FAIL [expected PASS] subtest: sec-fetch-site - Same origin, no options - registration

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • CRASH [expected OK] /html/anonymous-iframe/embedding.tentative.https.window.html?3-3
  • TIMEOUT [expected CRASH] /html/anonymous-iframe/indexeddb.tentative.https.window.html (#39254)
  • OK /html/browsers/browsing-the-web/navigating-across-documents/005.html (#27062)
    • PASS [expected FAIL] subtest: Link with onclick navigation and href navigation
  • OK /html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/a-click.html (#28697)
    • PASS [expected FAIL] subtest: aElement.click() before the load event must NOT replace
  • TIMEOUT [expected OK] /html/interaction/focus/the-autofocus-attribute/autofocus-dialog.html (#29087)
    • TIMEOUT [expected FAIL] subtest: <dialog>-contained autofocus element gets focused when the dialog is shown

      Test timed out
      

  • TIMEOUT [expected OK] /html/interaction/focus/the-autofocus-attribute/document-with-fragment-nonexistent.html (#28259)
    • TIMEOUT [expected FAIL] subtest: Autofocus elements in top-level browsing context's documents with non-existent fragments should work.

      Test timed out
      

  • OK /html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/allow-scripts-flag-changing-2.html (#39703)
    • FAIL [expected PASS] subtest: Meta refresh of the original iframe is not blocked if moved into a sandboxed iframe

      uncaught exception: Error: assert_unreached: The iframe into which the meta was moved must not refresh Reached unreachable code
      

  • OK /html/semantics/embedded-content/media-elements/playing-the-media-resource/loop-from-ended.tentative.html (#33778)
    • FAIL [expected PASS] subtest: play() with loop set to true after playback ended

      this argument is not a finite floating-point value
      

  • OK /html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-nav-location-assign.html (#32863)
    • FAIL [expected PASS] subtest: Navigating iframe loading='lazy' before it is loaded: location.assign

      uncaught exception: Error: assert_equals: expected "http://web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/support/blank.htm?nav" but got "http://web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/support/blank.htm?src"
      

  • OK /html/semantics/forms/form-submission-0/text-plain.window.html (#28687)
    • FAIL [expected PASS] subtest: text/plain: Basic File test (normal form)

      assert_equals: expected "basic=file-test.txt\r\n" but got ""
      

    • PASS [expected FAIL] subtest: text/plain: 0x00 in name (formdata event)
  • OK /html/semantics/forms/form-submission-0/urlencoded2.window.html (#28687)
    • FAIL [expected PASS] subtest: application/x-www-form-urlencoded: Basic test (formdata event)

      assert_equals: expected "basic=test" but got ""
      

    • FAIL [expected PASS] subtest: application/x-www-form-urlencoded: Basic File test (normal form)

      assert_equals: expected "basic=file-test.txt" but got ""
      

    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: Basic File test (formdata event)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: 0x00 in name (normal form)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: \r\n in name (formdata event)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: single quote in value (formdata event)
    • PASS [expected FAIL] subtest: application/x-www-form-urlencoded: backslash in filename (normal form)
  • OK /html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url.any.worker.html (#33909)
    • FAIL [expected PASS] subtest: Revoking a blob URL immediately after calling import will not fail

      promise_test: Unhandled rejection with value: object "TypeError: Dynamic import failed"
      

  • OK /preload/preload-invalid-resources.html (#39091)
    • PASS [expected FAIL] subtest: Preloading an invalid image (missing) should preload and not re-fetch
  • OK /service-workers/service-worker/fetch-event.https.html (#36234)
    • PASS [expected FAIL] subtest: Service Worker falls back to network in fetch event with POST form
  • CRASH [expected OK] /trusted-types/Element-setAttribute-setAttributeNS-sinks.tentative.html
  • CRASH [expected OK] /trusted-types/eval-csp-no-tt.html
  • OK [expected TIMEOUT] /trusted-types/trusted-types-navigation.html?06-10 (#37920)
    • PASS [expected TIMEOUT] subtest: Navigate a frame via anchor with javascript:-urls w/ default policy in report-only mode.
    • FAIL [expected NOTRUN] subtest: Navigate a window via anchor with javascript:-urls w/ a default policy throwing an exception in enforcing mode.

      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

    • FAIL [expected NOTRUN] subtest: Navigate a window via anchor with javascript:-urls w/ a default policy throwing an exception in report-only mode.

      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

  • CRASH [expected TIMEOUT] /uievents/mouse/cancel-mousedown-in-subframe.html
  • CRASH [expected ERROR] /wasm/webapi/empty-body.any.serviceworker.html
  • CRASH [expected OK] /webaudio/the-audio-api/the-analysernode-interface/test-analyser-output.html
  • TIMEOUT [expected OK] /webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.html (#29053)
    • TIMEOUT [expected PASS] subtest: StorageKey: test 3P about:blank window opened from a 3P iframe

      Test timed out
      

  • OK /webxr/xrSession_features_deviceSupport.https.html (#24357)
    • FAIL [expected PASS] subtest: Immersive XRSession requests with no supported device should reject

      assert_unreached: Should have rejected: undefined Reached unreachable code
      

  • CRASH [expected OK] /workers/Worker-timeout-cancel-order.html
Stable unexpected results that are known to be intermittent (27)
  • OK /FileAPI/url/url-with-fetch.any.html (#21517)
    • FAIL [expected PASS] subtest: Revoke blob URL after calling fetch, fetch should succeed

      promise_test: Unhandled rejection with value: object "TypeError: Network error occurred"
      

  • OK /IndexedDB/idbobjectstore_getAll.any.html (#39276)
    • PASS [expected FAIL] subtest: Get all values with transaction.commit()
  • OK /IndexedDB/idbobjectstore_getAll.any.worker.html (#39400)
    • PASS [expected FAIL] subtest: Get all values with transaction.commit()
  • FAIL [expected PASS] /_mozilla/mozilla/sslfail.html (#10760)
  • TIMEOUT [expected OK] /_mozilla/mozilla/window_resize_event.html (#36741)
    • TIMEOUT [expected PASS] subtest: Popup onresize event fires after resizeTo

      Test timed out
      

  • OK /_webgl/conformance/textures/misc/texture-upload-size.html (#21770)
    • PASS [expected FAIL] subtest: WebGL test #45
    • PASS [expected FAIL] subtest: WebGL test #47
    • PASS [expected FAIL] subtest: WebGL test #49
    • PASS [expected FAIL] subtest: WebGL test #51
    • FAIL [expected PASS] subtest: WebGL test #53

      assert_true: Texture was smaller than the expected size 2x2 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #55

      assert_true: getError expected: INVALID_VALUE. Was NO_ERROR : when calling texSubImage2D with the same texture upload with offset 1, 1 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #57

      assert_true: Texture was smaller than the expected size 2x2 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #59

      assert_true: getError expected: INVALID_VALUE. Was NO_ERROR : when calling texSubImage2D with the same texture upload with offset 1, 1 expected true got false
      

    • PASS [expected FAIL] subtest: WebGL test #61
    • PASS [expected FAIL] subtest: WebGL test #63
    • And 10 more unexpected results...
  • OK /content-security-policy/frame-ancestors/frame-ancestors-path-ignored.window.html (#36468)
    • FAIL [expected PASS] subtest: A 'frame-ancestors' CSP directive with a URL that includes a path should be ignored.

      assert_unreached: The IFrame should have been blocked (or cross-origin). It wasn't. Reached unreachable code
      

  • OK /css/css-cascade/layer-cssom-order-reverse.html (#36094)
    • PASS [expected FAIL] subtest: Delete layer invalidates @font-face
  • OK /css/css-fonts/generic-family-keywords-001.html (#37467)
    • FAIL [expected PASS] subtest: @font-face matching for quoted and unquoted generic(fangsong)

      assert_equals: quoted generic(fangsong) matches  @font-face rule expected 50 but got 30
      

    • FAIL [expected PASS] subtest: @font-face matching for quoted and unquoted generic(khmer-mul)

      assert_equals: quoted generic(khmer-mul) matches  @font-face rule expected 50 but got 30
      

  • OK /css/css-fonts/generic-family-keywords-002.html (#40929)
    • PASS [expected FAIL] subtest: font-family: -webkit-serif treated as <font-family>, not <generic-name>
    • PASS [expected FAIL] subtest: font-family: -webkit-sans-serif treated as <font-family>, not <generic-name>
    • PASS [expected FAIL] subtest: font-family: -webkit-cursive treated as <font-family>, not <generic-name>
    • PASS [expected FAIL] subtest: font-family: -webkit-fantasy treated as <font-family>, not <generic-name>
    • PASS [expected FAIL] subtest: font-family: -webkit-monospace treated as <font-family>, not <generic-name>
    • PASS [expected FAIL] subtest: font-family: -webkit-system-ui treated as <font-family>, not <generic-name>
    • PASS [expected FAIL] subtest: font-family: -webkit-math treated as <font-family>, not <generic-name>
    • FAIL [expected PASS] subtest: font-family: -webkit-generic(fangsong) treated as <font-family>, not <generic-name>

      assert_equals: expected 50 but got 30
      

    • FAIL [expected PASS] subtest: font-family: -webkit-generic(kai) treated as <font-family>, not <generic-name>

      assert_equals: expected 50 but got 30
      

    • FAIL [expected PASS] subtest: font-family: -webkit-generic(khmer-mul) treated as <font-family>, not <generic-name>

      assert_equals: expected 50 but got 30
      

    • And 12 more unexpected results...
  • OK /css/css-fonts/generic-family-keywords-003.html (#38994)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted math (drawing text in a canvas)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted generic(nastaliq) (drawing text in a canvas)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted ui-serif (drawing text in a canvas)
  • OK [expected TIMEOUT] /fetch/api/redirect/redirect-keepalive.https.any.html (#32153)
    • PASS [expected TIMEOUT] subtest: [keepalive][iframe][load] mixed content redirect; setting up
  • OK /fetch/metadata/generated/css-font-face.https.sub.tentative.html (#32732)
    • PASS [expected FAIL] subtest: sec-fetch-mode
    • PASS [expected FAIL] subtest: sec-fetch-dest
    • PASS [expected FAIL] subtest: sec-fetch-user
    • FAIL [expected PASS] subtest: sec-fetch-storage-access - Cross-site

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • OK /fetch/metadata/generated/css-font-face.sub.tentative.html (#34624)
    • FAIL [expected PASS] subtest: sec-fetch-storage-access - Not sent to non-trustworthy same-origin destination

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • FAIL [expected PASS] subtest: sec-fetch-storage-access - Not sent to non-trustworthy same-site destination

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • PASS [expected FAIL] subtest: sec-fetch-storage-access - Not sent to non-trustworthy cross-site destination
  • OK /fetch/metadata/generated/element-img-environment-change.https.sub.html (#30111)
    • FAIL [expected PASS] subtest: sec-fetch-site - Same site, no attributes

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • PASS [expected FAIL] subtest: sec-fetch-site - Same-Origin -> Cross-Site -> Same-Origin redirect, no attributes
    • FAIL [expected PASS] subtest: sec-fetch-site - Same-Origin -> Same-Site -> Same-Origin redirect, no attributes

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • FAIL [expected PASS] subtest: sec-fetch-site - Same-Origin -> Same Origin, no attributes

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • PASS [expected FAIL] subtest: sec-fetch-site - Same-Origin -> Same-Site, no attributes
    • FAIL [expected PASS] subtest: sec-fetch-site - Same-Site -> Same Origin, no attributes

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • PASS [expected FAIL] subtest: sec-fetch-site - Same-Site -> Same-Site, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-site - Same-Site -> Cross-Site, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-mode - attributes: crossorigin
    • FAIL [expected PASS] subtest: sec-fetch-mode - attributes: crossorigin=anonymous

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • And 2 more unexpected results...
  • OK /fetch/metadata/generated/element-img-environment-change.sub.html (#30111)
    • PASS [expected FAIL] subtest: sec-fetch-site - Not sent to non-trustworthy same-site destination, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-mode - Not sent to non-trustworthy cross-site destination, no attributes
    • FAIL [expected PASS] subtest: sec-fetch-user - Not sent to non-trustworthy cross-site destination, no attributes

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • FAIL [expected PASS] subtest: sec-fetch-site - HTTPS downgrade-upgrade, no attributes

      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • ERROR [expected OK] /focus/focus-event-after-switching-iframes.sub.html (#40368)
  • OK /html/browsers/history/the-history-interface/traverse_the_history_2.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • OK /html/browsers/history/the-history-interface/traverse_the_history_5.html (#21383)
    • FAIL [expected PASS] subtest: Multiple history traversals, last would be aborted

      assert_array_equals: Pages opened during history navigation expected property 1 to be 5 but got 3 (expected array [6, 5] got [6, 3])
      

  • OK /html/interaction/focus/the-autofocus-attribute/supported-elements.html (#24145)
    • PASS [expected NOTRUN] subtest: Non-HTMLElement should not support autofocus
  • TIMEOUT [expected OK] /html/interaction/focus/the-autofocus-attribute/update-the-rendering.html (#24145)
    • TIMEOUT [expected FAIL] subtest: "Flush autofocus candidates" should be happen before a scroll event and animation frame callbacks

      Test timed out
      

  • OK /html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url.any.html (#33948)
    • FAIL [expected PASS] subtest: Revoking a blob URL immediately after calling import will not fail

      promise_test: Unhandled rejection with value: object "TypeError: Dynamic import failed"
      

  • OK /navigation-timing/test-navigation-type-reload.html (#33334)
    • PASS [expected FAIL] subtest: Reload domComplete > Original domComplete
    • PASS [expected FAIL] subtest: Reload domContentLoadedEventStart > Original domContentLoadedEventStart
    • PASS [expected FAIL] subtest: Reload domInteractive > Original domInteractive
    • PASS [expected FAIL] subtest: Reload fetchStart > Original fetchStart
    • PASS [expected FAIL] subtest: Reload loadEventEnd > Original loadEventEnd
    • PASS [expected FAIL] subtest: Reload loadEventStart > Original loadEventStart
  • OK /preload/preload-error.sub.html (#37177)
    • FAIL [expected PASS] subtest: success (fetch): main

      assert_greater_than: http://web-platform.test:8000/preload/resources/dummy.xml?label=fetch should be loaded expected a number greater than 0 but got 0
      

    • PASS [expected FAIL] subtest: 404 (fetch): main
  • OK /resource-timing/buffer-full-add-then-clear.html (#40819)
    • PASS [expected FAIL] subtest: Test that if the buffer is cleared after entries were added to the secondary buffer, those entries make it into the primary one
  • OK [expected TIMEOUT] /trusted-types/trusted-types-navigation.html?01-05 (#38975)
    • PASS [expected TIMEOUT] subtest: Navigate a window via anchor with javascript:-urls in report-only mode.
    • PASS [expected NOTRUN] subtest: Navigate a window via anchor with javascript:-urls w/ default policy in report-only mode.
    • PASS [expected NOTRUN] subtest: Navigate a frame via anchor with javascript:-urls in enforcing mode.
  • OK [expected ERROR] /webxr/render_state_update.https.html (#27535)

@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 1, 2025

✨ Try run (#19822168393) succeeded.

@tharkum tharkum marked this pull request as ready for review December 1, 2025 12:58
@tharkum tharkum requested a review from gterzian as a code owner December 1, 2025 12:58
@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Dec 1, 2025
@tharkum tharkum requested review from jdm and mrobinson December 1, 2025 13:28
Copy link
Copy Markdown
Member

@mrobinson mrobinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, my main concern here is that this is a tricky issue and I think we should have a bit of a rustdoc explanation of it. This GStreamer behavior is extremely non-obvious.

volume: Cell<f64>,
/// <https://html.spec.whatwg.org/multipage/#dom-media-seeking>
seeking: Cell<bool>,
current_seek_position: Cell<f64>,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind adding rustdoc to this field? For instance what are the units here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Units of measurement are seconds.

Comment on lines +2017 to +2018
if let Err(err) = player.lock().unwrap().seek(time) {
error!("Seek error {:?}", err);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
if let Err(err) = player.lock().unwrap().seek(time) {
error!("Seek error {:?}", err);
if let Err(error) = player.lock().unwrap().seek(time) {
error!("Seek error {error:?}");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

// than the time of the end of the media resource, then the user agent must also seek to the
// time of the end of the media resource.
if self.current_playback_position.get() > duration {
self.seek(duration, /* approximate_for_speed */ false);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Please put the name of the variable after the value.

Copy link
Copy Markdown
Contributor Author

@tharkum tharkum Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other seek calls also use /* approximate_for_speed */ value ordering, so I guess need to change everywhere or do nothing or change only here... Suggestions?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was think just this callsite,
but this is a very minor issue.

@@ -548,6 +548,7 @@ pub(crate) struct HTMLMediaElement {
volume: Cell<f64>,
/// <https://html.spec.whatwg.org/multipage/#dom-media-seeking>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe clarify here what kinds of situations that seeking happens where this is also false? I understand that this is when triggered by the media engine. I think it's worth a rustdoc explanation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. I will add rustdoc for seeking and current_seek_position as well

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@servo-highfive servo-highfive added S-needs-code-changes Changes have not yet been made that were requested by a reviewer. and removed S-awaiting-review There is new code that needs to be reviewed. labels Dec 1, 2025
The low-level media `seek` request could be initiated by script
(DOM method call or setting of an IDL attribute), by the user agent
(seeking data) or by the media engine itself (e.g. gst_play_set_rate()).
And to distinguish between them we will use the latest seek position
(in seconds) to be able abort processing the `seek` algorithm
steps (13-17) for a `seek` request initiated by the media engine.

See https://html.spec.whatwg.org/multipage/#dom-media-seek

If the `seeking` is in progress, any callback which affects the current
playback position (`position changed`, `end of the playback`) shouldn't
be processed (event marshalling over IPC router is non-state conditional).

Testing: Regression in the following test causes by gstreamer issue when
the `gst_play_set_rate()` overrides the latest seek requested position
unconditionally and the user agent receives the `seek completion` event
with the unexpected seek position (0.5+ instead of 0.0)
- html/semantics/embedded-content/media-elements/preserves-pitch.html

See https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4762

Fixes: servo#37057

Signed-off-by: Andrei Volykhin <[email protected]>
@tharkum tharkum force-pushed the html-media-track-seek-request branch from 16494f1 to 31bc214 Compare December 2, 2025 05:52
@servo-highfive servo-highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-needs-code-changes Changes have not yet been made that were requested by a reviewer. labels Dec 2, 2025
@tharkum tharkum changed the title html: Track the script initiated media seeking state html: Track the script/UA initiated media seek request Dec 2, 2025
@tharkum tharkum requested a review from mrobinson December 2, 2025 05:55
@servo-highfive servo-highfive removed the S-awaiting-review There is new code that needs to be reviewed. label Dec 2, 2025
@mrobinson mrobinson added this pull request to the merge queue Dec 2, 2025
@servo-highfive servo-highfive added the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Dec 2, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to no response for status checks Dec 2, 2025
@servo-highfive servo-highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Dec 2, 2025
@mrobinson mrobinson added this pull request to the merge queue Dec 2, 2025
@servo-highfive servo-highfive added the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Dec 2, 2025
Merged via the queue into servo:main with commit d539ac8 Dec 2, 2025
37 checks passed
@servo-highfive servo-highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Dec 2, 2025
@tharkum tharkum deleted the html-media-track-seek-request branch December 2, 2025 13:18
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.

Media: <video> emit "seeked" event after the video is loaded when no seek is performed.

3 participants