【问题标题】:AudioBuffer - get data only from a particular sample of a particular length without decoding the entire soundAudioBuffer - 仅从特定长度的特定样本中获取数据,而不解码整个声音
【发布时间】:2026-01-22 19:35:01
【问题描述】:

我正在使用 JavaScript 开发 DAW,我需要能够加载许多(最多 30 个)长音频文件(每个最多 15 分钟),并且我不希望它们占用内存。我只是希望能够切割小块,处理它们并混入ScriptProcessorNode,但我遇到了几个问题:

  • AudioBuffer 会将整个音频文件加载到内存中未压缩
  • AudioBuffer.getChannelData() 将提取整个缓冲区 - 不可能只提取一小块(例如,从样本 1024 到样本 2048)
  • MediaElementAudioSourceNode,用于处理大文件 - 它不会让我从中提取任何数据,也不会让我从 URL 动态加载文件 - 它只允许我连接到 AudioContext 中的其他节点,但是我不想在任何地方连接它

有没有办法加载大型音频文件,例如,以 MP3 格式,将它们压缩为 MP3 格式在内存中,但将小块音频数据提取到 AudioBuffer?

例如:

var request = new XMLHttpRequest();
request.open('GET', 'my_15min_audioFile.ogg', true);
request.responseType = 'arraybuffer';
request.onload = function() {
    var longCompressed = new LongAudioNode(request.response);// something similar to fs.open
    var channel=1, fromSample=1024, length=2048;
    var block/**Float32Array*/ = longCompressed.extractBlock(channel, fromSample, length);/// similar to fs.read
    /// do something with this block and then request another from any random index I want
}
request.send();

【问题讨论】:

    标签: javascript audio html5-audio web-audio-api


    【解决方案1】:

    浏览器中没有 API 可以完全满足您的需求。但将来可能会有一个。 Web Codecs 可能会支持以流的形式读取解码数据。

    但是有一种解决方法可以在某些条件下工作。您可以使用 MP3 的编码数据扫描 ArrayBuffer 以查找帧头,然后相应地对其进行剪切。这些片段应该仍然是有效的 MP3,然后可以使用decodeAudioData() 解码。但是有一些陷阱。如果没有任何后处理,解码后的片段可能无法组合在一起。 phonograph 库就是使用这种技术构建的。

    【讨论】: