此页面由社区从英文翻译而来。了解更多并加入 MDN Web Docs 社区。

View in English Always switch to English

BaseAudioContext:createBuffer() 方法

基线 广泛可用

自 2021年4月 起,此特性已在主流浏览器中得到支持,可在大多数设备和浏览器版本中正常使用。

BaseAudioContext 接口的 createBuffer() 方法用于新建一个空的 AudioBuffer 对象,随后可以填充数据,并通过 AudioBufferSourceNode 播放。

更多关于音频片段的细节,请查阅 AudioBuffer 参考页面。

备注:createBuffer() 过去可以接收压缩音频数据,并返回解码后的采样数据,但这项功能已经从规范中删除,因为所有的解码工作都在主线程中完成,导致 createBuffer() 阻塞了其他代码的执行。异步方法 decodeAudioData() 能够完成相同的工作——传入 MP3 文件之类的压缩音频数据,并直接返回一个可以通过 AudioBufferSourceNode 播放的 AudioBuffer。对于诸如播放 MP3 这类简单使用场景,decodeAudioData() 就是你应当使用的。

如果想深入了解音频片段是如何工作的,以及这些参数的作用,请阅读基本概念指南中的音频片段:帧、样本和声道

语法

js
createBuffer(numOfChannels, length, sampleRate)

参数

numOfChannels

一个整数,表示音频片段应包含的声道数。默认值为 1,所有浏览器必须支持至少 32 个声道。

length

一个整数,表示音频片段的大小,单位是采样帧(每个采样帧的大小等于单个采样的字节数乘以 numOfChannels)。要确定特定秒数音频所需的 length,使用 numSeconds * sampleRate

sampleRate

线性音频数据的采样率,单位是每秒采样帧数。所有浏览器必须支持至少 8000 Hz 到 96000 Hz 范围内的采样率。

返回值

一个基于指定参数配置的 AudioBuffer

异常

NotSupportedError DOMException

如果一个或多个参数为负数或具有无效值(例如 numberOfChannels 高于支持的值,或 sampleRate 超出正常范围),则抛出此异常。

RangeError

如果没有足够的内存来分配音频片段,则抛出此异常。

示例

首先,我们将从几个浅显易懂的示例入手,来解释如何使用这些参数:

js
const audioCtx = new AudioContext();
const buffer = audioCtx.createBuffer(2, 22050, 44100);

如果你这样调用,你将会得到一个立体声(双声道)的音频片段,当它在一个 44100 Hz(非常常见,大多数普通声卡都运行在该频率下)的音频上下文(AudioContext)中播放的时候,会持续 0.5 秒:22050 帧 / 44100 Hz = 0.5 秒。

js
const audioCtx = new AudioContext();
const buffer = audioCtx.createBuffer(1, 22050, 22050);

如果你这样调用,你将会得到一个单声道的音频片段,当它在一个 44100 Hz 的音频上下文(AudioContext)中播放的时候,会被自动重采样到 44100 Hz(因此也会产生 44100 个采样帧),并持续 1 秒:44100 帧 / 44100 Hz = 1 秒。

备注:音频重采样与图片的缩放非常类似:假设你有一张 16 x 16 的图片,但希望它填充一个 32 x 32 的区域,你就需要对它进行缩放(重采样)。缩放后的结果质量会有所下降(可能会变得模糊或出现锯齿,取决于缩放算法),但它仍然可用,而且缩放后的图片占用的空间更小。重采样的音频原理相同——你能节省一些空间,但是也会无法准确再现高频内容(高音区)。

现在来看一个更加复杂的 createBuffer() 示例,我们将创建一个 3 秒的音频片段,用白噪声填充它,之后通过一个音频片段源节点(AudioBufferSourceNode)播放。代码中的注释应该能充分解释发生了什么。你可以实时运行代码,或者查看源代码

js
const audioCtx = new AudioContext();

// 创建一个 3 秒的立体声空音频片段,采样率与 AudioContext 相同
const myArrayBuffer = audioCtx.createBuffer(
  2,
  audioCtx.sampleRate * 3,
  audioCtx.sampleRate,
);

// 使用白噪声填充音频片段
// 即 -1.0 到 1.0 之间的随机数
for (let channel = 0; channel < myArrayBuffer.numberOfChannels; channel++) {
  // 这会给我们提供包含数据的实际 ArrayBuffer
  const nowBuffering = myArrayBuffer.getChannelData(channel);
  for (let i = 0; i < myArrayBuffer.length; i++) {
    // Math.random() 的范围是 [0; 1.0]
    // 音频需要在 [-1.0; 1.0] 之间
    nowBuffering[i] = Math.random() * 2 - 1;
  }
}

// 获取一个 AudioBufferSourceNode
// 这是当我们想要播放 AudioBuffer 时所使用的 AudioNode
const source = audioCtx.createBufferSource();
// 设置 AudioBufferSourceNode 的 buffer
source.buffer = myArrayBuffer;
// 将 AudioBufferSourceNode 连接到 destination,这样我们就能听到声音了
source.connect(audioCtx.destination);
// 开始播放音频源
source.start();

规范

规范
Web Audio API
# dom-baseaudiocontext-createbuffer

浏览器兼容性

参见