WebRTC网页打开摄像头并录制视频
时间:2021-12-03 作者:rustfisher
前面我们能打开本地摄像头,并且在网页上看到摄像头的预览图像。
本文我们使用MediaRecorder来录制视频。在网页上播放录制好的视频,并能提供下载功能。
html
首先创建一个html界面,放上一些元素
<video id="v1" playsinline autoplay muted></video>
<video id="v2" playsinline loop></video>
<div>
<button id="startCamera">开启摄像头</button>
<button id="stopCamera">停止摄像头</button>
<button id="record" disabled>录制</button>
<button id="play" disabled>播放</button>
<button id="download" disabled>下载视频</button>
</div>
<div> 录制使用的视频格式: <select id="codecSelect" disabled></select> </div>
<div>
<h4>视频设置</h4>
<p>回声消除: <input type="checkbox" id="echoCancellation"></p>
</div>
<div> <span id="msg" style="font-size:smaller"></span> </div>
<!-- 使用本地的适配器 -->
<script src="../js/adapter-域名" async></script>
-
video
- v1 用来预览
- v2 用来播放录制好的视频
-
button
控制摄像头开启、录制,下载等等 -
select
选择录制用的视频格式 -
input
选择回声消除
js
准备
先把界面上的元素拿到
\'use strict\';
let mediaRecorder;
let recordedBlobs; // 录制下来的内容
let isRecording = false;
// 先把页面元素拿到
const startCameraBtn = 域名ySelector(\'button#startCamera\'); // 启动摄像头按钮
const stopCameraBtn = 域名ySelector(\'button#stopCamera\');
const recordBtn = 域名ySelector(\'button#record\'); // 开始录制按钮
const playBtn = 域名ySelector(\'button#play\'); // 播放按钮
const downloadBtn = 域名ySelector(\'button#download\'); // 下载视频按钮
const codecSelector = 域名ySelector(\'#codecSelect\'); // 选择格式
const msgEle = 域名ySelector(\'span#msg\'); // 显示消息
const previewV1 = 域名ySelector(\'video#v1\'); // 预览用的
const recordedV2 = 域名ySelector(\'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 域名er(mimeType => {
return 域名peSupported(mimeType);
});
}
开启摄像头
同样要使用getUserMedia
方法。这里给视频指定了宽高。回声消除是可选项。
// 启动摄像头
域名ventListener(\'click\', async () => {
域名bled = true;
const isEchoCancellation = 域名ySelector(\'#echoCancellation\').checked;
const constraints = {
audio: {
echoCancellation: { exact: isEchoCancellation }
},
video: {
width: 1280, height: 720
}
};
await init(constraints);
});
async function init(constraints) {
try {
const stream = await 域名serMedia(constraints);
gotStream(stream);
} catch (e) {
showMsg(`域名serMedia error:${域名ring()}`);
}
}
function gotStream(stream) {
域名bled = false;
showMsg(\'拿到了 stream:\', stream);
域名am = stream;
域名bject = stream;
// 重置
var codecOption = 域名Child;
while (codecOption != null) {
域名veChild(codecOption);
codecOption = 域名Child;
}
getSupportedMimeTypes().forEach(mimeType => {
const option = 域名teElement(\'option\');
域名e = mimeType;
域名rText = 域名e;
域名ndChild(option);
});
域名bled = false; // 可以进行选择了
}
下面是停止摄像头的方法
域名ventListener(\'click\', () => {
var stream = 域名bject;
if (stream == null) {
return;
}
const tracks = 域名racks();
域名ach(function (track) {
域名();
});
域名bject = null;
域名am = null;
域名bled = true;
域名bled = false;
});
开始录制
开始录制视频
function startRecording() {
recordedBlobs = [];
const mimeType = 域名ons[域名ctedIndex].value;
const options = { mimeType };
try {
mediaRecorder = new MediaRecorder(域名am, options);
} catch (e) {
showMsg(`创建MediaRecorder出错: ${域名ngify(e)}`);
return;
}
showMsg(\'创建MediaRecorder\', mediaRecorder, \' -> options\', options);
域名Content = \'停止录制\';
isRecording = true;
域名bled = true;
域名bled = true;
域名bled = true;
域名op = (event) => {
showMsg(\'录制停止了: \' + event);
showMsg(\'录制的数据Blobs: \' + recordedBlobs);
};
域名taavailable = handleDataAvailable;
域名t();
showMsg(\'录制开始 mediaRecorder: \' + mediaRecorder);
}
function handleDataAvailable(event) {
if (域名 && 域名 > 0) {
域名(域名);
}
}
域名ventListener(\'click\', () => {
if (isRecording == false) {
startRecording();
} else {
stopRecording();
域名Content = \'开始录制\';
域名bled = false;
域名bled = false;
域名bled = false;
}
});
- 重置录制内容
recordedBlobs = []
- 拿到选定的视频格式
mimeType
- 新建MediaRecorder对象,传入前面获取到的流
- 处理各个按钮(ui)的状态
- mediaRecorder
- 设置停止监听器
onstop
- 监听录制数据
ondataavailable
,有数据来的时候存放在recordedBlobs
- 启动录制
域名t()
- 设置停止监听器
停止录制
function stopRecording() {
域名();
}
播放录制好的视频
录制好的视频内容存放在recordedBlobs
。新建Blob,交给video(recordedV2)来播放
域名ventListener(\'click\', () => {
const mimeType = 域名ons[域名ctedIndex].域名t(\';\', 1)[0];
const superBuffer = new Blob(recordedBlobs, { type: mimeType });
域名 = null;
域名bject = null;
域名 = 域名teObjectURL(superBuffer);
域名rols = true;
域名();
});
下载视频
录制好的视频内容存放在recordedBlobs
。
域名ventListener(\'click\', () => {
const blob = new Blob(recordedBlobs, { type: \'video/webm\' });
const url = 域名teObjectURL(blob);
const a = 域名teElement(\'a\');
域名lay = \'none\';
域名 = url;
域名load = \'视频_\' + new Date().getTime() + \'.webm\';
域名ndChild(a);
域名k();
setTimeout(() => {
域名veChild(a);
域名keObjectURL(url);
}, 100);
});
新建Blob和一个a
元素。根据blob创建ObjectURL,并传给a
元素的href。
修改下载文件的默认名字域名load
。
触发a
元素的click()
,即能让浏览器下载这个文件。
延迟把这个a
移除掉。
小结
getUserMedia()
开启视频拿到视频流。MediaRecorder录制视频。用Blob来播放和下载。
实现一个小的录制视频效果。视频数据缓存在对象里。
完整的效果请参考 视频录制
原文链接