preface

A few days ago, when the online written test, found that the browser agreed to open the camera, feeling like JS call, because of the written test at that time, also did not expect so much 🤣. Today, I have nothing todo. I looked at my todo and found this todo that calls the camera. Then I thought of 😂. Check online, sure enough JS has called the camera API, so write a demo, to avoid forgetting.

The body of the

Calling the Camera

There are two ways to implement this. One is to use navigator.getUserMedia (this feature has been removed from the Web standard, although some browsers still support it, but may stop supporting it at some point in the future, please try not to use this feature). The former one has been removed from the Web standard. Only for backward compatibility, the second is to use the navigator. MediaDevices. GetUserMedia (recommended), the two methods Safari seemingly don’t support…

  • The first waynavigator.getUserMediaUsage as shown in themdn, the code is as follows:

      
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Camera Call 1</title>
</head>

<body>
    <video id="v"></video>
    <script>! (function () {
            function userMedia() {
                return navigator.getUserMedia = navigator.getUserMedia ||
                    navigator.webkitGetUserMedia ||
                    navigator.mozGetUserMedia ||
                    navigator.msGetUserMedia || null;
            }
            if (userMedia()) {
                var constraints = {
                    video: true.audio: false
                };
                var media = navigator.getUserMedia(constraints, function (stream) {
                    var v = document.getElementById('v');
                    var url = window.URL || window.webkitURL;
                    v.src = url ? url.createObjectURL(stream) : stream;
                    v.play();
                }, function (error) {
                    console.log("ERROR");
                    console.log(error);
                });
            } else {
                console.log("Not supported");
            }
        })();
    </script>
</body>
</html>
Copy the code
  • The second waynavigator.mediaDevices.getUserMediaUsage as shown in themdn.navigator.mediaDevices.getUserMediaThe second one returns a Promise object with the following code:

      
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Camera Call 2</title>
</head>

<body>
    <video id="v"></video>
    <script>! (function () {
            // Older browsers may not implement mediaDevices at all, so we can set an empty object first
            if (navigator.mediaDevices === undefined) {
                navigator.mediaDevices = {};
            }
            if (navigator.mediaDevices.getUserMedia === undefined) {
                navigator.mediaDevices.getUserMedia = function (constraints) {
                    // First, get getUserMedia, if there is one
                    var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;

                    // Some browsers don't implement it at all - so return an error to the Promise reject to keep a unified interface
                    if(! getUserMedia) {return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
                    }

                    // Otherwise wrap a Promise for the old navigator.getUserMedia method
                    return new Promise(function (resolve, reject) { getUserMedia.call(navigator, constraints, resolve, reject); }); }}const constraints = {
                video: true.audio: false
            };
            let promise = navigator.mediaDevices.getUserMedia(constraints);
            promise.then(stream= > {
                let v = document.getElementById('v');
                // Older browsers may not have srcObject
                if ("srcObject" in v) {
                    v.srcObject = stream;
                } else {
                    // Prevent it from being used in newer browsers as it is no longer supported
                    v.src = window.URL.createObjectURL(stream);
                }
                v.onloadedmetadata = function (e) {
                    v.play();
                };
            }).catch(err= > {
                console.error(err.name + ":" + err.message);
            })
        })();
    </script>
</body>
</html>
Copy the code

Taking pictures

If videoPlaying is true, use a canvas to get the width and height of the video (default canvas is not displayed). Then use canvas’s drawImage and canvas’s toDataURL to return a data URL. Set this URL to an IMG tag 😀

  • The first waynavigator.getUserMediaImplementation code:

      
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Photo 1</title>
</head>
<body>
    <button id="take">Taking pictures</button>
    <br />
    <video id="v" style="width: 640px; height: 480px;"></video>
    <canvas id="canvas" style="display:none;"></canvas>
    <br />
    <img src="http://placehold.it/640&text=Your%20image%20here%20..." id="photo" alt="photo">
    <script>! (function () {
            function userMedia() {
                return navigator.getUserMedia = navigator.getUserMedia ||
                    navigator.webkitGetUserMedia ||
                    navigator.mozGetUserMedia ||
                    navigator.msGetUserMedia || null;
            }
            if (userMedia()) {
                let videoPlaying = false;
                let constraints = {
                    video: true.audio: false
                };
                let video = document.getElementById('v');
                let media = navigator.getUserMedia(constraints, function (stream) {
                    let url = window.URL || window.webkitURL;
                    video.src = url ? url.createObjectURL(stream) : stream;
                    video.play();
                    videoPlaying = true;
                }, function (error) {
                    console.log("ERROR");
                    console.log(error);
                });
                document.getElementById('take').addEventListener('click'.function () {
                    if (videoPlaying) {
                        let canvas = document.getElementById('canvas');
                        canvas.width = video.videoWidth;
                        canvas.height = video.videoHeight;
                        canvas.getContext('2d').drawImage(video, 0.0);
                        let data = canvas.toDataURL('image/webp');
                        document.getElementById('photo').setAttribute('src', data); }},false);
            } else {
                console.log("Not supported");
            }
        })();
    </script>
</body>
</html>
Copy the code

The second kind of the navigator. MediaDevices. GetUserMedia implementation method:


      
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Picture 2</title>
</head>

<body>
    <button id="take">Taking pictures</button>
    <br />
    <video id="v" style="width: 640px; height: 480px;"></video>
    <canvas id="canvas" style="display:none;"></canvas>
    <br />
    <img src="http://placehold.it/640&text=Your%20image%20here%20..." id="photo" alt="photo">
    <script>! (function () {
            // Older browsers may not implement mediaDevices at all, so we can set an empty object first
            if (navigator.mediaDevices === undefined) {
                navigator.mediaDevices = {};
            }
            if (navigator.mediaDevices.getUserMedia === undefined) {
                navigator.mediaDevices.getUserMedia = function (constraints) {
                    // First, get getUserMedia, if there is one
                    var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;

                    // Some browsers don't implement it at all - so return an error to the Promise reject to keep a unified interface
                    if(! getUserMedia) {return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
                    }

                    // Otherwise wrap a Promise for the old navigator.getUserMedia method
                    return new Promise(function (resolve, reject) { getUserMedia.call(navigator, constraints, resolve, reject); }); }}const constraints = {
                video: true.audio: false
            };
            let videoPlaying = false;
            let v = document.getElementById('v');
            let promise = navigator.mediaDevices.getUserMedia(constraints);
            promise.then(stream= > {
                // Older browsers may not have srcObject
                if ("srcObject" in v) {
                    v.srcObject = stream;
                } else {
                    // Prevent it from being used in newer browsers as it is no longer supported
                    v.src = window.URL.createObjectURL(stream);
                }
                v.onloadedmetadata = function (e) {
                    v.play();
                    videoPlaying = true;
                };
            }).catch(err= > {
                console.error(err.name + ":" + err.message);
            })
            document.getElementById('take').addEventListener('click'.function () {
                if (videoPlaying) {
                    let canvas = document.getElementById('canvas');
                    canvas.width = v.videoWidth;
                    canvas.height = v.videoHeight;
                    canvas.getContext('2d').drawImage(v, 0.0);
                    let data = canvas.toDataURL('image/webp');
                    document.getElementById('photo').setAttribute('src', data); }},false); }) ();</script>
</body>

</html>
Copy the code