- 浏览器兼容问题(mdn的兼容代码)
// 老的浏览器可能根本没有实现 mediaDevices,所以我们可以先设置一个空的对象
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {};
}
// 一些浏览器部分支持 mediaDevices。我们不能直接给对象设置 getUserMedia
// 因为这样可能会覆盖已有的属性。这里我们只会在没有 getUserMedia 属性的时候添加它。
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = function (constraints) {
// 首先,如果有 getUserMedia 的话,就获得它
const getUserMedia =
navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
// 一些浏览器根本没实现它 - 那么就返回一个 error 到 promise 的 reject 来保持一个统一的接口
if (!getUserMedia) {
return Promise.reject(
new Error("getUserMedia is not implemented in this browser"),
);
}
// 否则,为老的 navigator.getUserMedia 方法包裹一个 Promise
return new Promise(function (resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject);
});
};
}
- 选择摄像头
const enumeratorPromise = await navigator.mediaDevices.enumerateDevices()
const videoDevices = enumeratorPromise.filter(i => i.kind==='videoinput')
if(videoDevices.length===1) { // 只有一个不用选择
this.videoDeviceId = videoDevices[0].deviceId
this.dialogConfirmHandle()
} else {
this.videoDevices = videoDevices
this.dialogVisible = true // 此处弹出element ui的对话框嵌套单选框选择
}
- 显示视频
dialogConfirmHandle() {
// 视频铺满容器
const height = this.$refs.left.clientHeight
const width = this.$refs.left.clientWidth
// canvas宽高对齐容器以防照片显示不全
this.$refs.canvas.width = width
this.$refs.canvas.height = height
// 隐藏对话框把选择的摄像头赋值即:deviceId
this.dialogVisible = false
const constraints = {
audio:false,
video: {
deviceId: this.videoDeviceId,
width,
height
},
};
navigator.mediaDevices
.getUserMedia(constraints)
.then(stream => {
const video = this.$refs.video;
// 旧的浏览器可能没有 srcObject
if ("srcObject" in video) {
video.srcObject = stream;
} else {
// 防止在新的浏览器里使用它,因为它已经不再支持了
video.src = window.URL.createObjectURL(stream);
}
video.onloadedmetadata = video.play // 可用autoplay属性代替
})
.catch(function (err) {
console.log(err.name + ": " + err.message);
});
}
- 拍照,显示图片
photoConfirmHandle() {
const canvas = this.$refs.canvas;
canvas.getContext("2d").drawImage(this.$refs.video, 0, 0);
// 获取到base64格式图片
this.imgSrc = this.$refs.canvas.toDataURL()
}
- 截图
const imageData = canvas.getContext("2d").getImageData(x, y, cWidth, cHeight)
const cas = document.createElement('canvas')
cas.width = cWidth
cas.height = cHeight
cas.getContext('2d').putImageData(imageData, 0, 0)
const base64 = cas.toDataURL("image/jpeg", 1.0)
6.有坑
浏览器安全性问题,摄像头和麦克风权限只在https和localhost下允许访问。
解决方法:
1、在浏览器地址栏中输入“chrome://flags/#unsafely-treat-insecure-origin-as-secure”,回车,
2、在输入框中输入需要访问的地址,多个地址使用“,”隔开, 将Insecure origins treated as secure设置为Enabled
3、然后点击右下角弹出的Relaunch按钮,自动重启浏览器之后就可以在添加的http地址下调用摄像头和麦克风了。