[04天]Web端打打开用户摄像头拍照mediaDevices
在Web端打打开用户摄像头拍照,是通过navigator对象的新API mediaDevices对象实现。
先来一个完整例子:
打开用户摄像头播放录制内容,实时拍照下载
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>mediaDevices Demo</title>
</head>
<body>
<p>
<button id="open">打开</button>
<button id="close">关闭</button></button>
<button id="picture">拍照</button></button>
</p>
<video></video>
<script>
class MediaDevices{
constructor(videoDom) {
if (!this.test()) {
console.log('浏览器不支持')
return
}
this.video = videoDom
this.stream = null
}
// 测试浏览器是否已经支持该API
test() {
return !!navigator?.mediaDevices?.getUserMedia
}
// 打开并获取摄像头数据
getUserMedia() {
const constraints = window.constraints = {
audio: true, // 获取音频
video: true, // 获取视频
}
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => {
stream.onended = function() {
console.log('数据流结束')
}
this.stream = stream
this.video.srcObject = stream
this.video.play()
})
.catch(error => {
console.log(error)
})
}
// 拍照并下载
takePicture() {
const canvas = document.createElement('canvas')
canvas.width = this.video.videoWidth
canvas.height = this.video.videoHeight
const ctx = canvas.getContext('2d')
ctx.drawImage(this.video, 0, 0, canvas.width, canvas.height)
const a = document.createElement('a')
a.href = canvas.toDataURL()
a.download = new Date().getTime() + '.jpg'
a.dispatchEvent(new MouseEvent('click'))
}
// 停止
stop() {
this.video.pause()
this.stream.getTracks().forEach(track => track.stop())
}
}
const md = new MediaDevices(document.querySelector('video'))
document.querySelector('#open').addEventListener('click', () => {
md.getUserMedia()
})
document.querySelector('#close').addEventListener('click', () => {
md.stop()
})
document.querySelector('#picture').addEventListener('click', () => {
md.takePicture()
})
</script>
</body>
</html>分解
class MediaDevices{
constructor(videoDom) {
if (!this.test()) {
console.log('浏览器不支持')
return
}
this.video = videoDom
this.stream = null
}
// 测试浏览器是否已经支持该API
test() {
return !!navigator?.mediaDevices?.getUserMedia
}
// ...
}先创建一个类, 接收显示视频用的video标签,并写一个测试浏览器是否支持 mediaDevices API 的方法
class MediaDevices{
// ...
// 打开并获取摄像头数据
getUserMedia() {
const constraints = window.constraints = {
audio: true, // 获取音频
video: true, // 获取视频
}
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => {
stream.onended = function() {
console.log('数据流结束')
}
this.stream = stream
this.video.srcObject = stream
this.video.play()
})
.catch(error => {
console.log(error)
})
}
// ...
}添加核心方法
使用 mediaDevices.getUserMedia 方法打开摄像头,并将获取到的流做为srcObject 加载到video标签。然后播放video。
class MediaDevices{
// ...
// 拍照并下载
takePicture() {
const canvas = document.createElement('canvas')
canvas.width = this.video.videoWidth
canvas.height = this.video.videoHeight
const ctx = canvas.getContext('2d')
ctx.drawImage(this.video, 0, 0, canvas.width, canvas.height)
const a = document.createElement('a')
a.href = canvas.toDataURL('image/jpeg', 1.0)
a.download = new Date().getTime() + '.jpg'
a.dispatchEvent(new MouseEvent('click'))
}
// ...
}再添加一个拍照的方法
创建一个离屏画布,然后抓取视频帧画到画布上。
创建一个a标签,使用toDataURL API将画布中的图像转为DataURL做为a标签的href属性
对a标签触发一个点击事件,触发浏览器执行下载
至此打开摄像头拍照的目的达成
class MediaDevices{
// ...
// 停止
stop() {
this.video.pause()
this.stream.getTracks().forEach(track => track.stop())
}
}最后再添加一个停止视频播放,关闭摄像头方法。
扩展
mediaDevices.getDisplayMedia() 获取用户屏幕
提示用户选择显示器或显示器的一部分(例如窗口)以捕获为MediaStream 以便共享或记录。返回解析为MediaStream的Promise
提示:可将上例中的 getUserMedia 方法 替换为 getDisplayMedia 方法进行体验
扩展资料查阅: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices
2022-05-20 20:00:11
576
0
参与讨论