mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:06:59 +00:00
[dart:html] Unsuppress MediaDevices.getUserMedia
Bug: https://github.com/dart-lang/sdk/issues/35253 This API was suppressed initially due to issues with conversions between promises and futures. Now that that has been resolved, this should be unsuppressed. Tests have been refactored to use both navigator.getUserMedia and navigator.mediaDevices.getUserMedia. Change-Id: Ia131b303192c7eaa3f08475cf700a53665ab3584 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/147640 Reviewed-by: Sigmund Cherem <sigmund@google.com> Commit-Queue: Srujan Gaddam <srujzs@google.com>
This commit is contained in:
parent
7329ebe25e
commit
0afd7a6907
|
@ -20445,6 +20445,15 @@ class MediaDevices extends EventTarget {
|
||||||
|
|
||||||
@JSName('getSupportedConstraints')
|
@JSName('getSupportedConstraints')
|
||||||
_getSupportedConstraints_1() native;
|
_getSupportedConstraints_1() native;
|
||||||
|
|
||||||
|
Future<MediaStream> getUserMedia([Map constraints]) {
|
||||||
|
var constraints_dict = null;
|
||||||
|
if (constraints != null) {
|
||||||
|
constraints_dict = convertDartToNative_Dictionary(constraints);
|
||||||
|
}
|
||||||
|
return promiseToFuture<MediaStream>(
|
||||||
|
JS("", "#.getUserMedia(#)", this, constraints_dict));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
|
|
@ -20484,6 +20484,15 @@ class MediaDevices extends EventTarget {
|
||||||
|
|
||||||
@JSName('getSupportedConstraints')
|
@JSName('getSupportedConstraints')
|
||||||
_getSupportedConstraints_1() native;
|
_getSupportedConstraints_1() native;
|
||||||
|
|
||||||
|
Future<MediaStream> getUserMedia([Map? constraints]) {
|
||||||
|
var constraints_dict = null;
|
||||||
|
if (constraints != null) {
|
||||||
|
constraints_dict = convertDartToNative_Dictionary(constraints);
|
||||||
|
}
|
||||||
|
return promiseToFuture<MediaStream>(
|
||||||
|
JS("", "#.getUserMedia(#)", this, constraints_dict));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
|
|
@ -12,85 +12,81 @@ import 'package:async_helper/async_helper.dart';
|
||||||
|
|
||||||
// NOTE: To test enable chrome://flags/#enable-experimental-web-platform-features
|
// NOTE: To test enable chrome://flags/#enable-experimental-web-platform-features
|
||||||
|
|
||||||
main() async {
|
testUserMediaAudio(Future userMediaFuture) async {
|
||||||
|
try {
|
||||||
|
var mediaStream = await userMediaFuture;
|
||||||
|
expect(mediaStream, isNotNull);
|
||||||
|
expect(mediaStream is MediaStream, true);
|
||||||
|
var devices = window.navigator.mediaDevices;
|
||||||
|
var enumDevices = await devices.enumerateDevices();
|
||||||
|
expect(enumDevices.length > 1, true);
|
||||||
|
for (var device in enumDevices) {
|
||||||
|
var goodDevLabel = device.label.endsWith('Built-in Output') ||
|
||||||
|
device.label.endsWith('Built-in Microphone');
|
||||||
|
expect(goodDevLabel, true);
|
||||||
|
}
|
||||||
|
} on DomException catch (e) {
|
||||||
|
// Could fail if bot machine doesn't support audio or video.
|
||||||
|
expect(e.name == DomException.NOT_FOUND, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testUserMediaVideo(Future userMediaFuture) async {
|
||||||
|
try {
|
||||||
|
var mediaStream = await userMediaFuture;
|
||||||
|
expect(mediaStream, isNotNull);
|
||||||
|
|
||||||
|
var url = Url.createObjectUrlFromStream(mediaStream);
|
||||||
|
expect(url, isNotNull);
|
||||||
|
|
||||||
|
var video = new VideoElement()..autoplay = true;
|
||||||
|
|
||||||
|
var completer = new Completer();
|
||||||
|
video.onError.listen((e) {
|
||||||
|
completer.completeError(e);
|
||||||
|
});
|
||||||
|
video.onPlaying.first.then((e) {
|
||||||
|
completer.complete(video);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.body!.append(video);
|
||||||
|
video.src = url;
|
||||||
|
|
||||||
|
await completer.future;
|
||||||
|
} on DomException catch (e) {
|
||||||
|
// Could fail if bot machine doesn't support audio or video.
|
||||||
|
expect(e.name == DomException.NOT_FOUND, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
if (MediaStream.supported) {
|
if (MediaStream.supported) {
|
||||||
test('getUserMedia audio', () async {
|
test('getUserMedia audio', () async {
|
||||||
try {
|
await testUserMediaAudio(window.navigator
|
||||||
var mediaStream = await window.navigator.getUserMedia(audio: true);
|
.getUserMedia(audio: true)); // Deprecated way to get a media stream.
|
||||||
expect(mediaStream, isNotNull);
|
await testUserMediaAudio(
|
||||||
expect(mediaStream is MediaStream, true);
|
window.navigator.mediaDevices.getUserMedia({'audio': true}));
|
||||||
var devices = window.navigator.mediaDevices;
|
|
||||||
var enumDevices = await devices.enumerateDevices();
|
|
||||||
expect(enumDevices.length > 1, true);
|
|
||||||
for (var device in enumDevices) {
|
|
||||||
var goodDevLabel = device.label.endsWith('Built-in Output') ||
|
|
||||||
device.label.endsWith('Built-in Microphone');
|
|
||||||
expect(goodDevLabel, true);
|
|
||||||
}
|
|
||||||
} on DomException catch (e) {
|
|
||||||
// Could fail if bot machine doesn't support audio or video.
|
|
||||||
expect(e.name == DomException.NOT_FOUND, true);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('getUserMedia', () {
|
test('getUserMedia', () async {
|
||||||
return window.navigator.getUserMedia(video: true).then((stream) {
|
await testUserMediaVideo(window.navigator
|
||||||
expect(stream, isNotNull);
|
.getUserMedia(video: true)); // Deprecated way to get a media stream.
|
||||||
|
await testUserMediaVideo(
|
||||||
var url = Url.createObjectUrlFromStream(stream);
|
window.navigator.mediaDevices.getUserMedia({'video': true}));
|
||||||
expect(url, isNotNull);
|
|
||||||
|
|
||||||
var video = new VideoElement()..autoplay = true;
|
|
||||||
|
|
||||||
var completer = new Completer();
|
|
||||||
video.onError.listen((e) {
|
|
||||||
completer.completeError(e);
|
|
||||||
});
|
|
||||||
video.onPlaying.first.then((e) {
|
|
||||||
completer.complete(video);
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body!.append(video);
|
|
||||||
video.src = url;
|
|
||||||
|
|
||||||
return completer.future;
|
|
||||||
}).catchError((dynamic e) {
|
|
||||||
// Could fail if bot machine doesn't support audio or video.
|
|
||||||
expect(e.name == DomException.NOT_FOUND, true);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('getUserMediaComplexConstructor', () {
|
test('getUserMediaComplexConstructor', () async {
|
||||||
return window.navigator.getUserMedia(video: {
|
var videoOptions = {
|
||||||
'mandatory': {'minAspectRatio': 1.333, 'maxAspectRatio': 1.334},
|
'mandatory': {'minAspectRatio': 1.333, 'maxAspectRatio': 1.334},
|
||||||
'optional': [
|
'optional': [
|
||||||
{'minFrameRate': 60},
|
{'minFrameRate': 60},
|
||||||
{'maxWidth': 640}
|
{'maxWidth': 640}
|
||||||
]
|
]
|
||||||
}).then((stream) {
|
};
|
||||||
expect(stream, isNotNull);
|
await testUserMediaVideo(window.navigator.getUserMedia(
|
||||||
|
video: videoOptions)); // Deprecated way to get a media stream.
|
||||||
var url = Url.createObjectUrlFromStream(stream);
|
await testUserMediaVideo(
|
||||||
expect(url, isNotNull);
|
window.navigator.mediaDevices.getUserMedia({'video': videoOptions}));
|
||||||
|
|
||||||
var video = new VideoElement()..autoplay = true;
|
|
||||||
|
|
||||||
var completer = new Completer();
|
|
||||||
video.onError.listen((e) {
|
|
||||||
completer.completeError(e);
|
|
||||||
});
|
|
||||||
video.onPlaying.first.then((e) {
|
|
||||||
completer.complete(video);
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body!.append(video);
|
|
||||||
video.src = url;
|
|
||||||
|
|
||||||
return completer.future;
|
|
||||||
}).catchError((dynamic e) {
|
|
||||||
// Could fail if bot machine doesn't support audio or video.
|
|
||||||
expect(e.name == DomException.NOT_FOUND, true);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,85 +12,81 @@ import 'package:async_helper/async_helper.dart';
|
||||||
|
|
||||||
// NOTE: To test enable chrome://flags/#enable-experimental-web-platform-features
|
// NOTE: To test enable chrome://flags/#enable-experimental-web-platform-features
|
||||||
|
|
||||||
main() async {
|
testUserMediaAudio(Future userMediaFuture) async {
|
||||||
|
try {
|
||||||
|
var mediaStream = await userMediaFuture;
|
||||||
|
expect(mediaStream, isNotNull);
|
||||||
|
expect(mediaStream is MediaStream, true);
|
||||||
|
var devices = window.navigator.mediaDevices;
|
||||||
|
var enumDevices = await devices.enumerateDevices();
|
||||||
|
expect(enumDevices.length > 1, true);
|
||||||
|
for (var device in enumDevices) {
|
||||||
|
var goodDevLabel = device.label.endsWith('Built-in Output') ||
|
||||||
|
device.label.endsWith('Built-in Microphone');
|
||||||
|
expect(goodDevLabel, true);
|
||||||
|
}
|
||||||
|
} on DomException catch (e) {
|
||||||
|
// Could fail if bot machine doesn't support audio or video.
|
||||||
|
expect(e.name == DomException.NOT_FOUND, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testUserMediaVideo(Future userMediaFuture) async {
|
||||||
|
try {
|
||||||
|
var mediaStream = await userMediaFuture;
|
||||||
|
expect(mediaStream, isNotNull);
|
||||||
|
|
||||||
|
var url = Url.createObjectUrlFromStream(mediaStream);
|
||||||
|
expect(url, isNotNull);
|
||||||
|
|
||||||
|
var video = new VideoElement()..autoplay = true;
|
||||||
|
|
||||||
|
var completer = new Completer();
|
||||||
|
video.onError.listen((e) {
|
||||||
|
completer.completeError(e);
|
||||||
|
});
|
||||||
|
video.onPlaying.first.then((e) {
|
||||||
|
completer.complete(video);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.body.append(video);
|
||||||
|
video.src = url;
|
||||||
|
|
||||||
|
await completer.future;
|
||||||
|
} on DomException catch (e) {
|
||||||
|
// Could fail if bot machine doesn't support audio or video.
|
||||||
|
expect(e.name == DomException.NOT_FOUND, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
if (MediaStream.supported) {
|
if (MediaStream.supported) {
|
||||||
test('getUserMedia audio', () async {
|
test('getUserMedia audio', () async {
|
||||||
try {
|
await testUserMediaAudio(window.navigator
|
||||||
var mediaStream = await window.navigator.getUserMedia(audio: true);
|
.getUserMedia(audio: true)); // Deprecated way to get a media stream.
|
||||||
expect(mediaStream, isNotNull);
|
await testUserMediaAudio(
|
||||||
expect(mediaStream is MediaStream, true);
|
window.navigator.mediaDevices.getUserMedia({'audio': true}));
|
||||||
var devices = window.navigator.mediaDevices;
|
|
||||||
var enumDevices = await devices.enumerateDevices();
|
|
||||||
expect(enumDevices.length > 1, true);
|
|
||||||
for (var device in enumDevices) {
|
|
||||||
var goodDevLabel = device.label.endsWith('Built-in Output') ||
|
|
||||||
device.label.endsWith('Built-in Microphone');
|
|
||||||
expect(goodDevLabel, true);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// Could fail if bot machine doesn't support audio or video.
|
|
||||||
expect(e.name == DomException.NOT_FOUND, true);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('getUserMedia', () {
|
test('getUserMedia', () async {
|
||||||
return window.navigator.getUserMedia(video: true).then((stream) {
|
await testUserMediaVideo(window.navigator
|
||||||
expect(stream, isNotNull);
|
.getUserMedia(video: true)); // Deprecated way to get a media stream.
|
||||||
|
await testUserMediaVideo(
|
||||||
var url = Url.createObjectUrlFromStream(stream);
|
window.navigator.mediaDevices.getUserMedia({'video': true}));
|
||||||
expect(url, isNotNull);
|
|
||||||
|
|
||||||
var video = new VideoElement()..autoplay = true;
|
|
||||||
|
|
||||||
var completer = new Completer();
|
|
||||||
video.onError.listen((e) {
|
|
||||||
completer.completeError(e);
|
|
||||||
});
|
|
||||||
video.onPlaying.first.then((e) {
|
|
||||||
completer.complete(video);
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.append(video);
|
|
||||||
video.src = url;
|
|
||||||
|
|
||||||
return completer.future;
|
|
||||||
}).catchError((e) {
|
|
||||||
// Could fail if bot machine doesn't support audio or video.
|
|
||||||
expect(e.name == DomException.NOT_FOUND, true);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('getUserMediaComplexConstructor', () {
|
test('getUserMediaComplexConstructor', () async {
|
||||||
return window.navigator.getUserMedia(video: {
|
var videoOptions = {
|
||||||
'mandatory': {'minAspectRatio': 1.333, 'maxAspectRatio': 1.334},
|
'mandatory': {'minAspectRatio': 1.333, 'maxAspectRatio': 1.334},
|
||||||
'optional': [
|
'optional': [
|
||||||
{'minFrameRate': 60},
|
{'minFrameRate': 60},
|
||||||
{'maxWidth': 640}
|
{'maxWidth': 640}
|
||||||
]
|
]
|
||||||
}).then((stream) {
|
};
|
||||||
expect(stream, isNotNull);
|
await testUserMediaVideo(window.navigator.getUserMedia(
|
||||||
|
video: videoOptions)); // Deprecated way to get a media stream.
|
||||||
var url = Url.createObjectUrlFromStream(stream);
|
await testUserMediaVideo(
|
||||||
expect(url, isNotNull);
|
window.navigator.mediaDevices.getUserMedia({'video': videoOptions}));
|
||||||
|
|
||||||
var video = new VideoElement()..autoplay = true;
|
|
||||||
|
|
||||||
var completer = new Completer();
|
|
||||||
video.onError.listen((e) {
|
|
||||||
completer.completeError(e);
|
|
||||||
});
|
|
||||||
video.onPlaying.first.then((e) {
|
|
||||||
completer.complete(video);
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.append(video);
|
|
||||||
video.src = url;
|
|
||||||
|
|
||||||
return completer.future;
|
|
||||||
}).catchError((e) {
|
|
||||||
// Could fail if bot machine doesn't support audio or video.
|
|
||||||
expect(e.name == DomException.NOT_FOUND, true);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -315,11 +315,6 @@ interface SVGNumber {
|
||||||
[DartStrictTypeChecking, Custom] attribute float value;
|
[DartStrictTypeChecking, Custom] attribute float value;
|
||||||
};
|
};
|
||||||
|
|
||||||
[DartSupplemental]
|
|
||||||
interface MediaDevices {
|
|
||||||
[DartSuppress] Promise<MediaStream> getUserMedia(optional MediaStreamConstraints constraints);
|
|
||||||
};
|
|
||||||
|
|
||||||
[DartSupplemental]
|
[DartSupplemental]
|
||||||
interface Navigator {
|
interface Navigator {
|
||||||
[DartSuppress] void getUserMedia(MediaStreamConstraints constraints,
|
[DartSuppress] void getUserMedia(MediaStreamConstraints constraints,
|
||||||
|
|
Loading…
Reference in a new issue