JavaScript 浏览器调用摄像头拍摄视频
拍摄视频和录制音频的方法其实是差不多的,使用的也是 MediaRecorder
媒体录制接口,录制音频只需要申请麦克风,录制视频需要同时申请麦克风和摄像头。
目录
代码实现
HTML 放几个 button
和 video
:
1 | <!--Mr. Ma's Blog www.misterma.com--> |
video
主要用来预览摄像头画面和播放拍摄的视频。
下面的 JavaScript 因为注释比较多,看上去会有点长,但比较容易理解:
1 | const startCameraBtn = document.querySelector('#start-camera-btn'); // 打开摄像头按钮 |
上面的代码只是简单演示,没有做重复点击之类的判断。
详细说明
还是分几步写:
- 显示摄像头画面
- 录制视频
- 播放视频
- 导出视频
显示摄像头画面
使用 navigator.mediaDevices.getUserMedia
请求媒体输入许可,需要传入一个参数来设置媒体类型,我用的参数如下:
1 | const constraints = { |
上面的参数是同时申请视频和音频输入设备,视频使用的尺寸是 720*360。
用户授权完成后会返回一个 Promise
,成功 then
会返回一个媒体流,失败 catch
会返回错误信息。
把返回的媒体流传给 video
的 srcObject
,video
就可以显示摄像头画面了,同时也能播放麦克风声音。
录制视频
有了媒体流就可以创建 MediaRecorder
媒体录制接口,第一个参数 MediaStream
是媒体流,可以使用申请设备权限返回的媒体流,第二个参数是录制选项,我的录制选项是 {mimeType: 'video/webm'}
,使用 webm 格式来录制视频。webm 是 Google 的视频格式,Chromium 系的浏览器一般都支持,Firefox 和 Safari 不一定支持,可能需要把 mimeType
设置为 video/mp4
。
使用 MediaRecorder
的 start
方法开始录制,start
方法也可以传入一个 timeslice
参数,timeslice
参数可以设置一个毫秒值来把视频数据分割成多个数据块。
MediaRecorder
的 dataavailable
事件会在停止录制时触发,如果在 start
中设置了 timeslice
的话,每个 timeslice
周期结束也会触发。dataavailable
事件会返回一个 event
,使用 event.data
可以获取视频数据。
MediaRecorder
的 stop
方法可以停止录制,停止录制也会触发 MediaRecorder
的 stop
事件,停止录制后我使用 Blob
把视频数据转为了 Blob
数据。
播放视频
我用来播放视频的 video
元素和显示摄像头画面的是同一个,把 video
的 srcObject
设置为 null
可以停止播放摄像头画面。使用 URL.createObjectURL
把 Blob
视频数据转换为 DataURL
传给 video
的 src
,调用 video
的 play
方法就可以自动播放视频了。
我使用了 video
的 controls
控制组件来控制视频播放,给 video
加入 controls
属性,video
就会包含基本的播放控制功能,不需要手动编写播放控制。在 video
显示摄像头画面的时候我会禁用 controls
组件,在 video
需要播放视频的时候启用 controls
组件。
导出视频
- 使用
document.createElement
创建一个链接(不需要插入到页面) - 使用
URL.createObjectURL
把Blob
视频数据转为DataURL
传给链接的href
- 通过链接的
download
属性来设置文件名 - 调用链接的
click
来触发链接的点击事件
如果需要把视频上传到服务器,可以把视频 Blob
数据添加到 FormData
上传。