> 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/video-playing.md).

# 视频播放

将视频流传入场景

在场景中显示视频有三种不同方式：

* 将视频文件作为场景内容的一部分上传
* 从外部来源流式传输视频
* 通过 Decentraland cast 进行直播

{% 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 %}

在所有情况下，你都需要：

* 一个带有一个 [基础形状](/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/shape-components.md) 平面、立方体，甚至圆锥体之类的
* 一个 [材质](/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/materials.md) 并配合一个 `VideoTexture` 分配给其纹理
* 一个 `VideoPlayer` 组件来控制视频状态。

## 性能注意事项

请记住，流式视频会给玩家的机器带来相当大的负担。建议避免同时播放多个视频。

如果你的场景中同时播放太多视频，部分视频会被引擎暂停。屏幕的暂停优先级会根据多种因素确定，包括与玩家的距离、大小，以及屏幕是否在玩家视野内。可同时播放的视频最大数量取决于玩家的画质设置。

* 低：1
* 中：5
* 高：10

我们还建议在玩家靠近或执行某个动作时再开始播放视频。若在地平线远处的场景加载时就开始播放视频，会在玩家访问相邻场景时不必要地影响性能。

另外也要避免以非常高的分辨率流式传输视频。不要使用高于 *高清*.

也建议在 Basic（无光照）材质上播放视频，以降低性能负载，下面所有示例片段都是如此。

## 显示视频

以下说明适用于这三种视频显示方式：

1. 创建一个实体作为视频屏幕。给这个实体添加一个 `MeshRenderer` 组件，使其拥有可见的形状。
2. 创建一个 `VideoPlayer` 组件，既可以引用流式 URL，也可以指定视频文件路径。在这里你还可以设置视频的 `playing` 状态和音量。这个组件可以分配给视频屏幕实体，也可以分配给场景中的任何其他实体。
3. 创建一个 `VideoTexture` 对象，并在其 `videoPlayerEntity` 属性中指定拥有该 `VideoPlayer` 组件。
4. 创建一个 `材质`，将其分配给屏幕实体，并设置其 `纹理` 添加到 `VideoTexture` 你创建的。

此示例使用的是本地存储在 `/videos` 文件夹中的视频：

```ts
// #1
const screen = engine.addEntity()
MeshRenderer.setPlane(screen)
Transform.create(screen, { position: { x: 4, y: 1, z: 4 } })

// #2
VideoPlayer.create(screen, {
	src: 'videos/myVideo.mp4',
	playing: true,
})

// #3
const videoTexture = Material.Texture.Video({ videoPlayerEntity: screen })

// #4
Material.setBasicMaterial(screen, {
	texture: videoTexture,
})
```

要使用来自外部流式 URL 的视频，请将第 2 步改为使 `src` 中的属性 `VideoPlayer` 组件引用该流式 URL。

```ts
// #2
VideoPlayer.create(screen, {
	src: 'https://vz-7c61c1b5-d59.b-cdn.net/ccea595a-b910-4de6-b160-092819db021d/playlist.m3u8',
	playing: true,
})
```

参见 [使用 Decentraland cast 进行流式传输](#streaming-using-decentraland-cast) 了解如何使用这一第三种替代方法的详细信息。

## 关于外部直播

串流来源必须是一个 *https* URL（*http* 不支持 URL）。

你应该能够粘贴指向大多数流行视频流媒体网站视频的 URL。请注意这些平台的服务条款。

若要从本地设备上的视频文件进行直播，最简单的方法是将该视频上传到公开的 Google Drive，然后粘贴链接。

另一种选择是使用托管服务提供商，例如 [Vimeo](https://vimeo.com/) , [Livepeer Studio](https://livepeer.studio/) 或 [Serraform](https://serraform.gitbook.io/streaming-docs/guides/decentraland-playback) ，你向提供商支付费用，由其管理所有串流基础设施。

最强大的方法是搭建你自己的服务器，使用免费软件，但在类似以下的平台上为托管付费： [Digital Ocean](https://try.digitalocean.com/developerbrand/?_campaign=emea_brand_kw_en_cpc&_adgroup=digitalocean_exact_exact&_keyword=digitalocean&_device=c&_adposition=&_content=conversion&_medium=cpc&_source=bing\&msclkid=160bfc160a2a1bab9bbf9933594bd9c5\&utm_source=bing\&utm_medium=cpc\&utm_campaign=emea_brand_kw_en_cpc\&utm_term=digitalocean\&utm_content=DigitalOcean%20Exact_Exact) 或 [Cloudflare](https://www.cloudflare.com/products/cloudflare-stream/)。你可以部署类似 [Node Media Server](https://github.com/illuspas/Node-Media-Server)，它开箱即提供了你所需要的大部分功能。

这些选项在不同场景下各有优缺点。你应该结合自己的需求、技术能力和预算来评估哪种最适合你。

## 为成功直播配置 OBS

[OBS](https://obsproject.com/) 是一款流行且免费的流管理工具。

无论你使用的是场地提供的流密钥还是你自己的 RTMP 服务器，OBS 中的设置都对直播成功至关重要。你应当追求稳定、一致的连接。

### 简单的 OBS 设置

建议采用以下简单设置：

* 码率 2500kbps（适用于所有 Decentraland 场地）
* 音频码率 160kbps
* 视频编码器预设：硬件 NVENC
* 音频编码器 AAC
* 最大分辨率：720（更高会在 DCL 中引发问题）
* 帧率 30fps

{% hint style="warning" %}
**📔 注意**：请确保你在 OBS 中禁用 Multitrack streaming。你可以在 Settings > Stream 中找到此选项。
{% endhint %}

### 给新主播的建议

* 提前进行音频检查对于测试你与场地的设置至关重要。
* 像流密钥中错一个数字这样的小错误，最有可能搞砸直播。
* 分辨率不要超过 720，码率不要高于 2500 kbps。

## 直播串流

你可以通过以下方式从摄像头进行直播或共享屏幕： [直播串流](/creator/content-creator-zh/chang-jing-bian-ji-qi/shi-shi-yun-wei/live-streaming.md) 的功能 [管理员工具](/creator/content-creator-zh/chang-jing-bian-ji-qi/shi-shi-yun-wei/scene-admin.md) 智能物件从 URL 播放音频流。

这种流式传输方法使用与玩家之间实时通信相同的通信架构。它设置简单，而且比从外部来源流式传输的延迟要小得多。

1. 添加一个 [管理员工具](/creator/content-creator-zh/chang-jing-bian-ji-qi/shi-shi-yun-wei/scene-admin.md) 将 smart item 添加到你的场景中，以及一个 [视频播放器](/creator/content-creator-zh/chang-jing-bian-ji-qi/jiao-hu-xing/video-screen.md) 智能物件从 URL 播放音频流。
2. 将你的场景发布到 World 或 Genesis City。
3. 以有权限使用 Admin 工具的玩家身份进入场景。
4. 打开 Admin 控制台，选择 **视频** 选项卡，然后选择 **直播** 功能，然后点击 **获取流密钥** 按钮。
5. 复制 **服务器 URL** 和 *流密钥*\* 到你的流媒体软件（例如 OBS）中。
6. 按下 **激活** 按钮开始直播。

你也可以不向场景中添加 Video player smart item，而是使用 URL `livekit-video://current-stream` 作为视频源，在你的场景中播放该直播流。你仍然需要 Admin 工具来获取流密钥。

```ts
// #1
const screen = engine.addEntity()
MeshRenderer.setPlane(screen)
Transform.create(screen, { position: { x: 4, y: 1, z: 4 } })

// #2
VideoPlayer.create(screen, {
	src: `livekit-video://current-stream`,
	playing: true,
})

// #3
const videoTexture = Material.Texture.Video({ videoPlayerEntity: screen })

// #4
Material.setBasicMaterial(screen, {
	texture: videoTexture,
})
```

## 视频材质

大多数情况下，你会希望在无光照的 [Basic 材质](/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/materials.md#unlit-materials)上播放视频，而不是 PBR 材质。这会得到更明亮、更清晰的图像，而且性能更好。

```ts
Material.setBasicMaterial(screen, {
	texture: videoTexture,
})
```

通常建议在 Basic 无光照材质上播放视频，因为这对性能更友好。不过，如果你想将视频投射到 PBR 材质上，请记住，默认属性会让视频看起来相当不透明。你可以通过修改材质的其他属性来增强效果。以下是一些推荐设置，可让视频更突出：

```ts
Material.setPbrMaterial(screen, {
	texture: videoTexture,
	roughness: 1.0,
	specularIntensity: 0,
	metallic: 0,
	emissiveTexture: videoTexture,
	emissiveIntensity: 0.6,
	emissiveColor: Color3.White(),
})
```

{% hint style="info" %}
**💡 提示**：由于视频是作为纹理添加到材质中的，你也可以尝试材质的其他属性，例如用颜色对其进行染色，或添加其他纹理层，比如制作脏屏效果。

参见 [材质](/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/materials.md) 了解更多详情。
{% endhint %}

## 关于视频文件

支持以下文件格式：

* *.mp4*
* *.ogg*
* *.webm*

请记住，视频文件会增加场景的总大小，这会使玩家进入你的场景时下载时间更长。视频大小也可能让你超过 [场景限制](/creator/content-creator-zh/chang-jing-sdk7/you-hua/scene-limitations.md)，因为每个地块可用的最大容量为 15 MB。我们建议尽可能压缩视频，这样问题会小一些。

我们还建议在玩家靠近或执行某个动作触发时再开始播放视频。如果在场景远处地平线加载时就开始播放视频，会在玩家访问邻近场景时不必要地影响性能。

## 开始、暂停和停止视频

要开始播放视频或暂停它，请设置 `playing` 属性设为 *真* 或 *false*如果 `playing` 设置为 false，则视频会暂停在最后显示的帧。

你可以通过给屏幕添加指针事件来使其可切换，如下所示：

```ts
pointerEventsSystem.onPointerDown(
	{
		entity: screen,
		opts: { button: InputAction.IA_POINTER, hoverText: '播放/暂停' },
	},
	function () {
		const videoPlayer = VideoPlayer.getMutable(screen)
		videoPlayer.playing = !videoPlayer.playing
	}
)
```

要停止视频并将其返回到第一帧，请设置 `位置` 属性为 0。在下面的示例中，点击视频会停止它。

```ts
pointerEventsSystem.onPointerDown(
	{
		entity: screen,
		opts: { button: InputAction.IA_POINTER, hoverText: '停止' },
	},
	function () {
		const videoPlayer = VideoPlayer.getMutable(screen)
		videoPlayer.playing = false
		videoPlayer.position = 0
	}
)
```

## 配置视频播放器

可在以下 `VideoPlayer` 组件：

* `playing`：决定视频当前是否正在播放。若为 false，则视频暂停。

{% hint style="warning" %}
**📔 注意**：同时可播放的视频数量有限，取决于玩家的画质设置。如果场景播放的视频超过该数量，引擎会暂停优先级最低的视频。参见 [性能注意事项](#performance-considerations).
{% endhint %}

* `playbackRate`：更改视频播放速度。 *1* 。
* `volume`：允许你更改音频音量。 *1* 。
* `位置`：允许你设置视频的不同起始位置。它以距离视频原始开头后的秒数表示。 *0* 默认情况下，这会使其从视频的实际开头开始播放。
* `loop`：用于决定视频是循环连续播放，还是播放一次后停止的布尔值。 *false* 。

## 播放多个视频

为避免性能问题，请将同时播放的不同视频数量保持在较低水平；引擎只允许有限数量的视频同时播放，具体取决于玩家的画质设置（参见 [性能注意事项](#performance-considerations)）。不过，一个场景可以在多个不同屏幕上播放同一视频纹理的多个副本。这不受限制，因为与播放不同的视频相比，它对性能的影响要小得多。要在多个实体上播放同一个视频，只需将视频纹理对象的同一实例分配给 `材质` 每个屏幕实体的组件。

```ts
// #1
const screen1 = engine.addEntity()
MeshRenderer.setPlane(screen1)
Transform.create(screen1, { position: { x: 4, y: 1, z: 4 } })

const screen2 = engine.addEntity()
MeshRenderer.setPlane(screen2)
Transform.create(screen2, { position: { x: 6, y: 1, z: 4 } })

// #2
VideoPlayer.create(screen1, {
	src: 'https://vz-7c61c1b5-d59.b-cdn.net/ccea595a-b910-4de6-b160-092819db021d/playlist.m3u8',
	playing: true,
})

// #3
const videoTexture = Material.Texture.Video({ videoPlayerEntity: screen1 })

// #4
Material.setBasicMaterial(screen1, {
	texture: videoTexture,
})

Material.setBasicMaterial(screen2, {
	texture: videoTexture,
})
```

请注意，在上面的示例中，只需创建一个 `VideoPlayer` 组件，它控制两个视频屏幕的状态。在这种情况下，该组件被分配给 `screen1` 实体，但也可以分配给场景中的任何其他实体，不一定非要是某个屏幕。

## 视频事件

轻松处理视频中的状态变化，以响应视频开始播放、暂停等情况。例如，这可用于让动画与视频完美同步播放，确保它们与视频同时开始。

使用 `videoEventsSystem.registerVideoEventsEntity` 用于定义一个函数，该函数会在分配给某个实体的视频状态发生变化时运行。每次状态变化时，你的函数都可以检查新状态并做出相应响应。

```ts
import {
	engine,
	Entity,
	VideoPlayer,
	videoEventsSystem,
	VideoState,
} from '@dcl/sdk/ecs'

// ... 使用 VideoPlayer 组件、Transform、MeshRenderer.setPlane() 等创建 videoPlayerEntity ...

videoEventsSystem.registerVideoEventsEntity(
	videoPlayerEntity,
	function (videoEvent) {
		console.log(
			'视频事件 - 状态：' +
				videoEvent.state +
				'\n当前偏移：' +
				videoEvent.currentOffset +
				'\n视频长度：' +
				videoEvent.videoLength
		)

		switch (videoEvent.state) {
			case VideoState.VS_READY:
				console.log('视频事件 - 视频已就绪')
				break
			case VideoState.VS_NONE:
				console.log('视频事件 - 视频处于无状态')
				break
			case VideoState.VS_ERROR:
				console.log('视频事件 - 视频错误')
				break
			case VideoState.VS_SEEKING:
				console.log('视频事件 - 视频正在寻址')
				break
			case VideoState.VS_LOADING:
				console.log('视频事件 - 视频正在加载')
				break
			case VideoState.VS_BUFFERING:
				console.log('视频事件 - 视频正在缓冲')
				break
			case VideoState.VS_PLAYING:
				console.log('视频事件 - 视频开始播放')
				break
			case VideoState.VS_PAUSED:
				console.log('视频事件 - 视频已暂停')
				break
		}
	}
)
```

作为函数输入传入的 videoEvent 对象包含以下属性：

* `currentOffset` (*数字*）：视频中 `位置` 属性的当前值。该值显示的是视频原始起始点之后的秒数。 *-1* 如果视频尚未开始播放。
* `state`：新的视频状态，以 `VideoState` 枚举中的值表示。该枚举可以包含以下可能值：
  * `VideoState.VS_READY`
  * `VideoState.VS_NONE`
  * `VideoState.VS_ERROR`
  * `VideoState.VS_SEEKING`
  * `VideoState.VS_LOADING`
  * `VideoState.VS_BUFFERING`
  * `VideoState.VS_PLAYING`
  * `VideoState.VS_PAUSED`
* `videoLength` (*数字* ）：整个视频的时长，单位为秒。 *-1* 如果长度未知。
* `时间戳` ( *数字*）：一个 *lamport* 每当视频状态发生变化时都会递增的时间戳。
* `tickNumber` (*数字*）：事件发生的时间，以场景开始运行以来的计数刻度表示。

如果你在一个已经有回调的实体上重新注册回调（例如，改变状态变化时的行为），新的回调会替换旧的回调，并保留最后报告的状态。这意味着，对于已经向之前的回调报告过的状态，新回调不会再次被调用。

### 检查实体是否已注册

使用 `videoEventsSystem.hasVideoEventsEntity()` 用于检查某个实体是否已经注册了视频事件回调。

```ts
if (videoEventsSystem.hasVideoEventsEntity(videoPlayerEntity)) {
	console.log('该实体已经有一个视频事件监听器')
}
```

### 最新视频事件

使用以下方法查询视频的最后一次状态变化： `videoEventsSystem.getVideoState()`。这会返回最新的 `VideoEvent` 的值，或者在 `undefined` 如果尚未报告任何事件，则返回空值。你可以在系统中调用它，以便在不注册回调的情况下每帧轮询视频状态。

```ts
function mySystem() {
	const latestVideoEvent = videoEventsSystem.getVideoState(videoPlayerEntity)
	if (!latestVideoEvent) return

	console.log(`状态: ${latestVideoEvent.state}
当前偏移: ${latestVideoEvent.currentOffset}
视频长度: ${latestVideoEvent.videoLength}`)
    \n当前偏移: ${latestVideoEvent.currentOffset}
    \n视频长度: ${latestVideoEvent.videoLength}`)
}
```

## 视频上的 Alpha 遮罩

让视频屏幕呈现非矩形的一种巧妙方法是在平面上叠加一个 alpha 纹理。你可以把平面的一部分裁剪成任意想要的形状。

使用下面的图像将你的视频裁剪成圆形，并带有透明角。

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-4a71dbd3206e2ccafdba8990cb5099b48c9a97cf%2Fcircle_mask.png?alt=media)

```ts
const videoTexture = Material.Texture.Video({
	videoPlayerEntity: screen,
})
const alphaMask = Material.Texture.Common({
	src: 'assets/scene/circle_mask.png',
	wrapMode: TextureWrapMode.TWM_MIRROR,
})

Material.setBasicMaterial(screen, {
	texture: videoTexture,
	alphaTexture: alphaMask,
})
```

![](https://2460066822-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-29eeafc704d19336cc3b0dc023c91e278b4bcd94%2Fcircular-video-screen.png?alt=media)

{% hint style="warning" %}
**📔 注意**：在以前的版本中， `alphaTexture` 该属性只存在于 PBR 材质中。目前，它只在基础材质中有效。
{% endhint %}

## 在 glTF 模型上播放视频

你可以在 *glTF* 模型的材质，使用 [GltfNodeModifiers](/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/materials.md#modify-gltf-materials) 组件遍历所有玩家。参见 [修改 glTF 材质](/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/materials.md#modify-gltf-materials) 了解更多详情。

这使你可以在任何形状上播放视频，而不只是平面。例如，你可以在曲面屏幕上播放视频，甚至在 NPC 的整个身体上播放视频。

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

GltfContainer.create(myEntity, {
	src: 'models/myModel.glb',
})

Transform.create(myEntity, {
	position: Vector3.create(4, 0, 4),
})

VideoPlayer.create(myEntity, {
	src: 'https://vz-7c61c1b5-d59.b-cdn.net/ccea595a-b910-4de6-b160-092819db021d/playlist.m3u8',
	playing: true,
})

GltfNodeModifiers.create(myEntity, {
	modifiers: [
		{
			path: '',
			material: {
				material: {
					$case: 'pbr',
					pbr: {
						texture: Material.Texture.Video({
							videoPlayerEntity: myEntity,
						}),
					},
				},
			},
		},
	],
})
```

视频的映射将遵循模型使用的原始 UV 映射。这意味着，如果模型有一个映射到模型特定部分的纹理，那么视频也会映射到同一部分。

你也可以使用 `GltfNodeModifiers` 组件，让视频仅在模型内的特定网格上播放。例如，你可以在建筑物的某一面墙上播放它，即使该模型覆盖了整个建筑。参见 [修改 glTF 材质](/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/materials.md#modify-gltf-materials) 了解更多详情。

## 空间音频

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

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

```ts
VideoPlayer.create(entity, {
	src: 'https://player.vimeo.com/progressive_redirect/playback/1145666916/rendition/540p/file.mp4%20%28540p%29.mp4?loc=external&signature=db1cd6946851313cb8f7be60d1f6c30af0902bcc46fdae0ba2a06e5fdf44c329',
	playing: true,
	spatial: true,
})
```

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

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

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

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

Transform.create(videoPlayerEntity, {
	position: Vector3.create(8, 2, 8),
})

VideoPlayer.create(videoPlayerEntity, {
	src: 'https://player.vimeo.com/progressive_redirect/playback/1145666916/rendition/540p/file.mp4%20%28540p%29.mp4?loc=external&signature=db1cd6946851313cb8f7be60d1f6c30af0902bcc46fdae0ba2a06e5fdf44c329',
	playing: true,
	spatial: true,
	spatialMinDistance: 5,
	spatialMaxDistance: 10,
})

MeshRenderer.setPlane(videoPlayerEntity)

Material.setBasicMaterial(videoPlayerEntity, {
	texture: Material.Texture.Video({ videoPlayerEntity: videoPlayerEntity }),
})
```

{% hint style="warning" %}
**📔 注意**：某些视频格式不支持空间音频。请确保该流编码为 *mp4*, *m4a*，或 *mov*.
{% endhint %}

## 音频分析

你可以从 `VideoPlayer` 实体的音频轨道中读取实时振幅和频率数据，以驱动与视频配乐同步的响应式视觉效果。参见 [音频分析](/creator/content-creator-zh/chang-jing-sdk7/mei-ti/audio-analysis.md).

{% hint style="info" %}
**💡 提示**：要查看在 GLTF 模型而不是基本体上播放的视频，请参见 [`74,-8-gltfnodemodifier`](https://github.com/decentraland/sdk7-test-scenes/tree/main/scenes/74,-8-gltfnodemodifier) 测试场景，它使用 `GltfNodeModifiers` 视频纹理将 HLS 流驱动到特定的 GLTF 节点上。
{% endhint %}


---

# 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/video-playing.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.
