WebRTC技术详解:从0到1构建多人视频会议系统
上QQ阅读APP看书,第一时间看更新

2.8.4 MediaRecorder事件

1. start事件

当调用MediaRecorder.start()方法时触发该事件。此时启动录制,录制数据开始写入Blob,对应事件句柄onstart。

以下两种语法都可以为start事件设置处理函数。

MediaRecorder.onstart = (event) => { ... }
MediaRecorder.addEventListener('start', (event) => { ... })

代码清单2-56启动录制,并在onstart事件句柄中处理录制数据。

代码清单2-56 start事件示例

record.onclick = () => {
  mediaRecorder.start();
  console.log("recorder started");
}

  mediaRecorder.onstart = () => {
    // start事件处理流程
  }
2. pause事件

当调用MediaRecorder.pause()方法时触发该事件。此时暂停录制数据,对应事件句柄onpause。

以下两种语法都可以为pause事件设置处理函数。

MediaRecorder.onpause = (event) => { ... }
MediaRecorder.addEventListener('pause', (event) => { ... })

代码清单2-57在onclick事件中切换录制状态并在相应的事件句柄中输出日志。

代码清单2-57 pause事件示例

pause.onclick = () => {
  if(mediaRecorder.state === "recording") {
    mediaRecorder.pause();
  } else if(mediaRecorder.state === "paused") {
    mediaRecorder.resume();
  }
}
  mediaRecorder.onpause = () => {
    console.log("mediaRecorder paused!");
  }

  mediaRecorder.onresume = () => {
    console.log("mediaRecorder resumed!");
  }
3. resume事件

当调用MediaRecorder.resume()方法时触发该事件。此时由暂停恢复录制,对应事件句柄onresume。

以下两种语法都可以为resume事件设置处理函数。

MediaRecorder.onresume = (event) => { ... }
MediaRecorder.addEventListener('resume', (event) => { ... })
4. stop事件

当调用MediaRecorder.stop()方法或媒体流中止时触发该事件。此时停止录制数据,对应事件句柄onstop。

以下两种语法都可以为stop事件设置处理函数。

MediaRecorder.onstop = (event)  => { ... }
MediaRecorder.addEventListener('stop', (event)  => { ... })

代码清单2-58在ondataavailable事件句柄中将录制的数据保存到chunks数组,当录制停止时,使用chunks生成音频地址,回放录制的数据。

代码清单2-58 stop事件示例

mediaRecorder.onstop = (e) => {
  console.log("data available after MediaRecorder.stop() called.");
  let audio = document.createElement('audio');
  audio.controls = true;
  const blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
  const audioURL = window.URL.createObjectURL(blob);
  audio.srcObject = audioURL;
  console.log("recorder stopped");
}

mediaRecorder.ondataavailable = (e) => {
  chunks.push(e.data);
}
5. dataavailable事件

该事件用于处理录制数据,对应事件句柄ondataavailable,以下情况会触发该事件。

  • 媒体流终止,导致获取不到媒体数据。
  • 调用了MediaRecorder.stop()方法,将所有未处理的录制数据写入Blob,停止录制。
  • 调用了MediaRecorder.requestData()方法,将所有未处理的录制数据写入Blob,继续录制。
  • 如果在调用MediaRecorder.start()方法时传入了参数timeslice,则每隔timeslice(单位毫秒)触发一次该事件。

以下两种语法都可以为dataavailable事件设置处理函数。

MediaRecorder.ondataavailable = (event) => { ... }
MediaRecorder.addEventListener('dataavailable', (event) => { ... })
6. error事件

在创建录制对象或录制过程中出现错误时触发该事件,事件类型为MediaRecorderErr-orEvent,对应事件句柄onerror。

以下两种语法都可以为error事件设置处理函数。

MediaRecorder.onerror = (event) => { ... }
MediaRecorder.addEventListener(error, (event) => { ... })

表2-14列出了该事件触发时的错误名,错误名可以通过MediaRecorderErrorEvent.error.name获取。

表2-14 MediaRecorder错误名

054-01

代码清单2-59实现了录制流函数recordStream,在该函数中启动录制,保存录制数据,并在出错时打印错误信息。

代码清单2-59 error事件示例

function recordStream(stream) {
  let bufferList = [];
  let recorder = new MediaRecorder(stream);
  recorder.ondataavailable = (event) => {
    bufferList.push(event.data);
  };
  recorder.onerror = (event) => {
    let error = event.error;
    switch(error.name) {
      case InvalidStateError:
        console.log("You can't record the video right now. Try again later.");
        break;
      case SecurityError:
        console.log("Recording the specified source is not allowed due to security restrictions.");
        break;
      default:
        console.log("A problem occurred while trying to record the video.");
        break;
    }
  };
  recorder.start(100);
  return recorder;
}