aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/htmlmediaelement.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/htmlmediaelement.rs')
-rw-r--r--components/script/dom/htmlmediaelement.rs53
1 files changed, 46 insertions, 7 deletions
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index d1baab7d6d2..8ddef6d33cb 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -29,6 +29,7 @@ use net_traits::{
ResourceTimingType,
};
use pixels::Image;
+use script_bindings::codegen::GenericBindings::TimeRangesBinding::TimeRangesMethods;
use script_bindings::codegen::InheritTypes::{
ElementTypeId, HTMLElementTypeId, HTMLMediaElementTypeId, NodeTypeId,
};
@@ -1277,15 +1278,40 @@ impl HTMLMediaElement {
let time = f64::max(time, 0.);
// Step 8.
- // XXX(ferjm) seekable attribute: we need to get the information about
- // what's been decoded and buffered so far from servo-media
- // and add the seekable attribute as a TimeRange.
- if let Some(ref current_fetch_context) = *self.current_fetch_context.borrow() {
- if !current_fetch_context.is_seekable() {
- self.seeking.set(false);
- return;
+ let seekable = self.Seekable();
+ if seekable.Length() == 0 {
+ self.seeking.set(false);
+ return;
+ }
+ let mut nearest_seekable_position = 0.0;
+ let mut in_seekable_range = false;
+ let mut nearest_seekable_distance = f64::MAX;
+ for i in 0..seekable.Length() {
+ let start = seekable.Start(i).unwrap().abs();
+ let end = seekable.End(i).unwrap().abs();
+ if time >= start && time <= end {
+ nearest_seekable_position = time;
+ in_seekable_range = true;
+ break;
+ } else if time < start {
+ let distance = start - time;
+ if distance < nearest_seekable_distance {
+ nearest_seekable_distance = distance;
+ nearest_seekable_position = start;
+ }
+ } else {
+ let distance = time - end;
+ if distance < nearest_seekable_distance {
+ nearest_seekable_distance = distance;
+ nearest_seekable_position = end;
+ }
}
}
+ let time = if in_seekable_range {
+ time
+ } else {
+ nearest_seekable_position
+ };
// Step 9.
// servo-media with gstreamer does not support inaccurate seeking for now.
@@ -2402,6 +2428,19 @@ impl HTMLMediaElementMethods<crate::DomTypeHolder> for HTMLMediaElement {
)
}
+ // https://html.spec.whatwg.org/multipage/#dom-media-seekable
+ fn Seekable(&self) -> DomRoot<TimeRanges> {
+ let mut seekable = TimeRangesContainer::default();
+ if let Some(ref player) = *self.player.borrow() {
+ if let Ok(ranges) = player.lock().unwrap().seekable() {
+ for range in ranges {
+ let _ = seekable.add(range.start, range.end);
+ }
+ }
+ }
+ TimeRanges::new(self.global().as_window(), seekable, CanGc::note())
+ }
+
// https://html.spec.whatwg.org/multipage/#dom-media-buffered
fn Buffered(&self) -> DomRoot<TimeRanges> {
let mut buffered = TimeRangesContainer::default();