GetUserMedia – facingmode

Attualmente sto usando un tablet Android e GetUserMedia per scattare foto nel mio programma.

Apparentemente, la fotocamera predefinita usata da GetUserMedia è la fotocamera frontale. Come si usa la fotocamera posteriore come predefinita?

Ecco il mio codice per GetUserMedia:

navigator.getUserMedia({ "audio": false, "video": { mandatory: { minWidth: this.params.dest_width, minHeight: this.params.dest_height, //facingMode: "environment", }, } }, function(stream) { // got access, attach stream to video video.src = window.URL.createObjectURL( stream ) || stream; Webcam.stream = stream; Webcam.loaded = true; Webcam.live = true; Webcam.dispatch('load'); Webcam.dispatch('live'); Webcam.flip(); }, function(err) { return self.dispatch('error', "Could not access webcam."); }); 

Ho inserito facingMode nella parte “obbligatorio” ma non ha funzionato.

Per favore aiuto.

Aggiornamento: facingMode è ora disponibile in Chrome per Android attraverso il polyfill adapter.js !

facingMode non è ancora implementato in Chrome per Android , ma funziona in modo nativo in Firefox per Android.

Tuttavia, devi utilizzare i vincoli standard : (usa https fiddle per Chrome):

 var gum = mode => navigator.mediaDevices.getUserMedia({video: {facingMode: {exact: mode}}}) .then(stream => (video.srcObject = stream)) .catch(e => log(e)); var stop = () => video.srcObject && video.srcObject.getTracks().forEach(t => t.stop()); var log = msg => div.innerHTML += msg + "
";
   

Distribuendo la nostra app Web su Android tramite Cordova, ho provato più soluzioni per accedere alla telecamera posteriore. La soluzione che ha funzionato per me è stata:

 constraints = { audio: false, video: { width: 400, height: 300, deviceId: deviceId ? {exact: deviceId} : undefined } }; 

Recupero del DeviceId attraverso:

 navigator.mediaDevices.enumerateDevices() .then(function(devices) { // devices is an array of accessible audio and video inputs. deviceId is the property I used to switch cameras }) .catch(function(err) { console.log(err.name + ": " + error.message); }); 

Ho scelto di non usare un plug-in Cordova in modo che se decidessimo di allontanarci da Cordova, non ci sarebbe una migrazione così pesante.

Utilizzando il codice di Peter ( https://stackoverflow.com/a/41618462/7723861 ) mi è venuta in mente questa soluzione per ottenere la fotocamera posteriore:

 function handleSuccess(stream) { window.stream = stream; // make stream available to browser console video.srcObject = stream; } function handleError(error) { console.log('navigator.getUserMedia error: ', error); } var DEVICES = []; var final = null; navigator.mediaDevices.enumerateDevices() .then(function(devices) { var arrayLength = devices.length; for (var i = 0; i < arrayLength; i++) { var tempDevice = devices[i]; //FOR EACH DEVICE, PUSH TO DEVICES LIST THOSE OF KIND VIDEOINPUT (cameras) //AND IF THE CAMERA HAS THE RIGHT FACEMODE ASSING IT TO "final" if (tempDevice.kind == "videoinput") { DEVICES.push(tempDevice); if(tempDevice.facingMode == "environment" ||tempDevice.label.indexOf("facing back")>=0 ) {final = tempDevice;} } } var totalCameras = DEVICES.length; //If couldnt find a suitable camera, pick the last one... you can change to what works for you if(final == null) { //console.log("no suitable camera, getting the last one"); final = DEVICES[totalCameras-1]; }; //Set the constraints and call getUserMedia var constraints = { audio: false, video: { deviceId: {exact: final.deviceId} } }; navigator.mediaDevices.getUserMedia(constraints). then(handleSuccess).catch(handleError); }) .catch(function(err) { console.log(err.name + ": " + err.message); }); 

Nella versione più recente di Chrome (dopo la v52) le soluzioni adaper.js sembrano non funzionare. Quindi risolvo il problema enumerando prima i dispositivi. Ecco la mia soluzione. Non sono sicuro se c’è un modo migliore per capovolgere la fotocamera e mostrare il video sullo schermo. Ma devo prima fermare la traccia e ottenere un nuovo stream.

 let Video = function() { let cameras = []; let currCameraIndex = 0; let constraints = { audio: true, video: { deviceId: { exact: "" } } }; let videoCanvas = $('video#gum'); this.initialize = function() { return enumerateDevices() .then(startVideo); }; this.flipCamera = function() { currCameraIndex += 1; if (currCameraIndex >= cameras.length) { currCameraIndex = 0; } if (window.stream) { window.stream.getVideoTracks()[0].stop(); } return startVideo(); }; function enumerateDevices() { return navigator.mediaDevices.enumerateDevices() .then(function(devices) { devices.forEach(function(device) { console.log(device); if (device.kind === "videoinput") { cameras.push(device.deviceId); } }); console.log(cameras); }); } function startVideo() { constraints.video.deviceId.exact = cameras[currCameraIndex]; return navigator.mediaDevices.getUserMedia(constraints) .then(handleSuccess).catch(handleError); } function handleSuccess(stream) { videoCanvas[0].srcObject = stream; window.stream = stream; } function handleError(error) { alert(error); } }; 

Un bel frammento dandy che puoi usare è:

 var front = false; document.getElementById('flip-button').onclick = function() { front =` !front; }; var constraints = { video: { facingMode: (front? "user" : "environment") } }; 

Questo dovrebbe funzionare per te, si spera.