我正在使用jsartoolkit5
构建类似于this example的项目,我希望能够选择设备的后置摄像头,而不是Chrome
Android
选择前一个作为默认值。
根据此demo中的示例,如果设备有后置摄像头,我已添加以下代码自动切换摄像头。
var videoElement = document.querySelector('canvas');
function successCallback(stream) {
window.stream = stream; // make stream available to console
videoElement.src = window.URL.createObjectURL(stream);
videoElement.play();
}
function errorCallback(error) {
console.log('navigator.getUserMedia error: ', error);
}
navigator.mediaDevices.enumerateDevices().then(
function(devices) {
for (var i = 0; i < devices.length; i++) {
if (devices[i].kind == 'videoinput' && devices[i].label.indexOf('back') !== -1) {
if (window.stream) {
videoElement.src = null;
window.stream.stop();
}
var constraints = {
video: {
optional: [{
sourceId: devices[i].deviceId
}]
}
};
navigator.getUserMedia(constraints, successCallback, errorCallback);
}
}
}
);
问题在于它适用于<video>
代码,但不幸的是jsartoolkit
将内容呈现在canvas
内,因此会引发错误。
我还尝试按照Github存储库中this已关闭的问题中的说明进行操作,但这次我收到以下错误:DOMException: play() can only be initiated by a user gesture
。
您是否知道或有任何关于如何解决此问题的建议?
提前感谢您的回复!
答案 0 :(得分:5)
您正在混合旧的和新的getUserMedia语法
不推荐使用navigator.getUserMedia
,应首选navigator.mediaDevices.getUserMedia
。
另外,我认为optional
不再是约束字典的一部分了。
这部分几乎与此答案重复:https://stackoverflow.com/a/32364912/3702797
您应该可以直接致电
navigator.mediaDevices.getUserMedia({
video: {
facingMode: {
exact: 'environment'
}
}
})
但是Chrome仍然有this bug ,即使@ jib的答案声明它应该与adpater.js polyfill一起使用,我自己也无法让它在我的chrome上工作对于Android。
因此,以前的语法目前仅适用于Android版Firefox。
对于chrome,你确实需要使用enumerateDevices
以及 adapter.js 来使其工作,但不要混淆语法,一切都应该没问题:
let handleStream = s => {
document.body.append(
Object.assign(document.createElement('video'), {
autoplay: true,
srcObject: s
})
);
}
navigator.mediaDevices.enumerateDevices().then(devices => {
let sourceId = null;
// enumerate all devices
for (var device of devices) {
// if there is still no video input, or if this is the rear camera
if (device.kind == 'videoinput' &&
(!sourceId || device.label.indexOf('back') !== -1)) {
sourceId = device.deviceId;
}
}
// we didn't find any video input
if (!sourceId) {
throw 'no video input';
}
let constraints = {
video: {
sourceId: sourceId
}
};
navigator.mediaDevices.getUserMedia(constraints)
.then(handleStream);
});
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
Fiddle for chrome ,需要https。
您必须分叉jsartoolkit项目并编辑artoolkit.api.js。
主要项目目前停用mediaDevices.getUserMedia()
,因此您需要再次启用它,并且您还必须添加sourceId
选项的检查,我们稍后会添加ARController.getUserMediaThreeScene()
来电。{/ p>
您可以在this fork中找到这些编辑的粗略和丑陋的实现。
所以一旦完成,你将不得不重建js文件,然后记得在你的代码中包含adapter.js polyfill。
Here is a working fiddle使用项目演示之一。