audio-video

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Audio and Video in Decentraland

Decentraland 中的音频与视频

When to Use Which Media Component

何时使用哪种媒体组件

NeedComponentKey Difference
Sound effect from a file (click, explosion, footstep)
AudioSource
Local file, spatial, one-shot or looping
Background music or radio stream
AudioStream
External URL, non-spatial, continuous
Video on a surface (screen, billboard)
VideoPlayer
+
Material.Texture.Video
Requires a mesh to display on
Decision flow:
  1. Is it a local audio file? →
    AudioSource
  2. Is it a streaming URL (radio, live audio)? →
    AudioStream
  3. Is it video content? →
    VideoPlayer
    on a plane/mesh
需求组件关键区别
来自文件的音效(点击、爆炸、脚步声)
AudioSource
本地文件,空间音效,单次播放或循环播放
背景音乐或广播流
AudioStream
外部 URL,非空间音效,持续播放
在表面上显示视频(屏幕、广告牌)
VideoPlayer
+
Material.Texture.Video
需要通过网格来显示
决策流程:
  1. 是本地音频文件吗?→
    AudioSource
  2. 是流式 URL(广播、直播音频)吗?→
    AudioStream
  3. 是视频内容吗?→ 在平面或网格上使用
    VideoPlayer

Audio Sourcing

音频来源

Before referencing any audio file path in code, check
{baseDir}/references/audio-catalog.md
. It lists 50 free Decentraland audio clips with direct downloadable URLs that cover most needs (UI clicks, ambients, music, game mechanics, sound effects).
The expected workflow when a user asks for sound:
  1. Read this skill +
    references/audio-catalog.md
    .
  2. If the catalog has fitting clips, surface them to the user as suggestions — name the clip and what it would be used for.
  3. Ask how they want to proceed. Some creators want catalog clips downloaded; others prefer placeholder paths so they can drop in their own files later. Don't assume.
  4. If they pick catalog clips: download with
    curl -o assets/Audio/<name>.mp3 "<URL>"
    — these URLs work directly from
    Bash
    , no separate tool needed.
  5. If they want placeholders: use a clear placeholder path (e.g.
    assets/Audio/<name>.mp3
    ) and tell the user which files to drop in where.
  6. Reference the resulting local path in
    AudioSource.audioClipUrl
    .
Things to avoid:
  • Telling the user "I can't download audio files."
    Bash
    +
    curl
    works fine on the catalog URLs — the capability is there if they want it.
  • Recommending external sources (freesound / mixkit / pixabay) without first checking whether the catalog already has a fitting clip.
  • Downloading clips without asking — even if the catalog has a perfect match, confirm before pulling files into the project.
在代码中引用任何音频文件路径之前,先检查
{baseDir}/references/audio-catalog.md
。其中列出了 50 个可直接下载的免费 Decentraland 音频片段 URL,涵盖大多数需求(UI 点击声、环境音、音乐、游戏机制和音效)。
用户要求添加声音时,预期工作流如下:
  1. 阅读此 skill 和
    references/audio-catalog.md
    。
  2. 如果目录中有合适的片段,将其作为建议提供给用户——说明片段名称及其用途。
  3. 询问用户希望如何继续。有些创作者希望下载目录中的片段;另一些人则希望使用占位路径,以便之后放入自己的文件。不要擅自假设。
  4. 如果用户选择目录中的片段:使用
    curl -o assets/Audio/<name>.mp3 "<URL>"
    下载——这些 URL 可直接在
    Bash
    中使用,无需单独的 tool。
  5. 如果用户需要占位符:使用清晰的占位路径(例如
    assets/Audio/<name>.mp3
    ),并告知用户需要将哪些文件放到哪里。
  6. 在
    AudioSource.audioClipUrl
    中引用生成的本地路径。
需要避免的事项:
  • 对用户说“我无法下载音频文件。”
    Bash
    +
    curl
    可以直接处理目录中的 URL——如果用户需要,完全具备相应能力。
  • 在未先检查目录中是否已有合适片段的情况下,推荐外部来源(freesound / mixkit / pixabay)。
  • 未经询问就下载片段——即使目录中有完美匹配项,也应先将文件拉入项目之前与用户确认。

AudioSource (Sound Effects & Music)

AudioSource(音效与音乐)

Attach to any entity for positional sound. Fields:
audioClipUrl: string
(local file path, required),
playing?: boolean
,
loop?: boolean
,
volume?: number
(default 1.0),
pitch?: number
(playback speed, default 1.0),
currentTime?: number
(playback position in seconds, default 0),
global?: boolean
. Audio files go in
assets/Audio/
. Supported formats:
.mp3
(recommended for music),
.ogg
(recommended for sound effects, smaller),
.wav
. Keep audio files small — large files increase scene load time.
Audio is spatial by default — volume decreases with distance from the entity. Set
global: true
for non-spatial (same volume everywhere).
Retriggering (play a sound again on every click): use the helper
AudioSource.playSound(entity, clipUrl, resetCursor?)
— do NOT hand-mutate
getMutable().playing
.
playSound
writes a full component (via
createOrReplace
/
getMutableOrNull
), so it reliably re-emits even with identical params. Hand-setting
getMutable(entity).playing = true
(or the old "playing=false then playing=true" trick) can be silently swallowed by LWW-CRDT dedup when the values are unchanged — the second and later triggers may do nothing.
stopSound(entity, resetCursor?)
stops it.
resetCursor
defaults to
true
on both (start/stop at 0); pass
false
to resume/pause at the current
currentTime
.
typescript
AudioSource.playSound(entity, 'assets/Audio/click.mp3') // retriggers from 0 every call
AudioSource.stopSound(entity)                            // stops, resets cursor to 0
Both helpers return
false
if the entity has no
AudioSource
, so create the component first (e.g.
AudioSource.create(entity, { audioClipUrl, playing: false })
at init).
Players must interact with the scene (click) before audio can play (browser autoplay policy). If an audio file needs to be ready to play the instant the player interacts, use the
AssetLoad
component to pre-load the asset.
Before adding audio: Confirm with the user before fetching audio from external sources.
将组件附加到任意实体以产生位置音效。字段:
audioClipUrl: string
(本地文件路径,必填)、
playing?: boolean
、
loop?: boolean
、
volume?: number
(默认值为 1.0)、
pitch?: number
(播放速度,默认值为 1.0)、
currentTime?: number
(播放位置,单位为秒,默认值为 0)、
global?: boolean
。音频文件应放在
assets/Audio/
中。受支持的格式:
.mp3
(推荐用于音乐)、
.ogg
(推荐用于音效,文件更小)、
.wav
。音频文件应保持较小——大文件会增加场景加载时间。
音频默认具有空间效果——音量会随实体距离增加而降低。设置
global: true
可使用非空间音效(各处音量相同)。
**重新触发(每次点击时再次播放声音):**使用辅助方法
AudioSource.playSound(entity, clipUrl, resetCursor?)
——不要手动修改
getMutable().playing
。
playSound
会通过
createOrReplace
/
getMutableOrNull
写入完整组件,因此即使参数完全相同,也能可靠地重新触发。手动设置
getMutable(entity).playing = true
(或旧式的“先设为 playing=false,再设为 playing=true”技巧)在值未改变时可能会被 LWW-CRDT 去重静默吞掉——第二次及之后的触发可能不会执行任何操作。
stopSound(entity, resetCursor?)
用于停止播放。两个方法的
resetCursor
默认值均为
true
(从 0 开始或停止);传入
false
可在当前
currentTime
处继续或暂停。
typescript
AudioSource.playSound(entity, 'assets/Audio/click.mp3') // retriggers from 0 every call
AudioSource.stopSound(entity)                            // stops, resets cursor to 0
如果实体没有
AudioSource
,两个辅助方法都会返回
false
,因此必须先创建组件(例如,在初始化时执行
AudioSource.create(entity, { audioClipUrl, playing: false })
)。
玩家必须先与场景进行交互(点击),音频才能播放,这是浏览器自动播放策略的要求。如果音频文件需要在玩家交互的瞬间立即可用,请使用
AssetLoad
组件预加载资源。
添加音频之前:从外部来源获取音频前,先与用户确认。

AudioStream (Streaming)

AudioStream(流式播放)

Stream audio from a URL (radio, live streams). Key fields:
url
(streaming URL),
playing
,
volume
. Non-spatial by default — plays at same volume everywhere. Set
spatial: true
with
spatialMinDistance
/
spatialMaxDistance
for distance-based volume.
Query state with
AudioStream.getAudioState(entity)
which returns a
PBAudioEvent | undefined
— an object with a
state
field (a
MediaState
enum:
MS_PLAYING
,
MS_ERROR
, etc.) and a
timestamp
field, not a bare enum. Read the state as
AudioStream.getAudioState(entity)?.state
.
Before adding a streaming URL: If not provided by the user, confirm the source first.
从 URL 流式播放音频(广播、直播)。关键字段:
url
(流式 URL)、
playing
、
volume
。默认使用非空间音效——各处音量相同。设置
spatial: true
并使用
spatialMinDistance
/
spatialMaxDistance
,可实现基于距离的音量控制。
使用
AudioStream.getAudioState(entity)
查询状态,它返回
PBAudioEvent | undefined
——一个包含
state
字段(
MediaState
枚举:
MS_PLAYING
、
MS_ERROR
等)和
timestamp
字段的对象,而不是单独的枚举值。通过
AudioStream.getAudioState(entity)?.state
读取状态。
添加流式 URL 之前:如果用户未提供 URL,请先确认来源。

VideoPlayer

VideoPlayer

Play video on a surface. Key fields:
src
(URL or local path),
playing
,
loop
,
volume
,
playbackRate
,
position
(start time in seconds). Non-spatial by default — set
spatial: true
with min/max distances for positional audio.
Setup requires 3 steps: create entity with
MeshRenderer.setPlane()
, add
VideoPlayer
, create
Material.Texture.Video({ videoPlayerEntity })
and apply to material. Use
Material.setBasicMaterial
(recommended, better performance) or
Material.setPbrMaterial
with emissive for a brighter screen.
Monitor playback with
videoEventsSystem.registerVideoEventsEntity()
for state callbacks, or
videoEventsSystem.getVideoState()
for polling. States:
VS_READY
,
VS_PLAYING
,
VS_PAUSED
,
VS_ERROR
,
VS_BUFFERING
.
Share one VideoPlayer across multiple screens by referencing the same
videoPlayerEntity
in multiple
Material.Texture.Video()
calls.
To play video on a non-primitive shape (curved screens), use
GltfNodeModifiers
to swap the material of a GLTF model.
在表面上播放视频。关键字段:
src
(URL 或本地路径)、
playing
、
loop
、
volume
、
playbackRate
、
position
(起始时间,单位为秒)。默认使用非空间音效——设置
spatial: true
并指定最小和最大距离,可实现位置音频。
设置需要 3 个步骤:使用
MeshRenderer.setPlane()
创建实体,添加
VideoPlayer
,然后创建
Material.Texture.Video({ videoPlayerEntity })
并应用到材质。使用
Material.setBasicMaterial
(推荐,性能更好),或使用带 emissive 的
Material.setPbrMaterial
以获得更明亮的屏幕。
使用
videoEventsSystem.registerVideoEventsEntity()
监听播放状态回调,或使用
videoEventsSystem.getVideoState()
轮询状态。状态包括:
VS_READY
、
VS_PLAYING
、
VS_PAUSED
、
VS_ERROR
、
VS_BUFFERING
。
多个屏幕可以共享同一个 VideoPlayer,只需在多个
Material.Texture.Video()
调用中引用同一个
videoPlayerEntity
。
若要在非基本体形状上播放视频(例如曲面屏幕),可使用
GltfNodeModifiers
替换 GLTF 模型的材质。

Free Audio Files

免费音频文件

The audio catalog is the first place to look — see the Audio Sourcing section at the top of this skill. It lists 50 free Decentraland clips across music, ambient, interaction sounds, sound effects, and game mechanics, each with a
curl
-ready URL.
Read
{baseDir}/references/audio-catalog.md
before recommending audio so suggestions are concrete, then check with the user whether they want those clips downloaded or prefer placeholders.
Important:
AudioSource
only works with local files. Never use external URLs for
audioClipUrl
. Always download into
assets/Audio/
first.
音频目录是首选查找位置——参见本 skill 顶部的音频来源部分。其中列出了 50 个免费 Decentraland 片段,涵盖音乐、环境音、交互声音、音效和游戏机制,每个片段都提供可供
curl
直接使用的 URL。
在推荐音频之前先阅读
{baseDir}/references/audio-catalog.md
,以提供具体建议,然后询问用户希望下载这些片段还是使用占位符。
重要:
AudioSource
仅支持本地文件。切勿将外部 URL 用于
audioClipUrl
。必须先将文件下载到
assets/Audio/
。

Asset folder conventions

资源文件夹约定

  • Default for audio you download yourself:
    assets/Audio/
    .
  • Legacy scenes may already have audio under
    assets/scene/Audio/
    — that path still works; reuse it for any new clips in those scenes instead of creating a parallel
    assets/Audio/
    folder.
  • Creator Hub assets: audio imported directly through the Creator Hub UI lands in
    assets/Audio/
    (same as the standard path). Items from free DCL asset packs land in
    assets/asset-packs/
    and custom items in
    assets/custom/
    . Older scenes may also have user imports directly under
    assets/scene/
    . Reference these paths as-is — never move or rename them.
Always check the scene's existing folders before deciding where to put a new file.
  • 你自行下载的音频的默认位置:
    assets/Audio/
    。
  • 旧版场景中的音频可能已位于
    assets/scene/Audio/
    ——该路径仍然有效;对于这些场景中的新片段,应复用该路径,不要并行创建
    assets/Audio/
    文件夹。
  • Creator Hub 资源:通过 Creator Hub UI 直接导入的音频会位于
    assets/Audio/
    (与标准路径相同)。免费 DCL 资源包中的项目位于
    assets/asset-packs/
    ,自定义项目位于
    assets/custom/
    。旧版场景中,用户导入的资源也可能直接位于
    assets/scene/
    下。按原样引用这些路径——切勿移动或重命名。
决定新文件的存放位置前,务必检查场景中已有的文件夹。

Audio-reactive scenes (visualizers, beat sync)

音频响应式场景(可视化器、节拍同步)

For real-time amplitude + frequency-band data from any
AudioSource
,
AudioStream
, or
VideoPlayer
, use the dedicated
audio-analysis
skill. It covers the
AudioAnalysis
component (Unity-explorer only) used for music visualizers, equalizer bars, and reactive lights/particles.
如需从任意
AudioSource
、
AudioStream
或
VideoPlayer
获取实时振幅和频带数据,请使用专用的
audio-analysis
skill。该 skill 介绍了
AudioAnalysis
组件(仅支持 Unity-explorer),可用于音乐可视化器、均衡器条以及响应音频的灯光或粒子。

Permission for External Media

外部媒体的权限

[LEGACY]
External audio/video URLs do not require the
ALLOW_MEDIA_HOSTNAMES
permission. The permission and its
allowedMediaHostnames
list still exist in
@dcl/schemas
, but no current client enforces them — unity-explorer's hostname check is gated behind the
CHECK_ALLOWED_MEDIA_HOSTNAMES
compile define (set in no build config, so
SceneData.TryGetMediaUrl
just does a URL syntax check), and bevy-explorer has no enforcement. Only the retired web client enforced it. Do not add it for new scenes; current clients play external media without it.
[LEGACY]
外部音视频 URL 不需要
ALLOW_MEDIA_HOSTNAMES
权限。该权限及其
allowedMediaHostnames
列表仍存在于
@dcl/schemas
中,但当前没有任何客户端执行该权限——unity-explorer 的主机名检查受
CHECK_ALLOWED_MEDIA_HOSTNAMES
编译定义控制(未在任何构建配置中设置,因此
SceneData.TryGetMediaUrl
只进行 URL 语法检查),而 bevy-explorer 也不执行检查。只有已停用的 Web 客户端曾执行该权限。不要为新场景添加它;当前客户端无需该权限即可播放外部媒体。

Video Limits & Tips

视频限制与提示

  • Simultaneous videos: Avoid playing multiple videos at once. Only play more than 1 simultaneous video if explicitly requested. The maximum depends on each player's quality setting (as low as 1 on Low quality — see the Video Limits table in
    {baseDir}/references/media-reference.md
    ), so treat 1 as the only safe floor.
  • HTTPS required: Video sources must be HTTPS URLs — HTTP won't work
  • Distance-based control: Pause video when player is far away to save bandwidth
  • Supported formats:
    .mp4
    (H.264),
    .webm
    , HLS (
    .m3u8
    ) for live streaming
  • Live streaming: Use HLS (
    .m3u8
    ) URLs — most reliable across clients
  • 同时播放的视频:避免同时播放多个视频。只有在用户明确要求时,才可同时播放 1 个以上的视频。最大数量取决于每个播放器的质量设置(在低质量下可能低至 1 个——参见
    {baseDir}/references/media-reference.md
    中的视频限制表),因此应将 1 视为唯一安全下限。
  • 必须使用 HTTPS:视频源必须是 HTTPS URL——HTTP 无法使用
  • 基于距离的控制:当玩家距离较远时暂停视频,以节省带宽
  • 支持的格式:
    .mp4
    (H.264)、
    .webm
    、用于直播的 HLS(
    .m3u8
    )
  • 直播:使用 HLS(
    .m3u8
    )URL——在各类客户端中最为可靠

Example scenes

示例场景

Engine-team test scenes exercised against the real explorer:
  • audio-source-retrigger-test —
    AudioSource.playSound
    /
    stopSound
    , same-URL retrigger, URL-swap on one entity,
    resetCursor
    semantics, volume/pitch/loop variations, and why
    playSound
    beats hand-mutating
    getMutable
    (LWW dedup).
  • audio-visualization —
    AudioAnalysis
    music visualizer (see the
    audio-analysis
    skill).
For full code examples and implementation patterns, see
{baseDir}/references/media-patterns.md
. For component field details, see
{baseDir}/references/media-reference.md
.
引擎团队针对真实 explorer 验证过的测试场景:
  • audio-source-retrigger-test——
    AudioSource.playSound
    /
    stopSound
    、同一 URL 重新触发、在单个实体上切换 URL、
    resetCursor
    语义、音量/音高/循环变化,以及为何
    playSound
    优于手动修改
    getMutable
    (LWW 去重)。
  • audio-visualization——
    AudioAnalysis
    音乐可视化器(参见
    audio-analysis
    skill)。
有关完整代码示例和实现模式,请参阅
{baseDir}/references/media-patterns.md
。有关组件字段详情,请参阅
{baseDir}/references/media-reference.md
。