【问题标题】:How to play an MP3 file via JavaScript AudioWorklet?如何通过 JavaScript AudioWorklet 播放 MP3 文件?
【发布时间】:2023-01-15 09:17:37
【问题描述】:


我按照 this 示例创建了一个按预期工作的自定义 AudioWorkletProcessor。我现在想做的是从我的服务器(我目前正在使用 Python/Flask)将 MP3 音频流式传输到其中。

所以,例如

const response = await fetch(url);
const reader = response.body.getReader();

while (true) {
  const {value, done} = await reader.read();
  if (done) break;
  // do something with value
}

这给了我一个Uint8Array。如何将其内容传递给 AudioWorklet 而不是当前的 channel[i] = Math.random() * 2 - 1;

谢谢 :)

【问题讨论】:

    标签: javascript flask web-audio-api audio-worklet


    【解决方案1】:
    for (let i=0; i < value.length; i++) {
        channel[i] = value[i];
    }
    

    【讨论】:

    • 请详细一点。仅代码答案是不可取的,并且会被删除投票系统自动标记为“低质量”。
    【解决方案2】:

    首先,MP3 是一种压缩的音频文件格式,但 Web Audio API 节点仅适用于未压缩的样本数据。您需要使用 AudioContext 对象的 decodeAudioData() 方法将 MP3 文件的字节转换为 AudioBuffer 对象。

    其次,decodeAudioData() 并不是真正为流式传输而设计的,但因为您使用的是 MP3,所以您很幸运。看Encoding fails when I fetch audio content partially想要查询更多的信息。

    第三,AudioContext 对象不能从 AudioWorkletProcessor 内部访问,所以你必须从主线程调用 decodeAudioData(),然后使用它们将解压缩的数据从你的 AudioWorkletNode 传递给你的 AudioWorkletProcessor各自消息端口,可从每个对象的 port 属性访问。

    第四,AudioBuffer 不是可以使用postMessage() 通过消息端口发送的允许类型之一。幸运的是,缓冲区的 getChannelData() 方法返回的 Float32Array 是受支持的类型之一。

    我不确定您使用音频工作集的原因是什么。取决于你想用 MP3 做什么,但如果你只想播放它,那么有更简单的解决方案,可以降低 CPU 使用率。

    【讨论】:

      猜你喜欢
      • 2020-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-11
      • 2013-11-02
      • 2016-08-31
      • 1970-01-01
      相关资源
      最近更新 更多