5

我想以 2 秒的间隔记录本地和远程流并使用 Ajax 将其上传到服务器。但问题是,ondataavailable 方法被调用了两次,所以同一个视频被上传到服务器两次。第一个视频可播放且正常,而其余视频已损坏或非常小(不到一秒)。所有视频的大小几乎相同!

我也尝试过使用 MediaRecorder API,但问题是一样的。我已经尝试了 5 秒的间隔,但仍然没有运气!

这就是我获取本地流的方式:

navigator.mediaDevices.getUserMedia({
    video: false,
    audio: true
}).then(function (myStream) {
    localStream = myStream;

    localStream.getTracks().forEach(function (track) {
        yourConn.addTrack(track, localStream);
    });
}).catch(function (error) {
    streamAdded = false;
    console.warn('Could not detect microphone');
    return false;
});

这就是我执行录制的方式:

yourConn.ontrack = function (e) {
   remoteVideo.srcObject = e.streams[0];

   let recorder = RecordRTC([localStream, e.streams[0]], {
      mimeType: 'video/webm;codecs=h264',
      type: 'video',
      timeSlice: 5000,
      ondataavailable: function(blob) {
        uploadBlob(blob);
      },
   });

   recorder.startRecording();
}

上传Blob函数:

var formData = new FormData();
formData.append('recorded_file', mp4File);

$.ajax({
    url: myURL,
    data: formData,
    cache: false,
    contentType: false,
    processData: false,
    type: 'POST',
    success: function (response) {
        console.log(response);
    }
});

如何在没有任何问题的情况下记录两个流?

4

2 回答 2

2

(这个答案涵盖了MediaRecorder,尽管我怀疑它也适用于 RecordRTC JS 库。)

timeSlice: 5000参数将记录切成dataavailable,每 5 秒调用 一次。但是这些块不是独立可玩的。您应该 像这样加入他们以创建有效的媒体容器文件:

const data = [];
recorder.ondataavailable = e => data.push(e.data);
recorder.onstop = () => uploadBlob(new Blob(data, {type: data[0].type}));

如果最后上传所有内容不切实际,您可以尝试加入服务器上的 blob。

于 2019-09-04T23:31:34.060 回答
2

我已经通过Stop and Restart 方法解决了这个问题。当我得到第一个 blob 时,我正在停止记录器,然后我上传它并再次启动记录器。这样每次我都能得到一个完整的视频。

function initRecorder(remoteStream) {
    recorder = RecordRTC([stream, remoteStream], {
       type: 'video',
    });

    recorder.startRecording();
}

// in ontrack method:

initRecorder(remoteStream);  // initially start recording

let recordingInterval = setInterval(function () {
    if (!callInfo.isCallActive) clearInterval(recordingInterval);

    recorder.stopRecording(function () {
        let blob = recorder.getBlob();
        if(callInfo.isCallActive) {
            initRecorder(remoteStream);  // restart recording
        }
        if (blob.size) { // prevent empty blobs
            uploadBlob(blob, roomId);
        }
    });
}, 5000);
于 2019-09-05T07:35:51.583 回答