是否可以将多个webm blob /剪辑合并为一个顺序视频客户端?

时间:2017-06-21 22:06:22

标签: javascript video blob mediarecorder webm

我已经看过这个问题 -

Concatenate parts of two or more webm video blobs

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

我的问题的症结在于,在第一次播放后,我无法将多个blob webm剪辑组合成一个没有错误播放的剪辑。要直接找到问题,请滚动到前两个代码块之后的行,以便继续阅读背景。

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

我正在使用MediaRecorder WebAPI在chrome / firefox上录制视频。 (附带问题 - 除了闪存之外还有其他任何方式可以通过网络摄像头和麦克风录制视频/音频吗?因为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 = [];
}

调用函数finishRecording,并将场景(mimetype'video / webm'的blob数组)保存到scene数组中。保存后。然后,用户可以通过此过程记录和保存更多场景。然后,他可以使用以下代码块查看某个场景。

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

在上面的代码中,发生的事情是场景的blob数组变成一个大blob,其中一个url被创建并由视频的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]);
}

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

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

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

1 个答案:

答案 0 :(得分:2)

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

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

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

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

这是一个external demo,因为stacksnippets不适用于gUM ......

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