> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-zh/chang-jing-sdk7/mei-ti/audio-streaming.md).

# 音频流

在你的场景中播放实时音频流。

你可以从 URL 流式传输音频。这对于直接从网络电台播放音乐，或将会议直播流式传入你的场景很有用。

{% hint style="info" %}
**💡 提示**：在 [Creator Hub 中的场景编辑器](/creator/content-creator-zh/chang-jing-bian-ji-qi/kai-shi-shi-yong/about-editor.md)，你可以使用一个 **音频流** [智能物品](/creator/content-creator-zh/chang-jing-bian-ji-qi/jiao-hu-xing/smart-items.md) 以无代码方式实现此功能。
{% endhint %}

源中的音频必须采用以下格式之一： `.mp3`, `ogg`，或 `aac`。源还必须是一个 *https* URL（*http* 不支持 URL），并且来源应具有 [CORS 策略（跨源资源共享）](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) 允许外部访问它。如果不是这样，你可能需要搭建一台服务器作为代理，并以有效的方式暴露该流。

{% hint style="warning" %}
**📔 注意**：若要改为在场景中播放预录音效，请参见 [声音](/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/sounds.md).
{% endhint %}

要将音频流添加到你的场景，只需添加一个 `AudioStream` 组件到一个实体：

```ts
const streamEntity = engine.addEntity()

AudioStream.create(streamEntity, {
	url: 'https://icecast.ravepartyradio.org/ravepartyradio-192.mp3',
	playing: true,
	volume: 0.8,
})
```

{% hint style="warning" %}
**📔 注意**：流式音频没有空间位置效果，在整个场景中都会以恒定音量播放。如果玩家走出场景，他们将完全听不到该流。
{% endhint %}

设置该组件的音量 `AudioStream` 通过更改其 `volume` 属性。

切换 `AudioStream` 通过设置其……来开启或关闭该组件 `playing` 属性设为 *真* 或 *false*.

{% hint style="info" %}
**📔 注意**：并非所有流媒体服务都允许在其网站外播放其音频。以下是在 Decentraland 中可用的一些示例：

```ts
DELTA = "https://cdn.instream.audio/:9069/stream?_=171cd6c2b6e"
GRAFFITI = "https://n07.radiojar.com/2qm1fc5kb.m4a?1617129761=&rj-tok=AAABeIR7VqwAilDFeUM39SDjmw&rj-ttl=5"
ISLA NEGRA = "https://radioislanegra.org/listen/up/basic.aac"
```

{% endhint %}

## 流状态

你可以使用以下任一方式监控音频流的状态： `audioEventsSystem` （基于回调，推荐）或通过轮询使用 `AudioStream.getAudioState()`.

### 使用 audioEventsSystem（推荐）

注册一个仅在流状态变化时触发的回调。这也是用于 `AudioSource` 实体（参见 [检测声音何时结束](/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/sounds.md#detect-when-a-sound-finishes)).

```ts
import { engine, AudioStream, MediaState } from '@dcl/sdk/ecs'
import { audioEventsSystem } from '@dcl/sdk/ecs'

export function main() {
	const entity = engine.addEntity()

	AudioStream.create(entity, {
		playing: true,
		volume: 1,
		url: 'https://audio-edge-es6pf.mia.g.radiomast.io/ref-128k-mp3-stereo',
	})

	audioEventsSystem.registerAudioEventsEntity(entity, (event) => {
		console.log('Stream state: ', event.state)

		if (event.state === MediaState.MS_ERROR) {
			// 尝试重新连接
		}
	})
}
```

### 使用 getAudioState 轮询

你也可以使用以下方法在每一帧轮询流的状态： `AudioStream.getAudioState()`。这将返回一个 `PBAudioEvent` 对象（或者 `undefined` 如果尚未报告任何状态），并带有一个 `state` 字段和一个 `时间戳` 字段。该 `state` 字段的值是 `MediaState` 枚举：

* `MS_NONE`
* `MS_LOADING`
* `MS_READY`
* `MS_PLAYING`
* `MS_PAUSED`
* `MS_BUFFERING`
* `MS_SEEKING`
* `MS_ERROR`

```ts
export function main() {
	const entity = engine.addEntity()

	AudioStream.create(entity, {
		playing: true,
		volume: 1,
		url: 'https://audio-edge-es6pf.mia.g.radiomast.io/ref-128k-mp3-stereo',
	})

	let lastState: MediaState | undefined = undefined
	engine.addSystem(() => {
		const currentState = AudioStream.getAudioState(entity)?.state
		if (lastState !== currentState) {
			console.log('Stream state: ', currentState)
			lastState = currentState

			if (currentState == MediaState.MS_ERROR) {
				// 尝试重新连接
			}
		}
	})
}
```

## 空间音频

默认情况下，来自某个 `AudioStream` 组件的视频是全局的，这意味着在整个场景中都会以恒定音量听到它。如果玩家离开场景，则完全听不到该流。

要使音频具有空间效果，请将 `spatial` 属性设为 *真*.

```ts
AudioStream.create(entity, {
	url: 'https://radioislanegra.org/listen/up/stream',
    playing: true,
	spatial: true,
})
```

现在，音频将从拥有该……的实体的位置播放 `AudioStream` 组件的实体位置传出，并且玩家越靠近，声音会越大。

使用以下属性控制空间音频：

* `spatialMinDistance`：音频开始具有空间效果的最小距离。如果玩家更近，音频将以最大音量播放。 *0* 。
* `spatialMaxDistance`：音频可被听到的最大距离。如果玩家距离更远，音频将以 0 音量播放。 *60* 默认情况下

```ts
const audioStreamEntity = engine.addEntity();

Transform.create(audioStreamEntity, {
    position: Vector3.create(8, 0, 8),
});

AudioStream.create(audioStreamEntity, {
    url: 'https://radioislanegra.org/listen/up/stream',
    playing: true,
    volume: 1.0,
    spatial: true,
    spatialMinDistance: 5,
    spatialMaxDistance: 10
});
```

{% hint style="warning" %}
**📔 注意**：某些音频格式不支持空间音频。请确保流音频编码为 *mp3*, *AAC-LC* 或 *FLAC*.
{% endhint %}

## 音频分析

你可以从一个……读取实时幅度和频率数据 `AudioStream` 实体，以驱动如均衡器或随节拍脉动的灯光等响应式视觉效果。参见 [音频分析](/creator/content-creator-zh/chang-jing-sdk7/mei-ti/audio-analysis.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.decentraland.org/creator/content-creator-zh/chang-jing-sdk7/mei-ti/audio-streaming.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
