4

使用媒体记录器,我可以在 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);

我尝试使用 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);

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

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);

函数“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);
}

有没有办法获取可搜索的 blob 并将它们上传到 azure?

4

2 回答 2

0

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

MediaRecorder 不会像您发现的那样创建分段或 SeekHead 元素。为此,它需要能够看到未来,以了解未来压缩的视频和音频元素在文件中的大小。

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

我想,有可能在您的浏览器中创建 Javascript 软件,该软件可以转换 MediaRecorder 发出的数据流,使其可以即时查找。为了使您的流可搜索,您需要每隔一段时间插入 SeekHead 元素。您将缓冲多秒的流,然后在每个缓冲区中定位 Cluster 元素,然后编写一个指向其中一些元素的 SeekHead 元素。(Chrome 的 MediaRecorder 输出以视频关键帧开头的集群。)如果你成功地做到了这一点,你就会对 Matroska / webm 了解很多。

于 2021-03-06T17:27:42.700 回答
0

突然,我们的 Face on camera 网络摄像头记录器组件停止保存 webm blob。

在控制台中有关于{EBML_ID: "55b0", type: "unknown", ...}reader.read(element) 期间的警告,然后在调用时出现“未捕获(承诺中)错误:在 EBMLEncoder.js 中未找到未知模式条目” tools.makeMetadataSeekable(...)

忽略解码器中的未知元素解决了该问题:

  ...
  var ebmlElms = decoder.decode(this.result);
  ebmlElms.forEach(function (element) {
      if (element.type !== 'unknown') {
          reader.read(element);
      }
  });
  reader.stop();
  ...

ts-ebml npm 包上的相关问题https://github.com/legokichi/ts-ebml/issues/33具有类似的解决方法

于 2021-08-03T16:12:33.103 回答