【问题标题】:How do I programatically play an webm audio I just recorded in HTML5?如何以编程方式播放我刚刚用 HTML5 录制的 webm 音频?
【发布时间】:2017-11-23 02:13:24
【问题描述】:

我刚刚录制了一段音频,我想用纯 Javascript 代码播放它。

这是我的代码:

navigator.getUserMedia({audio: true},function(stream){
    var recorder = new MediaRecorder(stream);

    recorder.start(1000);

    recorder.ondataavailable = function(e){
        console.log(e.data);
        // var buffer = new Blob([e.data],{type: "video/webm"});
    };
});

我必须在ondataavailable 中做什么才能播放存储在内存中的音频块,而无需在HTML 中使用audiovideo 标记?

【问题讨论】:

    标签: javascript html audio webrtc mediarecorder


    【解决方案1】:

    我真的不明白您为什么不想要音频或视频元素,但无论如何,第一步是相同的。

    MediaRecorder.ondataavailable 事件将定期触发,并包含一个 data 属性,其中包含一大块已录制的媒体。 您需要存储这些块,以便能够在录制结束时将它们合并到单个 Blob 中。
    要合并它们,您只需调用new Blob(chunks_array),其中chunks_array 是一个数组,其中包含您从dataavailable.data 获得的所有块Blob。

    一旦你得到了这个最终的 Blob,你就可以将它用作普通媒体,例如,通过 URL.createObjectURL 方法在 MediaElement 中播放它,或者将它转换为 ArrayBuffer,然后通过 WebAudio 对其进行解码API 或您喜欢的任何其他方式。

    navigator.mediaDevices.getUserMedia({audio: true})
    .then(recordStream)
    .catch(console.error);
    
    function recordStream(stream){
      const chunks = []; // an Array to store all our chunks
      const rec = new MediaRecorder(stream);
      rec.ondataavailable  = e => chunks.push(e.data);
      rec.onstop = e => {
        stream.getTracks().forEach(s => s.stop());
        finalize(chunks);
      };
      rec.start();
      setTimeout(()=>rec.stop(), 5000); // stop the recorder in 5s
    }
    function finalize(chunks){
      const blob = new Blob(chunks);
      playMedia(blob);
    }
    function playMedia(blob){
      const ctx = new AudioContext();
      const fileReader = new FileReader();
      fileReader.onload = e =>  ctx.decodeAudioData(fileReader.result)
      .then(buf => {
        btn.onclick = e => {
          const source = ctx.createBufferSource();
          source.buffer = buf;
          source.connect(ctx.destination);
          source.start(0);
        };
        btn.disabled = false;
      });
      fileReader.readAsArrayBuffer(blob);
    }
    <button id="btn" disabled>play</button>

    And as a plnkr 用于 chrome 及其严格的 iframe 限制。

    【讨论】:

    • 嘿,谢谢。我不能复制一个块而不是整个序列吗?我实际上是在寻找一种使用 Web Audio Api 的对象和方法来重现它的方法,例如 audioContext audioBuffer audioBufferSourceNode
    • @VictorFerreira 在第一个块之前,您总是至少需要所有先前的块:例如,如果您录制的时间足够长以获取 10 个块,您可以仅从 5 个第一个构建文件,但不能从第五个人。元数据保存在第一个块中。
    猜你喜欢
    • 1970-01-01
    • 2020-05-26
    • 2019-11-04
    • 2013-04-05
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多