audio-analysis
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAudioAnalysis
AudioAnalysis
Real-time audio signal analysis attached to any entity that already has an , , or . The renderer analyzes the audio frame buffer and writes results back into the component each tick. Scenes read those results to drive visualizers, beat-reactive geometry, audio-driven lights, etc.
AudioSourceAudioStreamVideoPlayer可附加到任何已经具有 、 或 的实体上的实时音频信号分析。renderer 对音频帧缓冲区进行分析,并在每个 tick 将结果回写到该组件中。场景读取这些结果,以驱动可视化器、节拍响应几何体、音频驱动的灯光等。
AudioSourceAudioStreamVideoPlayerRULE: Requires an audio-emitting component on the same entity
规则:同一实体上必须存在音频输出组件
AudioAnalysisAudioSourceAudioStreamVideoPlayerAudioAnalysisAudioAnalysisAudioSourceAudioStreamVideoPlayerAudioAnalysisRULE: Audio must be playing for non-zero output
规则:音频必须正在播放才能产生非零输出
Values are derived from live audio frames. If the source is paused, muted, or not yet loaded, and all stay at . There is no "ready" event — start your reactive systems unconditionally, they will simply animate toward while silent.
amplitudebands[]00这些值派生自实时音频帧。如果源已暂停、静音或尚未加载, 和所有 都会保持为 。不存在“ready”事件——请无条件启动你的响应系统;静音时,它们只会逐渐回落至 。
amplitudebands[]00RULE: Only the Unity explorer implements this
规则:仅 Unity explorer 实现此功能
Bevy and the mobile Godot explorer ignore the component (no analysis written). Treat as a Unity-explorer-only enhancement and design fallbacks (e.g. a base scale that doesn't depend on ) so the scene still looks reasonable elsewhere.
AudioAnalysisamplitudeBevy 和移动端 Godot explorer 会忽略该组件(不会写入分析结果)。将 视为仅限 Unity explorer 的增强功能,并设计回退方案(例如采用不依赖 的基础缩放),确保场景在其他环境中仍然呈现合理效果。
AudioAnalysisamplitudeRULE: Read via readIntoView
into a pre-allocated view
readIntoView规则:通过 readIntoView
读取到预分配的 view
readIntoViewreadIntoViewtryReadIntoViewAudioAnalysisView = { amplitude: number, bands: number[] }newbandsreadIntoViewtryReadIntoViewAudioAnalysisView = { amplitude: number, bands: number[] }newbandsRULE: Use createAudioAnalysis
, not create
createAudioAnalysiscreate规则:使用 createAudioAnalysis
,而不是 create
createAudioAnalysiscreateUse the helper . It pre-fills all required protobuf fields (8 bands + amplitude + mode) with safe defaults. Calling the raw requires you to provide every band/amplitude field manually. Use to overwrite an existing one without throwing.
AudioAnalysis.createAudioAnalysis(entity, mode?, amplitudeGain?, bandsGain?)AudioAnalysis.create(entity, {...})createOrReplaceAudioAnalysis请使用辅助函数 。它会以安全默认值预填所有必需的 protobuf 字段(8 个频段 + 振幅 + 模式)。如果调用原始的 ,则必须手动提供每个频段/振幅字段。请使用 覆盖现有组件,且不会抛出异常。
AudioAnalysis.createAudioAnalysis(entity, mode?, amplitudeGain?, bandsGain?)AudioAnalysis.create(entity, {...})createOrReplaceAudioAnalysisImport
Import
typescript
import {
AudioAnalysis,
AudioAnalysisView,
PBAudioAnalysisMode,
AudioSource, // or AudioStream / VideoPlayer
engine,
Transform,
} from "@dcl/sdk/ecs";
import { Vector3 } from "@dcl/sdk/math";AudioAnalysisView@dcl/sdk/ecstypescript
import {
AudioAnalysis,
AudioAnalysisView,
PBAudioAnalysisMode,
AudioSource, // or AudioStream / VideoPlayer
engine,
Transform,
} from "@dcl/sdk/ecs";
import { Vector3 } from "@dcl/sdk/math";AudioAnalysisView@dcl/sdk/ecsComponent fields
组件字段
Output (filled by the renderer; read in your systems):
| Field | Type | Range | Notes |
|---|---|---|---|
| | | Aggregate signal strength of the current audio frame. |
| | | Lowest frequency bin (sub-bass). |
| | | Increasing frequency bins, log-spaced under MODE_LOGARITHMIC. |
| | | Highest frequency bin (treble/air). |
Inputs (configure once at create time):
| Field | Type | Default | Notes |
|---|---|---|---|
| | | |
| | | Multiplier applied to |
| | | Multiplier applied to all 8 bands. Only used in MODE_LOGARITHMIC. |
Values are unbounded floats — gains can push them above. Clamp or scale in your system if the visual you drive needs1. For typical music at default gains, expect peaks roughly in0..1with normal content sitting0..1.0..0.5
输出(由 renderer 填充;在你的 system 中读取):
| Field | Type | Range | Notes |
|---|---|---|---|
| | | 当前音频帧的汇总信号强度。 |
| | | 最低频率区间(超低频)。 |
| | | 频率依次升高的区间,在 MODE_LOGARITHMIC 下按对数间隔排列。 |
| | | 最高频率区间(高音/空气声)。 |
输入(创建时配置一次):
| Field | Type | Default | Notes |
|---|---|---|---|
| | | |
| | | 应用于 |
| | | 应用于全部 8 个频段的乘数。仅在 MODE_LOGARITHMIC 中使用。 |
数值不受上限约束——增益可能将其推高至以上。如果所驱动的视觉效果需要1范围,请在 system 中对这些值进行 clamp 或缩放。对于采用默认增益的典型音乐,峰值大致预计在0..1范围内,而普通内容通常位于0..1。0..0.5
AudioAnalysisView
AudioAnalysisView
Read-only convenience shape used by / :
readIntoViewtryReadIntoViewtypescript
type AudioAnalysisView = {
amplitude: number;
bands: number[]; // length 8 — bands[0] = lowest freq, bands[7] = highest
};供 / 使用的只读便捷结构:
readIntoViewtryReadIntoViewtypescript
type AudioAnalysisView = {
amplitude: number;
bands: number[]; // length 8 — bands[0] = lowest freq, bands[7] = highest
};Reading the data
读取数据
typescript
const view: AudioAnalysisView = { amplitude: 0, bands: new Array<number>(8) };
engine.addSystem(() => {
// Throws if the entity has no AudioAnalysis
AudioAnalysis.readIntoView(audioEntity, view);
// Or, defensive variant — returns false if missing, no throw
// if (!AudioAnalysis.tryReadIntoView(audioEntity, view)) return
// view.amplitude and view.bands[0..7] are now populated
});readIntoView(entity, out)outAudioAnalysistryReadIntoView(entity, out): booleanfalsetypescript
const view: AudioAnalysisView = { amplitude: 0, bands: new Array<number>(8) };
engine.addSystem(() => {
// Throws if the entity has no AudioAnalysis
AudioAnalysis.readIntoView(audioEntity, view);
// Or, defensive variant — returns false if missing, no throw
// if (!AudioAnalysis.tryReadIntoView(audioEntity, view)) return
// view.amplitude and view.bands[0..7] are now populated
});readIntoView(entity, out)outAudioAnalysistryReadIntoView(entity, out): booleanfalseCommon patterns
常见模式
typescript
// 1. Pulse an entity's scale to overall amplitude
const view: AudioAnalysisView = { amplitude: 0, bands: new Array<number>(8) };
engine.addSystem(() => {
AudioAnalysis.readIntoView(audioEntity, view);
const t = Transform.getMutable(pulseEntity);
const s = 1 + view.amplitude * 10; // base 1, gain to taste
t.scale = Vector3.create(s, s, s);
});
// 2. 8-bar equalizer (one entity per band, scale Y by bands[i])
for (const [entity, _] of engine.getEntitiesWith(VisualBar, Transform)) {
const i = VisualBar.get(entity).index; // 0..7
Transform.getMutable(entity).scale = Vector3.create(
1,
view.bands[i] * BAR_HEIGHT,
1
);
}
// 3. Bass-only kick — react to the lowest band
const bass = view.bands[0] + view.bands[1]; // sub + low
if (bass > 0.7) {
/* trigger flash */
}
// 4. Custom gains (less sensitive amplitude, punchier bands)
AudioAnalysis.createAudioAnalysis(
audioEntity,
PBAudioAnalysisMode.MODE_LOGARITHMIC,
2.0,
0.1
);For a complete music visualizer (audio source + amplitude sphere + 8-band equalizer bars), see .
{baseDir}/references/audio-analysis-example.mdtypescript
// 1. Pulse an entity's scale to overall amplitude
const view: AudioAnalysisView = { amplitude: 0, bands: new Array<number>(8) };
engine.addSystem(() => {
AudioAnalysis.readIntoView(audioEntity, view);
const t = Transform.getMutable(pulseEntity);
const s = 1 + view.amplitude * 10; // base 1, gain to taste
t.scale = Vector3.create(s, s, s);
});
// 2. 8-bar equalizer (one entity per band, scale Y by bands[i])
for (const [entity, _] of engine.getEntitiesWith(VisualBar, Transform)) {
const i = VisualBar.get(entity).index; // 0..7
Transform.getMutable(entity).scale = Vector3.create(
1,
view.bands[i] * BAR_HEIGHT,
1
);
}
// 3. Bass-only kick — react to the lowest band
const bass = view.bands[0] + view.bands[1]; // sub + low
if (bass > 0.7) {
/* trigger flash */
}
// 4. Custom gains (less sensitive amplitude, punchier bands)
AudioAnalysis.createAudioAnalysis(
audioEntity,
PBAudioAnalysisMode.MODE_LOGARITHMIC,
2.0,
0.1
);有关完整的音乐可视化器(音频源 + 振幅球 + 8 段均衡器柱),请参阅 。
{baseDir}/references/audio-analysis-example.mdMode selection
模式选择
- (default) — bands are log-spaced and gain-scaled to roughly fit
MODE_LOGARITHMICfor typical music. Use this for visualizers, scaling, color reactivity.0..1andamplitudeGainapply.bandsGain - — raw FFT-derived magnitudes, linearly spaced. Lower bands dominate visually because most musical energy is there.
MODE_RAW/amplitudeGainare ignored. Use only if you intend to do your own normalization.bandsGain
- (默认)——频段按对数间隔排列,并通过增益缩放,使典型音乐的值大致落在
MODE_LOGARITHMIC范围内。适用于可视化器、缩放和颜色响应。0..1和amplitudeGain会生效。bandsGain - ——采用线性间隔排列的原始 FFT 幅值。由于大部分音乐能量集中在低频区域,因此低频段在视觉上会占据主导。
MODE_RAW/amplitudeGain会被忽略。仅在你打算自行进行归一化时使用。bandsGain
Gotchas
常见陷阱
- Component ID is .
1212 - and
amplitudeGainare no-ops in MODE_RAW. Setting them won't error, but the renderer ignores them outside MODE_LOGARITHMIC.bandsGain - Output values can exceed with high gains or loud source material. Clamp downstream if you feed UI bars or alpha channels expecting
1.0.0..1 - Throttled updates. The renderer runs analysis under a frame-time budget — values update each frame in normal conditions but can skip frames under heavy load. Drive smooth animations with interpolation rather than assuming a fixed update cadence.
dt - Multi-source scenes. Each audio-emitting entity needs its own if you want to react to that specific source. There is no global mix-down; you pick the entity to analyze.
AudioAnalysis - Works on audio too — call
VideoPlayeron the same entity that hasAudioAnalysis.createAudioAnalysis(videoEntity). The renderer taps the video's audio frame buffer the same way it does forVideoPlayer. IMPORTANT: the video must be a progressive file (MP4/WebM with direct URL), not an HLS stream (.m3u8). HLS streams play with audible sound but the renderer writes zeros to the AudioAnalysis component (its audio decodes on a path the analyzer does not tap). Verified inAudioSource, which demonstrates AudioSource and VideoPlayer side by side.88,-10-audio-visualization - No interaction.
pitchchanges playback speed; the analysis runs on the actual played audio frames, so a higher pitch shifts perceived band energy upward. This is expected, not a bug.AudioSource.pitch - Don't call before
readIntoView. Reading without the component throws. UsecreateAudioAnalysisif the component may not be attached yet (e.g. analysis added at runtime).tryReadIntoView
- 组件 ID 为 。
1212 - 和
amplitudeGain在 MODE_RAW 下不起作用。 设置它们不会报错,但 renderer 在 MODE_LOGARITHMIC 之外会忽略它们。bandsGain - 输出值可能超过 。 较高的增益或响度较高的源素材都可能导致这种情况。如果将这些值用于要求
1.0范围的 UI 柱或 alpha 通道,请在下游进行 clamp。0..1 - 更新经过节流。 renderer 会在帧时间预算内运行分析——正常情况下值每帧更新,但在负载较重时可能跳过部分帧。驱动平滑动画时应使用 插值,不要假定固定的更新频率。
dt - 多源场景。 如果希望对特定源作出响应,每个音频输出实体都需要自己的 。不存在全局混音;你需要选择要分析的实体。
AudioAnalysis - 同样支持 音频——请在同一具有
VideoPlayer的实体上调用VideoPlayer。renderer 对视频音频帧缓冲区的处理方式与对AudioAnalysis.createAudioAnalysis(videoEntity)相同。重要:视频必须采用渐进式文件(具有直接 URL 的 MP4/WebM),而不能使用 HLS 流(.m3u8)。 HLS 流虽然可以听到声音,但 renderer 会向AudioSource组件写入零值(其音频解码路径不是分析器所接入的路径)。已在AudioAnalysis中验证,该场景并排展示了88,-10-audio-visualization和AudioSource。VideoPlayer - 不存在与 的交互。
pitch会改变播放速度;分析基于实际播放的音频帧运行,因此更高的 pitch 会使感知到的频段能量向上移动。这是预期行为,并非 bug。AudioSource.pitch - 不要在调用 前执行
createAudioAnalysis。 如果实体尚未附加组件就读取,调用将抛出异常。如果组件可能在运行时才附加(例如动态添加分析),请使用readIntoView。tryReadIntoView
Permissions
权限
No special scene permission is needed beyond what the underlying / / already requires. Streamed audio still needs in for its hostname (see skill).
AudioSourceAudioStreamVideoPlayerALLOW_MEDIA_HOSTNAMESscene.jsonaudio-video除了底层 / / 本身要求的权限外,无需特殊的场景权限。流式音频仍需在 中通过 授权其主机名(参见 audio-video skill)。
AudioSourceAudioStreamVideoPlayerscene.jsonALLOW_MEDIA_HOSTNAMESExample scenes
示例场景
- audio-visualization — engine-team test scene: two independent visualizer groups side by side. Group 0: +
AudioSourcedriving 8 bars + amplitude sphere. Group 1:AudioAnalysis.createAudioAnalysis()(progressive MP4) +VideoPlayerdriving its own bars + sphere from the video's soundtrack. Each group has its own pre-allocatedAudioAnalysis.createAudioAnalysis()and its ownAudioAnalysisViewcall per frame. Demonstrates that AudioAnalysis works identically on VideoPlayer entities, and documents the progressive-video requirement (HLS streams write zeros).readIntoView
- audio-visualization——引擎团队的测试场景:两个独立的可视化器组并排展示。第 0 组:+
AudioSource,驱动 8 根柱和振幅球。第 1 组:AudioAnalysis.createAudioAnalysis()(渐进式 MP4)+VideoPlayer,通过视频的音轨驱动自己的柱和球。每个组都有自己预先分配的AudioAnalysis.createAudioAnalysis(),并在每帧分别调用AudioAnalysisView。该场景证明readIntoView在AudioAnalysis实体上的工作方式与在VideoPlayer实体上完全相同,并记录了渐进式视频要求(HLS 流会写入零值)。AudioSource
Resources
资源
- — full music visualizer scene from the SDK examples (audio source + amplitude pulse + 8-bar equalizer).
{baseDir}/references/audio-analysis-example.md - Source PRs: protocol #328, js-sdk-toolchain #1256, unity-explorer #6361.
- Reference scene: .
sdk7-goerli-plaza/audio-visualization
- ——SDK 示例中的完整音乐可视化器场景(音频源 + 振幅脉冲 + 8 段均衡器)。
{baseDir}/references/audio-analysis-example.md - 源代码 PR:protocol #328、js-sdk-toolchain #1256、unity-explorer #6361。
- 参考场景:。
sdk7-goerli-plaza/audio-visualization