HTML5根据navigator.mediaDevices.getUserMedia启用手机上摄

2021-02-22 03:56 jianzhan

navigator.mediaDevices.getUserMedia

应新项目规定,必须完成挪动端app嵌入H5网页页面进行实人验证的作用。开启getUserMedia文本文档,连接以下:
https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedia
看上去很简易,最后却写的怀疑人生。

API自然环境

难题1:(为何无论如何配备都显示信息外置摄像头)

想一切正常应用API务必在https自然环境下开展,不然你会发现无论如何写,都只能启用默认设置的摄像头(绝大多数全是外置,仅有少一部分是后置)
前端开发开发设计者能够将文档提交至"码云"库房,获得https连接随后在手机上上预览
连接:码云库房通道

难题2:(API在安卓系统和ios实际效果1样吗?)

依据官方文本文档,现阶段navigator.mediaDevices.getUserMedia在ios上只适用11版本号以上,且只能在safari一切正常运作。安卓系统现阶段沒有发现版本号限定,必须适配的编码以下

if (navigator.mediaDevices === undefined) {
    navigator.mediaDevices = {};
 }
if (navigator.mediaDevices.getUserMedia === undefined) {
    navigator.mediaDevices.getUserMedia = function (constraints) {
    var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;
	if (!getUserMedia) {
	    return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
	}
	return new Promise(function (resolve, reject) {
		getUserMedia.call(navigator, constraints, resolve, reject);
	});
  }
}

难题3:(第1次开启取得成功启用外置摄像头,第2次必须启用后置却黑屏或不成功)

不成功的缘故许多,例举两个1刚开始我遇到的难题
1.外置摄像头启用后,摄像作用必须关掉后才可以一切正常实行第2次启用,不然会出错:机器设备被占有。处理方式,在每次实行启用方式前,先关掉摄像机器设备。

if (window.stream) {
    window.stream.getTracks().forEach(track => {
          track.stop();
    });
}

亲测有效,其他找了许多终止的方式都沒有实际效果。
2.启用后置API的方式還是没法唤起后置摄像头,因而我寻找此外1个方式,根据查询手机上摄像头ID,来立即唤起后置。

var deviceInfoId="", //摄像头ID
    num = 0, //摄像头数量
    carema = []; //摄像头ID数字能量数组
    //在网页页面载入进行后得到机器设备ID数字能量数组
window.onload = navigator.mediaDevices.enumerateDevices().then(gotDevices);
function gotDevices(deviceInfos) {
        for (let i = 0; i < deviceInfos.length; ++i) {
            if (deviceInfos[i].kind === 'videoinput') {
                carema.push(deviceInfos[i].deviceId)
              }
        }
        deviceInfoId = carema[后置部位];
}
            var constraints = {
                audio: false,
                video: {
                    deviceId: deviceInfoId,
                    //放在app里边必须下面配备1下
                    "permissions": {
                        "audio-capture": {
                            "description": "Required to capture audio using getUserMedia()"
                        },
                        "video-capture": {
                            "description": "Required to capture video using getUserMedia()"
                        }
                    }
                }
            };
            navigator.mediaDevices.getUserMedia(constraints)
                .then(function (stream) {
                    var video = document.getElementById('video');
                    try {
                        window.stream = stream;
                        video.srcObject = stream;
                    } catch (error) {
                        video.src = window.URL.createObjectURL(stream);
                    }
                    this.localMediaStream = stream;
                    // video.play();   这个加不加仿佛沒有危害
                })
                .catch(function (err) {
                    console.log(err.name + ": " + err.message);
                });

假如只是1部手机上能够这样,可是检测了多部手机上发现摄像头数字能量数组没什么规律性可循,这个方式慎用。
假如网页页面上加上挑选摄像机器设备的按钮的话,这个方式還是非常好的。查询机器设备能启用几个摄像头连接以下:https://webrtc.github.io/samples/src/content/devices/input-output/
因为大家的新项目网页页面不期待出現切换按钮,应对后置出現的诸多BUG,最后挑选舍弃,应用input启用摄像头。

 <input class="card_input" v-on:change="appCapture($event)" type="file" accept="image/*" capture="camera" />

取得成功启用后用canvas完成成像并融入显示屏尺寸

我这里的编码是取video的宽高随后拷贝给canvas,这样可让canvas和video维持1致,只用给video设定宽度100%,高宽比调整成适合的值,就完成了融入手机上显示屏。

  var video = document.getElementById('video');
            var canvas = document.getElementById('canvas'),
                ctx = canvas.getContext('2d'),
                CHeight = video.clientHeight, //获得显示屏尺寸让canvas自融入
                CWidth = video.clientWidth;
            canvas.width = CWidth;
            canvas.height = CHeight;
            //localMediaStream 在data里界定1个{}
            if (localMediaStream) {
                ctx.drawImage(video, 0, 0, CWidth, CHeight);
                var dataURL = canvas.toDataURL('image/jpeg'); //dataURL = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA'
                img.src = dataURL;

video成像镜像系统难题

API唤起的外置摄像头是相反的,很不舒适很不舒适。
以后用css解决1下给video加上 transform: rotate(180deg),能够完成翻转,可是還是沒有做到和手机上1样的实际效果。
这时候候能够挑选根据机器设备ID启用外置摄像头,外置摄像头的laval1直全是“default”,也是有的是空值,可是也能完成。
配备编码以下:

 var constraints = window.constraints = {
                audio: false,
                video: {
                    sourceId: 'default',
                    facingMode:  { exact: "user" } 
                }
              };

完善启用自身手机上的外置摄像头!!!

详细编码以下:
网页页面编码:

<div @click='moveToCameraAVG()' v-cloak>
     <img v-if="imginfo!==''" :src="imginfo" />
     <div class="warm_title2">点一下自拍1张头像</div>
</div>
<video id="video" class="pic_video" playsinline autoplay x5-video-player-type="h5" style='object-fit:fill'></video>
<canvas id="canvas" class="canvas_pic" style='margin: 0;padding: 0;'></canvas>
<div class="bottom_div">
    <div>照相</div>
    <img src='images/pic_btn.png' class="capture-btn" @click='captureAvg' />
</div>
 // 头像照相机
        moveToCameraAVG() {
            var self = this;
            if (navigator.mediaDevices === undefined) {
                navigator.mediaDevices = {};
            }
            if (navigator.mediaDevices.getUserMedia === undefined) {
                navigator.mediaDevices.getUserMedia = function (constraints) {
                    var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;
                    if (!getUserMedia) {
                        return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
                    }
                    return new Promise(function (resolve, reject) {
                        getUserMedia.call(navigator, constraints, resolve, reject);
                    });
                }
            }
            if (window.stream) {
                window.stream.getTracks().forEach(track => {
                    track.stop();
                });
            }
            var constraints = window.constraints = {
                audio: false,
                video: {
                    sourceId: 'default',
                    facingMode:  { exact: "user" } 
                }
              };
            navigator.mediaDevices.getUserMedia(constraints)
                .then(function (stream) {
                    var video = document.getElementById('video');
                    try {
                        window.stream = stream;
                        video.srcObject = stream;
                    } catch (error) {
                        video.src = window.URL.createObjectURL(stream);
                    }
                    self.localMediaStream = stream;
                    video.play();
                })
                .catch(function (err) {
                    alert(err.name + ": " + err.message);
                });
        },
        //终止监控摄像头
        stopCapture: function () {
            var video = document.getElementById('video');
            if (!video.srcObject) return
            let stream = video.srcObject
            let tracks = stream.getTracks();
            tracks.forEach(track => {
                track.stop()
            })
        },
        // 头像相片
        captureAvg() {
            var vm = this;
            var video = document.getElementById('video');
            var canvas = document.getElementById('canvas'),
                ctx = canvas.getContext('2d'),
                CHeight = video.clientHeight, //获得显示屏尺寸让canvas自融入
                CWidth = video.clientWidth;
            canvas.width = CWidth;
            canvas.height = CHeight;
            if (vm.localMediaStream) {
                ctx.drawImage(video, 0, 0, CWidth, CHeight);
                var dataURL = canvas.toDataURL('image/jpeg'); //dataURL = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA'
                vm.imginfo = dataURL;
                // 终止监控摄像头
                video.pause();
                this.stopCapture();
            }
        },

到此这篇有关HTML5根据navigator.mediaDevices.getUserMedia启用手机上摄像头难题的文章内容就详细介绍到这了,更多有关HTML5启用 摄像头內容请检索脚本制作之家之前的文章内容或再次访问下面的有关文章内容,期待大伙儿之后多多适用脚本制作之家!