likes
comments
collection
share

HTML5使用MediaRecorder录制视频

作者站长头像
站长
· 阅读数 5

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.ondataavailabledataavailable事件触发时调用。dataavailable当MediaRcorder将媒体数据传递给程序时触发。
recorder.state录制的状态:inactive(未开始或停止),recording(正在录制),paused(暂停)
recorder.streamonly-read, 返回创建MediaRecorder时传递给MediaRecorder构造函数的流
recorder.mimeTypeonly-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媒体元素录制

现在,我们从摄像头中读取视频流,实现录制下载的功能。先来查看效果。

HTML5使用MediaRecorder录制视频 按照上面分析的录制流程。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);
    });
});