зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1377146 - Remove AudioStreamTrack and VideoStreamTrack from js. r=jib,smaug
Differential Revision: https://phabricator.services.mozilla.com/D8063 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
d36a59550f
Коммит
f5f6f6fdb4
|
@ -546,10 +546,6 @@ DOMInterfaces = {
|
|||
'headerFile': 'MediaStreamList.h',
|
||||
},
|
||||
|
||||
'MediaStreamTrack': {
|
||||
'concrete': False
|
||||
},
|
||||
|
||||
'MediaRecorder': {
|
||||
'headerFile': 'MediaRecorder.h',
|
||||
},
|
||||
|
|
|
@ -7,17 +7,10 @@
|
|||
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
#include "mozilla/dom/AudioStreamTrackBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
JSObject*
|
||||
AudioStreamTrack::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return AudioStreamTrack_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
void
|
||||
AudioStreamTrack::GetLabel(nsAString& aLabel, CallerType aCallerType)
|
||||
{
|
||||
|
|
|
@ -20,10 +20,7 @@ public:
|
|||
const MediaTrackConstraints& aConstraints = MediaTrackConstraints())
|
||||
: MediaStreamTrack(aStream, aTrackID, aInputTrackID, aSource, aConstraints) {}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
AudioStreamTrack* AsAudioStreamTrack() override { return this; }
|
||||
|
||||
const AudioStreamTrack* AsAudioStreamTrack() const override { return this; }
|
||||
|
||||
// WebIDL
|
||||
|
|
|
@ -657,27 +657,45 @@ DOMMediaStream::GetId(nsAString& aID) const
|
|||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::GetAudioTracks(nsTArray<RefPtr<AudioStreamTrack> >& aTracks) const
|
||||
DOMMediaStream::GetAudioTracks(nsTArray<RefPtr<AudioStreamTrack>>& aTracks) const
|
||||
{
|
||||
for (const RefPtr<TrackPort>& info : mTracks) {
|
||||
AudioStreamTrack* t = info->GetTrack()->AsAudioStreamTrack();
|
||||
if (t) {
|
||||
if (AudioStreamTrack* t = info->GetTrack()->AsAudioStreamTrack()) {
|
||||
aTracks.AppendElement(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::GetVideoTracks(nsTArray<RefPtr<VideoStreamTrack> >& aTracks) const
|
||||
DOMMediaStream::GetAudioTracks(nsTArray<RefPtr<MediaStreamTrack>>& aTracks) const
|
||||
{
|
||||
for (const RefPtr<TrackPort>& info : mTracks) {
|
||||
VideoStreamTrack* t = info->GetTrack()->AsVideoStreamTrack();
|
||||
if (t) {
|
||||
if (info->GetTrack()->AsAudioStreamTrack()) {
|
||||
aTracks.AppendElement(info->GetTrack());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::GetVideoTracks(nsTArray<RefPtr<VideoStreamTrack>>& aTracks) const
|
||||
{
|
||||
for (const RefPtr<TrackPort>& info : mTracks) {
|
||||
if (VideoStreamTrack* t = info->GetTrack()->AsVideoStreamTrack()) {
|
||||
aTracks.AppendElement(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::GetVideoTracks(nsTArray<RefPtr<MediaStreamTrack>>& aTracks) const
|
||||
{
|
||||
for (const RefPtr<TrackPort>& info : mTracks) {
|
||||
if (info->GetTrack()->AsVideoStreamTrack()) {
|
||||
aTracks.AppendElement(info->GetTrack());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DOMMediaStream::GetTracks(nsTArray<RefPtr<MediaStreamTrack> >& aTracks) const
|
||||
{
|
||||
|
|
|
@ -367,7 +367,9 @@ public:
|
|||
void GetId(nsAString& aID) const;
|
||||
|
||||
void GetAudioTracks(nsTArray<RefPtr<AudioStreamTrack> >& aTracks) const;
|
||||
void GetAudioTracks(nsTArray<RefPtr<MediaStreamTrack> >& aTracks) const;
|
||||
void GetVideoTracks(nsTArray<RefPtr<VideoStreamTrack> >& aTracks) const;
|
||||
void GetVideoTracks(nsTArray<RefPtr<MediaStreamTrack> >& aTracks) const;
|
||||
void GetTracks(nsTArray<RefPtr<MediaStreamTrack> >& aTracks) const;
|
||||
MediaStreamTrack* GetTrackById(const nsAString& aId) const;
|
||||
void AddTrack(MediaStreamTrack& aTrack);
|
||||
|
|
|
@ -211,6 +211,12 @@ MediaStreamTrack::GetParentObject() const
|
|||
return mOwningStream->GetParentObject();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
MediaStreamTrack::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return MediaStreamTrack_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
void
|
||||
MediaStreamTrack::GetId(nsAString& aID) const
|
||||
{
|
||||
|
|
|
@ -386,7 +386,7 @@ public:
|
|||
DOMEventTargetHelper)
|
||||
|
||||
nsPIDOMWindowInner* GetParentObject() const;
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override = 0;
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
virtual AudioStreamTrack* AsAudioStreamTrack() { return nullptr; }
|
||||
virtual VideoStreamTrack* AsVideoStreamTrack() { return nullptr; }
|
||||
|
|
|
@ -9,17 +9,9 @@
|
|||
#include "MediaStreamGraph.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
#include "mozilla/dom/VideoStreamTrackBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
JSObject*
|
||||
VideoStreamTrack::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return VideoStreamTrack_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
void
|
||||
VideoStreamTrack::AddVideoOutput(MediaStreamVideoSink* aSink)
|
||||
{
|
||||
|
|
|
@ -23,10 +23,7 @@ public:
|
|||
const MediaTrackConstraints& aConstraints = MediaTrackConstraints())
|
||||
: MediaStreamTrack(aStream, aTrackID, aInputTrackID, aSource, aConstraints) {}
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
VideoStreamTrack* AsVideoStreamTrack() override { return this; }
|
||||
|
||||
const VideoStreamTrack* AsVideoStreamTrack() const override { return this; }
|
||||
|
||||
void AddVideoOutput(MediaStreamVideoSink* aSink);
|
||||
|
|
|
@ -79,7 +79,7 @@ CaptureTask::AttachTrack()
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
dom::VideoStreamTrack* track = mImageCapture->GetVideoStreamTrack();
|
||||
dom::MediaStreamTrack* track = mImageCapture->GetVideoStreamTrack();
|
||||
track->AddPrincipalChangeObserver(this);
|
||||
track->AddListener(mEventListener.get());
|
||||
track->AddDirectListener(this);
|
||||
|
@ -90,7 +90,7 @@ CaptureTask::DetachTrack()
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
dom::VideoStreamTrack* track = mImageCapture->GetVideoStreamTrack();
|
||||
dom::MediaStreamTrack* track = mImageCapture->GetVideoStreamTrack();
|
||||
track->RemovePrincipalChangeObserver(this);
|
||||
track->RemoveListener(mEventListener.get());
|
||||
track->RemoveDirectListener(this);
|
||||
|
|
|
@ -28,7 +28,7 @@ LogModule* GetICLog()
|
|||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(ImageCapture, DOMEventTargetHelper,
|
||||
mVideoStreamTrack)
|
||||
mTrack)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ImageCapture)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
|
@ -36,14 +36,13 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
|||
NS_IMPL_ADDREF_INHERITED(ImageCapture, DOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(ImageCapture, DOMEventTargetHelper)
|
||||
|
||||
ImageCapture::ImageCapture(VideoStreamTrack* aVideoStreamTrack,
|
||||
ImageCapture::ImageCapture(VideoStreamTrack* aTrack,
|
||||
nsPIDOMWindowInner* aOwnerWindow)
|
||||
: DOMEventTargetHelper(aOwnerWindow)
|
||||
, mTrack(aTrack)
|
||||
{
|
||||
MOZ_ASSERT(aOwnerWindow);
|
||||
MOZ_ASSERT(aVideoStreamTrack);
|
||||
|
||||
mVideoStreamTrack = aVideoStreamTrack;
|
||||
MOZ_ASSERT(aTrack);
|
||||
}
|
||||
|
||||
ImageCapture::~ImageCapture()
|
||||
|
@ -53,7 +52,7 @@ ImageCapture::~ImageCapture()
|
|||
|
||||
already_AddRefed<ImageCapture>
|
||||
ImageCapture::Constructor(const GlobalObject& aGlobal,
|
||||
VideoStreamTrack& aTrack,
|
||||
MediaStreamTrack& aTrack,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
|
@ -62,15 +61,20 @@ ImageCapture::Constructor(const GlobalObject& aGlobal,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ImageCapture> object = new ImageCapture(&aTrack, win);
|
||||
if (!aTrack.AsVideoStreamTrack()) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ImageCapture> object = new ImageCapture(aTrack.AsVideoStreamTrack(), win);
|
||||
|
||||
return object.forget();
|
||||
}
|
||||
|
||||
VideoStreamTrack*
|
||||
MediaStreamTrack*
|
||||
ImageCapture::GetVideoStreamTrack() const
|
||||
{
|
||||
return mVideoStreamTrack;
|
||||
return mTrack;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -118,25 +122,25 @@ ImageCapture::TakePhotoByMediaEngine()
|
|||
mVideoTrack->RemovePrincipalChangeObserver(this);
|
||||
}
|
||||
|
||||
RefPtr<VideoStreamTrack> mVideoTrack;
|
||||
RefPtr<ImageCapture> mImageCapture;
|
||||
const RefPtr<VideoStreamTrack> mVideoTrack;
|
||||
const RefPtr<ImageCapture> mImageCapture;
|
||||
bool mPrincipalChanged;
|
||||
};
|
||||
|
||||
RefPtr<MediaEnginePhotoCallback> callback =
|
||||
new TakePhotoCallback(mVideoStreamTrack, this);
|
||||
return mVideoStreamTrack->GetSource().TakePhoto(callback);
|
||||
new TakePhotoCallback(mTrack, this);
|
||||
return mTrack->GetSource().TakePhoto(callback);
|
||||
}
|
||||
|
||||
void
|
||||
ImageCapture::TakePhoto(ErrorResult& aResult)
|
||||
{
|
||||
// According to spec, VideoStreamTrack.readyState must be "live"; however
|
||||
// According to spec, MediaStreamTrack.readyState must be "live"; however
|
||||
// gecko doesn't implement it yet (bug 910249). Instead of readyState, we
|
||||
// check VideoStreamTrack.enable before bug 910249 is fixed.
|
||||
// check MediaStreamTrack.enable before bug 910249 is fixed.
|
||||
// The error code should be INVALID_TRACK, but spec doesn't define it in
|
||||
// ImageCaptureError. So it returns PHOTO_ERROR here before spec updates.
|
||||
if (!mVideoStreamTrack->Enabled()) {
|
||||
if (!mTrack->Enabled()) {
|
||||
PostErrorEvent(ImageCaptureError::PHOTO_ERROR, NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
@ -211,7 +215,7 @@ ImageCapture::CheckPrincipal()
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal = mVideoStreamTrack->GetPrincipal();
|
||||
nsCOMPtr<nsIPrincipal> principal = mTrack->GetPrincipal();
|
||||
|
||||
if (!GetOwner()) {
|
||||
return false;
|
||||
|
|
|
@ -21,20 +21,21 @@ LogModule* GetICLog();
|
|||
namespace dom {
|
||||
|
||||
class Blob;
|
||||
class MediaStreamTrack;
|
||||
class VideoStreamTrack;
|
||||
|
||||
/**
|
||||
* Implementation of https://dvcs.w3.org/hg/dap/raw-file/default/media-stream-
|
||||
* capture/ImageCapture.html.
|
||||
* The ImageCapture accepts a VideoStreamTrack as input source. The image will
|
||||
* be sent back as a JPG format via Blob event.
|
||||
* Implementation of https://dvcs.w3.org/hg/dap/raw-file/default/media-stream-
|
||||
* capture/ImageCapture.html.
|
||||
* The ImageCapture accepts a video MediaStreamTrack as input source. The image
|
||||
* will be sent back as a JPG format via Blob event.
|
||||
*
|
||||
* All the functions in ImageCapture are run in main thread.
|
||||
* All the functions in ImageCapture are run in main thread.
|
||||
*
|
||||
* There are two ways to capture image, MediaEngineSource and MediaStreamGraph.
|
||||
* When the implementation of MediaEngineSource supports TakePhoto(),
|
||||
* it uses the platform camera to grab image. Otherwise, it falls back
|
||||
* to the MediaStreamGraph way.
|
||||
* There are two ways to capture image, MediaEngineSource and MediaStreamGraph.
|
||||
* When the implementation of MediaEngineSource supports TakePhoto(),
|
||||
* it uses the platform camera to grab image. Otherwise, it falls back
|
||||
* to the MediaStreamGraph way.
|
||||
*/
|
||||
|
||||
class ImageCapture final : public DOMEventTargetHelper
|
||||
|
@ -49,8 +50,8 @@ public:
|
|||
// WebIDL members.
|
||||
void TakePhoto(ErrorResult& aResult);
|
||||
|
||||
// The MediaStream passed into the constructor.
|
||||
VideoStreamTrack* GetVideoStreamTrack() const;
|
||||
// The MediaStreamTrack passed into the constructor.
|
||||
MediaStreamTrack* GetVideoStreamTrack() const;
|
||||
|
||||
// nsWrapperCache member
|
||||
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
|
||||
|
@ -62,10 +63,10 @@ public:
|
|||
nsPIDOMWindowInner* GetParentObject() { return GetOwner(); }
|
||||
|
||||
static already_AddRefed<ImageCapture> Constructor(const GlobalObject& aGlobal,
|
||||
VideoStreamTrack& aTrack,
|
||||
MediaStreamTrack& aTrack,
|
||||
ErrorResult& aRv);
|
||||
|
||||
ImageCapture(VideoStreamTrack* aVideoStreamTrack,
|
||||
ImageCapture(VideoStreamTrack* aTrack,
|
||||
nsPIDOMWindowInner* aOwnerWindow);
|
||||
|
||||
// Post a Blob event to script.
|
||||
|
@ -85,7 +86,7 @@ protected:
|
|||
// should return NS_ERROR_NOT_IMPLEMENTED.
|
||||
nsresult TakePhotoByMediaEngine();
|
||||
|
||||
RefPtr<VideoStreamTrack> mVideoStreamTrack;
|
||||
RefPtr<VideoStreamTrack> mTrack;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -152,8 +152,6 @@ var interfaceNamesInGlobalScope =
|
|||
{name: "AudioProcessingEvent", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "AudioScheduledSourceNode", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "AudioStreamTrack", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "AudioWorkletNode", insecureContext: false, disabled: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
@ -1154,8 +1152,6 @@ var interfaceNamesInGlobalScope =
|
|||
{name: "ValidityState", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VideoPlaybackQuality", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VideoStreamTrack", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VisualViewport", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* http://dev.w3.org/2011/webrtc/editor/getusermedia.html
|
||||
*
|
||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
// [Constructor(optional MediaTrackConstraints audioConstraints)]
|
||||
interface AudioStreamTrack : MediaStreamTrack {
|
||||
// static sequence<DOMString> getSourceIds ();
|
||||
};
|
|
@ -10,10 +10,10 @@
|
|||
* W3C liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[Pref="dom.imagecapture.enabled", Constructor(VideoStreamTrack track)]
|
||||
[Pref="dom.imagecapture.enabled", Constructor(MediaStreamTrack track)]
|
||||
interface ImageCapture : EventTarget {
|
||||
// readonly attribute PhotoSettingsOptions photoSettingsOptions;
|
||||
readonly attribute VideoStreamTrack videoStreamTrack;
|
||||
readonly attribute MediaStreamTrack videoStreamTrack;
|
||||
attribute EventHandler onphoto;
|
||||
attribute EventHandler onerror;
|
||||
// attribute EventHandler onphotosettingschange;
|
||||
|
|
|
@ -29,8 +29,8 @@ dictionary MediaStreamConstraints {
|
|||
Constructor (sequence<MediaStreamTrack> tracks)]
|
||||
interface MediaStream : EventTarget {
|
||||
readonly attribute DOMString id;
|
||||
sequence<AudioStreamTrack> getAudioTracks ();
|
||||
sequence<VideoStreamTrack> getVideoTracks ();
|
||||
sequence<MediaStreamTrack> getAudioTracks ();
|
||||
sequence<MediaStreamTrack> getVideoTracks ();
|
||||
sequence<MediaStreamTrack> getTracks ();
|
||||
MediaStreamTrack? getTrackById (DOMString trackId);
|
||||
void addTrack (MediaStreamTrack track);
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* http://dev.w3.org/2011/webrtc/editor/getusermedia.html
|
||||
*
|
||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
// [Constructor(optional MediaTrackConstraints videoConstraints)]
|
||||
interface VideoStreamTrack : MediaStreamTrack {
|
||||
// static sequence<DOMString> getSourceIds ();
|
||||
// void takePhoto ();
|
||||
// attribute EventHandler onphoto;
|
||||
// attribute EventHandler onphotoerror;
|
||||
};
|
|
@ -387,7 +387,6 @@ WEBIDL_FILES = [
|
|||
'AudioParamMap.webidl',
|
||||
'AudioProcessingEvent.webidl',
|
||||
'AudioScheduledSourceNode.webidl',
|
||||
'AudioStreamTrack.webidl',
|
||||
'AudioTrack.webidl',
|
||||
'AudioTrackList.webidl',
|
||||
'AudioWorklet.webidl',
|
||||
|
@ -918,7 +917,6 @@ WEBIDL_FILES = [
|
|||
'URLSearchParams.webidl',
|
||||
'ValidityState.webidl',
|
||||
'VideoPlaybackQuality.webidl',
|
||||
'VideoStreamTrack.webidl',
|
||||
'VideoTrack.webidl',
|
||||
'VideoTrackList.webidl',
|
||||
'VisualViewport.webidl',
|
||||
|
|
|
@ -5,16 +5,10 @@
|
|||
[MediaStreamTrack interface: attribute onoverconstrained]
|
||||
expected: FAIL
|
||||
|
||||
[MediaStreamTrack must be primary interface of [object AudioStreamTrack\]]
|
||||
[MediaStreamTrack interface: [object MediaStreamTrack\] must inherit property "getCapabilities()" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[Stringification of [object AudioStreamTrack\]]
|
||||
expected: FAIL
|
||||
|
||||
[MediaStreamTrack interface: [object AudioStreamTrack\] must inherit property "getCapabilities()" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[MediaStreamTrack interface: [object AudioStreamTrack\] must inherit property "onoverconstrained" with the proper type]
|
||||
[MediaStreamTrack interface: [object MediaStreamTrack\] must inherit property "onoverconstrained" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[OverconstrainedErrorEvent interface: existence and properties of interface object]
|
||||
|
|
Загрузка…
Ссылка в новой задаче