For the complete documentation index, see llms.txt. This page is also available as Markdown.

音频分析

从场景中播放的音频读取实时振幅和频率数据,以驱动响应式视觉效果。

该 音频分析 组件会读取场景中正在播放的音频源的实时数据,因此你可以让视觉效果随音乐驱动。每一帧,它会报告一个整体的 振幅 值,以及 8 个频段 (从低到高),你可以用它们来缩放、着色或为实体制作动画。

常见用途:

  • 随着低音跳动的立方体。

  • 随节拍脉动的灯光。

  • 均衡器风格的条形可视化器。

  • 会响应音乐的材质或按比例缩放的道具。

音频分析 是一个只读数据流——你的场景只消费这些值,运行时会填充它们。它适用于通过一个 AudioSource、一个 AudioStream,或者一个 VideoPlayer.

最小示例

下面的场景会播放一个声音,并将 音频分析 附加到同一实体上,然后使用音频的振幅在每一帧缩放一个立方体。

import {
  engine,
  Transform,
  MeshRenderer,
  AudioSource,
  AudioAnalysis,
  AudioAnalysisView,
} from "@dcl/sdk/ecs";
import { Vector3 } from "@dcl/sdk/math";

export function main() {
  // 在一个实体上播放声音
  const audioEntity = engine.addEntity();
  Transform.create(audioEntity);
  AudioSource.create(audioEntity, {
    audioClipUrl: "sounds/music.mp3",
    playing: true,
    loop: true,
  });

  // 将 AudioAnalysis 附加到同一实体,以开始接收分析数据
  AudioAnalysis.createAudioAnalysis(audioEntity);

  // 一个可复用的视图对象,组件会在每一帧写入其中
  const analysis: AudioAnalysisView = {
    amplitude: 0,
    bands: new Array<number>(8),
  };

  // 一个会随音频振幅脉动的立方体
  const cube = engine.addEntity();
  MeshRenderer.setBox(cube);
  Transform.create(cube, { position: Vector3.create(8, 1, 8) });

  // 每帧读取最新的分析值并缩放立方体
  engine.addSystem(() => {
    AudioAnalysis.readIntoView(audioEntity, analysis);
    const s = 1 + analysis.amplitude * 10;
    Transform.getMutable(cube).scale = Vector3.create(s, s, s);
  });
}

关键调用有:

  1. AudioAnalysis.createAudioAnalysis(entity) ——将组件附加到拥有该 AudioSource, AudioStream,或 VideoPlayer。默认使用对数模式(见 模式).

  2. AudioAnalysis.readIntoView(entity, analysis) ——复制最新的 振幅 和 8 个频段 值到你提供的一个视图对象中。

每一帧读取数据

音频分析 设计为从系统中每帧读取一次。推荐模式如下:

  1. 只分配一个 AudioAnalysisView 对象,且只分配一次。

  2. 在系统中,调用 readIntoView 来刷新它。

  3. 直接使用这些值,或者在多个系统之间共享该视图。

如果被分析的实体可能尚未拥有一个 音频分析 组件(例如它稍后才创建,或被动态移除),请使用 tryReadIntoView 代替。它会在 false 组件缺失时返回 true ,并在写入值时返回。

💡 提示:调用 readIntoView 一次并让多个系统共享同一个视图对象,比反复读取组件更便宜。

对特定频段做出响应

这 8 个频段覆盖了从低到高的可听频谱。 bands[0] 是最低的(低音),而 bands[7] 是最高的(高音)。你可以用不同的频段驱动不同的实体,来构建一个经典均衡器。

这与下面示例场景中使用的模式相同: 音频可视化示例场景,仅保留了核心部分。

模式

音频分析 支持两种分析模式,在创建组件时设置:

  • PBAudioAnalysisMode.MODE_LOGARITHMIC (默认):值会按对数曲线缩放,这更接近人耳感知音量变化的方式。最适合视觉响应。

  • PBAudioAnalysisMode.MODE_RAW:未经处理的振幅和 FFT 频段值。如果你想应用自己的缩放,请使用它。

调节对数模式

在对数模式下,你可以传入两个可选的增益乘数:

  • amplitudeGain ——应用于整体振幅的乘数。默认值为 5.

  • bandsGain ——应用于全部 8 个频段的乘数。默认值为 0.05.

较高的增益会让数值更敏感;较低的增益会让它们更细微。

替换现有组件

createAudioAnalysis 如果实体已经有一个 音频分析 组件,则会失败。要在运行时切换模式或增益,请使用 createOrReplaceAudioAnalysis,它具有相同的参数签名。

组件参考

AudioAnalysis.createAudioAnalysis(entity, mode?, amplitudeGain?, bandsGain?)

将一个 音频分析 字段设为 实体附加上去。如果组件已存在,则会失败。

  • 实体 (Entity):拥有该 AudioSource, AudioStream,或 VideoPlayer 、你想分析的实体。

  • mode (PBAudioAnalysisMode,可选): MODE_LOGARITHMIC (默认)或 MODE_RAW.

  • amplitudeGain (数值,可选):对数模式下的振幅乘数。默认值 5.

  • bandsGain (数值,可选):对数模式下的频段乘数。默认值 0.05.

AudioAnalysis.createOrReplaceAudioAnalysis(entity, mode?, amplitudeGain?, bandsGain?)

与上面相同,但会替换实体上现有的 音频分析 组件,而不是失败。

AudioAnalysis.readIntoView(entity, out)

将最新值读取到 out。如果 实体 没有一个 音频分析 组件。

  • 实体 (Entity):带有该组件的实体。

  • out (AudioAnalysisView):你提供的视图对象。必须具有 个频段 预先分配的 8 个数字。

AudioAnalysis.tryReadIntoView(entity, out): boolean

与 readIntoView相同,但在 false 实体没有 音频分析 组件时返回,而不是抛出异常。返回 true 时会写入值。

AudioAnalysisView

你分配的一个普通对象,用于接收分析数据:

注意事项和限制

  • 8 个频段,固定不变。 频段数量固定为 8。没有可用于请求更多或更少频段的 API。

  • 每次分析对应一个音频源。 每个 音频分析 组件都会分析其所附加实体的音频。要分析多个源,请将 音频分析 附加到每一个源上。

  • 实时视频流不会被分析。 有一个已知问题: 音频分析 在以下情况下会收不到数据: VideoPlayer 源是一个非渐进式流,例如一个 .m3u8 HLS URL:流的音频会播放,但分析值会一直为零。视频文件(例如 .mp4)会被正确分析。

  • 暂停的音频不会报告更新。 当底层音频停止或暂停时,组件值会停止变化。你最后读取到的值会保留在视图对象中,直到音频再次播放。

  • 便宜,但不是免费的。 逐帧分析的设计目标是开销很低(在桌面端每个源低于一毫秒)。避免将 音频分析 同时附加到过多源上,除非你确实需要这些数据。当可视化器不可见时,移除该组件。

最后更新于