Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrates media track selection #24265

Merged
merged 1 commit into from Oct 2, 2019
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -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;
@@ -18,6 +19,7 @@ pub struct AudioTrack {
label: DOMString,
language: DOMString,
enabled: Cell<bool>,
track_list: Option<Dom<AudioTrackList>>,
}

impl AudioTrack {
@@ -26,6 +28,7 @@ impl AudioTrack {
kind: DOMString,
label: DOMString,
language: DOMString,
track_list: Option<&AudioTrackList>,
) -> AudioTrack {
AudioTrack {
reflector_: Reflector::new(),
@@ -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)),
}
}

@@ -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,
)
@@ -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);
}
}
@@ -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;
@@ -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,
)
@@ -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()
@@ -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,
@@ -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();
@@ -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 => {
@@ -1530,6 +1546,7 @@ impl HTMLMediaElement {
kind,
DOMString::new(),
DOMString::new(),
Some(&*self.AudioTracks()),
);

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

// Steps 2. & 3.
@@ -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
@@ -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;
@@ -18,6 +19,7 @@ pub struct VideoTrack {
label: DOMString,
language: DOMString,
selected: Cell<bool>,
track_list: Option<Dom<VideoTrackList>>,
}

impl VideoTrack {
@@ -26,6 +28,7 @@ impl VideoTrack {
kind: DOMString,
label: DOMString,
language: DOMString,
track_list: Option<&VideoTrackList>,
) -> VideoTrack {
VideoTrack {
reflector_: Reflector::new(),
@@ -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)),
}
}

@@ -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,
)
@@ -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);
}
}
@@ -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;
@@ -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,
)
@@ -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()
@@ -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,
@@ -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 || {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.