2015-08-19 20 views
5

Attualmente sto utilizzando un tablet Android e GetUserMedia per scattare foto nel mio programma.GetUserMedia - facingmode

Apparentemente, la fotocamera predefinita utilizzata 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 "obbligatoria", ma non ha funzionato.

Per favore aiuto.

risposta

12

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

facingMode è not yet implemented in Chrome for Android, ma funziona in modo nativo in Firefox per Android.

È necessario utilizzare standard vincoli tuttavia: (usate 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 + "<br>";
<button onclick="stop();gum('user')">Front</button> 
 
<button onclick="stop();gum('environment')">Back</button> 
 
<div id="div"></div><br> 
 
<video id="video" height="320" autoplay></video> 
 
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

La sintassi { exact: } significa che è necessario il vincolo, e le cose non riuscire se l'utente non ha la fotocamera giusta. Se lo lasci fuori, allora il vincolo è facoltativo, che in Firefox per Android significa che cambia solo il valore predefinito nel selettore della telecamera nel prompt delle autorizzazioni.

+2

In alternativa, è possibile utilizzare [ 'enumerateDevices()'] (https: // developer. mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices) per consentire all'utente di capovolgere le telecamere. Vedi https://webrtc.github.io/samples/src/content/devices/input-output/ – jib

+0

In questo momento, sul mio telefono, questo non funziona.Chrome sta sostenendo il supporto di facingMode, ma in realtà non funziona, e sembra che stia facendo casino sull'adattatore-latest.js. Sono stato in grado di usare il codice in adapter-latest.js per trovare qualcosa che funzioni, un po 'più come la risposta di Peter Unsworth. – user12861

+0

@ user12861 Una [correzione] (https://github.com/webrtc/adapter/pull/371) all'adattatore è imminente. – jib

3

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 è stato:

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

Recupero della 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 utilizzare un plugin Cordova in modo che se si sceglie di allontanarsi da Cordova, non ci sarebbe una migrazione così pesante.

+0

come fai a sapere quale delle fotocamere in enumerateDevices è anteriore e quale è posteriore? Penso che il primo sia rivolto all'utente (davanti) e il secondo sia posteriore, ma (dove) è specificato? – anneb

+0

Quindi in alcuni casi possiamo fare affidamento sul fatto che device.label è "fotocamera 1, frontale" o "fotocamera 0, rivolta indietro". Ma ho anche visto alcuni telefoni dove questo non è riportato, ad es. su LG D852 entrambi i device.labels per i dispositivi della fotocamera sono stringhe vuote. – deweydb

0

Un frammento abbastanza Dandy è possibile utilizzare è:

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

Questo dovrebbe funzionare per voi si spera.

1

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

Utilizzando il codice di Peter (https://stackoverflow.com/a/41618462/7723861) sono arrivato fino a 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); 
}); 
+0

Questo tipo di funziona per alcuni casi, ma per iOS11 questo non funziona. Invece sto usando '' 'constraints.video.facingMode = {exact:" environment "}' '' – deweydb