【问题标题】:MediaRecorder API recorder won't call onstop when recording multiple tracksMediaRecorder API 录制器在录制多个音轨时不会调用 onstop
【发布时间】:2020-05-23 17:11:46
【问题描述】:

我的 MediaRecorder API 出现了一个非常奇怪的问题,过去两天我一直无法解决。

这个简化的示例工作得很好,当我点击 Chrome UI 的“停止共享”按钮时,一切都会适当地停止:

desktopStream = await navigator.mediaDevices.getDisplayMedia({
    video: true,
    audio: true,
});

let rec = new MediaRecorder(desktopStream, {
    mimeType: "video/webm; codecs=vp8,opus",
});

rec.onstop = async () => {
  desktopStream.getTracks().forEach((s) => s.stop());
  desktopStream = null;

  //blobs.push(MediaRecorder.requestData());
  blob = new Blob(blobs, {
    type: "video/webm",
  });
};

但它不会,它会继续录制(或者某些 MediaTrack 会继续运行,不完全确定):

desktopStream = await navigator.mediaDevices.getDisplayMedia({
    video: true,
    audio: true,
});

voiceStream = await navigator.mediaDevices.getUserMedia({
    video: false,
    audio: true,
  });

// this is the culprit, when commented everything works as expected
desktopStream.addTrack(voiceStream.getAudioTracks()[0]);

let rec = new MediaRecorder(desktopStream, {
    mimeType: "video/webm; codecs=vp8,opus",
});

rec.onstop = async () => {
  //explicitly stop tracks
  desktopStream.getTracks().forEach((s) => s.stop();
  voiceStream.getTracks().forEach((s) => s.stop());

  desktopStream = null;
  voiceStream = null;

  //blobs.push(MediaRecorder.requestData());
  blob = new Blob(blobs, {
    type: "video/webm",
  });
};

第二个代码块导致 chrome 仍然显示这个红色的录制图标。我读过很多次你需要在 forEach 循环中手动停止轨道,我这样做了,但它从来没有做到这一点,似乎没有调用 recorder.onstop 函数。

这是完整的小提琴:https://jsfiddle.net/agcty/xhb0c4o3/19/

重现步骤:

  1. 点击“开始录制”
  2. 选择屏幕
  3. 几秒钟内做任何事情
  4. 点击 Chrome 的“停止共享”按钮,而不是小提琴中的按钮
  5. 红色的录音图标仍会显示,点击“下载”时无法下载录音
  6. 点击“停止录制”(小提琴中的按钮),现在录制已正确停止
  7. 现在注释行“desktopStream.addTrack(voiceStream.getAudioTracks()[0]);”
  8. 一切正常

【问题讨论】:

    标签: javascript screen-capture web-mediarecorder


    【解决方案1】:

    好的,经过非常广泛的调试后,我发现当您单击“停止共享”按钮时,记录器实际上并没有停止。这只是我因措辞而做出的错误假设。

    根据文档 (https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/onstop),当正在录制的所有 MediaStreams 停止或手动停止记录器时,记录器将停止。

    “停止共享”仅停止 screenStream MediaTracks。没有发生任何不间断的事件。第一个示例有效,因为这是唯一被捕获的流,因此停止它意味着自动调用 onstop。

    在视觉上看起来像:

    解决方法有点隐藏,但效果很好:

    只需在 screenStream 轨道停止时添加一个事件侦听器,然后手动停止 voiceStream 轨道,导致记录器不再捕获任何内容,这反过来意味着它完全停止。耶。

    screenStream.getTracks().forEach((track) =>
          track.addEventListener("ended", () => {
            voiceStream.getAudioTracks().forEach((audio) => audio.stop());
            if (recorder) recorder.stop();
            recorder = null;
          })
        ); 
    

    【讨论】:

      猜你喜欢
      • 2018-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多