Skip to content

Commit f5e6eb2

Browse files
authored
media element: support seekable attribute (#36541)
support seekable attribute in `htmlmediaelement`, modify `seek` algorithm to use `seekable` attribute. related [specs](https://html.spec.whatwg.org/multipage/media.html#dom-media-seekable) Testing: Run WPT Test Fixes: #22297 Will wait for servo/media#435 before turning this to ready for review. cc @jdm @xiaochengh Signed-off-by: rayguo17 <[email protected]>
1 parent 15199ba commit f5e6eb2

File tree

5 files changed

+59
-39
lines changed

5 files changed

+59
-39
lines changed

Cargo.lock

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/script/dom/htmlmediaelement.rs

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use net_traits::{
2929
ResourceTimingType,
3030
};
3131
use pixels::Image;
32+
use script_bindings::codegen::GenericBindings::TimeRangesBinding::TimeRangesMethods;
3233
use script_bindings::codegen::InheritTypes::{
3334
ElementTypeId, HTMLElementTypeId, HTMLMediaElementTypeId, NodeTypeId,
3435
};
@@ -1277,15 +1278,40 @@ impl HTMLMediaElement {
12771278
let time = f64::max(time, 0.);
12781279

12791280
// Step 8.
1280-
// XXX(ferjm) seekable attribute: we need to get the information about
1281-
// what's been decoded and buffered so far from servo-media
1282-
// and add the seekable attribute as a TimeRange.
1283-
if let Some(ref current_fetch_context) = *self.current_fetch_context.borrow() {
1284-
if !current_fetch_context.is_seekable() {
1285-
self.seeking.set(false);
1286-
return;
1281+
let seekable = self.Seekable();
1282+
if seekable.Length() == 0 {
1283+
self.seeking.set(false);
1284+
return;
1285+
}
1286+
let mut nearest_seekable_position = 0.0;
1287+
let mut in_seekable_range = false;
1288+
let mut nearest_seekable_distance = f64::MAX;
1289+
for i in 0..seekable.Length() {
1290+
let start = seekable.Start(i).unwrap().abs();
1291+
let end = seekable.End(i).unwrap().abs();
1292+
if time >= start && time <= end {
1293+
nearest_seekable_position = time;
1294+
in_seekable_range = true;
1295+
break;
1296+
} else if time < start {
1297+
let distance = start - time;
1298+
if distance < nearest_seekable_distance {
1299+
nearest_seekable_distance = distance;
1300+
nearest_seekable_position = start;
1301+
}
1302+
} else {
1303+
let distance = time - end;
1304+
if distance < nearest_seekable_distance {
1305+
nearest_seekable_distance = distance;
1306+
nearest_seekable_position = end;
1307+
}
12871308
}
12881309
}
1310+
let time = if in_seekable_range {
1311+
time
1312+
} else {
1313+
nearest_seekable_position
1314+
};
12891315

12901316
// Step 9.
12911317
// servo-media with gstreamer does not support inaccurate seeking for now.
@@ -2402,6 +2428,19 @@ impl HTMLMediaElementMethods<crate::DomTypeHolder> for HTMLMediaElement {
24022428
)
24032429
}
24042430

2431+
// https://html.spec.whatwg.org/multipage/#dom-media-seekable
2432+
fn Seekable(&self) -> DomRoot<TimeRanges> {
2433+
let mut seekable = TimeRangesContainer::default();
2434+
if let Some(ref player) = *self.player.borrow() {
2435+
if let Ok(ranges) = player.lock().unwrap().seekable() {
2436+
for range in ranges {
2437+
let _ = seekable.add(range.start, range.end);
2438+
}
2439+
}
2440+
}
2441+
TimeRanges::new(self.global().as_window(), seekable, CanGc::note())
2442+
}
2443+
24052444
// https://html.spec.whatwg.org/multipage/#dom-media-buffered
24062445
fn Buffered(&self) -> DomRoot<TimeRanges> {
24072446
let mut buffered = TimeRangesContainer::default();

components/script_bindings/webidls/HTMLMediaElement.webidl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ interface HTMLMediaElement : HTMLElement {
4545
[Throws] attribute double defaultPlaybackRate;
4646
[Throws] attribute double playbackRate;
4747
readonly attribute TimeRanges played;
48-
// readonly attribute TimeRanges seekable;
48+
readonly attribute TimeRanges seekable;
4949
readonly attribute boolean ended;
5050
[CEReactions] attribute boolean autoplay;
5151
[CEReactions] attribute boolean loop;

tests/wpt/meta/html/dom/idlharness.https.html.ini

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2322,9 +2322,6 @@
23222322
[HTMLSelectElement interface: document.createElement("select") must inherit property "autocomplete" with the proper type]
23232323
expected: FAIL
23242324

2325-
[HTMLMediaElement interface: attribute seekable]
2326-
expected: FAIL
2327-
23282325
[HTMLTableSectionElement interface: attribute align]
23292326
expected: FAIL
23302327

@@ -6487,36 +6484,24 @@
64876484
[HTMLMediaElement interface: document.createElement("video") must inherit property "preservesPitch" with the proper type]
64886485
expected: FAIL
64896486

6490-
[HTMLMediaElement interface: document.createElement("video") must inherit property "seekable" with the proper type]
6491-
expected: FAIL
6492-
64936487
[HTMLMediaElement interface: document.createElement("audio") must inherit property "getStartDate()" with the proper type]
64946488
expected: FAIL
64956489

64966490
[HTMLMediaElement interface: document.createElement("audio") must inherit property "preservesPitch" with the proper type]
64976491
expected: FAIL
64986492

6499-
[HTMLMediaElement interface: document.createElement("audio") must inherit property "seekable" with the proper type]
6500-
expected: FAIL
6501-
65026493
[HTMLMediaElement interface: new Audio() must inherit property "getStartDate()" with the proper type]
65036494
expected: FAIL
65046495

65056496
[HTMLMediaElement interface: new Audio() must inherit property "preservesPitch" with the proper type]
65066497
expected: FAIL
65076498

6508-
[HTMLMediaElement interface: new Audio() must inherit property "seekable" with the proper type]
6509-
expected: FAIL
6510-
65116499
[HTMLMediaElement interface: operation getStartDate()]
65126500
expected: FAIL
65136501

65146502
[HTMLMediaElement interface: attribute preservesPitch]
65156503
expected: FAIL
65166504

6517-
[HTMLMediaElement interface: attribute seekable]
6518-
expected: FAIL
6519-
65206505
[HTMLMapElement interface: attribute name]
65216506
expected: FAIL
65226507

tests/wpt/meta/html/semantics/embedded-content/media-elements/seeking/seek-to-currentTime.html.ini

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)