在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
navigator.mediaDevices.getUserMedia 应项目要求,需要实现移动端app嵌入H5页面完成实人认证的功能。打开getUserMedia文档,链接如下: API环境 问题一:(为什么不管怎么配置都显示前置摄像头) 想正常使用API必须在https环境下进行,否则你会发现不管怎么写,都只能调用默认的摄像头(大部分都是前置,只有少部分是后置) 问题二:(API在安卓和ios效果一样吗?) 根据官方文档,目前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); }); } } 问题三:(第一次启用成功调用前置摄像头,第二次需要调用后置却黑屏或者失败) 失败的原因很多,列举两个一开始我遇到的问题 if (window.stream) { window.stream.getTracks().forEach(track => { track.stop(); }); } 亲测有用,别的找了很多停止的方法都没有效果。 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里面需要下面配置一下 "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); }); 如果只是一部手机可以这样,但是测试了多部手机发现摄像头数组毫无规律可循,这个方法慎用。 <input class="card_input" v-on:change="appCapture($event)" type="file" accept="image/*" capture="camera" /> 成功调用后用canvas实现成像并适应屏幕大小 我这里的代码是取video的宽高然后复制给canvas,这样可以让canvas和video保持一致,只用给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里定义一个{} 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唤醒的前置摄像头是相反的,很不舒服很不舒服。 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">点击自拍一张头像</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调用 摄像头内容请搜索极客世界以前的文章或继续浏览下面的相关文章,希望大家以后多多支持极客世界! |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论