diff options
Diffstat (limited to 'components/script/dom/htmlmediaelement.rs')
-rw-r--r-- | components/script/dom/htmlmediaelement.rs | 53 |
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(); |