Select Android 设备上的后置摄像头 - jsartoolkit5
Select rear camera on Android device - jsartoolkit5
我正在使用 jsartoolkit5
构建一个类似于 this example 的项目,我希望能够 select 我设备的后置摄像头而不是让 Chrome
上 Android
select 默认为前面一个。
根据此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
.
您知道如何解决这个问题或有什么建议吗?
提前感谢您的回复!
主要问题:
您正在混合新旧 getUserMedia 语法。
navigator.getUserMedia
已弃用,navigator.mediaDevices.getUserMedia
应该是首选。
另外,我认为 optional
不再是约束字典的一部分。
默认解决方案
这部分几乎是这个答案的重复:
你应该可以直接调用
navigator.mediaDevices.getUserMedia({
video: {
facingMode: {
exact: 'environment'
}
}
})
但是 chrome 仍然有 this bug, and even if @jib's answer states that it should work with 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 一起工作
您必须 fork jsartoolkit 项目并编辑 artoolkit.api.js。
主项目目前禁用 mediaDevices.getUserMedia()
,因此您需要再次启用它,并且您还必须添加对 sourceId
选项的检查,我们将添加稍后在 ARController.getUserMediaThreeScene()
通话中。
您可以在 this fork 中找到这些编辑的粗略和丑陋的实现。
所以一旦完成,您将不得不重建 js 文件,然后记得在您的代码中包含 adapter.js polyfill。
Here is a working fiddle 使用项目的演示之一。
我正在使用 jsartoolkit5
构建一个类似于 this example 的项目,我希望能够 select 我设备的后置摄像头而不是让 Chrome
上 Android
select 默认为前面一个。
根据此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
.
您知道如何解决这个问题或有什么建议吗?
提前感谢您的回复!
主要问题:
您正在混合新旧 getUserMedia 语法。
navigator.getUserMedia
已弃用,navigator.mediaDevices.getUserMedia
应该是首选。
另外,我认为 optional
不再是约束字典的一部分。
默认解决方案
这部分几乎是这个答案的重复:
你应该可以直接调用
navigator.mediaDevices.getUserMedia({
video: {
facingMode: {
exact: 'environment'
}
}
})
但是 chrome 仍然有 this bug, and even if @jib's answer states that it should work with 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 一起工作
您必须 fork jsartoolkit 项目并编辑 artoolkit.api.js。
主项目目前禁用 mediaDevices.getUserMedia()
,因此您需要再次启用它,并且您还必须添加对 sourceId
选项的检查,我们将添加稍后在 ARController.getUserMediaThreeScene()
通话中。
您可以在 this fork 中找到这些编辑的粗略和丑陋的实现。
所以一旦完成,您将不得不重建 js 文件,然后记得在您的代码中包含 adapter.js polyfill。
Here is a working fiddle 使用项目的演示之一。