目录
1.功能需求
2.API
3.完整代码
4.效果
5.遇到问题
1.功能需求
需求:下面需求图
本来应该使用小程序做,但是为了以后复用考虑,决定使用vue嵌入小程序中。
所以需求就是 调用手机摄像头 实现拍照打卡功能(电脑通用)
2.API
MediaDevices.getUserMedia()
该 API 会提示用户给予使用媒体输入的许可,媒体输入会产生一个MediaStream,里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道(来自硬件或者虚拟视频源,比如相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、A/D转换器等等),也可能是其它轨道类型。
它返回一个 Promise 对象,成功后会 resolve 回调一个 MediaStream 对象。若用户拒绝了使用权限,或者需要的媒体源不可用,Promise 会 reject 回调一个 PermissionDeniedError 或者 NotFoundError。
浏览器会弹出弹窗,询问是否允许使用摄像头
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {/* 用户允许使用摄像头 *//* 使用这个stream stream */
})
.catch(function(err) {/* 不允许使用摄像头 *//* 处理error */
});
constraints 参数介绍:
参数包含了 video 和 audio 两个成员的 MediaStreamConstraints 对象,用于说明请求的媒体类型。必须至少一个类型或者两个同时可以被指定。
具体使用参考文档:MediaDevices.getUserMedia()
3.完整代码
完整代码:
<template><div class="publish"><video ref="video"></video><canvas style="display: none" id="canvasCamera" ref="canvas"></canvas><div v-if="imgSrc" class="img_bg_camera"><img :src="imgSrc" class="tx_img" /></div><button @click="OpenCamera">打开摄像头</button><button @click="CloseCamera">关闭摄像头</button><button @click="setImage">拍照</button></div>
</template><script>
export default {data() {return {mediaStreamTrack: {},video_stream: '', // 视频streamimgSrc: '', // 拍照图片canvas: null,context: null,};},mounted() {// 进入页面 自动调用摄像头this.getCamera();},methods: {// 调用打开摄像头功能getCamera() {// 获取 canvas 画布this.canvas = document.getElementById('canvasCamera');this.context = this.canvas.getContext('2d');// 旧版本浏览器可能根本不支持mediaDevices,我们首先设置一个空对象if (navigator.mediaDevices === undefined) {navigator.mediaDevices = {};}// 正常支持版本navigator.mediaDevices.getUserMedia({video: true,//默认前置//video: { facingMode: { exact: "environment" } },//后置}).then((stream) => {// 摄像头开启成功this.mediaStreamTrack = typeof stream.stop === 'function' ? stream : stream.getTracks()[0];this.video_stream = stream;this.$refs.video.srcObject = stream;this.$refs.video.play();}).catch(err => {console.log(err);});},// 拍照 绘制图片setImage() {console.log('拍照');// 点击canvas画图this.context.drawImage(this.$refs.video,0,0,200,100,);// 获取图片base64链接const image = this.canvas.toDataURL('image/png');this.imgSrc = image;this.$emit('refreshDataList', this.imgSrc);},// 打开摄像头OpenCamera() {console.log('打开摄像头');this.getCamera();},// 关闭摄像头CloseCamera() {console.log('关闭摄像头');this.$refs.video.srcObject.getTracks()[0].stop();},},
};
</script><style lang="scss" scoped>
video {width: 100%;height: 300px;
}
canvas {width: 100%;height: 300px;
}
button {width: 100px;height: 40px;position: relative;bottom: 0;left: 0;background-color: rgb(22, 204, 195);
}
.img_bg_camera {img {width: 300px;height: 200px;}
}
</style>
4.效果
只写了简单的摄像头功能点页面,方便大家看代码
有需要在这基础上修改样式就好了
5.遇到问题
1.navigator.mediaDevices 为 undefined
原因:navigator.mediaDevices在目前以下三种情况下可以获取到
1.地址为localhost:// 访问时
2.地址为https:// 时
3.为文件访问file:///
解决:因为我这里需要用手机访问,所以只能不能使用localhost,就采取修改chrome浏览器的安全策略
①.在chrome浏览器的地址栏中输入: chrome://flags/#unsafely-treat-insecure-origin-as-secure,将该 Disabled 切换成 enable 状态;
②.在输入框中填写需要开启的域名或地址(带上端口号),如果有多个,则以逗号分隔;
③.重启浏览器生效
其他解决方式:关于navigator.mediaDevices为undefined,获取不到媒体权限的问题
2.电脑可以启用摄像头,手机不行
1.因为我是使用微信二维码扫码预览,一直无法进入navigator.mediaDevices .getUserMedia()方法,无法打开摄像头,后面采用网址的方式预览,换了其他浏览器才可以
参考:
https://jsrun.net/5j6Kp