【问题标题】:Save the Duration from a Blob in a Browser [duplicate]在浏览器中保存 Blob 的持续时间 [重复]
【发布时间】:2018-01-30 02:37:02
【问题描述】:

我正在使用window.MediaRecorder 录制一个 wav 音频文件,然后将其上传到 S3。我将数据块保存到一个数组中,然后在录制完成后用它们创建一个 Blob。这工作正常,我在录制或播放文件时没有问题。但是,我一生都无法弄清楚如何设置生成的 Blob 文件的持续时间。

每当我在本地下载文件或将其上传到 s3 时,任何地方都没有持续时间元数据。我将音频的持续时间保存为用户记录,但无法有效地将其附加到音频文件中。我觉得应该有一个简单的解决方案,但我只是花了几个小时搜索,似乎找不到任何东西。它必须是可能的,所以我错过了什么?

【问题讨论】:

标签: javascript file audio blob wav


【解决方案1】:

您可能已经找到了解决方案,但我将其发布给其他对此感兴趣的人查看。

您可以使用 MediaRecorder.onstartonstop 事件。

  1. 当 MediaRecorder 的 onstart 事件被触发时,您需要使用 Date.now() 之类的方法获取当前日期。
  2. 触发 onstop 事件时,也获取当前日期。
  3. 您需要减去这两个日期才能获得录制音频的持续时间。

参考资料:

【讨论】:

  • 顺便说一句,我不太确定 .wav 文件在 Firefox 和 Chrome 中是否默认支持(不确定其他文件)。 Firefox 可以记录 .ogg 文件和 Chrome .webm 文件。希望对您有所帮助。
  • 如何使用持续时间将其设置到 blob 上?
  • TBH 我不记得我在实现它时为什么需要它,但是我假设我想要一种简单的方法来保持我的数据库中的持续时间,以使其他转换步骤更直接。因此,您不必将持续时间存储在 blob 中,我使用隐藏输入来存储持续时间并将其作为音频的元数据发送到数据库。
  • @CoreyCole,您无法在 webm/opus 编码文件中设置持续时间。持续时间是通过事后解析二进制文件得出的。
【解决方案2】:

我已经对这个问题进行了大量研究,我得出的结论是,由于 webm 文件的编码方式,为了获得持续时间,您必须解析二进制文件并将所有帧相加为一个持续时间。这是非常复杂和乏味的。如果您对此感兴趣,请阅读How to parse webm

我走的路线要简单得多。记录文件后,您应该获取它并将其附加到音频元素。如果您现在检查持续时间,您仍然会发现它是不正确的。您需要做的是等待loadedmetadata 事件。此时您可以运行以下函数:

checkForDuration(cb =()=> {}) {
  if(this.element.duration === Infinity) {
    this.element.currentTime = 1e101;
    this.element.ontimeupdate = function() {
      this.ontimeupdate = ()=> {return;};
      cb();
    };
  } else {
    cb();
  }
}

在调用回调时,您可以检查音频元素的持续时间属性以获取正确的持续时间。然后,您可以将持续时间存储在数据库中以供将来检索。

【讨论】:

    【解决方案3】:

    有一个封装了浏览器原生MediaRecorder 的库,称为RecordRTC。它公开了一个名为 getSeekableBlob() 的函数。

    确保在您的网页中包含 EBML.js CDN,因为 getSeekableBlob() 取决于它:

    <script src="https://www.webrtc-experiment.com/EBML.js"></script>
    

    您可以查看示例用法here

    function stopRecordingCallback() {
        video.muted = false;
        video.volume = 1;
        video.src = video.srcObject = null;
        getSeekableBlob(recorder.getBlob(), function(seekableBlob) {
            video.src = URL.createObjectURL(seekableBlob);
            recorder.stream.stop();
            recorder.destroy();
            recorder = null;
            document.getElementById('btn-start-recording').disabled = false;
            invokeSaveAsDialog(seekableBlob, 'seekable-recordrtc.webm');
        });
    }
    

    【讨论】:

      猜你喜欢
      • 2012-08-26
      • 1970-01-01
      • 2016-09-10
      • 2021-08-07
      • 2015-01-28
      • 2019-11-03
      • 2011-10-11
      • 2015-05-09
      • 2012-07-31
      相关资源
      最近更新 更多