mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
MediaSession API DOM bindings
This commit is contained in:
parent
7da8d75a7e
commit
4b5b4d19bf
6 changed files with 262 additions and 0 deletions
94
components/script/dom/mediametadata.rs
Normal file
94
components/script/dom/mediametadata.rs
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::MediaMetadataBinding;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::MediaMetadataBinding::MediaMetadataInit;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::MediaMetadataBinding::MediaMetadataMethods;
|
||||||
|
use crate::dom::bindings::error::Fallible;
|
||||||
|
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
||||||
|
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
|
||||||
|
use crate::dom::bindings::str::DOMString;
|
||||||
|
use crate::dom::mediasession::MediaSession;
|
||||||
|
use crate::dom::window::Window;
|
||||||
|
use dom_struct::dom_struct;
|
||||||
|
|
||||||
|
#[dom_struct]
|
||||||
|
pub struct MediaMetadata {
|
||||||
|
reflector_: Reflector,
|
||||||
|
session: MutNullableDom<MediaSession>,
|
||||||
|
title: DomRefCell<DOMString>,
|
||||||
|
artist: DomRefCell<DOMString>,
|
||||||
|
album: DomRefCell<DOMString>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MediaMetadata {
|
||||||
|
fn new_inherited(init: &MediaMetadataInit) -> MediaMetadata {
|
||||||
|
MediaMetadata {
|
||||||
|
reflector_: Reflector::new(),
|
||||||
|
// TODO(ferjm): Set active media session?
|
||||||
|
session: Default::default(),
|
||||||
|
title: DomRefCell::new(init.title.clone()),
|
||||||
|
artist: DomRefCell::new(init.artist.clone()),
|
||||||
|
album: DomRefCell::new(init.album.clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(global: &Window, init: &MediaMetadataInit) -> DomRoot<MediaMetadata> {
|
||||||
|
reflect_dom_object(
|
||||||
|
Box::new(MediaMetadata::new_inherited(init)),
|
||||||
|
global,
|
||||||
|
MediaMetadataBinding::Wrap,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://w3c.github.io/mediasession/#dom-mediametadata-mediametadata
|
||||||
|
pub fn Constructor(
|
||||||
|
window: &Window,
|
||||||
|
init: &MediaMetadataInit,
|
||||||
|
) -> Fallible<DomRoot<MediaMetadata>> {
|
||||||
|
Ok(MediaMetadata::new(window, init))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn queue_update_metadata_algorithm(&self) {
|
||||||
|
if self.session.get().is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MediaMetadataMethods for MediaMetadata {
|
||||||
|
/// https://w3c.github.io/mediasession/#dom-mediametadata-title
|
||||||
|
fn Title(&self) -> DOMString {
|
||||||
|
self.title.borrow().clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://w3c.github.io/mediasession/#dom-mediametadata-title
|
||||||
|
fn SetTitle(&self, value: DOMString) -> () {
|
||||||
|
*self.title.borrow_mut() = value;
|
||||||
|
self.queue_update_metadata_algorithm();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://w3c.github.io/mediasession/#dom-mediametadata-artist
|
||||||
|
fn Artist(&self) -> DOMString {
|
||||||
|
self.artist.borrow().clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://w3c.github.io/mediasession/#dom-mediametadata-artist
|
||||||
|
fn SetArtist(&self, value: DOMString) -> () {
|
||||||
|
*self.artist.borrow_mut() = value;
|
||||||
|
self.queue_update_metadata_algorithm();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://w3c.github.io/mediasession/#dom-mediametadata-album
|
||||||
|
fn Album(&self) -> DOMString {
|
||||||
|
self.album.borrow().clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://w3c.github.io/mediasession/#dom-mediametadata-album
|
||||||
|
fn SetAlbum(&self, value: DOMString) -> () {
|
||||||
|
*self.album.borrow_mut() = value;
|
||||||
|
self.queue_update_metadata_algorithm();
|
||||||
|
}
|
||||||
|
}
|
70
components/script/dom/mediasession.rs
Normal file
70
components/script/dom/mediasession.rs
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::MediaSessionBinding;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::MediaSessionBinding::MediaSessionAction;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::MediaSessionBinding::MediaSessionActionHandler;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::MediaSessionBinding::MediaSessionMethods;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::MediaSessionBinding::MediaSessionPlaybackState;
|
||||||
|
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
||||||
|
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
|
||||||
|
use crate::dom::mediametadata::MediaMetadata;
|
||||||
|
use crate::dom::window::Window;
|
||||||
|
use dom_struct::dom_struct;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
#[dom_struct]
|
||||||
|
pub struct MediaSession {
|
||||||
|
reflector_: Reflector,
|
||||||
|
/// https://w3c.github.io/mediasession/#dom-mediasession-metadata
|
||||||
|
metadata: MutNullableDom<MediaMetadata>,
|
||||||
|
/// https://w3c.github.io/mediasession/#dom-mediasession-playbackstate
|
||||||
|
playback_state: DomRefCell<MediaSessionPlaybackState>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MediaSession {
|
||||||
|
fn new_inherited() -> MediaSession {
|
||||||
|
MediaSession {
|
||||||
|
reflector_: Reflector::new(),
|
||||||
|
metadata: Default::default(),
|
||||||
|
playback_state: DomRefCell::new(MediaSessionPlaybackState::None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(global: &Window) -> DomRoot<MediaSession> {
|
||||||
|
reflect_dom_object(
|
||||||
|
Box::new(MediaSession::new_inherited()),
|
||||||
|
global,
|
||||||
|
MediaSessionBinding::Wrap,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MediaSessionMethods for MediaSession {
|
||||||
|
fn GetMetadata(&self) -> Option<DomRoot<MediaMetadata>> {
|
||||||
|
self.metadata.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn SetMetadata(&self, value: Option<&MediaMetadata>) {
|
||||||
|
self.metadata.set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://w3c.github.io/mediasession/#dom-mediasession-playbackstate
|
||||||
|
fn PlaybackState(&self) -> MediaSessionPlaybackState {
|
||||||
|
*self.playback_state.borrow()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://w3c.github.io/mediasession/#dom-mediasession-playbackstate
|
||||||
|
fn SetPlaybackState(&self, value: MediaSessionPlaybackState) {
|
||||||
|
*self.playback_state.borrow_mut() = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn SetActionHandler(
|
||||||
|
&self,
|
||||||
|
_action: MediaSessionAction,
|
||||||
|
_handler: Option<Rc<MediaSessionActionHandler>>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -398,8 +398,10 @@ pub mod mediaelementaudiosourcenode;
|
||||||
pub mod mediaerror;
|
pub mod mediaerror;
|
||||||
pub mod mediafragmentparser;
|
pub mod mediafragmentparser;
|
||||||
pub mod medialist;
|
pub mod medialist;
|
||||||
|
pub mod mediametadata;
|
||||||
pub mod mediaquerylist;
|
pub mod mediaquerylist;
|
||||||
pub mod mediaquerylistevent;
|
pub mod mediaquerylistevent;
|
||||||
|
pub mod mediasession;
|
||||||
pub mod mediastream;
|
pub mod mediastream;
|
||||||
pub mod mediastreamtrack;
|
pub mod mediastreamtrack;
|
||||||
pub mod messagechannel;
|
pub mod messagechannel;
|
||||||
|
|
|
@ -12,6 +12,7 @@ use crate::dom::bindings::str::DOMString;
|
||||||
use crate::dom::bluetooth::Bluetooth;
|
use crate::dom::bluetooth::Bluetooth;
|
||||||
use crate::dom::gamepadlist::GamepadList;
|
use crate::dom::gamepadlist::GamepadList;
|
||||||
use crate::dom::mediadevices::MediaDevices;
|
use crate::dom::mediadevices::MediaDevices;
|
||||||
|
use crate::dom::mediasession::MediaSession;
|
||||||
use crate::dom::mimetypearray::MimeTypeArray;
|
use crate::dom::mimetypearray::MimeTypeArray;
|
||||||
use crate::dom::navigatorinfo;
|
use crate::dom::navigatorinfo;
|
||||||
use crate::dom::permissions::Permissions;
|
use crate::dom::permissions::Permissions;
|
||||||
|
@ -34,6 +35,7 @@ pub struct Navigator {
|
||||||
mediadevices: MutNullableDom<MediaDevices>,
|
mediadevices: MutNullableDom<MediaDevices>,
|
||||||
gamepads: MutNullableDom<GamepadList>,
|
gamepads: MutNullableDom<GamepadList>,
|
||||||
permissions: MutNullableDom<Permissions>,
|
permissions: MutNullableDom<Permissions>,
|
||||||
|
mediasession: MutNullableDom<MediaSession>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Navigator {
|
impl Navigator {
|
||||||
|
@ -48,6 +50,7 @@ impl Navigator {
|
||||||
mediadevices: Default::default(),
|
mediadevices: Default::default(),
|
||||||
gamepads: Default::default(),
|
gamepads: Default::default(),
|
||||||
permissions: Default::default(),
|
permissions: Default::default(),
|
||||||
|
mediasession: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,4 +189,10 @@ impl NavigatorMethods for Navigator {
|
||||||
self.mediadevices
|
self.mediadevices
|
||||||
.or_init(|| MediaDevices::new(&self.global()))
|
.or_init(|| MediaDevices::new(&self.global()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// https://w3c.github.io/mediasession/#dom-navigator-mediasession
|
||||||
|
fn MediaSession(&self) -> DomRoot<MediaSession> {
|
||||||
|
self.mediasession
|
||||||
|
.or_init(|| MediaSession::new(self.global().as_window()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
30
components/script/dom/webidls/MediaMetadata.webidl
Normal file
30
components/script/dom/webidls/MediaMetadata.webidl
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
/*
|
||||||
|
* The origin of this IDL file is
|
||||||
|
* https://w3c.github.io/mediasession/#mediametadata
|
||||||
|
*/
|
||||||
|
|
||||||
|
dictionary MediaImage {
|
||||||
|
required USVString src;
|
||||||
|
DOMString sizes = "";
|
||||||
|
DOMString type = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
[Exposed=Window,
|
||||||
|
Constructor(optional MediaMetadataInit init = {})]
|
||||||
|
interface MediaMetadata {
|
||||||
|
attribute DOMString title;
|
||||||
|
attribute DOMString artist;
|
||||||
|
attribute DOMString album;
|
||||||
|
// TODO: https://github.com/servo/servo/issues/10072
|
||||||
|
// attribute FrozenArray<MediaImage> artwork;
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary MediaMetadataInit {
|
||||||
|
DOMString title = "";
|
||||||
|
DOMString artist = "";
|
||||||
|
DOMString album = "";
|
||||||
|
sequence<MediaImage> artwork = [];
|
||||||
|
};
|
57
components/script/dom/webidls/MediaSession.webidl
Normal file
57
components/script/dom/webidls/MediaSession.webidl
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
/*
|
||||||
|
* The origin of this IDL file is
|
||||||
|
* https://w3c.github.io/mediasession/#mediasession
|
||||||
|
*/
|
||||||
|
|
||||||
|
[Exposed=Window]
|
||||||
|
partial interface Navigator {
|
||||||
|
[SameObject] readonly attribute MediaSession mediaSession;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MediaSessionPlaybackState {
|
||||||
|
"none",
|
||||||
|
"paused",
|
||||||
|
"playing"
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MediaSessionAction {
|
||||||
|
"play",
|
||||||
|
"pause",
|
||||||
|
"seekbackward",
|
||||||
|
"seekforward",
|
||||||
|
"previoustrack",
|
||||||
|
"nexttrack",
|
||||||
|
"skipad",
|
||||||
|
"stop",
|
||||||
|
"seekto"
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary MediaSessionActionDetails {
|
||||||
|
required MediaSessionAction action;
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary MediaSessionSeekActionDetails : MediaSessionActionDetails {
|
||||||
|
double? seekOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary MediaSessionSeekToActionDetails : MediaSessionActionDetails {
|
||||||
|
required double seekTime;
|
||||||
|
boolean? fastSeek;
|
||||||
|
};
|
||||||
|
|
||||||
|
callback MediaSessionActionHandler = void(MediaSessionActionDetails details);
|
||||||
|
|
||||||
|
[Exposed=Window]
|
||||||
|
interface MediaSession {
|
||||||
|
attribute MediaMetadata? metadata;
|
||||||
|
|
||||||
|
attribute MediaSessionPlaybackState playbackState;
|
||||||
|
|
||||||
|
void setActionHandler(MediaSessionAction action, MediaSessionActionHandler? handler);
|
||||||
|
|
||||||
|
//void setPositionState(optional MediaPositionState? state);
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue