Select rear camera on Android device - jsartoolkit5

I am creating a project similar to this example with jsartoolkit5 , and I would like to be able to select the rear view camera of my device, and not let Chrome on Android choose the front one by default.

Following the example in this demo, I added the code below to automatically switch from the camera if the device has a rear camera.

 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); } } } ); 

The problem is that it works fine for the <video> , but unfortunately jsartoolkit displays the contents inside the canvas and therefore throws an error. I also tried following the instructions in this closed issue in the Github repository, but this time I get the following error: DOMException: play() can only be initiated by a user gesture .

Do you know or have any suggestion on how to solve this problem?

Thanks in advance for your answers!

+6
source share
1 answer

Main problem:

You mix the old and new getUserMedia syntax.
navigator.getUserMedia deprecated, and navigator.mediaDevices.getUserMedia should be preferred. Also, I think optional no longer included in the constraint dictionary.

Default solution

This part almost duplicates this answer: fooobar.com/questions/290065 / ...

You should be able to call directly

 navigator.mediaDevices.getUserMedia({ video: { facingMode: { exact: 'environment' } } }) 

But chrome still has this error , and even if @jib says that it should work with adpater.js polyfill, I myself could not get it to work on my chrome for Android.

Thus, the previous syntax will only work in Firefox for Android.

For chrome, you really need to use enumerateDevices along with the .js adapter to make it work, but don't mix the syntax and everything should be fine:

 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.imtqy.com/adapter/adapter-latest.js"></script> 

Fiddle for chrome , which requires https.

Make it work with jsartoolkit

You will need the fork jsartoolkit project and edit artoolkit.api.js .

The main project is currently disabling mediaDevices.getUserMedia() , so you will need to enable it again, and you also need to add a check for the sourceId parameter, which we will add later in the ARController.getUserMediaThreeScene() call.

You can find a rough and ugly implementation of these changes in this fork .

So, once this is done, you will have to rebuild the js files, and then remember to include the adapter.js polyfill in your code.

Here is a working script that uses one of the project demos.

+5
source

Source: https://habr.com/ru/post/1014186/


All Articles