26

I am using navigate.getUserMedia() method to capture video on my mobile and do further processing on it. But as of now it is capturing the video using the front camera. How do i make it to access the rear facing camera??

Below is some sample code which i am using in my application:

  navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
  if (navigator.getUserMedia){
    navigator.getUserMedia({video: true}, successCallback, errorCallback);

Thanks in advance

Vinay C
  • 387
  • 1
  • 7
  • 16
  • I think this question is too general, it can depend on the vendor, software and model of the device. – cerkiewny May 29 '13 at 06:45
  • 3
    But this code runs on variety of platforms,.. problem is that it accesses front camera, so there might be some way we can specify it to access rear camera,.. or get a popup of available cameras and let user choose from it.. – Vinay C May 29 '13 at 08:47

5 Answers5

28

This example on simpl.info demonstrates the use of MediaStreamTrack.getSources to select from multiple video sources.

https://simpl.info/getusermedia/sources/

I can confirm that this works in Chrome 32.

freakTheMighty
  • 1,172
  • 1
  • 12
  • 27
  • 3
    This should be the right answer. While not implemented on all devices I can confirm it works in chrome on android not in the regular browser though on my gs2(i know its old). Doesnt work in ios7 but I will be testing this on ios8 beta 3 as soon as I get to the office on Monday. – John S Jul 20 '14 at 14:37
  • well it didn't solve my problem as it doesn't work on iOS safari. Both cameras activated my front camera – djolf Jul 12 '19 at 10:30
26

You can use facingMode to choose "user" or "environment" for front or back camera respectively. Not sure about browser support but it works on Android Chrome 58.

Use

navigator.getUserMedia({video: { facingMode: { exact: "environment" } } },
successCallback, errorCallback);

or, to allow fallback to some other camera

navigator.getUserMedia({video: { facingMode: "environment" } },
successCallback, errorCallback);

instead of

navigator.getUserMedia({video: true}, successCallback, errorCallback);

From https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia

user1318499
  • 1,327
  • 11
  • 33
6
//----------------------------------------------------------------------
//  Here we list all media devices, in order to choose between
//  the front and the back camera.
//      videoDevices[0] : Front Camera
//      videoDevices[1] : Back Camera
//  I used an array to save the devices ID 
//  which i get using devices.forEach()
//  Then set the video resolution.
//----------------------------------------------------------------------
navigator.mediaDevices.enumerateDevices()
.then(devices => {
    var videoDevices = [0,0];
    var videoDeviceIndex = 0;
    devices.forEach(function(device) {
    console.log(device.kind + ": " + device.label +
        " id = " + device.deviceId);
    if (device.kind == "videoinput") {  
        videoDevices[videoDeviceIndex++] =  device.deviceId;    
    }
    });


    var constraints =  {width: { min: 1024, ideal: 1280, max: 1920 },
    height: { min: 776, ideal: 720, max: 1080 },
    deviceId: { exact: videoDevices[1]  } 
};
return navigator.mediaDevices.getUserMedia({ video: constraints });

})
.then(stream => {
    if (window.webkitURL) {
    video.src = window.webkitURL.createObjectURL(stream);
    localMediaStream = stream;
    } else if (video.mozSrcObject !== undefined) {
    video.mozSrcObject = stream;
    } else if (video.srcObject !== undefined) {
    video.srcObject = stream;
    } else {
    video.src = stream;
    }})
.catch(e => console.error(e));
Marcello B.
  • 4,177
  • 11
  • 45
  • 65
Nadhir Houari
  • 390
  • 4
  • 10
  • it will be a better answer if you describe your code there! – Deep Kakkar Mar 20 '17 at 10:46
  • I'm going to explain some lines here. **videoDevices** : is a simple array, which will contain the **id** of the frond and the rear camera. **devices.forEach** : will list all media devices (videos and audio). If a **device.kind == "videoinput"**, its mean it is a video media device, we save the IDs of all videos devices in the previous array **videoDevices**. **var contraints** contains the video resolution and which camera we would like to start. **videoDevices[1] = back Camera** and **videoDevices[0] = front Camera**. Than we pass the constraint to the **getUSerMedia** function. – Nadhir Houari Mar 07 '18 at 13:28
1

Long story short: If you want to select a rear camera on the OLD device which not supported facingMode constraint - you need to use sourceId: { exact: device.id } constraint inside the video: {} config.

Long:

export interface SourceInfo {
  facing: string; // "environment"
  id: string; // "bcb8d32aebb99fdf1d5f2fdb4ec4ec28a381b83f5e3c96cbcb30c4ab757380da"
  kind: string; // "video"
  label: string; // ""
}

code (typescript):

(navigator as any).getUserMedia =
      (navigator as any).getUserMedia ||
      (navigator as any).webkitGetUserMedia ||
      (navigator as any).mozGetUserMedia ||
      (navigator as any).msGetUserMedia;

if (navigator.getUserMedia && (window as any).MediaStreamTrack) {
      (MediaStreamTrack as any).getSources((sources: SourceInfo[]) => {

    this.videoSources = sources.filter((source: SourceInfo) => {
      return source.kind === 'video';
      // or source.facing === 'environment'
    });
    // console.log('got video sources', this.videoSources);

    try {
      const rearCameraDevice = this.videoSources.find((device: SourceInfo) => device.facing === 'environment');
      const anyCameraDevice = this.videoSources[0];
      const constraints = {
        video: {
          mandatory: {
            sourceId: rearCameraDevice.id || anyCameraDevice.id
          }
          // these both not work with old constraints...it's new syntax
          // deviceId: this.videoSources[0].id
          // deviceId: { exact: this.videoSources[0].id }
        }
      };
      navigator.getUserMedia(
        <any>constraints, 
        this.successOldStream.bind(this), 
        this.errorOldStream.bind(this)
      );
    } catch (error) {
      console.error(error);
    }

});
} else {
  console.error('your browser not supported camera/media capturing')
}
Igor Kurkov
  • 4,318
  • 2
  • 30
  • 31
0

You can use facingMode to choose "user" or "environment" for front or back camera respectively. Not sure about browser support but it works on Android Chrome 58.

Use

navigator.getU

serMedia({video: { facingMode: { exact: "environment" } } },
successCallback, errorCallback);

or, to allow fallback to some other camera

navigator.getUserMedia({video: { facingMode: "environment" } },
successCallback, errorCallback);
instead of

navigator.getUserMedia({video: true}, successCallback, errorCallback);

From https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia

This example on simpl.info demonstrates the use of MediaStreamTrack.getSources to select from multiple video sources.

https://simpl.info/getusermedia/sources/

I can confirm that this works in Chrome 32.

cerkiewny
  • 2,761
  • 18
  • 36