HTML5通过navigator.mediaDevices.getUserMedia调用手机摄像头问题
副标题[/!--empirenews.page--]
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" } } }; 完美调用自己手机的前置摄像头!!! 完整代码如下: (编辑:好传媒网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |