是否可以将多个webm blob /片段合并到一个顺序的视频客户端中?

Upa*_*ram 5 javascript video blob webm mediarecorder

我已经看过这个问题了-

串联两个或多个WebM视频Blob的部分

并在此处尝试了示例代码-https : //developer.mozilla.org/en-US/docs/Web/API/MediaSource-(无修改),希望将blob转换为arraybuffers并将它们附加到MediaSource WebAPI,但即使示例代码也无法在我认为兼容的Chrome浏览器上运行。

我的问题的症结在于,第一次播放后,我无法将多个Blob Webm剪辑合并成一个没有正确播放的剪辑。要直接解决该问题,请滚动至前两个代码块之后的行,以使背景继续阅读。

我正在设计一个Web应用程序,允许演示者记录他/她自己的场景并解释图表和视频。

我正在使用MediaRecorder WebAPI在chrome / firefox上录制视频。(旁边的问题-除通过Flash之外,我还可以通过网络摄像头和麦克风录制视频/音频吗?因为非Chrome / Firefox用户代理不支持MediaRecorder)。

navigator.mediaDevices.getUserMedia(constraints)
    .then(gotMedia)
    .catch(e => { console.error('getUserMedia() failed: ' + e); });

function gotMedia(stream) {
    recording = true;
    theStream = stream;
    vid.src = URL.createObjectURL(theStream);
    try {
        recorder = new MediaRecorder(stream);
    } catch (e) {
        console.error('Exception while creating MediaRecorder: ' + e);
        return;
    }

    theRecorder = recorder;
    recorder.ondataavailable = 
        (event) => {
            tempScene.push(event.data);
        };

    theRecorder.start(100);
}

function finishRecording() {
    recording = false;
    theRecorder.stop();
    theStream.getTracks().forEach(track => { track.stop(); });

    while(tempScene[0].size != 1) {
        tempScene.splice(0,1);
    }

    console.log(tempScene);

    scenes.push(tempScene);
    tempScene = [];
}
Run Code Online (Sandbox Code Playgroud)

调用函数finishRecording,并将场景(mimetype'video / webm'的blob数组)保存到scenes数组。保存后。然后,用户可以通过此过程记录并保存更多场景。然后,他可以使用下面的这段代码查看特定的场景。

function showScene(sceneNum) {
    var sceneBlob = new Blob(scenes[sceneNum], {type: 'video/webm; codecs=vorbis,vp8'});
    vid.src = URL.createObjectURL(sceneBlob);
    vid.play();
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,场景的Blob数组变成了一个大Blob,该Blob会为该Blob创建一个网址,并由视频的src属性指向该网址,因此-[blob,blob,blob] => sceneBlob(一个对象,不是数组)


到现在为止,一切正常且正常。这是问题的开始

我尝试通过将每个场景的Blob数组组合到一个长Blob数组中,将所有场景合并为一个。此功能的目的是使用户可以按他/她认为合适的顺序订购场景,因此他可以选择不包括场景。因此,它们的记录顺序不一定相同,所以-

场景1:[blob-1,blob-1]场景2:[blob-2,blob-2]最终:[blob-2,blob-2,blob-1,blob-1]

然后我制作了最终的Blob数组的Blob,所以-final:[blob,blob,blob,blob] => finalBlob下面的代码用于合并场景Blob数组

function mergeScenes() {
    scenes[scenes.length] = [];
    for(var i = 0; i < scenes.length - 1; i++) {
        scenes[scenes.length - 1] = scenes[scenes.length - 1].concat(scenes[i]);
    }
    mergedScenes = scenes[scenes.length - 1];
    console.log(scenes[scenes.length - 1]);
}
Run Code Online (Sandbox Code Playgroud)

可以在第二小段代码中使用showScene函数来查看此最终场景,因为它是作为场景数组中的最后一个场景追加的。当使用showScene函数播放视频时,它将一直播放所有场景。但是,如果我在第一次播放视频后按播放,则它只会播放最后一个场景。另外,如果我通过浏览器下载并播放视频,则第一次可以正确播放-随后的时间,我会看到相同的错误。

我究竟做错了什么?如何将文件合并到一个包含所有场景的视频中?非常感谢您抽出宝贵时间阅读本文并为我提供帮助,如果需要澄清任何内容,请告诉我。

我正在使用一个元素来显示场景

Kai*_*ido 5

文件的标题(元数据)应该只附加到您获得的第一个数据块。
你不能通过一个接一个地粘贴来制作一个新的视频文件,它们有一个结构。

那么如何解决这个问题呢?

如果我正确理解您的问题,您需要的是能够合并所有录制的视频,就像它只是暂停一样。嗯,这可以实现,多亏了MediaRecorder.pause()方法。

您可以保持流打开,只需暂停 MediaRecorder。在每个pause事件中,您都可以生成一个新视频,其中包含从录制开始到此事件的所有帧。

这是一个外部演示,因为 stacksnippets 不适用于 gUM ...

如果您还需要在每个恢复和暂停事件之间制作更短的视频,您可以简单地为这些较小的部分创建新的 MediaRecorder,同时保持大部分的运行。