无法使用 EBML.js 从媒体记录器创建可搜索的视频 blob - MediaRecorder API - Chrome

Kg7*_*Kg7 7 javascript google-chrome webrtc web-mediarecorder ebml

使用媒体记录器,我可以在 azure 上上传和附加视频 blob。但使用以下代码下载时无法搜索组合视频 -

var chunks =[];
var mediaRecorder = new MediaRecorder(stream, 'video/x-matroska;codecs=vp8,opus');
mediaRecorder.ondataavailable = function(event) {
  if(event.data && event.data.size > 0) {
       chunks.push(event.data);
       appendBlockToAzure(chunks);
    }
};
mediaRecorder.start(10000);
Run Code Online (Sandbox Code Playgroud)

我尝试使用 EBML.js,如果我使用以下代码,那么我会得到可查找的视频文件。这种方法需要在最后处理文件。因此,最终文件的大小可能为 1GB,这将需要很长时间才能上传。

var chunks =[];
var mediaRecorder = new MediaRecorder(stream, 'video/x-matroska;codecs=vp8,opus');
mediaRecorder.ondataavailable = function(event) {
   if(event.data && event.data.size > 0) {
        chunks.push(event.data);
        if(mediaRecorder.state == "inactive") { //if media recorder is stopped
            var combined = new Blob(chunks, { type: event.data.type });
            getSeekableBlob(combined, function (seekableBlob) {
                   saveCombinedVideoToAzure(seekableBlob);  
            });
        }
    }
 };
mediaRecorder.start(10000);
Run Code Online (Sandbox Code Playgroud)

这就是我想同时上传到天蓝色的原因。如果我使用以下代码,则会记录未知标签警告,然后记录长度错误。另外,视频文件无法播放。

var seekablechunks =[];
var mediaRecorder = new MediaRecorder(stream, 'video/x-matroska;codecs=vp8,opus');
mediaRecorder.ondataavailable = function(event) {
   if(event.data && event.data.size > 0) {
        getSeekableBlob(event.data, function (seekableBlob) {
             seekablechunks.push(seekableBlob);
             saveCombinedVideoToAzure(seekablechunks);  
        });
   }
 };
mediaRecorder.start(10000);
Run Code Online (Sandbox Code Playgroud)

函数“getSeekableBlob”:

function getSeekableBlob(inputBlob, callback) {
  // EBML.js copyrights goes to: https://github.com/legokichi/ts-ebml
  if(typeof EBML === 'undefined') {
      throw new Error('Please link: https://www.webrtc- experiment.com/EBML.js');
  }

  var reader = new EBML.Reader();
  var decoder = new EBML.Decoder();
  var tools = EBML.tools;

  var fileReader = new FileReader();
  fileReader.onload = function (e) {
      var ebmlElms = decoder.decode(this.result);
      ebmlElms.forEach(function (element) {
          reader.read(element);
      });
      reader.stop();
      var refinedMetadataBuf = tools.makeMetadataSeekable(reader.metadatas, reader.duration, reader.cues);
      var body = this.result.slice(reader.metadataSize);

      var newBlob = new Blob([refinedMetadataBuf, body], {
          type: 'video/webm'
      });

      callback(newBlob);
  };
  fileReader.readAsArrayBuffer(inputBlob);
}
Run Code Online (Sandbox Code Playgroud)

有没有办法获取可查找的 blob 并将其上传到 azure?

O. *_*nes 4

对于开放式媒体流源(例如 MediaRecorder)来说,创建包含SeekHead 元素的文件是一个挑战。SeekHead 元素中的 Seek 元素包含文件中元素的字节偏移量。

正如您所发现的,MediaRecorder 不会创建段或 SeekHead 元素。为此,它需要能够预见未来,了解文件中未来压缩视频和音频元素的大小。

处理此问题的一个好方法可能是在服务器上对上传的文件进行后处理。当文件完全上传时,您可以使用ts-ebml在服务器上以流式传输方式执行此操作。

我想,可以在浏览器中创建 Javascript 软件,该软件可以转换 MediaRecorder 发出的数据流,以便可以动态查找。为了使您的流可搜索,您需要经常插入 SeekHead 元素。您可以缓冲流的数秒,然后在每个缓冲区中找到 Cluster 元素,然后写入指向其中一些元素的 SeekHead 元素。(Chrome 的 MediaRecorder 输出以视频关键帧开头的簇。)如果您成功地做到了这一点,您将了解很多关于 Matroska / webm 的知识。