title: Select camera on Android Chrome
body: <p>I came across several questions on this subject. I'm trying to select the rear camera on an Android device running Chrome.</p>
  
  <p>So, after some reading : </p>
  
  <pre><code>var selector = document.getElementById('video-source-selector');
  navigator.mediaDevices.enumerateDevices()
    .then(function(devices) {
      var videoDevices = devices.map(function (item) {
        if(item.kind === 'videoinput'){
          return item;
        }
      }).filter(function( element ) {
         return element !== undefined;
      });
      var max = videoDevices.length;
      videoDevices.forEach(function(device, i) {
        var html = '';
        var div = document.createElement('div');
        if(i === max-1){ // last element reached
          html += '&lt;option value="'+device.deviceId+'" selected&gt;'+ device.label +'&lt;/option&gt;';
        }
        else {
          html += '&lt;option value="'+device.deviceId+'"&gt;'+ device.label +'&lt;/option&gt;';
        }
        div.innerHTML = html;
        selector.appendChild(div.childNodes[0]);
  
        console.log(device.kind + ": " + device.label +
          " id = " + device.deviceId);
      });
    })
    .catch(function(err) {
      console.log(err.name + ": " + err.message);
    });
    selector.addEventListener("change", function(){
      console.log(selector.value); // Works as supposed : returns the ID of the selected device
    });
  </code></pre>
  
  <p>Then, as I'm using Three.js in this app, I'm binding this ID to Jerome Etienne three extension WebcamGrabbing (<a href="https://github.com/jeromeetienne/threex.webar" rel="nofollow noreferrer">https://github.com/jeromeetienne/threex.webar</a>):</p>
  
  <pre><code>var videoGrabbing = new THREEx.WebcamGrabbing(selector.value);
  </code></pre>
  
  <p>Then I had to modify <code>THREEx.WebcamGrabbing</code> class this way (I removed the irrelevant parts):</p>
  
  <pre><code>THREEx.WebcamGrabbing = function(sourceDeviceId){
  
      ...
  
      console.log('webcamgrabbing : ', sourceDeviceId); // returns the expected ID
  
      var constraints = {
              video: {
                optional: [{
                  sourceId: sourceDeviceId
                }]
              }
      }
  
  
      // try to get user media
      navigator.getUserMedia( constraints, function(stream){
              domElement.src = URL.createObjectURL(stream);
      }, function(error) {
              console.error("Cant getUserMedia()! due to ", error);
      });
  
  
      ...
  }
  </code></pre>
  
  <p>But still, Chrome on Android is still giving me the stream of the face camera, whatever device I select...</p>
  
  <p>What do I miss?</p>
  
  <p>EDIT : Based on this topic (<a href="https://stackoverflow.com/questions/32086122/getusermedia-facingmode">GetUserMedia - facingmode</a>), I came up with some logs to see what's happening here :</p>
  
  <pre><code>   var constraints = {
              audio: false,
              video: { facingMode: { exact: "environment" } }
      }
  
      console.log('Try to get stream with constraints:', constraints);
  
      navigator.getUserMedia( constraints, function(stream){
              var videoTracks = stream.getVideoTracks();
  
              console.log('Got stream with constraints:', constraints);  // Ok
              console.log('Using video device: ' + videoTracks[0].label);  // &gt; Using video device: camera 0, facing back
  
              for(var i = 0; i &lt; videoTracks.length; i++){
                console.log('Found video device with contraints : ', videoTracks[i].label); // Found video device with contraints :  camera 0, facing back
              }
  
              domElement.src = URL.createObjectURL(stream);
      }, function(error) {
              console.error("Cant getUserMedia()! due to ", error);
      });
  </code></pre>