3

我正在使用 捕获用户的音频和视频,navigator.mediaDevices.getUserMedia()然后使用MediaRecorderondataavailable在本地存储该视频和音频 blob 以便稍后上传。

现在我正在处理一个问题,由于某种原因,ondataavailable在录音中途停止调用。我不知道为什么,也没有收到任何错误的警报。那么首先,有谁知道为什么会发生这种情况以及如何捕捉错误?

其次,我试图重现。通过做这样的事情。

navigator.mediaDevices.getUserMedia({ audio: true, video: true })
  .then(function(camera) {
          local_media_stream = camera;
          camera.getVideoTracks()[0].onended = function() { console.log("VIDEO ENDED") }
          camera.getAudioTracks()[0].onended = function() { console.log("Audio ENDED") }
          camera.onended = function() { console.log("--- ENDED") }
          camera.onremovetrack = (event) => { console.log(`${event.track.kind} track removed`); };
  }).catch(function(error) {
        alert('Unable to capture your camera. Please check logs.' + error);
        console.error(error);
  });

并记录流

recorder = new MediaRecorder(local_media_stream, {
    mimeType: encoding_options,
    audioBitsPerSecond: 128000,
    videoBitsPerSecond: bits_per_second,
});
recorder.ondataavailable = function(e) {
    save_blob(e.data, blob_index)
    blob_index++;
}
recorder.onstop = function(e) {
    console.log("recorder stopped");
    console.log(e)
}
recorder.onerror = function(error) {
    console.log("recorder error");
    alert(error)
    throw error;
}
recorder.onstart = function() {
    console.log('started');
};
recorder.onpause = function() {
    console.log('paused');
};
recorder.onresume = function() {
    console.log('resumed');
};
recorder.start(15000)

然后我尝试手动终止流以希望通过执行来重现发生的任何问题

local_media_stream.getVideoTracks()[0].stop()

Nowondataavailable不再被调用,但没有任何 onended 事件被调用。录制仍在进行中,并且local_media_stream仍然处于活动状态。

如果我也杀死音频

local_media_stream.getAudioTracks()[0].stop()

现在local_media_stream未激活,但仍然没有调用事件,告诉我流停止并且记录器仍在运行,但从ondatavailable未被调用。

我能做些什么?我想知道本地流正在成功录制,如果没有收到警报,我至少可以通知用户录制不再保存。

4

2 回答 2

1

MediaRecorder 有一个recorder.stop() 方法。我没有看到您在示例代码中调用它。尝试调用它。

当您调用track[n].stop()媒体流的轨道时,您告诉他们停止向 MediaRecorder 提供数据。因此,不出所料,MediaRecorder 停止生成其编码输出流。

如果您在 Google Chrome 上运行,您也可以尝试比您的recorder.start(15000). 或者dataavailable使用recorder.requestData().

于 2021-01-27T21:27:21.787 回答
0

停止两个轨道应该停止你的录音机,它在 FF 和 Chrome 中都对我有用:https ://jsfiddle.net/gpt51d6y/

但这不太可能您的用户称自己为stop()自己。
很可能问题不在于 MediaRecorder,而在此之前在于 MediaStream 的轨道。
所有轨道都静音的 MediaRecorder 不会发出新的 dataavailable 事件,因为从它的角度来看,仍有可能发生的事情,轨道可能随时取消静音。

以具有硬件一键通功能的麦克风为例,每次用户释放此类按钮时,该麦克风的音轨都会静音,但 MediaRecorder,即使在此期间不会录制任何内容,仍然有增加其内部时间,以便“间隙”不会在最终媒体中“粘合”。然而,由于它没有任何东西传递给它的图表,它也不会发出新的数据可用事件,它只会调整将发出的下一个块中的时间戳。

对于您试图找出问题所在的情况,您可以尝试监听 MediaRecorder 的错误事件,在某些情况下它可能会触发。

但是您也绝对应该将事件添加到其流的每个轨道,并且不要忘记静音事件

recorder.stream.getTracks().forEach( (track) => {
  track.onmute = track.onended = console.warn;
};
于 2021-01-28T05:51:43.547 回答