[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
522
0
参与讨论