音频分析
从场景中播放的音频读取实时振幅和频率数据,以驱动响应式视觉效果。
该 音频分析 组件会读取场景中正在播放的音频源的实时数据,因此你可以让视觉效果随音乐驱动。每一帧,它会报告一个整体的 振幅 值,以及 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);
});
}关键调用有:
AudioAnalysis.createAudioAnalysis(entity)——将组件附加到拥有该AudioSource,AudioStream,或VideoPlayer。默认使用对数模式(见 模式).AudioAnalysis.readIntoView(entity, analysis)——复制最新的振幅和 8个频段值到你提供的一个视图对象中。
每一帧读取数据
音频分析 设计为从系统中每帧读取一次。推荐模式如下:
只分配一个
AudioAnalysisView对象,且只分配一次。在系统中,调用
readIntoView来刷新它。直接使用这些值,或者在多个系统之间共享该视图。
如果被分析的实体可能尚未拥有一个 音频分析 组件(例如它稍后才创建,或被动态移除),请使用 tryReadIntoView 代替。它会在 false 组件缺失时返回 true ,并在写入值时返回。
对特定频段做出响应
这 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源是一个非渐进式流,例如一个.m3u8HLS URL:流的音频会播放,但分析值会一直为零。视频文件(例如.mp4)会被正确分析。暂停的音频不会报告更新。 当底层音频停止或暂停时,组件值会停止变化。你最后读取到的值会保留在视图对象中,直到音频再次播放。
便宜,但不是免费的。 逐帧分析的设计目标是开销很低(在桌面端每个源低于一毫秒)。避免将
音频分析同时附加到过多源上,除非你确实需要这些数据。当可视化器不可见时,移除该组件。
最后更新于