mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
HTMLMediaElement seeking
This commit is contained in:
parent
2db141fb8b
commit
75407822bc
5 changed files with 124 additions and 19 deletions
24
Cargo.lock
generated
24
Cargo.lock
generated
|
@ -3025,7 +3025,7 @@ dependencies = [
|
|||
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo-media 0.1.0 (git+https://github.com/servo/media)",
|
||||
"servo-media 0.1.0 (git+https://github.com/ferjm/media?branch=seek)",
|
||||
"servo_allocator 0.0.1",
|
||||
"servo_arc 0.1.1",
|
||||
"servo_atoms 0.0.1",
|
||||
|
@ -3261,9 +3261,9 @@ name = "servo-media"
|
|||
version = "0.1.0"
|
||||
source = "git+https://github.com/servo/media#3b347d7b0431c58611e2bd7b22d34062b64cda26"
|
||||
dependencies = [
|
||||
"servo-media-audio 0.1.0 (git+https://github.com/servo/media)",
|
||||
"servo-media-gstreamer 0.1.0 (git+https://github.com/servo/media)",
|
||||
"servo-media-player 0.1.0 (git+https://github.com/servo/media)",
|
||||
"servo-media-audio 0.1.0 (git+https://github.com/ferjm/media?branch=seek)",
|
||||
"servo-media-gstreamer 0.1.0 (git+https://github.com/ferjm/media?branch=seek)",
|
||||
"servo-media-player 0.1.0 (git+https://github.com/ferjm/media?branch=seek)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3279,7 +3279,7 @@ dependencies = [
|
|||
"petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo_media_derive 0.1.0 (git+https://github.com/servo/media)",
|
||||
"servo_media_derive 0.1.0 (git+https://github.com/ferjm/media?branch=seek)",
|
||||
"smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -3296,8 +3296,8 @@ dependencies = [
|
|||
"gstreamer-player 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo-media-audio 0.1.0 (git+https://github.com/servo/media)",
|
||||
"servo-media-player 0.1.0 (git+https://github.com/servo/media)",
|
||||
"servo-media-audio 0.1.0 (git+https://github.com/ferjm/media?branch=seek)",
|
||||
"servo-media-player 0.1.0 (git+https://github.com/ferjm/media?branch=seek)",
|
||||
"zip 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -4586,12 +4586,12 @@ dependencies = [
|
|||
"checksum servo-fontconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "93f799b649b4a2bf362398910eca35240704c7e765e780349b2bb1070d892262"
|
||||
"checksum servo-fontconfig-sys 4.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b46d201addcfbd25c1798ad1281d98c40743824e0b0f1e611bd3d5d0d31a7b8d"
|
||||
"checksum servo-freetype-sys 4.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d00ab791f66cd2ec58e72c91b6076cee20fac560463aa871404eb31dfc9c4ff"
|
||||
"checksum servo-media 0.1.0 (git+https://github.com/servo/media)" = "<none>"
|
||||
"checksum servo-media-audio 0.1.0 (git+https://github.com/servo/media)" = "<none>"
|
||||
"checksum servo-media-gstreamer 0.1.0 (git+https://github.com/servo/media)" = "<none>"
|
||||
"checksum servo-media-player 0.1.0 (git+https://github.com/servo/media)" = "<none>"
|
||||
"checksum servo-media 0.1.0 (git+https://github.com/ferjm/media?branch=seek)" = "<none>"
|
||||
"checksum servo-media-audio 0.1.0 (git+https://github.com/ferjm/media?branch=seek)" = "<none>"
|
||||
"checksum servo-media-gstreamer 0.1.0 (git+https://github.com/ferjm/media?branch=seek)" = "<none>"
|
||||
"checksum servo-media-player 0.1.0 (git+https://github.com/ferjm/media?branch=seek)" = "<none>"
|
||||
"checksum servo-skia 0.30000019.1 (registry+https://github.com/rust-lang/crates.io-index)" = "82eddddcf9512dd7c60eccdb486e60e5bd4930afaa4da2d7d4afdff75950fb88"
|
||||
"checksum servo_media_derive 0.1.0 (git+https://github.com/servo/media)" = "<none>"
|
||||
"checksum servo_media_derive 0.1.0 (git+https://github.com/ferjm/media?branch=seek)" = "<none>"
|
||||
"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c"
|
||||
"checksum shared_library 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8254bf098ce4d8d7cc7cc6de438c5488adc5297e5b7ffef88816c0a91bd289c1"
|
||||
"checksum sig 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c6649e43c1a1e68d29ed56d0dc3b5b6cf3b901da77cf107c4066b9e3da036df5"
|
||||
|
|
|
@ -22,3 +22,5 @@ opt-level = 3
|
|||
#
|
||||
# [patch."https://github.com/servo/<repository>"]
|
||||
# <crate> = { path = "/path/to/local/checkout" }
|
||||
[patch."https://github.com/servo/media"]
|
||||
servo-media = { git = "https://github.com/ferjm/media", branch = "seek" }
|
||||
|
|
|
@ -74,6 +74,8 @@ scan
|
|||
screen
|
||||
scroll-position
|
||||
search
|
||||
seeked
|
||||
seeking
|
||||
select
|
||||
serif
|
||||
statechange
|
||||
|
|
|
@ -170,10 +170,12 @@ pub struct HTMLMediaElement {
|
|||
show_poster: Cell<bool>,
|
||||
/// https://html.spec.whatwg.org/multipage/#dom-media-duration
|
||||
duration: Cell<f64>,
|
||||
/// https://html.spec.whatwg.org/multipage/media.html#official-playback-position
|
||||
/// https://html.spec.whatwg.org/multipage/#official-playback-position
|
||||
playback_position: Cell<f64>,
|
||||
/// https://html.spec.whatwg.org/multipage/media.html#default-playback-start-position
|
||||
/// https://html.spec.whatwg.org/multipage/#default-playback-start-position
|
||||
default_playback_start_position: Cell<f64>,
|
||||
/// https://html.spec.whatwg.org/multipage/#dom-media-seeking
|
||||
seeking: Cell<bool>,
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-media-networkstate>
|
||||
|
@ -223,6 +225,7 @@ impl HTMLMediaElement {
|
|||
duration: Cell::new(f64::NAN),
|
||||
playback_position: Cell::new(0.),
|
||||
default_playback_start_position: Cell::new(0.),
|
||||
seeking: Cell::new(false),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -969,8 +972,69 @@ impl HTMLMediaElement {
|
|||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-media-seek
|
||||
fn seek(&self, _time: f64, _approximate_for_speed: bool) {
|
||||
// XXX
|
||||
fn seek(&self, time: f64, approximate_for_speed: bool) {
|
||||
// Step 1.
|
||||
self.show_poster.set(false);
|
||||
|
||||
// Step 2.
|
||||
if self.ready_state.get() == ReadyState::HaveNothing {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 3.
|
||||
if self.seeking.get() {
|
||||
// This will cancel only the sync part of the seek algorithm.
|
||||
self.generation_id.set(self.generation_id.get() + 1);
|
||||
}
|
||||
|
||||
// Step 4.
|
||||
// The flag will be cleared when the media engine tells us the seek was done.
|
||||
self.seeking.set(true);
|
||||
|
||||
// Step 5.
|
||||
// XXX(ferjm) The rest of the steps should be run in parallel, so seeking cancelation
|
||||
// can be done properly. No other browser does it yet anyway.
|
||||
|
||||
// Step 6.
|
||||
let time = f64::min(time, self.Duration());
|
||||
|
||||
// Step 7.
|
||||
let time = f64::max(time, 0.);
|
||||
|
||||
// Step 8.
|
||||
// XXX(ferjm) seekable attribute.
|
||||
|
||||
// Step 9.
|
||||
let accurate = !approximate_for_speed;
|
||||
|
||||
// Step 10.
|
||||
let window = window_from_node(self);
|
||||
let task_source = window.media_element_task_source();
|
||||
task_source.queue_simple_event(self.upcast(), atom!("seeking"), &window);
|
||||
|
||||
// Step 11.
|
||||
// XXX self.player.seek(time, accurate);
|
||||
|
||||
// The rest of the steps are handled when the media engine signals a
|
||||
// ready state change or otherwise satisfies seek completion and signals
|
||||
// a position change.
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-media-seek
|
||||
fn seek_sync(&self) {
|
||||
// Step 14.
|
||||
self.seeking.set(false);
|
||||
|
||||
// Step 15.
|
||||
self.time_marches_on();
|
||||
|
||||
// Step 16.
|
||||
let window = window_from_node(self);
|
||||
let task_source = window.media_element_task_source();
|
||||
task_source.queue_simple_event(self.upcast(), atom!("timeupdate"), &window);
|
||||
|
||||
// Step 17.
|
||||
task_source.queue_simple_event(self.upcast(), atom!("seeked"), &window);
|
||||
}
|
||||
|
||||
fn setup_media_player(&self) -> Result<(), ServoMediaError> {
|
||||
|
@ -1043,7 +1107,10 @@ impl HTMLMediaElement {
|
|||
|
||||
// Step 8.
|
||||
if self.default_playback_start_position.get() > 0. {
|
||||
self.seek(self.default_playback_start_position.get(), /* approximate_for_speed*/ false);
|
||||
self.seek(
|
||||
self.default_playback_start_position.get(),
|
||||
/* approximate_for_speed*/ false,
|
||||
);
|
||||
_jumped = true;
|
||||
}
|
||||
|
||||
|
@ -1084,6 +1151,20 @@ impl HTMLMediaElement {
|
|||
PlayerEvent::FrameUpdated => {
|
||||
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
|
||||
},
|
||||
PlayerEvent::SeekData(_) => {
|
||||
// XXX byte-range request
|
||||
},
|
||||
PlayerEvent::SeekDone(_) => {
|
||||
// Continuation of
|
||||
// https://html.spec.whatwg.org/multipage/#dom-media-seek
|
||||
|
||||
// Step 13.
|
||||
let task = MediaElementMicrotask::SeekedTask {
|
||||
elem: DomRoot::from_ref(self),
|
||||
generation_id: self.generation_id.get(),
|
||||
};
|
||||
ScriptThread::await_stable_state(Microtask::MediaElement(task));
|
||||
},
|
||||
PlayerEvent::Error => {
|
||||
self.error.set(Some(&*MediaError::new(
|
||||
&*window_from_node(self),
|
||||
|
@ -1206,6 +1287,14 @@ impl HTMLMediaElementMethods for HTMLMediaElement {
|
|||
self.seek(*time, /* approximate_for_speed */ false);
|
||||
}
|
||||
}
|
||||
|
||||
fn Seeking(&self) -> bool {
|
||||
self.seeking.get()
|
||||
}
|
||||
|
||||
fn FastSeek(&self, time: Finite<f64>) {
|
||||
self.seek(*time, /* approximat_for_speed */ true);
|
||||
}
|
||||
}
|
||||
|
||||
impl VirtualMethods for HTMLMediaElement {
|
||||
|
@ -1263,6 +1352,10 @@ pub enum MediaElementMicrotask {
|
|||
PauseIfNotInDocumentTask {
|
||||
elem: DomRoot<HTMLMediaElement>,
|
||||
},
|
||||
SeekedTask {
|
||||
elem: DomRoot<HTMLMediaElement>,
|
||||
generation_id: u32,
|
||||
},
|
||||
}
|
||||
|
||||
impl MicrotaskRunnable for MediaElementMicrotask {
|
||||
|
@ -1282,6 +1375,14 @@ impl MicrotaskRunnable for MediaElementMicrotask {
|
|||
elem.internal_pause_steps();
|
||||
}
|
||||
},
|
||||
&MediaElementMicrotask::SeekedTask {
|
||||
ref elem,
|
||||
generation_id,
|
||||
} => {
|
||||
if generation_id == elem.generation_id.get() {
|
||||
elem.seek_sync();
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,11 +34,11 @@ interface HTMLMediaElement : HTMLElement {
|
|||
const unsigned short HAVE_FUTURE_DATA = 3;
|
||||
const unsigned short HAVE_ENOUGH_DATA = 4;
|
||||
readonly attribute unsigned short readyState;
|
||||
// readonly attribute boolean seeking;
|
||||
readonly attribute boolean seeking;
|
||||
|
||||
// playback state
|
||||
attribute double currentTime;
|
||||
// void fastSeek(double time);
|
||||
void fastSeek(double time);
|
||||
readonly attribute unrestricted double duration;
|
||||
// Date getStartDate();
|
||||
readonly attribute boolean paused;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue