mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Implement play, pause, paused, and autoplay APIs.
This commit is contained in:
parent
5960fbe604
commit
e3db11fd8b
20 changed files with 118 additions and 399 deletions
|
@ -162,6 +162,8 @@ pub struct HTMLMediaElement {
|
|||
generation_id: Cell<u32>,
|
||||
first_data_load: Cell<bool>,
|
||||
error: MutNullableHeap<JS<MediaError>>,
|
||||
paused: Cell<bool>,
|
||||
autoplaying: Cell<bool>,
|
||||
}
|
||||
|
||||
impl HTMLMediaElement {
|
||||
|
@ -177,6 +179,8 @@ impl HTMLMediaElement {
|
|||
generation_id: Cell::new(0),
|
||||
first_data_load: Cell::new(true),
|
||||
error: Default::default(),
|
||||
paused: Cell::new(true),
|
||||
autoplaying: Cell::new(true),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,6 +189,28 @@ impl HTMLMediaElement {
|
|||
&self.htmlelement
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#playing-the-media-resource:internal-pause-steps
|
||||
fn internal_pause_steps(&self) {
|
||||
// Step 1
|
||||
self.autoplaying.set(false);
|
||||
|
||||
// Step 2
|
||||
if !self.Paused() {
|
||||
// 2.1
|
||||
self.paused.set(true);
|
||||
|
||||
// 2.2
|
||||
self.queue_fire_simple_event("timeupdate");
|
||||
|
||||
// 2.3
|
||||
self.queue_fire_simple_event("pause");
|
||||
|
||||
// TODO 2.4 (official playback position)
|
||||
}
|
||||
|
||||
// TODO step 3 (media controller)
|
||||
}
|
||||
|
||||
fn queue_fire_simple_event(&self, type_: &'static str) {
|
||||
let win = window_from_node(self);
|
||||
let task = FireSimpleEventTask::new(self, type_);
|
||||
|
@ -260,11 +286,19 @@ impl HTMLMediaElement {
|
|||
if old_ready_state <= HAVE_CURRENT_DATA {
|
||||
self.queue_fire_simple_event("canplay");
|
||||
|
||||
//TODO: check paused state
|
||||
self.queue_fire_simple_event("playing");
|
||||
if !self.Paused() {
|
||||
self.queue_fire_simple_event("playing");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: autoplay-related logic
|
||||
if self.autoplaying.get() &&
|
||||
self.Paused() &&
|
||||
self.Autoplay() {
|
||||
self.paused.set(false);
|
||||
// TODO: show poster
|
||||
self.queue_fire_simple_event("play");
|
||||
self.queue_fire_simple_event("playing");
|
||||
}
|
||||
|
||||
self.queue_fire_simple_event("canplaythrough");
|
||||
}
|
||||
|
@ -274,7 +308,7 @@ impl HTMLMediaElement {
|
|||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#concept-media-load-algorithm
|
||||
fn invoke_resource_selection_algorithm(&self, base_url: Url) {
|
||||
fn invoke_resource_selection_algorithm(&self) {
|
||||
// Step 1
|
||||
self.network_state.set(NETWORK_NO_SOURCE);
|
||||
|
||||
|
@ -282,7 +316,8 @@ impl HTMLMediaElement {
|
|||
// TODO step 3 (delay load event)
|
||||
|
||||
// Step 4
|
||||
ScriptThread::await_stable_state(ResourceSelectionTask::new(self, base_url));
|
||||
let doc = document_from_node(self);
|
||||
ScriptThread::await_stable_state(ResourceSelectionTask::new(self, doc.base_url()));
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#concept-media-load-algorithm
|
||||
|
@ -434,7 +469,9 @@ impl HTMLMediaElement {
|
|||
// 4.4
|
||||
self.change_ready_state(HAVE_NOTHING);
|
||||
|
||||
// TODO 4.5 (paused)
|
||||
if !self.Paused() {
|
||||
self.paused.set(true);
|
||||
}
|
||||
// TODO 4.6 (seeking)
|
||||
// TODO 4.7 (playback position)
|
||||
// TODO 4.8 (timeline offset)
|
||||
|
@ -444,11 +481,10 @@ impl HTMLMediaElement {
|
|||
// TODO step 5 (playback rate)
|
||||
// Step 6
|
||||
self.error.set(None);
|
||||
// TODO autoplay flag
|
||||
self.autoplaying.set(true);
|
||||
|
||||
// Step 7
|
||||
let doc = document_from_node(self);
|
||||
self.invoke_resource_selection_algorithm(doc.base_url());
|
||||
self.invoke_resource_selection_algorithm();
|
||||
|
||||
// TODO step 8 (stop previously playing resource)
|
||||
}
|
||||
|
@ -463,6 +499,11 @@ impl HTMLMediaElementMethods for HTMLMediaElement {
|
|||
self.ready_state.get()
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-media-autoplay
|
||||
make_bool_getter!(Autoplay, "autoplay");
|
||||
// https://html.spec.whatwg.org/multipage/#dom-media-autoplay
|
||||
make_bool_setter!(SetAutoplay, "autoplay");
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-media-src
|
||||
make_url_getter!(Src, "src");
|
||||
// https://html.spec.whatwg.org/multipage/#dom-media-src
|
||||
|
@ -488,6 +529,60 @@ impl HTMLMediaElementMethods for HTMLMediaElement {
|
|||
fn GetError(&self) -> Option<Root<MediaError>> {
|
||||
self.error.get()
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-media-play
|
||||
fn Play(&self) {
|
||||
// Step 1
|
||||
if self.network_state.get() == NETWORK_EMPTY {
|
||||
self.invoke_resource_selection_algorithm();
|
||||
}
|
||||
|
||||
// TODO step 2 (seek backwards)
|
||||
|
||||
// TODO step 3 (media controller)
|
||||
|
||||
// Step 4
|
||||
if self.Paused() {
|
||||
// 4.1
|
||||
self.paused.set(false);
|
||||
|
||||
// TODO 4.2 (show poster)
|
||||
|
||||
// 4.3
|
||||
self.queue_fire_simple_event("play");
|
||||
|
||||
// 4.4
|
||||
let state = self.ready_state.get();
|
||||
if state == HAVE_NOTHING ||
|
||||
state == HAVE_METADATA ||
|
||||
state == HAVE_CURRENT_DATA {
|
||||
self.queue_fire_simple_event("waiting");
|
||||
} else {
|
||||
self.queue_fire_simple_event("playing");
|
||||
}
|
||||
|
||||
// 4.5
|
||||
self.autoplaying.set(false);
|
||||
|
||||
// TODO 4.6 (media controller)
|
||||
}
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-media-pause
|
||||
fn Pause(&self) {
|
||||
// Step 1
|
||||
if self.network_state.get() == NETWORK_EMPTY {
|
||||
self.invoke_resource_selection_algorithm();
|
||||
}
|
||||
|
||||
// Step 2
|
||||
self.internal_pause_steps();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-media-paused
|
||||
fn Paused(&self) -> bool {
|
||||
self.paused.get()
|
||||
}
|
||||
}
|
||||
|
||||
impl VirtualMethods for HTMLMediaElement {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue