HTML5使用MediaRecorder录制视频
1. 什么是 MediaRecorder
MediaRecorder 是浏览器提供的一个强大且简单的 API。专门用于音频和视频的录制。使用 MediaRecorder 构造器,创建一个实例对象,对指定的MediaStream
对象进行录制。具体方法可以查看MediaRecorder。
2. 可以录制什么?
可以录制任何的媒体形式标签,例如<audio>
, <video>
, <canvas>
。<audio>
, <video>
可以是网络上的媒体文件,也可以是本机的设备采集(麦克风和摄像头)。 <canvas>
的内容更自由,任何绘制在画布上的用户操作,2d或3d图像,都可以进行录制。录制结果是标准编码后的媒体数据流
,该流可以注入<video>
标签,也可以打包成为文件,甚至可以进一步进行流级别的数据处理(例如:画面识别,动态插入内容,播放跳转等)。引用至MediaRecord。
媒体数据流的编码过程由浏览器实现,因此依赖于浏览器的能力。Chrome和firefox支持性好。移动端兼容安卓内置的chrome内核浏览器。ios和ie不支持。
3. MediaRecorder 方法API
方法 | 描述 |
---|---|
var recorder = MediaRecorder()) | 构造函数: 创建一个新的MediaRecorder对象,用于记录录制操作中的数据 |
recorder.start(timeslice) | 开始录制:将媒体录制到一个多多个Blob对象中, timeslice:间隔时间,每间隔该时间将数据统一返回。 recorder.state = recording |
recorder.pause() | 录制暂停: 会保留当前的数据收集,以便后续恢复使用。 recorder.state = paused |
recorder.resume() | 恢复录制:继续收集数据到Blob中,recorder.state = recording |
recorder.requestData() | 接收数据:引发dataavailable事件,该事件返回数据为捕获到媒体的数据,并创建一个Blob对象将数据放入其中 |
recorder.stop() | 停止录制:引发dataavailable事件(将收集数据到Blob中),触发停止事件。recorder.state = inactive |
MediaRecorder.isTypeSupported(mimeType) | 判断浏览器编码能力的api,浏览器是否支持。 |
4. MediaRecorder 事件与属性
事件 | 描述 |
---|---|
recorder.onstart = () =>() | start()方法调用时触发 |
recorder.onpause = () =>() | pause()方法调用时触发 |
recorder.onresume = () =>() | resume()方法调用时触发 |
recorder.onstop = () =>() | stop()方法调用时触发 |
recorder.onerror = () =>() | 录制过程中发生异常时触发 |
recorder.ondataavailable | dataavailable事件触发时调用。dataavailable当MediaRcorder将媒体数据传递给程序时触发。 |
recorder.state | 录制的状态:inactive(未开始或停止),recording(正在录制),paused(暂停) |
recorder.stream | only-read, 返回创建MediaRecorder时传递给MediaRecorder构造函数的流 |
recorder.mimeType | only-read, MIME类型,用于描述录制媒体的格式 |
ignoreMutedMedia | 用以指定MediaRecorder是否录制无声的输入源。如果是false, 会录制无声的音频或者黑屏的视频,默认值是false |
videoBitsPerSecond | 返回视频采用的编码率 |
audioBitsPerSecond | 返回音频采用的编码率 |
ondataavailable 详解:
- 假如媒体流结束,未传达到ondataavailable的媒体数据将会在单个Blob中传递。
- stop方法调用时,将所有录制开始或上次dataavailable事件事件发生以来的所有媒体数据都会被放到的Blob中传递,然后结束。
- requestData()调用:将所有录制开发或上次 |dataavailable事件事件发生以来的所有媒体都会被传递,然后再创建爱你一个新的Blob,媒体捕获继续进入新的Blob。
- start(timeslice)如果有timeslice,则每隔
timeslice
就会触发一个dataavailable事件。
5. 录制流程分析
- 1.设置MediaStream或HTMLMediaElement(例如audio或video元素)作为媒体数据的来源
- 2.创建MediaRecorder对象,指定媒体资源流和任何其他所需选项,例如MIME
- 3.设置ondataavailable作为 dataavailable事件的处理函数,只要有接收数据,就会调用此方法
- 4.媒体源数据准备完毕,调用start()开始录制
- 5.每当有数据时,dataavailable事件处理程序就会别调用。该事件有一个data属性,值 为Blob包含的媒体数据
- 6.当源媒体停止播放时,录制会自动停止,也可以随时通过调用停止录制方法stop()来停止。
tips: 录制的多个媒体片段的单个Blob不一定能单独播放,媒体需要在播放前重新组装。
6. 使用HTML媒体元素录制
现在,我们从摄像头中读取视频流,实现录制下载的功能。先来查看效果。
按照上面分析的录制流程。html dom如下:
<div class="left">
<div id="startButton" class="button">Start</div>
<h2>Preview</h2>
<div class="video"><video id="preview" width="100%" height="auto" autoplay muted></video></div>
</div>
<div class="right">
<div class="rightBtn">
<div id="stopButton" class="button">Stop</div>
<a id="downloadButton" class="button">Download</a>
</div>
<h2>Recording</h2>
<div class="video"><video id="recording" width="160" height="120" controls></video></div>
</div>
相关js如下:
let preview = document.getElementById("preview");
let recording = document.getElementById("recording");
let startButton = document.getElementById("startButton");
let stopButton = document.getElementById("stopButton");
let downloadButton = document.getElementById("downloadButton");
let dataChunks = [];
let recorder;
// 开始录制
function startRecording(stream, lengthInMS) {
recorder = new MediaRecorder(stream);
recorder.ondataavailable = (event) => {
let data = event.data;
dataChunks.push(data);
};
recorder.start(1000);
console.log(recorder.state + " start to recording .....");
}
stopButton.addEventListener("click", () => {
// close the recording
preview.srcObject.getTracks().forEach((track) => track.stop());
recorder.stop();
// Play recorded video
let recordedBlob = new Blob(dataChunks, { type: "video/webm" });
recording.src = URL.createObjectURL(recordedBlob);
// Save download video, click the download button, you can download it
downloadButton.href = recording.src;
downloadButton.download = "RecordedVideo.webm";
});
startButton.addEventListener("click", () => {
// get the stream
navigator.mediaDevices
.getUserMedia({
audio: true,
video: true,
})
.then((stream) => {
// set the stream to left video
preview.srcObject = stream;
// set the stream to <a> for download
downloadButton.href = stream;
// captureStream: which is streaming a real-time capture of the content being rendered in the media element.
// A MediaStream object which can be used as a source for audio or video data by other media
preview.captureStream =
preview.captureStream || preview.mozCaptureStream;
startRecording(preview.captureStream());
})
.catch((err) => {
console.log("recording error: ", err);
});
});
转载自:https://juejin.cn/post/7005113182247190541