流挂起时,远程流上的WebRTC MediaRecorder会剪切

时间:2019-03-24 05:34:43

标签: javascript html5 video video-streaming webrtc

问题:

在WebRTC单播视频会议期间,我可以成功地将视频从移动设备的网络摄像头流传输到便携式计算机/台式机。我想在笔记本电脑/台式机上录制远程流。 (设置是将移动设备流式传输到笔记本电脑/台式机)。

但是,视频流通常会不时挂起。这不是问题,因为“查看者”方面会赶上来。但是,远程流的录制将在第一次挂起时停止。

最小和已删除的实现(本地记录):

我可以成功记录来自navigator.mediaDevices.getUserMedia()的本地流,如下所示:

const recordedChunks = [];

navigator.mediaDevices.getUserMedia({
    video: true,
    audio: false
}).then(stream => {
    const localVideoElement = document.getElementById('local-video');
    localVideoElement.srcObject = stream;
    return stream;
}).then(stream => {
    const mediaRecorder = new MediaRecorder(stream);
    mediaRecorder.ondataavailable = (event) => {
        if(event.data && event.data.size > 0) {
            recordedChunks.push(event.data);
        }
    };
    mediaRecorder.start({ mimeType: 'video/webm;codecs=vp9' }, 10);
});

我可以很容易地下载它,如下所示:

const blob = new Blob(recordedChunks, { type: 'video/webm' });

const url = URL.createObjectURL(blob);
const a = document.createElement('a');
document.body.appendChild(a);
a.style = 'display: none';
a.href = url;
a.download = 'test.webm';
a.click();
window.URL.revokeObjectURL(url);

最小和已删除的实现(远程记录):

我使用的设置要求记录远程流,而不是本地流,因为IOS Safari不支持MediaRecorder API。我包括了以上内容,以表明该记录在本地运行。远程流录制的实现没有什么不同,除了我为视频手动添加了0 Hz音轨之外,因为Chrome似乎存在一个错误,即如果没有音轨,它将无法录制。

const mediaStream = new MediaStream();
const audioContext = new AudioContext();

const destinationNode = audioContext.createMediaStreamDestination();

const oscillatorNode = audioContext.createOscillator();
oscillatorNode.frequency.setValueAtTime(0, audioContext.currentTime);
oscillatorNode.connect(destinationNode);

const audioTrack = destinationNode.stream.getAudioTracks()[0];
const videoTrack = remoteStream.getVideoTracks()[0]; // Defined somewhere else.

mediaStream.addTrack(videoTrack);
mediaStream.addTrack(audioTrack);

然后,我执行与上面的本地流示例完全相同的操作来记录mediaStream变量。

如前所述,在远程流挂起的第一点(可能是由于网络延迟),远程记录会停止,因此在下载时,.webm文件的持续时间会转换为{{1} },通过.mp4,仅与第一次挂起发生的时间一样长。

尝试缓解:

我尝试缓解此问题的一种尝试是,我不是通过记录来自WebRTC的ffmpeg事件的回调中获得的远程流,而是使用来自远程视频元素的视频流ontrack。这无法解决问题。

任何帮助将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:1)

希望有人能够为您发布实际的修复程序。同时,一种讨厌,低效,完全不推荐的解决方法:

  1. 将传入的MediaStream路由到视频元素。
  2. 使用requestAnimationFrame()将绘图框架安排​​到画布上。 (请注意,这消除了原始视频中的任何同步锁相,这不是您想要做的。不幸的是,据我所知,我们没有办法知道何时出现传入帧。)
  3. 使用CanvasCaptureMediaStream作为视频源。
  4. 在新的MediaStream中将CanvasCaptureMediaStream的视频轨道与原始MediaStream的音频轨道重新组合。
  5. 将此新MediaStream用于MediaRecorder。

我已经在过去的项目中做到了这一点,在这些项目中,我需要以编程方式操纵音频和视频。可行!

一个重要的警告是,Chrome中存在一个错误,即即使捕获流已附加到画布上,如果选项卡未激活/不可见,画布也不会被更新。而且,当然,如果选项卡未处于活动状态,requestAnimationFrame最好只能严格限制,因此您需要另一个帧时钟源。 (我使用音频处理器,哈哈!)