Skip to content

Commit

Permalink
Integrates media track selection
Browse files Browse the repository at this point in the history
  • Loading branch information
sreeise committed Sep 22, 2019
1 parent 4fe8238 commit 5ea79c6
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 14 deletions.
16 changes: 14 additions & 2 deletions components/script/dom/audiotrack.rs
Expand Up @@ -2,9 +2,10 @@
* 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::audiotracklist::AudioTrackList;
use crate::dom::bindings::codegen::Bindings::AudioTrackBinding::{self, AudioTrackMethods};
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::window::Window;
use dom_struct::dom_struct;
Expand All @@ -18,6 +19,7 @@ pub struct AudioTrack {
label: DOMString,
language: DOMString,
enabled: Cell<bool>,
track_list: Option<Dom<AudioTrackList>>,
}

impl AudioTrack {
Expand All @@ -26,6 +28,7 @@ impl AudioTrack {
kind: DOMString,
label: DOMString,
language: DOMString,
track_list: Option<&AudioTrackList>,
) -> AudioTrack {
AudioTrack {
reflector_: Reflector::new(),
Expand All @@ -34,6 +37,7 @@ impl AudioTrack {
label: label.into(),
language: language.into(),
enabled: Cell::new(false),
track_list: track_list.map(|t| Dom::from_ref(t)),
}
}

Expand All @@ -43,9 +47,12 @@ impl AudioTrack {
kind: DOMString,
label: DOMString,
language: DOMString,
track_list: Option<&AudioTrackList>,
) -> DomRoot<AudioTrack> {
reflect_dom_object(
Box::new(AudioTrack::new_inherited(id, kind, label, language)),
Box::new(AudioTrack::new_inherited(
id, kind, label, language, track_list,
)),
window,
AudioTrackBinding::Wrap,
)
Expand Down Expand Up @@ -96,6 +103,11 @@ impl AudioTrackMethods for AudioTrack {

// https://html.spec.whatwg.org/multipage/#dom-audiotrack-enabled
fn SetEnabled(&self, value: bool) {
if let Some(list) = self.track_list.as_ref() {
if let Some(idx) = list.find(self) {
list.set_enabled(idx, value);
}
}
self.set_enabled(value);
}
}
24 changes: 20 additions & 4 deletions components/script/dom/audiotracklist.rs
Expand Up @@ -11,6 +11,7 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::eventtarget::EventTarget;
use crate::dom::htmlmediaelement::HTMLMediaElement;
use crate::dom::window::Window;
use crate::task_source::TaskSource;
use dom_struct::dom_struct;
Expand All @@ -19,19 +20,28 @@ use dom_struct::dom_struct;
pub struct AudioTrackList {
eventtarget: EventTarget,
tracks: DomRefCell<Vec<Dom<AudioTrack>>>,
media_element: Option<Dom<HTMLMediaElement>>,
}

impl AudioTrackList {
pub fn new_inherited(tracks: &[&AudioTrack]) -> AudioTrackList {
pub fn new_inherited(
tracks: &[&AudioTrack],
media_element: Option<&HTMLMediaElement>,
) -> AudioTrackList {
AudioTrackList {
eventtarget: EventTarget::new_inherited(),
tracks: DomRefCell::new(tracks.iter().map(|track| Dom::from_ref(&**track)).collect()),
media_element: media_element.map(|m| Dom::from_ref(m)),
}
}

pub fn new(window: &Window, tracks: &[&AudioTrack]) -> DomRoot<AudioTrackList> {
pub fn new(
window: &Window,
tracks: &[&AudioTrack],
media_element: Option<&HTMLMediaElement>,
) -> DomRoot<AudioTrackList> {
reflect_dom_object(
Box::new(AudioTrackList::new_inherited(tracks)),
Box::new(AudioTrackList::new_inherited(tracks, media_element)),
window,
AudioTrackListBinding::Wrap,
)
Expand All @@ -41,6 +51,10 @@ impl AudioTrackList {
self.tracks.borrow().len()
}

pub fn find(&self, track: &AudioTrack) -> Option<usize> {
self.tracks.borrow().iter().position(|t| &**t == track)
}

pub fn item(&self, idx: usize) -> Option<DomRoot<AudioTrack>> {
self.tracks
.borrow()
Expand All @@ -55,7 +69,6 @@ impl AudioTrackList {
.position(|track| track.enabled())
}

// TODO(#22799) Integrate DOM Audio and Video track selection with media player.
pub fn set_enabled(&self, idx: usize, value: bool) {
let track = match self.item(idx) {
Some(t) => t,
Expand All @@ -68,6 +81,9 @@ impl AudioTrackList {
}
// Set the tracks enabled status.
track.set_enabled(value);
if let Some(media_element) = self.media_element.as_ref() {
media_element.set_audio_track(idx, value);
}

// Queue a task to fire an event named change.
let global = &self.global();
Expand Down
22 changes: 20 additions & 2 deletions components/script/dom/htmlmediaelement.rs
Expand Up @@ -1435,6 +1435,22 @@ impl HTMLMediaElement {
Ok(())
}

pub fn set_audio_track(&self, idx: usize, enabled: bool) {
if let Some(ref player) = *self.player.borrow() {
if let Err(err) = player.lock().unwrap().set_audio_track(idx as i32, enabled) {
warn!("Could not set audio track {:#?}", err);
}
}
}

pub fn set_video_track(&self, idx: usize, enabled: bool) {
if let Some(ref player) = *self.player.borrow() {
if let Err(err) = player.lock().unwrap().set_video_track(idx as i32, enabled) {
warn!("Could not set video track {:#?}", err);
}
}
}

fn handle_player_event(&self, event: &PlayerEvent) {
match *event {
PlayerEvent::EndOfStream => {
Expand Down Expand Up @@ -1530,6 +1546,7 @@ impl HTMLMediaElement {
kind,
DOMString::new(),
DOMString::new(),
Some(&*self.AudioTracks()),
);

// Steps 2. & 3.
Expand Down Expand Up @@ -1585,6 +1602,7 @@ impl HTMLMediaElement {
kind,
DOMString::new(),
DOMString::new(),
Some(&*self.VideoTracks()),
);

// Steps 2. & 3.
Expand Down Expand Up @@ -2217,14 +2235,14 @@ impl HTMLMediaElementMethods for HTMLMediaElement {
fn AudioTracks(&self) -> DomRoot<AudioTrackList> {
let window = window_from_node(self);
self.audio_tracks_list
.or_init(|| AudioTrackList::new(&window, &[]))
.or_init(|| AudioTrackList::new(&window, &[], Some(self)))
}

// https://html.spec.whatwg.org/multipage/#dom-media-videotracks
fn VideoTracks(&self) -> DomRoot<VideoTrackList> {
let window = window_from_node(self);
self.video_tracks_list
.or_init(|| VideoTrackList::new(&window, &[]))
.or_init(|| VideoTrackList::new(&window, &[], Some(self)))
}

// https://html.spec.whatwg.org/multipage/#dom-media-texttracks
Expand Down
16 changes: 14 additions & 2 deletions components/script/dom/videotrack.rs
Expand Up @@ -4,8 +4,9 @@

use crate::dom::bindings::codegen::Bindings::VideoTrackBinding::{self, VideoTrackMethods};
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::videotracklist::VideoTrackList;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use std::cell::Cell;
Expand All @@ -18,6 +19,7 @@ pub struct VideoTrack {
label: DOMString,
language: DOMString,
selected: Cell<bool>,
track_list: Option<Dom<VideoTrackList>>,
}

impl VideoTrack {
Expand All @@ -26,6 +28,7 @@ impl VideoTrack {
kind: DOMString,
label: DOMString,
language: DOMString,
track_list: Option<&VideoTrackList>,
) -> VideoTrack {
VideoTrack {
reflector_: Reflector::new(),
Expand All @@ -34,6 +37,7 @@ impl VideoTrack {
label: label.into(),
language: language.into(),
selected: Cell::new(false),
track_list: track_list.map(|t| Dom::from_ref(t)),
}
}

Expand All @@ -43,9 +47,12 @@ impl VideoTrack {
kind: DOMString,
label: DOMString,
language: DOMString,
track_list: Option<&VideoTrackList>,
) -> DomRoot<VideoTrack> {
reflect_dom_object(
Box::new(VideoTrack::new_inherited(id, kind, label, language)),
Box::new(VideoTrack::new_inherited(
id, kind, label, language, track_list,
)),
window,
VideoTrackBinding::Wrap,
)
Expand Down Expand Up @@ -96,6 +103,11 @@ impl VideoTrackMethods for VideoTrack {

// https://html.spec.whatwg.org/multipage/#dom-videotrack-selected
fn SetSelected(&self, value: bool) {
if let Some(list) = self.track_list.as_ref() {
if let Some(idx) = list.find(self) {
list.set_selected(idx, value);
}
}
self.set_selected(value);
}
}
24 changes: 20 additions & 4 deletions components/script/dom/videotracklist.rs
Expand Up @@ -11,6 +11,7 @@ use crate::dom::bindings::root::Dom;
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::eventtarget::EventTarget;
use crate::dom::htmlmediaelement::HTMLMediaElement;
use crate::dom::videotrack::VideoTrack;
use crate::dom::window::Window;
use crate::task_source::TaskSource;
Expand All @@ -20,19 +21,28 @@ use dom_struct::dom_struct;
pub struct VideoTrackList {
eventtarget: EventTarget,
tracks: DomRefCell<Vec<Dom<VideoTrack>>>,
media_element: Option<Dom<HTMLMediaElement>>,
}

impl VideoTrackList {
pub fn new_inherited(tracks: &[&VideoTrack]) -> VideoTrackList {
pub fn new_inherited(
tracks: &[&VideoTrack],
media_element: Option<&HTMLMediaElement>,
) -> VideoTrackList {
VideoTrackList {
eventtarget: EventTarget::new_inherited(),
tracks: DomRefCell::new(tracks.iter().map(|track| Dom::from_ref(&**track)).collect()),
media_element: media_element.map(|m| Dom::from_ref(m)),
}
}

pub fn new(window: &Window, tracks: &[&VideoTrack]) -> DomRoot<VideoTrackList> {
pub fn new(
window: &Window,
tracks: &[&VideoTrack],
media_element: Option<&HTMLMediaElement>,
) -> DomRoot<VideoTrackList> {
reflect_dom_object(
Box::new(VideoTrackList::new_inherited(tracks)),
Box::new(VideoTrackList::new_inherited(tracks, media_element)),
window,
VideoTrackListBinding::Wrap,
)
Expand All @@ -42,6 +52,10 @@ impl VideoTrackList {
self.tracks.borrow().len()
}

pub fn find(&self, track: &VideoTrack) -> Option<usize> {
self.tracks.borrow().iter().position(|t| &**t == track)
}

pub fn item(&self, idx: usize) -> Option<DomRoot<VideoTrack>> {
self.tracks
.borrow()
Expand All @@ -56,7 +70,6 @@ impl VideoTrackList {
.position(|track| track.selected())
}

// TODO(#22799) Integrate DOM Audio and Video track selection with media player.
pub fn set_selected(&self, idx: usize, value: bool) {
let track = match self.item(idx) {
Some(t) => t,
Expand All @@ -80,6 +93,9 @@ impl VideoTrackList {
}

track.set_selected(value);
if let Some(media_element) = self.media_element.as_ref() {
media_element.set_video_track(idx, value);
}

let _ = source.queue_with_canceller(
task!(media_track_change: move || {
Expand Down

0 comments on commit 5ea79c6

Please sign in to comment.