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);