JavaScript uses the Mediadevices API to select the camera

Source: Internet
Author: User
Tags event listener

Most smartphones have front and rear cameras, and when you create a video app you may want to select or toggle the front and rear camera.

If you're developing a chat app, you're probably going to want to call a front-facing camera, but if you're developing a photo software, you'll be more inclined to use the rear-facing camera. In this article we will explore how to select or switch the camera through mediadevices API and media constraints (media constraints).

Preparatory work

To follow this article with hands-on practice you need:

    • An IOS or Android device with two cameras to test if your computer has two cameras that can

    • Ngrok so you can easily access your items via mobile device (also because I think ngrok fried chicken sticks)

    • This GitHub library code lets you get started.

To get the code, first clone the item and checkout it to initial-project tag.

git clone https://github. com/philnash/mediadevices-camera-selection. Git -B initial-project

CD mediadevices-camera-selection

This start-up project has already prepared some HTML and CSS for you, so we can focus our attention on JavaScript. You can open index.html directly, but I suggest you use a webserver to host the files. I like to use NPM's serve module. I have introduced serve in this library and you need to use NPM to install dependencies and start the service.

NPM Install

NPM start

After the service is running, we need to open a tunnel with Ngrok. Serve with 5000 port managed file, to use Ngrok to open the tunnel to this port, a new command line window to enter the following command:

' Ngrok http 5000 '

OK, now you can access this site on the public network, you can open this website on the mobile device, so you can test it next. Make sure you open the HTTPS URL because the API we use is only available in a secure environment.

The site looks like this:

Get Media Stream

Our first task was to get the video stream from any camera to display on the screen. After completing this we will investigate how to select a specific camera. To open App.js, we start by selecting the button and the video element from the DOM:

App.js

Const video = document. getElementById(' video ');

Const button = document. getElementById(' button ');

When the user taps or touches the button, we use the mediadevices API to request camera permissions. To do this, we're going to call Navigator.mediaDevices.getUserMedia and pass the media constraints object. Let's start with a simple constraints, we only need the video, so we set video to True,audio set to false.

Getusermedia will return a promise, and when resolve we can access the media stream of the camera. By assigning the media stream to the Srcobj property of the video element, we can see the video from the screen.

Button. AddEventListener(' click ', Event => {

Const Constraints = {

Video: true,

Audio: false

};

Navigator. Mediadevices

. Getusermedia(Constraints)

. Then (Stream => {

Video. Srcobject = Stream;

})

. catch(Error => {

Console. Error(Error);

});

});

Save the file, reload the page, and then click the button. You should be able to see a Permissions dialog box requesting access to your webcam, and the video should appear on the authorization screen. Try it on your computer and mobile phone, I tried it on my iPhone, and I chose the front-facing camera.

If you're using an iPhone, make sure you're trying in Safari because other browsers seem to have no effect.

Available cameras

The media Devices API gives us a way to enumerate all available audio and video input devices. We're going to use the enumeratedevices function toBox build option so that we can use it to select the camera we want to see. Open App.js again and select from DOMElements:

Const video = document. getElementById(' video ');

Const button = document. getElementById(' button ');

Const SELECT = document. getElementById(' select ');

Enumeratedevices will return a promise, so let's write a function to accept the promise result. This function receives a media device array as a parameter.

The first thing to do is to emptyAny of the existing options, and then insert an empty。 It then loops through all the devices, filtering out devices that are not "videoinput" types. Then we create aThe   element, using the device ID as option value, is the device label as option text. We also have to deal with a situation where if a device does not have a label present, a simple "Camera n" is generated as a label. Const VIDEO = document.getElementById (' video '); Const BUTTON = document.getElementById (' button '); Const SELECT = document.getElementById (' select ');  function gotdevices (mediadevices) {    select.innerhtml = ';   select.appendchild (document.createelement (' option '));   let count = 1;    mediadevices.foreach (Mediadevice = {     if (mediadevice.kind = = ' Videoinput ') {      const option = document.createelement (' option ');       option.value = Mediadevice.deviceid;       const label = Mediadevice.label | | ' Camera ${count++} ';       const textnode = document.createtextnode (label);       option.appendchild (Textnode);       select.appendchild (option);     }   }); } at the end of the app.js call Enumeratedevices. ' Navigator.mediaDevices.enumerateDevices () then (gotdevices); ' Refresh the page and look at the drop-down selection box next to the button. If you're using Android, or if you're using Chrome or Firefox, you'll be able to see the available camera names. On the IPhone, however, you will see the generic name "Camera 1" and "Camera 2" that our function generates. On IOS only you authorize at least one webcam to the website, you can see the name of the camera. This makes it even more inconvenient to choose the camera on our interface, because even though you can get the device ID, you can't tell which camera is which.   Currently we have not processed the dropdown selection box to change the camera. Before that, let's look at another way to change which camera is used. The Facingmode facingmode constraint is an alternative to choosing a camera. This method is less accurate than getting the ID from the Enumeratedevices function, but it works very well on mobile devices. For this constraint, there are four options for you to choose from: User, Environment (environment), left and right. This constraint is described in detail in the documentation on the MDN, and for the purposes of this article we will use the user and environment models, which correspond exactly to the front and rear cameras on the mobile device. To use the Facingmode constraint we need to modify the constraints object used when calling Getusermedia. For video We need an object to control the specific constraints instead of giving a true value. Modify the code like this to use the front-facing camera: Button.addeventlistener (' click ', event = {   const videoconstraints = {    & Nbsp;facingmode: ' user '    };   const constraints = {     video:videoconstraints,& nbsp    audio:false   }; Now you can test it with your phone. You should be able to see the front-facing camera being used. Change Facingmode to EnvIronment try again, the rear camera should be used. Let's put the code together with the results obtained above through enumeratedevices, as long as we have access to the camera data, we can build a camera switcher. Toggle camera Now we have the code to pick the user or the environment camera when we first select it, but if we're going to switch the camera, there's one more job to do. First, we should keep a reference to the current stream so that we can stop the current stream when we switch to another stream. Add an extra variable and auxiliary function at the front of the App.js to stop the tracks in the stream. Const VIDEO = document.getElementById (' video '); Const BUTTON = document.getElementById (' button '); Const SELECT = document.getElementById (' select '); Let currentstream;  function Stopmediatracks (stream) {   stream.gettracks (). ForEach (track = {      track.stop ();   }); } function Stopmediatracks receives a media stream, loops through each media track in the stream, and calls the Stop method to stop the media rail. We want to change the camera when we click the same button, so we need to update the event listener for the button. If there is currently a media stream, we should stop it first. And then we're going to check  element to see if a specific device is selected, and then construct the media constraints object based on this.

This modifies the button's click-handling function and video constraints:

Button. AddEventListener(' click ', Event => {

if (typeof currentstream !== ' undefined ') {

stopmediatracks(currentstream);

}

const Videoconstraints = {};

if (select. value = = = ) {

Videoconstraints. Facingmode = ' Environment ';

} Else {

Videoconstraints. DeviceId = {exact: Select. Value };

}

Const Constraints = {

Video: videoconstraints,

Audio: false

};

The exact constraint is used when we want to select a device through DeviceId. However, for Facingmode, we did not use exact constraint, otherwise we would fail on a device that does not recognize the user or environment mode, which will cause us to not get any media devices.

When we get permission to use the video, we have to modify something else within the click handler function. Assigns a new stream passed to the function to Currentstream for subsequent calls to stop, triggering another enumeratedevices call.

Enumeratedevices returns a promise, so we can return it directly in our then function, and then link to create a new then pass the result to the Gotdevices function processing.

Replace the existing Getusermedia call with the following code:

Button. AddEventListener(' click ', Event => {

if (typeof currentstream !== ' undefined ') {

stopmediatracks(currentstream);

}

const Videoconstraints = {};

if (select. value = = = ) {

Videoconstraints. Facingmode = ' Environment ';

} Else {

Videoconstraints. DeviceId = {exact: Select. Value };

}

Const Constraints = {

Video: videoconstraints,

Audio: false

};

Navigator. Mediadevices

. Getusermedia(Constraints)

. Then (Stream => {

Currentstream = Stream;

Video. Srcobject = Stream;

return navigator. mediadevices. Enumeratedevices();

})

. Then (gotdevices)

. catch(Error => {

Console. Error(Error);

});

});

When you have added all the code, your app.js should look like this file. Refresh the page and you'll be happy to choose and change the camera. This page is available on both the mobile device and the computer.

Next

We've seen how to select a user's webcam by using Facingmode and deviceId constraints. Remember, Facingmode is more reliable before you have permission to use the camera, but choosing deviceId is more accurate. You can get all the code in this article from the GitHub repository, and you can also try the online version of the app here.

If you are building a video app using Twilio video, you can use these constraints when calling connect or Createlocalvideotrack.

For video chat, selecting and switching cameras is a very useful feature that allows users to select exactly the camera they want to use in your app's interface, and also to share your screen during a video call.

JavaScript uses the Mediadevices API to select the camera

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.