JavaScript 浏览器调用摄像头拍摄视频
之前写了 浏览器调用麦克风录制音频 和 调用摄像头拍摄照片 ,这里就继续来调用摄像头拍摄视频。
拍摄视频和录制音频的方法其实是差不多的,使用的也是 MediaRecorder
媒体录制接口,录制音频只需要申请麦克风,录制视频需要同时申请麦克风和摄像头。
下面简单实现显示摄像头画面、拍摄视频、播放视频、导出视频,访问 浏览器录制视频demo 可以查看最终效果。
代码实现
HTML 放几个 button
和 video
:
<!--Mr. Ma's Blog www.misterma.com-->
<button type="button" id="start-camera-btn">打开摄像头</button>
<button type="button" id="start-btn">开始录像</button>
<button type="button" id="stop-btn">停止录像</button>
<button type="button" id="play-btn">播放视频</button>
<button type="button" id="export-btn">导出视频</button>
<video width="720" height="360" controls></video>
video
主要用来预览摄像头画面和播放拍摄的视频。
下面的 JavaScript 因为注释比较多,看上去会有点长,但比较容易理解:
const startCameraBtn = document.querySelector('#start-camera-btn'); // 打开摄像头按钮
const startBtn = document.querySelector('#start-btn'); // 开始录像按钮
const stopBtn = document.querySelector('#stop-btn'); // 停止录像按钮
const playBtn = document.querySelector('#play-btn'); // 播放视频按钮
const exportBtn = document.querySelector('#export-btn'); // 导出视频按钮
const videoEl = document.querySelector('video'); // 视频播放元素
let videoData = []; // 存放视频数据
let cameraStream = null; // 存放媒体流
let mediaRecorder = null; // 存放媒体录制对象
// 打开摄像头按钮点击
startCameraBtn.addEventListener('click', () => {
// 申请视频和音频的参数
const constraints = {
audio: true,
video: {
width: 720,
height: 360
}
};
// 申请摄像头和麦克风权限
navigator.mediaDevices.getUserMedia(constraints).then(stream => {
cameraStream = stream;
// 禁用 video 的控制组件
videoEl.controls = false;
// 把媒体流传给 video 的 srcObject
videoEl.srcObject = cameraStream;
// 播放画面和声音
videoEl.play();
}).catch(info => {
alert('错误' + info);
});
});
// 开始录像按钮点击
startBtn.addEventListener('click', () => {
// 创建媒体录制
mediaRecorder = new MediaRecorder(cameraStream, {mimeType: 'video/webm'});
// 开始录制
mediaRecorder.start();
// 处理视频数据
mediaRecorder.addEventListener('dataavailable', ev => {
videoData.push(ev.data);
});
// 录制停止事件
mediaRecorder.addEventListener('stop', () => {
videoData = new Blob(videoData);
});
});
// 停止录像按钮点击
stopBtn.addEventListener('click', () => {
mediaRecorder.stop();
});
// 播放视频点击
playBtn.addEventListener('click', () => {
if (videoData === null) return false;
// 清除 video 的媒体流
videoEl.srcObject = null;
// 把视频数据转为 URL 传给 video 的 src
videoEl.src = URL.createObjectURL(videoData);
// 播放视频
videoEl.play();
// 启用 video 的控制组件
videoEl.controls = true;
// 删除媒体流
cameraStream = null;
});
// 导出视频按钮点击
exportBtn.addEventListener('click', () => {
if (videoData === null) return false;
const link = document.createElement('a');
link.href = URL.createObjectURL(videoData);
link.download = 'video.webm';
link.click();
});
上面的代码只是简单演示,没有做重复点击之类的判断。
详细说明
还是分几步写:
- 显示摄像头画面
- 录制视频
- 播放视频
- 导出视频
显示摄像头画面
使用 navigator.mediaDevices.getUserMedia
请求媒体输入许可,需要传入一个参数来设置媒体类型,我用的参数如下:
const constraints = {
audio: true,
video: {
width: 720,
height: 360
}
};
上面的参数是同时申请视频和音频输入设备,视频使用的尺寸是 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
上传。
之前写录制音频的时候使用的也是 MediaRecorder
媒体录制接口,要查看这里没有使用到的 MediaRecorder
方法和事件说明可以访问 JavaScript 浏览器调用麦克风录音 。
类似文章:
版权声明:本文为原创文章,版权归 Mr. Ma's Blog 所有,转载请联系博主获得授权。
本文地址:https://www.misterma.com/archives/909/
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。