WebRTC网页打开摄像头并录制视频
前面我们能打开本地摄像头,并且在网页上看到摄像头的预览图像。
本文我们使用MediaRecorder来录制视频。在网页上播放录制好的视频,并能提供下载功能。
html
首先创建一个html界面,放上一些元素
录制使用的视频格式:视频设置回声消除:
video
- v1 用来预览
- v2 用来播放录制好的视频
button
控制摄像头开启、录制,下载等等select
选择录制用的视频格式input
选择回声消除
先把界面上的元素拿到
'use strict';
let mediaRecorder;
let recordedBlobs;
// 录制下来的内容
let isRecording = false;
// 先把页面元素拿到
const startCameraBtn = document.querySelector('button#startCamera');
// 启动摄像头按钮
const stopCameraBtn = document.querySelector('button#stopCamera');
const recordBtn = document.querySelector('button#record');
// 开始录制按钮
const playBtn = document.querySelector('button#play');
// 播放按钮
const downloadBtn = document.querySelector('button#download');
// 下载视频按钮
const codecSelector = document.querySelector('#codecSelect');
// 选择格式
const msgEle = document.querySelector('span#msg');
// 显示消息
const previewV1 = document.querySelector('video#v1');
// 预览用的
const recordedV2 = document.querySelector('video#v2');
// 用来播放录制好的视频
视频支持的格式
先预定几个可能的格式,然后一个个来判断是否支持。找到支持的格式。
function getSupportedMimeTypes() {
const possibleTypes = [
'video/webm;
codecs=vp9,opus',
'video/webm;
codecs=vp8,opus',
'video/webm;
codecs=h264,opus',
'video/mp4;
codecs=h264,aac',
];
return possibleTypes.filter(mimeType => {
return MediaRecorder.isTypeSupported(mimeType);
});
}
开启摄像头
同样要使用
getUserMedia
方法。这里给视频指定了宽高。回声消除是可选项。// 启动摄像头
startCameraBtn.addEventListener('click', async () => {
startCameraBtn.disabled = true;
const isEchoCancellation = document.querySelector('#echoCancellation').checked;
const constraints = {
audio: {
echoCancellation: { exact: isEchoCancellation }
},
video: {
width: 1280, height: 720
}
};
await init(constraints);
});
async function init(constraints) {
try {
const stream = await navigator.mediaDevices.getUserMedia(constraints);
gotStream(stream);
} catch (e) {
showMsg(`navigator.getUserMedia error:${e.toString()}`);
}
}function gotStream(stream) {
recordBtn.disabled = false;
showMsg('拿到了 stream:', stream);
window.stream = stream;
previewV1.srcObject = stream;
// 重置
var codecOption = codecSelector.lastChild;
while (codecOption != null) {
codecSelector.removeChild(codecOption);
codecOption = codecSelector.lastChild;
}getSupportedMimeTypes().forEach(mimeType => {
const option = document.createElement('option');
option.value = https://www.it610.com/article/mimeType;
option.innerText = option.value;
codecSelector.appendChild(option);
});
codecSelector.disabled = false;
// 可以进行选择了
}
下面是停止摄像头的方法
stopCameraBtn.addEventListener('click', () => {
var stream = previewV1.srcObject;
if (stream == null) {
return;
}
const tracks = stream.getTracks();
tracks.forEach(function (track) {
track.stop();
});
previewV1.srcObject = null;
window.stream = null;
codecSelector.disabled = true;
startCameraBtn.disabled = false;
});
开始录制
开始录制视频
function startRecording() {
recordedBlobs = [];
const mimeType = codecSelector.options[codecSelector.selectedIndex].value;
const options = { mimeType };
try {
mediaRecorder = new MediaRecorder(window.stream, options);
} catch (e) {
showMsg(`创建MediaRecorder出错: ${JSON.stringify(e)}`);
return;
}showMsg('创建MediaRecorder', mediaRecorder, ' -> options', options);
recordBtn.textContent = '停止录制';
isRecording = true;
playBtn.disabled = true;
downloadBtn.disabled = true;
codecSelector.disabled = true;
mediaRecorder.onstop = (event) => {
showMsg('录制停止了: ' + event);
showMsg('录制的数据Blobs: ' + recordedBlobs);
};
mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start();
showMsg('录制开始 mediaRecorder: ' + mediaRecorder);
}function handleDataAvailable(event) {
if (event.data && event.data.size > 0) {
recordedBlobs.push(event.data);
}
}recordBtn.addEventListener('click', () => {
if (isRecording == false) {
startRecording();
} else {
stopRecording();
recordBtn.textContent = '开始录制';
playBtn.disabled = false;
downloadBtn.disabled = false;
codecSelector.disabled = false;
}
});
- 重置录制内容
recordedBlobs = []
- 拿到选定的视频格式
mimeType
- 新建MediaRecorder对象,传入前面获取到的流
- 处理各个按钮(ui)的状态
- mediaRecorder
- 设置停止监听器
onstop
- 监听录制数据
ondataavailable
,有数据来的时候存放在recordedBlobs
- 启动录制
mediaRecorder.start()
- 设置停止监听器
function stopRecording() {
mediaRecorder.stop();
}
播放录制好的视频
录制好的视频内容存放在
recordedBlobs
。新建Blob,交给video(recordedV2)来播放playBtn.addEventListener('click', () => {
const mimeType = codecSelector.options[codecSelector.selectedIndex].value.split(';
', 1)[0];
const superBuffer = new Blob(recordedBlobs, { type: mimeType });
recordedV2.src = https://www.it610.com/article/null;
recordedV2.srcObject = null;
recordedV2.src = window.URL.createObjectURL(superBuffer);
recordedV2.controls = true;
recordedV2.play();
});
下载视频
录制好的视频内容存放在
recordedBlobs
。downloadBtn.addEventListener('click', () => {
const blob = new Blob(recordedBlobs, { type: 'video/webm' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = https://www.it610.com/article/url;
a.download ='视频_' + new Date().getTime() + '.webm';
document.body.appendChild(a);
a.click();
setTimeout(() => {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 100);
});
新建Blob和一个
a
元素。根据blob创建ObjectURL,并传给a
元素的href。修改下载文件的默认名字
a.download
。触发
a
元素的click()
,即能让浏览器下载这个文件。延迟把这个
a
移除掉。小结
getUserMedia()
开启视频拿到视频流。MediaRecorder录制视频。用Blob来播放和下载。实现一个小的录制视频效果。视频数据缓存在对象里。
完整的效果请参考 视频录制
【WebRTC网页打开摄像头并录制视频】原文链接
推荐阅读
- 如何在Mac中的文件选择框中打开系统隐藏文件夹
- 使用协程爬取网页,计算网页数据大小
- 【70号】Day26朋友日
- 分享!如何分分钟实现微信扫二维码调用外部浏览器打开指定页面的功能
- web网页模板|如此优秀的JS轮播图,写完老师都沉默了
- [成长]“青椒”给我打开了一扇窗——我的青椒学习之旅
- 你有跟人打过架吗()
- 思维导图让你换一种打开方式学数学
- 花时间做自己
- IOST任务教程