From 749a6595ad123dfc36d31bc9d8ab9ff81ca0020f Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 6 May 2019 20:19:45 -0700 Subject: [PATCH 01/12] Update servo-media --- Cargo.lock | 20 ++++++++++---------- components/script/dom/rtcpeerconnection.rs | 3 ++- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a3d0abc071..e56520c1ae9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3857,7 +3857,7 @@ dependencies = [ [[package]] name = "servo-media" version = "0.1.0" -source = "git+https://github.com/servo/media#01cd9be1b8e92e036b4ddff0294893f7e53ef373" +source = "git+https://github.com/servo/media#8691ca03a37c45bf7efa9430e434dd5fbf0abfa3" dependencies = [ "servo-media-audio 0.1.0 (git+https://github.com/servo/media)", "servo-media-player 0.1.0 (git+https://github.com/servo/media)", @@ -3868,7 +3868,7 @@ dependencies = [ [[package]] name = "servo-media-audio" version = "0.1.0" -source = "git+https://github.com/servo/media#01cd9be1b8e92e036b4ddff0294893f7e53ef373" +source = "git+https://github.com/servo/media#8691ca03a37c45bf7efa9430e434dd5fbf0abfa3" dependencies = [ "boxfnonce 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "byte-slice-cast 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3884,7 +3884,7 @@ dependencies = [ [[package]] name = "servo-media-dummy" version = "0.1.0" -source = "git+https://github.com/servo/media#01cd9be1b8e92e036b4ddff0294893f7e53ef373" +source = "git+https://github.com/servo/media#8691ca03a37c45bf7efa9430e434dd5fbf0abfa3" dependencies = [ "boxfnonce 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3898,7 +3898,7 @@ dependencies = [ [[package]] name = "servo-media-gstreamer" version = "0.1.0" -source = "git+https://github.com/servo/media#01cd9be1b8e92e036b4ddff0294893f7e53ef373" +source = "git+https://github.com/servo/media#8691ca03a37c45bf7efa9430e434dd5fbf0abfa3" dependencies = [ "boxfnonce 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "byte-slice-cast 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3932,7 +3932,7 @@ dependencies = [ [[package]] name = "servo-media-gstreamer-render" version = "0.1.0" -source = "git+https://github.com/servo/media#01cd9be1b8e92e036b4ddff0294893f7e53ef373" +source = "git+https://github.com/servo/media#8691ca03a37c45bf7efa9430e434dd5fbf0abfa3" dependencies = [ "gstreamer 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer-video 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3942,7 +3942,7 @@ dependencies = [ [[package]] name = "servo-media-gstreamer-render-unix" version = "0.1.0" -source = "git+https://github.com/servo/media#01cd9be1b8e92e036b4ddff0294893f7e53ef373" +source = "git+https://github.com/servo/media#8691ca03a37c45bf7efa9430e434dd5fbf0abfa3" dependencies = [ "glib 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "gstreamer 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3955,7 +3955,7 @@ dependencies = [ [[package]] name = "servo-media-player" version = "0.1.0" -source = "git+https://github.com/servo/media#01cd9be1b8e92e036b4ddff0294893f7e53ef373" +source = "git+https://github.com/servo/media#8691ca03a37c45bf7efa9430e434dd5fbf0abfa3" dependencies = [ "ipc-channel 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3966,7 +3966,7 @@ dependencies = [ [[package]] name = "servo-media-streams" version = "0.1.0" -source = "git+https://github.com/servo/media#01cd9be1b8e92e036b4ddff0294893f7e53ef373" +source = "git+https://github.com/servo/media#8691ca03a37c45bf7efa9430e434dd5fbf0abfa3" dependencies = [ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3975,7 +3975,7 @@ dependencies = [ [[package]] name = "servo-media-webrtc" version = "0.1.0" -source = "git+https://github.com/servo/media#01cd9be1b8e92e036b4ddff0294893f7e53ef373" +source = "git+https://github.com/servo/media#8691ca03a37c45bf7efa9430e434dd5fbf0abfa3" dependencies = [ "boxfnonce 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4074,7 +4074,7 @@ dependencies = [ [[package]] name = "servo_media_derive" version = "0.1.0" -source = "git+https://github.com/servo/media#01cd9be1b8e92e036b4ddff0294893f7e53ef373" +source = "git+https://github.com/servo/media#8691ca03a37c45bf7efa9430e434dd5fbf0abfa3" dependencies = [ "proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 962eb0fb02c..0d865a8c920 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -37,6 +37,7 @@ use crate::task_source::TaskSource; use dom_struct::dom_struct; use servo_media::streams::registry::MediaStreamId; +use servo_media::streams::MediaStreamType; use servo_media::webrtc::{ BundlePolicy, GatheringState, IceCandidate, IceConnectionState, SdpType, SessionDescription, SignalingState, WebRtcController, WebRtcSignaller, @@ -128,7 +129,7 @@ impl WebRtcSignaller for RTCSignaller { ); } - fn on_add_stream(&self, _: &MediaStreamId) {} + fn on_add_stream(&self, _: &MediaStreamId, _: MediaStreamType) {} fn close(&self) { // do nothing From 106cc4a1f7a9454e0f551d13806cf44a02bc32c9 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 7 May 2019 12:49:47 -0700 Subject: [PATCH 02/12] Add MediaStreamTrack interface --- components/script/dom/mediastreamtrack.rs | 35 +++++++++++++++++++ components/script/dom/mod.rs | 1 + .../dom/webidls/MediaStreamTrack.webidl | 24 +++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 components/script/dom/mediastreamtrack.rs create mode 100644 components/script/dom/webidls/MediaStreamTrack.webidl diff --git a/components/script/dom/mediastreamtrack.rs b/components/script/dom/mediastreamtrack.rs new file mode 100644 index 00000000000..13ca065bc9f --- /dev/null +++ b/components/script/dom/mediastreamtrack.rs @@ -0,0 +1,35 @@ +/* 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::codegen::Bindings::MediaStreamTrackBinding; +use crate::dom::bindings::reflector::reflect_dom_object; +use crate::dom::bindings::root::DomRoot; +use crate::dom::eventtarget::EventTarget; +use crate::dom::globalscope::GlobalScope; +use dom_struct::dom_struct; +use servo_media::streams::registry::MediaStreamId; + +#[dom_struct] +pub struct MediaStreamTrack { + eventtarget: EventTarget, + #[ignore_malloc_size_of = "defined in servo-media"] + id: MediaStreamId, +} + +impl MediaStreamTrack { + pub fn new_inherited(id: MediaStreamId) -> MediaStreamTrack { + MediaStreamTrack { + eventtarget: EventTarget::new_inherited(), + id, + } + } + + pub fn new(global: &GlobalScope, id: MediaStreamId) -> DomRoot { + reflect_dom_object( + Box::new(MediaStreamTrack::new_inherited(id)), + global, + MediaStreamTrackBinding::Wrap, + ) + } +} diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index ff1688fb6c3..576c288d6f4 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -399,6 +399,7 @@ pub mod medialist; pub mod mediaquerylist; pub mod mediaquerylistevent; pub mod mediastream; +pub mod mediastreamtrack; pub mod messageevent; pub mod mimetype; pub mod mimetypearray; diff --git a/components/script/dom/webidls/MediaStreamTrack.webidl b/components/script/dom/webidls/MediaStreamTrack.webidl new file mode 100644 index 00000000000..03180966b9f --- /dev/null +++ b/components/script/dom/webidls/MediaStreamTrack.webidl @@ -0,0 +1,24 @@ +/* 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/. */ + +// https://w3c.github.io/mediacapture-main/#dom-mediastreamtrack + +[Exposed=Window, Pref="dom.webrtc.enabled"] +interface MediaStreamTrack : EventTarget { + // readonly attribute DOMString kind; + // readonly attribute DOMString id; + // readonly attribute DOMString label; + // attribute boolean enabled; + // readonly attribute boolean muted; + // attribute EventHandler onmute; + // attribute EventHandler onunmute; + // readonly attribute MediaStreamTrackState readyState; + // attribute EventHandler onended; + // MediaStreamTrack clone(); + // void stop(); + // MediaTrackCapabilities getCapabilities(); + // MediaTrackConstraints getConstraints(); + // MediaTrackSettings getSettings(); + // Promise applyConstraints(optional MediaTrackConstraints constraints); +}; From a9ab13b279d8234a56c58a6907362c4f48dd6138 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 7 May 2019 12:49:47 -0700 Subject: [PATCH 03/12] Use MediaStreamTracks in MediaStreams --- components/script/dom/htmlmediaelement.rs | 10 +++-- components/script/dom/mediadevices.rs | 11 ++++-- components/script/dom/mediastream.rs | 37 +++++++++++++------ components/script/dom/mediastreamtrack.rs | 4 ++ components/script/dom/rtcpeerconnection.rs | 10 +++-- .../script/dom/webidls/MediaStream.webidl | 2 +- 6 files changed, 51 insertions(+), 23 deletions(-) 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); From 36abbca0a64d1886bf813e801aad3d3dec66a434 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 7 May 2019 14:09:50 -0700 Subject: [PATCH 04/12] Add stream types to tracks, add MediaStreamTrack.id and MediaStreamTrack.kind --- components/script/dom/bindings/trace.rs | 3 +- components/script/dom/mediadevices.rs | 5 ++- components/script/dom/mediastreamtrack.rs | 38 +++++++++++++++++-- .../dom/webidls/MediaStreamTrack.webidl | 4 +- 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 56805e4d9fe..874ce68888c 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -105,6 +105,7 @@ use servo_media::audio::panner_node::{DistanceModel, PanningModel}; use servo_media::audio::param::ParamType; use servo_media::player::Player; use servo_media::streams::registry::MediaStreamId; +use servo_media::streams::MediaStreamType; use servo_media::webrtc::WebRtcController; use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; use smallvec::SmallVec; @@ -490,7 +491,7 @@ unsafe_no_jsmanaged_fields!(NodeId); unsafe_no_jsmanaged_fields!(AnalysisEngine, DistanceModel, PanningModel, ParamType); unsafe_no_jsmanaged_fields!(dyn Player); unsafe_no_jsmanaged_fields!(WebRtcController); -unsafe_no_jsmanaged_fields!(MediaStreamId); +unsafe_no_jsmanaged_fields!(MediaStreamId, MediaStreamType); unsafe_no_jsmanaged_fields!(Mutex); unsafe_no_jsmanaged_fields!(RenderApiSender); unsafe_no_jsmanaged_fields!(ResourceFetchTiming); diff --git a/components/script/dom/mediadevices.rs b/components/script/dom/mediadevices.rs index 460d3b0fc2c..bcc575a2ef6 100644 --- a/components/script/dom/mediadevices.rs +++ b/components/script/dom/mediadevices.rs @@ -18,6 +18,7 @@ use crate::dom::mediastreamtrack::MediaStreamTrack; use crate::dom::promise::Promise; use dom_struct::dom_struct; use servo_media::streams::capture::{Constrain, ConstrainRange, MediaTrackConstraintSet}; +use servo_media::streams::MediaStreamType; use servo_media::ServoMedia; use std::rc::Rc; @@ -55,13 +56,13 @@ impl MediaDevicesMethods for MediaDevices { let stream = MediaStream::new(&self.global()); if let Some(constraints) = convert_constraints(&constraints.audio) { if let Some(audio) = media.create_audioinput_stream(constraints) { - let track = MediaStreamTrack::new(&self.global(), audio); + let track = MediaStreamTrack::new(&self.global(), audio, MediaStreamType::Audio); stream.add_track(&track); } } if let Some(constraints) = convert_constraints(&constraints.video) { if let Some(video) = media.create_videoinput_stream(constraints) { - let track = MediaStreamTrack::new(&self.global(), video); + let track = MediaStreamTrack::new(&self.global(), video, MediaStreamType::Video); stream.add_track(&track); } } diff --git a/components/script/dom/mediastreamtrack.rs b/components/script/dom/mediastreamtrack.rs index b178feab6b3..79da91e0e45 100644 --- a/components/script/dom/mediastreamtrack.rs +++ b/components/script/dom/mediastreamtrack.rs @@ -2,32 +2,43 @@ * 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::codegen::Bindings::MediaStreamTrackBinding; +use crate::dom::bindings::codegen::Bindings::MediaStreamTrackBinding::{ + self, MediaStreamTrackMethods, +}; use crate::dom::bindings::reflector::reflect_dom_object; use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::str::DOMString; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use dom_struct::dom_struct; use servo_media::streams::registry::MediaStreamId; +use servo_media::streams::MediaStreamType; #[dom_struct] pub struct MediaStreamTrack { eventtarget: EventTarget, #[ignore_malloc_size_of = "defined in servo-media"] id: MediaStreamId, + #[ignore_malloc_size_of = "defined in servo-media"] + ty: MediaStreamType, } impl MediaStreamTrack { - pub fn new_inherited(id: MediaStreamId) -> MediaStreamTrack { + pub fn new_inherited(id: MediaStreamId, ty: MediaStreamType) -> MediaStreamTrack { MediaStreamTrack { eventtarget: EventTarget::new_inherited(), id, + ty, } } - pub fn new(global: &GlobalScope, id: MediaStreamId) -> DomRoot { + pub fn new( + global: &GlobalScope, + id: MediaStreamId, + ty: MediaStreamType, + ) -> DomRoot { reflect_dom_object( - Box::new(MediaStreamTrack::new_inherited(id)), + Box::new(MediaStreamTrack::new_inherited(id, ty)), global, MediaStreamTrackBinding::Wrap, ) @@ -36,4 +47,23 @@ impl MediaStreamTrack { pub fn id(&self) -> MediaStreamId { self.id } + + pub fn ty(&self) -> MediaStreamType { + self.ty + } +} + +impl MediaStreamTrackMethods for MediaStreamTrack { + /// https://w3c.github.io/mediacapture-main/#dom-mediastreamtrack-kind + fn Kind(&self) -> DOMString { + match self.ty { + MediaStreamType::Video => "video".into(), + MediaStreamType::Audio => "audio".into(), + } + } + + /// https://w3c.github.io/mediacapture-main/#dom-mediastreamtrack-id + fn Id(&self) -> DOMString { + self.id.id().to_string().into() + } } diff --git a/components/script/dom/webidls/MediaStreamTrack.webidl b/components/script/dom/webidls/MediaStreamTrack.webidl index 03180966b9f..7fecc681b7b 100644 --- a/components/script/dom/webidls/MediaStreamTrack.webidl +++ b/components/script/dom/webidls/MediaStreamTrack.webidl @@ -6,8 +6,8 @@ [Exposed=Window, Pref="dom.webrtc.enabled"] interface MediaStreamTrack : EventTarget { - // readonly attribute DOMString kind; - // readonly attribute DOMString id; + readonly attribute DOMString kind; + readonly attribute DOMString id; // readonly attribute DOMString label; // attribute boolean enabled; // readonly attribute boolean muted; From 70e1c29ae98f0dd4090c0093850ee07faba0dcbe Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 7 May 2019 14:33:55 -0700 Subject: [PATCH 05/12] Add MediaStream.getVideoTracks(), MediaStream.getAudioTracks() --- components/script/dom/mediastream.rs | 21 +++++++++++++++++++ .../script/dom/webidls/MediaStream.webidl | 4 ++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/components/script/dom/mediastream.rs b/components/script/dom/mediastream.rs index ed80b2c8cb1..8cf68e80490 100644 --- a/components/script/dom/mediastream.rs +++ b/components/script/dom/mediastream.rs @@ -10,6 +10,7 @@ use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::mediastreamtrack::MediaStreamTrack; use dom_struct::dom_struct; +use servo_media::streams::MediaStreamType; use std::cell::Ref; #[dom_struct] @@ -52,4 +53,24 @@ impl MediaStreamMethods for MediaStream { .map(|x| DomRoot::from_ref(&**x)) .collect() } + + /// https://w3c.github.io/mediacapture-main/#dom-mediastream-getaudiotracks + fn GetAudioTracks(&self) -> Vec> { + self.tracks + .borrow() + .iter() + .filter(|x| x.ty() == MediaStreamType::Audio) + .map(|x| DomRoot::from_ref(&**x)) + .collect() + } + + /// https://w3c.github.io/mediacapture-main/#dom-mediastream-getvideotracks + fn GetVideoTracks(&self) -> Vec> { + self.tracks + .borrow() + .iter() + .filter(|x| x.ty() == MediaStreamType::Video) + .map(|x| DomRoot::from_ref(&**x)) + .collect() + } } diff --git a/components/script/dom/webidls/MediaStream.webidl b/components/script/dom/webidls/MediaStream.webidl index 47a73fed66e..650ad1ed95d 100644 --- a/components/script/dom/webidls/MediaStream.webidl +++ b/components/script/dom/webidls/MediaStream.webidl @@ -11,8 +11,8 @@ [Exposed=Window, Pref="dom.webrtc.enabled"] interface MediaStream : EventTarget { // readonly attribute DOMString id; - // sequence getAudioTracks(); - // sequence getVideoTracks(); + sequence getAudioTracks(); + sequence getVideoTracks(); sequence getTracks(); // MediaStreamTrack? getTrackById(DOMString trackId); // void addTrack(MediaStreamTrack track); From 571c3d6d0e9785a611f39357ca9736259aa23004 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 7 May 2019 14:39:10 -0700 Subject: [PATCH 06/12] Add MediaStream.getTrackById() --- components/script/dom/mediastream.rs | 10 ++++++++++ components/script/dom/webidls/MediaStream.webidl | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/components/script/dom/mediastream.rs b/components/script/dom/mediastream.rs index 8cf68e80490..395abd95ab6 100644 --- a/components/script/dom/mediastream.rs +++ b/components/script/dom/mediastream.rs @@ -6,6 +6,7 @@ use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::MediaStreamBinding::{self, MediaStreamMethods}; use crate::dom::bindings::reflector::reflect_dom_object; use crate::dom::bindings::root::{Dom, DomRoot}; +use crate::dom::bindings::str::DOMString; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::mediastreamtrack::MediaStreamTrack; @@ -73,4 +74,13 @@ impl MediaStreamMethods for MediaStream { .map(|x| DomRoot::from_ref(&**x)) .collect() } + + /// https://w3c.github.io/mediacapture-main/#dom-mediastream-gettrackbyid + fn GetTrackById(&self, id: DOMString) -> Option> { + self.tracks + .borrow() + .iter() + .find(|x| x.id().id().to_string() == &*id) + .map(|x| DomRoot::from_ref(&**x)) + } } diff --git a/components/script/dom/webidls/MediaStream.webidl b/components/script/dom/webidls/MediaStream.webidl index 650ad1ed95d..10b151225de 100644 --- a/components/script/dom/webidls/MediaStream.webidl +++ b/components/script/dom/webidls/MediaStream.webidl @@ -14,7 +14,7 @@ interface MediaStream : EventTarget { sequence getAudioTracks(); sequence getVideoTracks(); sequence getTracks(); - // MediaStreamTrack? getTrackById(DOMString trackId); + MediaStreamTrack? getTrackById(DOMString trackId); // void addTrack(MediaStreamTrack track); // void removeTrack(MediaStreamTrack track); // MediaStream clone(); From 477ca175e38b232535bdad47eb71f1f2152b4da4 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 7 May 2019 14:45:48 -0700 Subject: [PATCH 07/12] Add MediaStream.addTrack() and MediaStream.removeTrack() --- components/script/dom/mediastream.rs | 15 +++++++++++++++ components/script/dom/webidls/MediaStream.webidl | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/components/script/dom/mediastream.rs b/components/script/dom/mediastream.rs index 395abd95ab6..38a9ce5f652 100644 --- a/components/script/dom/mediastream.rs +++ b/components/script/dom/mediastream.rs @@ -83,4 +83,19 @@ impl MediaStreamMethods for MediaStream { .find(|x| x.id().id().to_string() == &*id) .map(|x| DomRoot::from_ref(&**x)) } + + /// https://w3c.github.io/mediacapture-main/#dom-mediastream-addtrack + fn AddTrack(&self, track: &MediaStreamTrack) { + let existing = self.tracks.borrow().iter().find(|x| *x == &track).is_some(); + + if existing { + return; + } + self.add_track(track) + } + + /// https://w3c.github.io/mediacapture-main/#dom-mediastream-removetrack + fn RemoveTrack(&self, track: &MediaStreamTrack) { + self.tracks.borrow_mut().retain(|x| *x != track); + } } diff --git a/components/script/dom/webidls/MediaStream.webidl b/components/script/dom/webidls/MediaStream.webidl index 10b151225de..5b991f2e53a 100644 --- a/components/script/dom/webidls/MediaStream.webidl +++ b/components/script/dom/webidls/MediaStream.webidl @@ -15,8 +15,8 @@ interface MediaStream : EventTarget { sequence getVideoTracks(); sequence getTracks(); MediaStreamTrack? getTrackById(DOMString trackId); - // void addTrack(MediaStreamTrack track); - // void removeTrack(MediaStreamTrack track); + void addTrack(MediaStreamTrack track); + void removeTrack(MediaStreamTrack track); // MediaStream clone(); // readonly attribute boolean active; // attribute EventHandler onaddtrack; From 229ce3643156eff39b119429e6c579d32634eb5c Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 7 May 2019 14:56:46 -0700 Subject: [PATCH 08/12] Add {MediaStream, MediaStreamTrack}.clone() --- components/script/dom/mediastream.rs | 11 ++++++++++- components/script/dom/mediastreamtrack.rs | 7 ++++++- components/script/dom/webidls/MediaStream.webidl | 2 +- components/script/dom/webidls/MediaStreamTrack.webidl | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/components/script/dom/mediastream.rs b/components/script/dom/mediastream.rs index 38a9ce5f652..a5edb458337 100644 --- a/components/script/dom/mediastream.rs +++ b/components/script/dom/mediastream.rs @@ -4,7 +4,7 @@ use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::MediaStreamBinding::{self, MediaStreamMethods}; -use crate::dom::bindings::reflector::reflect_dom_object; +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; @@ -98,4 +98,13 @@ impl MediaStreamMethods for MediaStream { fn RemoveTrack(&self, track: &MediaStreamTrack) { self.tracks.borrow_mut().retain(|x| *x != track); } + + /// https://w3c.github.io/mediacapture-main/#dom-mediastream-clone + fn Clone(&self) -> DomRoot { + let new = MediaStream::new(&self.global()); + for track in &*self.tracks.borrow() { + new.add_track(&track) + } + new + } } diff --git a/components/script/dom/mediastreamtrack.rs b/components/script/dom/mediastreamtrack.rs index 79da91e0e45..2cc0bde7442 100644 --- a/components/script/dom/mediastreamtrack.rs +++ b/components/script/dom/mediastreamtrack.rs @@ -5,7 +5,7 @@ use crate::dom::bindings::codegen::Bindings::MediaStreamTrackBinding::{ self, MediaStreamTrackMethods, }; -use crate::dom::bindings::reflector::reflect_dom_object; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::str::DOMString; use crate::dom::eventtarget::EventTarget; @@ -66,4 +66,9 @@ impl MediaStreamTrackMethods for MediaStreamTrack { fn Id(&self) -> DOMString { self.id.id().to_string().into() } + + /// https://w3c.github.io/mediacapture-main/#dom-mediastreamtrack-clone + fn Clone(&self) -> DomRoot { + MediaStreamTrack::new(&self.global(), self.id, self.ty) + } } diff --git a/components/script/dom/webidls/MediaStream.webidl b/components/script/dom/webidls/MediaStream.webidl index 5b991f2e53a..7483cde2d36 100644 --- a/components/script/dom/webidls/MediaStream.webidl +++ b/components/script/dom/webidls/MediaStream.webidl @@ -17,7 +17,7 @@ interface MediaStream : EventTarget { MediaStreamTrack? getTrackById(DOMString trackId); void addTrack(MediaStreamTrack track); void removeTrack(MediaStreamTrack track); - // MediaStream clone(); + MediaStream clone(); // readonly attribute boolean active; // attribute EventHandler onaddtrack; // attribute EventHandler onremovetrack; diff --git a/components/script/dom/webidls/MediaStreamTrack.webidl b/components/script/dom/webidls/MediaStreamTrack.webidl index 7fecc681b7b..2f8bfb0bbec 100644 --- a/components/script/dom/webidls/MediaStreamTrack.webidl +++ b/components/script/dom/webidls/MediaStreamTrack.webidl @@ -15,7 +15,7 @@ interface MediaStreamTrack : EventTarget { // attribute EventHandler onunmute; // readonly attribute MediaStreamTrackState readyState; // attribute EventHandler onended; - // MediaStreamTrack clone(); + MediaStreamTrack clone(); // void stop(); // MediaTrackCapabilities getCapabilities(); // MediaTrackConstraints getConstraints(); From 318c6857a9d8a8716b214dad1eb4ef27704f520c Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 7 May 2019 15:14:42 -0700 Subject: [PATCH 09/12] Add RTCTrackEvent --- components/script/dom/mod.rs | 1 + components/script/dom/rtctrackevent.rs | 78 +++++++++++++++++++ .../script/dom/webidls/RTCTrackEvent.webidl | 23 ++++++ 3 files changed, 102 insertions(+) create mode 100644 components/script/dom/rtctrackevent.rs create mode 100644 components/script/dom/webidls/RTCTrackEvent.webidl diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 576c288d6f4..00274c3b86b 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -451,6 +451,7 @@ pub mod rtcicecandidate; pub mod rtcpeerconnection; pub mod rtcpeerconnectioniceevent; pub mod rtcsessiondescription; +pub mod rtctrackevent; pub mod screen; pub mod serviceworker; pub mod serviceworkercontainer; diff --git a/components/script/dom/rtctrackevent.rs b/components/script/dom/rtctrackevent.rs new file mode 100644 index 00000000000..9c5d7bec362 --- /dev/null +++ b/components/script/dom/rtctrackevent.rs @@ -0,0 +1,78 @@ +/* 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::codegen::Bindings::EventBinding::EventBinding::EventMethods; +use crate::dom::bindings::codegen::Bindings::RTCTrackEventBinding::{self, RTCTrackEventMethods}; +use crate::dom::bindings::error::Fallible; +use crate::dom::bindings::inheritance::Castable; +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::event::Event; +use crate::dom::globalscope::GlobalScope; +use crate::dom::mediastreamtrack::MediaStreamTrack; +use crate::dom::window::Window; +use dom_struct::dom_struct; +use servo_atoms::Atom; + +#[dom_struct] +pub struct RTCTrackEvent { + event: Event, + track: Dom, +} + +impl RTCTrackEvent { + #[allow(unrooted_must_root)] + fn new_inherited(track: &MediaStreamTrack) -> RTCTrackEvent { + RTCTrackEvent { + event: Event::new_inherited(), + track: Dom::from_ref(track), + } + } + + pub fn new( + global: &GlobalScope, + type_: Atom, + bubbles: bool, + cancelable: bool, + track: &MediaStreamTrack, + ) -> DomRoot { + let trackevent = reflect_dom_object( + Box::new(RTCTrackEvent::new_inherited(&track)), + global, + RTCTrackEventBinding::Wrap, + ); + { + let event = trackevent.upcast::(); + event.init_event(type_, bubbles, cancelable); + } + trackevent + } + + pub fn Constructor( + window: &Window, + type_: DOMString, + init: &RTCTrackEventBinding::RTCTrackEventInit, + ) -> Fallible> { + Ok(RTCTrackEvent::new( + &window.global(), + Atom::from(type_), + init.parent.bubbles, + init.parent.cancelable, + &init.track, + )) + } +} + +impl RTCTrackEventMethods for RTCTrackEvent { + // https://w3c.github.io/webrtc-pc/#dom-rtctrackevent-track + fn Track(&self) -> DomRoot { + DomRoot::from_ref(&*self.track) + } + + // https://dom.spec.whatwg.org/#dom-event-istrusted + fn IsTrusted(&self) -> bool { + self.event.IsTrusted() + } +} diff --git a/components/script/dom/webidls/RTCTrackEvent.webidl b/components/script/dom/webidls/RTCTrackEvent.webidl new file mode 100644 index 00000000000..6eafd2a514e --- /dev/null +++ b/components/script/dom/webidls/RTCTrackEvent.webidl @@ -0,0 +1,23 @@ +/* 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/. */ + +// https://w3c.github.io/webrtc-pc/#dom-rtctrackevent + +[Constructor(DOMString type, RTCTrackEventInit eventInitDict), + Exposed=Window] +interface RTCTrackEvent : Event { + // readonly attribute RTCRtpReceiver receiver; + readonly attribute MediaStreamTrack track; + // [SameObject] + // readonly attribute FrozenArray streams; + // readonly attribute RTCRtpTransceiver transceiver; +}; + +// https://www.w3.org/TR/webrtc/#dom-rtctrackeventinit +dictionary RTCTrackEventInit : EventInit { + // required RTCRtpReceiver receiver; + required MediaStreamTrack track; + // sequence streams = []; + // required RTCRtpTransceiver transceiver; +}; From 72701d96c4d59a07e03746842ed317632c34d253 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 7 May 2019 15:26:20 -0700 Subject: [PATCH 10/12] Add RTCPeerConnection.ontrack --- components/atoms/static_atoms.txt | 1 + components/script/dom/rtcpeerconnection.rs | 26 ++++++++++++++++++- .../dom/webidls/RTCPeerConnection.webidl | 12 +++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/components/atoms/static_atoms.txt b/components/atoms/static_atoms.txt index 7a6022cb64c..a42e998c958 100644 --- a/components/atoms/static_atoms.txt +++ b/components/atoms/static_atoms.txt @@ -108,6 +108,7 @@ text time timeupdate toggle +track transitionend unhandledrejection unload diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 3e8cb8eba43..9ec1940bbb3 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -26,10 +26,12 @@ use crate::dom::event::{Event, EventBubbles, EventCancelable}; 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 crate::dom::rtcicecandidate::RTCIceCandidate; use crate::dom::rtcpeerconnectioniceevent::RTCPeerConnectionIceEvent; use crate::dom::rtcsessiondescription::RTCSessionDescription; +use crate::dom::rtctrackevent::RTCTrackEvent; use crate::dom::window::Window; use crate::task::TaskCanceller; use crate::task_source::networking::NetworkingTaskSource; @@ -129,7 +131,17 @@ impl WebRtcSignaller for RTCSignaller { ); } - fn on_add_stream(&self, _: &MediaStreamId, _: MediaStreamType) {} + fn on_add_stream(&self, id: &MediaStreamId, ty: MediaStreamType) { + let this = self.trusted.clone(); + let id = *id; + let _ = self.task_source.queue_with_canceller( + task!(on_add_stream: move || { + let this = this.root(); + this.on_add_stream(id, ty); + }), + &self.canceller, + ); + } fn close(&self) { // do nothing @@ -239,6 +251,15 @@ impl RTCPeerConnection { event.upcast::().fire(self.upcast()); } + fn on_add_stream(&self, id: MediaStreamId, ty: MediaStreamType) { + if self.closed.get() { + return; + } + let track = MediaStreamTrack::new(&self.global(), id, ty); + let event = RTCTrackEvent::new(&self.global(), atom!("track"), false, false, &track); + event.upcast::().fire(self.upcast()); + } + /// https://www.w3.org/TR/webrtc/#update-ice-gathering-state fn update_gathering_state(&self, state: GatheringState) { // step 1 @@ -400,6 +421,9 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { /// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-icecandidate event_handler!(icecandidate, GetOnicecandidate, SetOnicecandidate); + /// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-ontrack + event_handler!(track, GetOntrack, SetOntrack); + /// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-iceconnectionstatechange event_handler!( iceconnectionstatechange, diff --git a/components/script/dom/webidls/RTCPeerConnection.webidl b/components/script/dom/webidls/RTCPeerConnection.webidl index 0f00f3b5b95..58cb7301ea3 100644 --- a/components/script/dom/webidls/RTCPeerConnection.webidl +++ b/components/script/dom/webidls/RTCPeerConnection.webidl @@ -114,3 +114,15 @@ enum RTCSignalingState { "have-remote-pranswer", "closed" }; + +partial interface RTCPeerConnection { + // sequence getSenders(); + // sequence getReceivers(); + // sequence getTransceivers(); + // RTCRtpSender addTrack(MediaStreamTrack track, + // MediaStream... streams); + // void removeTrack(RTCRtpSender sender); + // RTCRtpTransceiver addTransceiver((MediaStreamTrack or DOMString) trackOrKind, + // optional RTCRtpTransceiverInit init); + attribute EventHandler ontrack; +}; From b4ddf6837f53f126f4b26dea5fedc07ca826ff6f Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 7 May 2019 15:59:54 -0700 Subject: [PATCH 11/12] Add constructors for MediaStream --- components/script/dom/mediastream.rs | 23 +++++++++++++++++++ .../script/dom/webidls/MediaStream.webidl | 10 ++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/components/script/dom/mediastream.rs b/components/script/dom/mediastream.rs index a5edb458337..2ae573b290e 100644 --- a/components/script/dom/mediastream.rs +++ b/components/script/dom/mediastream.rs @@ -4,12 +4,14 @@ use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::MediaStreamBinding::{self, MediaStreamMethods}; +use crate::dom::bindings::error::Fallible; 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::globalscope::GlobalScope; use crate::dom::mediastreamtrack::MediaStreamTrack; +use crate::dom::window::Window; use dom_struct::dom_struct; use servo_media::streams::MediaStreamType; use std::cell::Ref; @@ -36,6 +38,27 @@ impl MediaStream { ) } + pub fn Constructor(global: &Window) -> Fallible> { + Ok(MediaStream::new(&global.global())) + } + + pub fn Constructor_(_: &Window, stream: &MediaStream) -> Fallible> { + Ok(stream.Clone()) + } + + pub fn Constructor__( + global: &Window, + tracks: Vec>, + ) -> Fallible> { + let new = MediaStream::new(&global.global()); + for track in tracks { + // this is quadratic, but shouldn't matter much + // if this becomes a problem we can use a hash map + new.AddTrack(&track) + } + Ok(new) + } + pub fn get_tracks(&self) -> Ref<[Dom]> { Ref::map(self.tracks.borrow(), |tracks| &**tracks) } diff --git a/components/script/dom/webidls/MediaStream.webidl b/components/script/dom/webidls/MediaStream.webidl index 7483cde2d36..b1d5664a7f7 100644 --- a/components/script/dom/webidls/MediaStream.webidl +++ b/components/script/dom/webidls/MediaStream.webidl @@ -4,11 +4,11 @@ // https://w3c.github.io/mediacapture-main/#dom-mediastream -// [Exposed=Window, -// Constructor, -// Constructor(MediaStream stream), -// Constructor(sequence tracks)] -[Exposed=Window, Pref="dom.webrtc.enabled"] +[Exposed=Window, + Constructor, + Constructor(MediaStream stream), + Constructor(sequence tracks), +Pref="dom.webrtc.enabled"] interface MediaStream : EventTarget { // readonly attribute DOMString id; sequence getAudioTracks(); From 7d5e493759271805aa84d3cad5fccb410a4296f4 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 8 May 2019 19:14:53 -0700 Subject: [PATCH 12/12] pref-gate RTCTrackEvent --- components/script/dom/webidls/RTCTrackEvent.webidl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/script/dom/webidls/RTCTrackEvent.webidl b/components/script/dom/webidls/RTCTrackEvent.webidl index 6eafd2a514e..fa07f36b9f5 100644 --- a/components/script/dom/webidls/RTCTrackEvent.webidl +++ b/components/script/dom/webidls/RTCTrackEvent.webidl @@ -5,7 +5,7 @@ // https://w3c.github.io/webrtc-pc/#dom-rtctrackevent [Constructor(DOMString type, RTCTrackEventInit eventInitDict), - Exposed=Window] + Exposed=Window, Pref="dom.webrtc.enabled"] interface RTCTrackEvent : Event { // readonly attribute RTCRtpReceiver receiver; readonly attribute MediaStreamTrack track;