目录
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: '', // 视频stream
imgSrc: '', // 拍照图片
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()方法,无法打开摄像头,后面采用网址的方式预览,换了其他浏览器才可以