diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 8d41a685b7b..a2202da57e2 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -840,9 +840,13 @@ impl HTMLMediaElement { self.fetch_request(None); }, SrcObject::MediaStream(ref stream) => { - for stream in stream.get_tracks() { - if let Err(_) = - self.player.borrow().as_ref().unwrap().set_stream(&stream) + for stream in &*stream.get_tracks() { + if let Err(_) = self + .player + .borrow() + .as_ref() + .unwrap() + .set_stream(&stream.id()) { self.queue_dedicated_media_source_failure_steps(); } diff --git a/components/script/dom/mediadevices.rs b/components/script/dom/mediadevices.rs index 0a4f00e2472..460d3b0fc2c 100644 --- a/components/script/dom/mediadevices.rs +++ b/components/script/dom/mediadevices.rs @@ -14,6 +14,7 @@ use crate::dom::bindings::root::DomRoot; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::mediastream::MediaStream; +use crate::dom::mediastreamtrack::MediaStreamTrack; use crate::dom::promise::Promise; use dom_struct::dom_struct; use servo_media::streams::capture::{Constrain, ConstrainRange, MediaTrackConstraintSet}; @@ -51,18 +52,20 @@ impl MediaDevicesMethods for MediaDevices { InCompartment::Already(&in_compartment_proof), ); let media = ServoMedia::get().unwrap(); - let mut tracks = vec![]; + let stream = MediaStream::new(&self.global()); if let Some(constraints) = convert_constraints(&constraints.audio) { if let Some(audio) = media.create_audioinput_stream(constraints) { - tracks.push(audio) + let track = MediaStreamTrack::new(&self.global(), audio); + stream.add_track(&track); } } if let Some(constraints) = convert_constraints(&constraints.video) { if let Some(video) = media.create_videoinput_stream(constraints) { - tracks.push(video) + let track = MediaStreamTrack::new(&self.global(), video); + stream.add_track(&track); } } - let stream = MediaStream::new(&self.global(), tracks); + p.resolve_native(&stream); p } diff --git a/components/script/dom/mediastream.rs b/components/script/dom/mediastream.rs index 42588afc476..ed80b2c8cb1 100644 --- a/components/script/dom/mediastream.rs +++ b/components/script/dom/mediastream.rs @@ -3,38 +3,53 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::cell::DomRefCell; -use crate::dom::bindings::codegen::Bindings::MediaStreamBinding; +use crate::dom::bindings::codegen::Bindings::MediaStreamBinding::{self, MediaStreamMethods}; use crate::dom::bindings::reflector::reflect_dom_object; -use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; +use crate::dom::mediastreamtrack::MediaStreamTrack; use dom_struct::dom_struct; -use servo_media::streams::registry::MediaStreamId; +use std::cell::Ref; #[dom_struct] pub struct MediaStream { eventtarget: EventTarget, - #[ignore_malloc_size_of = "defined in servo-media"] - tracks: DomRefCell>, + tracks: DomRefCell>>, } impl MediaStream { - pub fn new_inherited(tracks: Vec) -> MediaStream { + pub fn new_inherited() -> MediaStream { MediaStream { eventtarget: EventTarget::new_inherited(), - tracks: DomRefCell::new(tracks), + tracks: DomRefCell::new(vec![]), } } - pub fn new(global: &GlobalScope, tracks: Vec) -> DomRoot { + pub fn new(global: &GlobalScope) -> DomRoot { reflect_dom_object( - Box::new(MediaStream::new_inherited(tracks)), + Box::new(MediaStream::new_inherited()), global, MediaStreamBinding::Wrap, ) } - pub fn get_tracks(&self) -> Vec { - self.tracks.borrow_mut().clone() + pub fn get_tracks(&self) -> Ref<[Dom]> { + Ref::map(self.tracks.borrow(), |tracks| &**tracks) + } + + pub fn add_track(&self, track: &MediaStreamTrack) { + self.tracks.borrow_mut().push(Dom::from_ref(track)) + } +} + +impl MediaStreamMethods for MediaStream { + /// https://w3c.github.io/mediacapture-main/#dom-mediastream-gettracks + fn GetTracks(&self) -> Vec> { + self.tracks + .borrow() + .iter() + .map(|x| DomRoot::from_ref(&**x)) + .collect() } } diff --git a/components/script/dom/mediastreamtrack.rs b/components/script/dom/mediastreamtrack.rs index 13ca065bc9f..b178feab6b3 100644 --- a/components/script/dom/mediastreamtrack.rs +++ b/components/script/dom/mediastreamtrack.rs @@ -32,4 +32,8 @@ impl MediaStreamTrack { MediaStreamTrackBinding::Wrap, ) } + + pub fn id(&self) -> MediaStreamId { + self.id + } } diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 0d865a8c920..3e8cb8eba43 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -585,10 +585,12 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { // https://w3c.github.io/webrtc-pc/#legacy-interface-extensions fn AddStream(&self, stream: &MediaStream) { - let mut tracks = stream.get_tracks(); - - for ref track in tracks.drain(..) { - self.controller.borrow().as_ref().unwrap().add_stream(track); + for track in &*stream.get_tracks() { + self.controller + .borrow() + .as_ref() + .unwrap() + .add_stream(&track.id()); } } diff --git a/components/script/dom/webidls/MediaStream.webidl b/components/script/dom/webidls/MediaStream.webidl index 0257e3c6061..47a73fed66e 100644 --- a/components/script/dom/webidls/MediaStream.webidl +++ b/components/script/dom/webidls/MediaStream.webidl @@ -13,7 +13,7 @@ interface MediaStream : EventTarget { // readonly attribute DOMString id; // sequence getAudioTracks(); // sequence getVideoTracks(); - // sequence getTracks(); + sequence getTracks(); // MediaStreamTrack? getTrackById(DOMString trackId); // void addTrack(MediaStreamTrack track); // void removeTrack(MediaStreamTrack track);