

# IVS 录制 \$1 实时直播功能
<a name="rt-recording"></a>

IVS 实时直播功能有两种录制选项：
+ 使用单个参与者录制时，每个发布者的媒体都录制在单独的文件中。
+ 相比之下，合成录制将所有发布者的媒体合并到一个视图中，并将其录制在一个文件中。

单个参与者录制不会产生额外的 Amazon IVS 费用，而合成录制则会按编码视频的小时费率收费。两种录制选项都会产生标准 S3 存储和请求费用。有关详细信息，请参阅 [Amazon IVS 定价](https://aws.amazon.com/ivs/pricing/)。

要获得更具可定制性的解决方案，请考虑使用开源 [IVSStageSaver](https://github.com/aws-samples/amazon-ivs-stage-recorder) 项目作为您自己的自托管式录制服务的基础。

## 单个参与者录制
<a name="ind-par-rec"></a>

此选项非常适合只有一个发布者的直播或需要对每个发布者进行单独录制的情况，尤其是出于审核目的。有关更多详细信息，请参阅[单个参与者录制](rt-individual-participant-recording.md)。

![\[使用单个参与者录制会将每个发布者的媒体录制在单独的文件中。\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/images/Individual_Participant_Recording.png)


## 合成录制
<a name="comp-rec"></a>

此选项将来自多个发布者的媒体合并到一个视图中，并将其录制在一个文件中，非常适合视频点播体验。有关更多详细信息，请参阅[合成录制](rt-composite-recording.md)。

![\[使用服务器端合成将舞台录制到 S3 存储桶。\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/images/Composite_Recording.png)


## 缩略图
<a name="thumbnails"></a>

可以为单个参与者录制和合成（多参与者）录制设置 IVS 实时直播的缩略图录制。要启用或禁用缩略图录制并调整生成缩略图的间隔，请执行下面的操作：
+ 对于单个参与者录制，请使用 `thumbnailConfiguration` 属性。
+ 对于合成录制，请使用 `thumbnailConfigurations` 属性。

缩略图间隔范围为 1 至 86400 秒（24 小时）；默认情况下，缩略图录制处于禁用状态。有关详细信息，请参阅 [Amazon IVS Real-Time Streaming API Reference](https://docs.aws.amazon.com//ivs/latest/RealTimeAPIReference/Welcome.html)。

缩略图配置包括 `storage` 字段，可以将其设置为 `SEQUENTIAL` 和/或 `LATEST`。`storage` 字段确定缩略图的 S3 存储行为：
+ `SEQUENTIAL` 以串行方式保存所有缩略图。这是默认值。
+ `LATEST` 仅保存最新的缩略图，并覆盖前一个缩略图。

如果同时指定 `SEQUENTIAL` 和 `LATEST`，则缩略图将写入两个单独的 S3 路径，一个用于连续存档，一个用于最新缩略图。

# IVS 单个参与者录制 \$1 实时直播功能
<a name="rt-individual-participant-recording"></a>

本文档介绍如何使用将个别参与者记录与 IVS 实时直播功能结合使用。

需要支付标准 S3 存储和请求费用。缩略图不会产生额外 IVS 费用。有关详细信息，请参阅 [Amazon IVS 定价](https://aws.amazon.com/ivs/pricing/)。

## 简介
<a name="ind-part-rec-introduction"></a>

单个参与者录制允许 IVS 实时直播客户将 IVS 暂存区发布者单独录制到 S3 存储桶中。当为暂存区启用单个参与者录制功能时，发布者的内容将在其开始发布到暂存区时进行录制。

**注意：**如果您需要将所有暂存区参与者混合到一个视频中，则合成录制功能更合适。有关录制 IVS 实时直播内容的摘要，请参阅[录制](rt-recording.md)。

![\[使用单个参与者录制会将每个发布者的媒体录制在单独的文件中。\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/images/Individual_Participant_Recording.png)


## 工作流
<a name="ind-part-rec-workflow"></a>

![\[使用单个参与者录制将每个发布者的媒体录制在单独文件中的工作流程。\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/images/Workflow_Participant_Recording.png)


### 1. 创建 S3 存储桶
<a name="ind-part-rec-create-s3-bucket"></a>

您将需要使用 S3 存储桶来写入 VOD。有关详细信息，请参阅有关[如何创建存储桶](https://docs.aws.amazon.com/AmazonS3/latest/userguide/creating-bucket.html)的 S3 文档。请注意，对于单个参与者录制，必须在与 IVS 暂存区相同的亚马逊云科技区域中创建 S3 存储桶。

**重要**：如果使用现有 S3 存储桶：
+ **对象所有权**设置必须为**强制存储桶拥有者**或**首选存储桶拥有者**。
+ **默认加密**设置必须是**具有 Amazon S3 托管密钥的服务器端加密 (SSE-S3)**。

有关详细信息，请参阅有关[控制对象所有权](https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html)和[使用加密保护数据](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingEncryption.html)的 S3 文档。

### 2. 创建 StorageConfiguration 对象
<a name="ind-part-rec-create-storageconfig-object"></a>

创建存储桶后，调用 IVS 实时直播 API 来[创建 StorageConfiguration 对象](https://docs.aws.amazon.com//ivs/latest/RealTimeAPIReference/API_CreateStorageConfiguration.html)。成功创建存储配置后，IVS 将有权写入所提供的 S3 存储桶。您可以在多个暂存区重复使用此 StorageConfiguration 对象。

### 3. 创建带有参与者令牌的暂存区
<a name="ind-part-rec-create-stage-with-part-tokens"></a>

现在，您需要[创建一个已启用单个参与者录制的 IVS 暂存区](https://docs.aws.amazon.com//ivs/latest/RealTimeAPIReference/API_CreateStage.html)（通过设置 AutoParticipantRecordingConfiguration 对象），以及每个发布者的参与者令牌。

以下请求创建一个包含两个参与者令牌并已启用单个参与者录制功能的暂存区。

```
POST /CreateStage HTTP/1.1
Content-type: application/json

{
   "autoParticipantRecordingConfiguration": { 
      "mediaTypes": ["AUDIO_VIDEO"],
      "storageConfigurationArn": "arn:aws:ivs:us-west-2:123456789012:storage-configuration/AbCdef1G2hij",
      "thumbnailConfiguration": {
         "recordingMode": "INTERVAL",
         "storage": ["LATEST", "SEQUENTIAL"],
         "targetIntervalSeconds": 60
      }
   },
   "name": "TestStage",
   "participantTokenConfigurations": [ 
      { 
         "capabilities": ["PUBLISH", "SUBSCRIBE"],
         "duration": 20160,
         "userId": "1"
      },
      { 
         "capabilities": ["PUBLISH", "SUBSCRIBE"],
         "duration": 20160,
         "userId": "2"
      }
   ]
}
```

### 4. 以活跃发布者的身份加入暂存区
<a name="ind-part-rec-join-stage-as-active-pub"></a>

将参与者令牌分发给您的发布者，让他们加入暂存区并开始[向其发布](https://docs.aws.amazon.com//ivs/latest/RealTimeUserGuide/getting-started-pub-sub.html)。

当他们加入暂存区并开始使用 [IVS 实时直播功能广播 SDK](https://docs.aws.amazon.com//ivs/latest/RealTimeUserGuide/broadcast.html) 之一向暂存区发布内容时，参与者录制过程会自动开始，并向您发送一个 [EventBridge 事件](eventbridge.md)，指示录制已开始。（该事件为“IVS 参与者录制状态更改 – 录制开始”。） 同时，参与者录制过程开始将 VOD 和元数据文件写入配置的 S3 存储桶。注意：不保证连接时间极短（少于 5 秒）的参与者会被录制。

有两种方法可以获取每个录制的 S3 前缀：
+ 侦听 EventBridge 事件：

  ```
  {
     "version": "0",
     "id": "12345678-1a23-4567-a1bc-1a2b34567890",
     "detail-type": "IVS Participant Recording State Change",
     "source": "aws.ivs",
     "account": "123456789012",
     "time": "2024-03-13T22:19:04Z",
     "region": "us-east-1",
     "resources": ["arn:aws:ivs:us-west-2:123456789012:stage/AbCdef1G2hij"],
     "detail": {
        "session_id": "st-ZyXwvu1T2s",
        "event_name": "Recording Start",
        "participant_id": "xYz1c2d3e4f",
        "recording_s3_bucket_name": "ivs-recordings",
        "recording_s3_key_prefix": "<stage_id>/<session_id>/<participant_id>/2024-01-01T12-00-55Z"
     }
  }
  ```
+ 使用 [GetParticipant](https://docs.aws.amazon.com//ivs/latest/RealTimeAPIReference/API_GetParticipant.html) API 操作：响应包含录制参与者的 S3 存储桶和前缀。以下是请求：

  ```
  POST /GetParticipant HTTP/1.1
  Content-type: application/json
  {
     "participantID": "xYz1c2d3e4f",
     "sessionId": "st-ZyXwvu1T2s",
     "stageArn": "arn:aws:ivs:us-west-2:123456789012:stage/AbCdef1G2hij"
  }
  ```

  以下是响应：

  ```
  Content-type: application/json
  {
     "participant": {
        ...
        "recordingS3BucketName": "ivs-recordings",
        "recordingS3Prefix": "<stage_id>/<session_id>/<participant_id>",
        "recordingState": "ACTIVE",
        ...
     }
  }
  ```

### 5. 播放 VOD
<a name="ind-part-rec-play-back-vod"></a>

录制完成后，您可以使用 [IVS 播放器](https://debug.ivsdemos.com/?p=ivs)进行观看。有关为 VOD 播放设置 CloudFront 分配的说明，请参阅[播放私有存储桶中的录制内容](https://docs.aws.amazon.com//ivs/latest/RealTimeUserGuide/rt-composite-recording.html#comp-rec-playback)。

## 纯音频录制
<a name="ind-part-rec-audio-only-recordings"></a>

设置单个参与者录制时，您可以选择仅将音频 HLS 分段写入您的 S3 存储桶。要使用此功能，请在创建暂存区时选择 `AUDIO_ONLY mediaType`：

```
POST /CreateStage HTTP/1.1
Content-type: application/json

{
   "autoParticipantRecordingConfiguration": { 
      "storageConfigurationArn": "arn:aws:ivs:us-west-2:123456789012:storage-configuration/AbCdef1G2hij",
      "mediaTypes": ["AUDIO_ONLY"],
      "thumbnailConfiguration": {
         "recordingMode": "DISABLED"
      }
   },
   "name": "TestStage",
   "participantTokenConfigurations": [ 
      { 
         "capabilities": ["PUBLISH", "SUBSCRIBE"],
         "duration": 20160,
         "userId": "1"
      },
      { 
         "capabilities": ["PUBLISH", "SUBSCRIBE"],
         "duration": 20160,
         "userId": "2"
      }
   ]
}
```

## 仅缩略图录制
<a name="ind-part-rec-recording-thumbnail-only"></a>

设置单个参与者录制时，您可以选择仅将缩略图写入您的 S3 存储桶。要使用此功能，请在创建暂存区时将 `mediaType` 设置为 `NONE`。这可确保不会生成任何 HLS 片段；仍会创建缩略图并将其写入您的 S3 存储桶。

```
POST /CreateStage HTTP/1.1
Content-type: application/json
{
   "autoParticipantRecordingConfiguration": { 
      "storageConfigurationArn": "arn:aws:ivs:us-west-2:123456789012:storage-configuration/AbCdef1G2hij",
      "mediaTypes": ["NONE"],
      "thumbnailConfiguration": {
         "recordingMode": "INTERVAL",
         "storage": ["LATEST", "SEQUENTIAL"],
         "targetIntervalSeconds": 60
      }
   },
   "name": "TestStage",
   "participantTokenConfigurations": [ 
      { 
         "capabilities": ["PUBLISH", "SUBSCRIBE"],
         "duration": 20160,
         "userId": "1"
      },
      { 
         "capabilities": ["PUBLISH", "SUBSCRIBE"],
         "duration": 20160,
         "userId": "2"
      }
   ]
}
```

## 录制内容
<a name="ind-part-rec-recording-contents"></a>

当单个参与者录制处于活动状态时，HLS 视频片段、元数据文件和缩略图将开始写入创建暂存区时提供的 S3 存储桶。此内容可以进行后期处理或作为点播视频播放。

请注意，录制完成后，将通过 EventBridge 发送“IVS 参与者录制状态更改 – 录制结束”事件。建议仅在收到此事件后播放或处理录制的流。有关详细信息，请参阅[将 EventBridge 与 IVS 实时直播功能结合使用](eventbridge.md)。

以下是 IVS 实时会话录制的示例目录结构和内容：

```
s3://mybucket/stageId/stageSessionId/participantId/timestamp
   events
      recording-started.json
      recording-ended.json
   media
      hls
	 multivariant.m3u8
         high
            playlist.m3u8
            1.mp4
      thumbnails
         high
            1.jpg
            2.jpg
      latest_thumbnail
         high
            thumb.jpg
```

`events` 文件夹包含与录制事件相对应的元数据文件。记录开始、成功结束或以失败结束时会生成 JSON 元数据文件：
+ `events/recording-started.json`
+ `events/recording-ended.json`
+ `events/recording-failed.json`

给定 `events` 文件夹包含 `recording-started.json` 以及 `recording-ended.json` 或 `recording-failed.json` 之一。其中包含与录制会话及其输出格式相关的元数据。JSON 详细信息如下。

`media` 文件夹包含支持的媒体内容。`hls` 子文件夹包含录制会话期间生成的所有媒体和清单文件，可以使用 IVS 播放器进行播放。如果已配置，则 `thumbnails` 和 `latest_thumbnail` 子文件夹包含在录制会话期间生成的 JPEG 缩略图媒体文件。

## 合并片段化的单个参与者录制
<a name="ind-part-rec-merge-frag"></a>

录制配置的 `recordingReconnectWindowSeconds` 属性允许您指定一个时段（以秒为单位），在此期间，如果舞台发布者与舞台断开连接，然后重新连接，则 IVS 会尝试录制到与前一个会话相同的 S3 前缀。换句话说，如果发布者断开连接，然后在指定的间隔内重新连接，则多个录制将被视为单个录制并合并在一起。

如果在 `SEQUENTIAL` 模式下启用了缩略图录制，则缩略图也会合并到同一个 `recordingS3Prefix` 下。合并录制后，缩略图计数器会从为上一个录制写入的上一个缩略图值重新开始。

**Amazon EventBridge 中的 IVS 录制状态更改事件：**录制结束事件和录制结束的 JSON 元数据文件延迟了至少 `recordingReconnectWindowSeconds`，因为 IVS 会等待以确保没有启动新流。

有关设置合并流功能的说明，请参阅《*Amazon IVS 实时直播功能入门*》中的[步骤 2：创建具有可选参与者录制功能的舞台](getting-started-create-stage.md)。

### 资格
<a name="ind-part-rec-merge-frag-eligibility"></a>

要使用相同 S3 前缀合并多个录制，所有录制必须满足某些条件：
+ 舞台的 AutoParticipantRecordingConfiguration 的 `recordingReconnectWindowSeconds` 属性值设置为大于 0。
+ 用于写入 VOD 构件的 `StorageConfigurationArn` 对于每个录制都是相同的。
+ 参与者离开和重新加入舞台之间的时间差（以秒为单位）小于或等于 `recordingReconnectWindowSeconds`。

请注意，`recordingReconnectWindowSeconds` 的默认值为 0，这会禁用合并。

## 同步多个参与者录制
<a name="ind-part-rec-sync-multiple"></a>

单个参与者录制包括 HLS 播放列表中的 `EXT-X-PROGRAM-DATE-TIME` 标签，这些标签提供精确的 UTC 时间戳，精度为毫秒，便于在后期处理期间同步多个参与者的录制。

当您单独录制多个参与者并想要创建同步的合成（例如并排或画中画布局）时，即使参与者在不同的时间加入舞台或遇到网络中断可能导致的不连续性，也可以使用这些时间戳来准确对齐录制。

每位参与者的 HLS 播放列表都包含标记以下内容的 `EXT-X-PROGRAM-DATE-TIME` 标签：
+ 录制的开始（第一段）。
+ 录制期间的任何不连续点；例如，发生拼接时。

这些时间戳使用毫秒精度，并使用相同的时间参考在所有参与者之间同步。

### HLS 播放列表示例
<a name="ind-part-rec-sync-multiple-hls-playlist"></a>

```
#EXTM3U
#EXT-X-VERSION:7
#EXT-X-TARGETDURATION:12
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MAP:URI="init-0.mp4"
#EXT-X-PROGRAM-DATE-TIME:2024-01-01T12:00:00.000Z
#EXTINF:3.30091,
0.mp4
#EXTINF:5.63794,
1.mp4
#EXTINF:2.74290,
2.mp4
#EXT-X-DISCONTINUITY
#EXT-X-MAP:URI="init-1.mp4"
#EXT-X-PROGRAM-DATE-TIME:2024-01-01T12:00:52.772Z
#EXTINF:2.54412,
3.mp4
#EXTINF:5.63649,
4.mp4
```

`EXT-X-PROGRAM-DATE-TIME` 标签提供了第一段和每个不连续点的确切 UTC 时间，从而可以与其他参与者的录制精确同步。

### 同步工作流程
<a name="ind-part-rec-sync-multiple-workflow"></a>

要同步多个参与者录制，请从每个参与者的 HLS 播放列表中提取 `EXT-X-PROGRAM-DATE-TIME` 时间戳并使用这些时间戳来计算时间偏移。然后，可以在后期处理合成过程中使用 FFmpeg 等视频处理工具应用这些偏移。当录制中出现不连续性时，这些时间戳会提供必要的时间参考，以便在整个录制过程中保持准确的同步。

注意：要实现无需后期处理的实时同步输出，请考虑使用服务器端合成而不是单个参与者录制。

## JSON 元数据文件
<a name="ind-part-rec-json-metadata-files"></a>

此元数据采用 JSON 格式，它包含以下信息：


| 字段 | 类型 | 必需 | 描述 | 
| --- | --- | --- | --- | 
| `stage_arn` | 字符串 | 是 | 用作录制来源的暂存区的 ARN。 | 
| `session_id` | 字符串 | 是 | 代表录制参与者的暂存区 `session_id` 的字符串。 | 
| `participant_id` | 字符串 | 是 | 代表录制参与者标识符的字符串。 | 
| `recording_started_at` | 字符串 | 有条件 | 录制开始时的 RFC 3339 UTC 时间戳。这在 `recording_status` 为 `RECORDING_START_FAILED` 时不可用。另请参阅下面 `recording_ended_at` 的说明。 | 
| `recording_ended_at` | 字符串 | 条件 | 录制结束时的 RFC 3339 UTC 时间戳。此选项仅在 `recording_status` 为 `"RECORDING_ENDED"` 或 `"RECORDING_ENDED_WITH_FAILURE"` 时可用。 **注意：**`recording_started_at` 和 `recording_ended_at` 是这些事件生成时的时间戳，可能与 HLS 视频分段的时间戳并非完全一致。要准确确定录制的持续时间，请使用 `duration_ms` 字段。 | 
| `recording_status` | 字符串 | 是 | 录制的状态。有效值：`"RECORDING_STARTED"`、`"RECORDING_ENDED"`、`"RECORDING_START_FAILED"`、`"RECORDING_ENDED_WITH_FAILURE"`。 | 
| `recording_status_message` | 字符串 | 条件 | 状态的描述性信息。此选项仅在 `recording_status` 为 `"RECORDING_ENDED"` 或 `"RECORDING_ENDED_WITH_FAILURE"` 时可用。 | 
| `media` | 对象 | 是 | 包含可用于此录制的媒体内容的枚举对象的对象。有效值：`"hls"`。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-individual-participant-recording.html)  | 对象 | 是 | 描述 Apple HLS 格式输出的枚举字段。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-individual-participant-recording.html)  | integer | 条件 | 所录制 HLS 内容的时长（以毫秒为单位）。此选项仅在 `recording_status` 为 `"RECORDING_ENDED"` 或 `"RECORDING_ENDED_WITH_FAILURE"` 时可用。如果在完成任何录制之前发生故障，则该值为 0。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-individual-participant-recording.html)  | 字符串 | 是 | 存储 HLS 内容的 S3 前缀的相对路径。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-individual-participant-recording.html)  | 字符串 | 是 | HLS 主播放列表文件的名称。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-individual-participant-recording.html)  | 对象 | 是 | 元数据对象的呈现数组（HLS 变体）。始终至少有一个呈现。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-individual-participant-recording.html)  | 字符串 | 是 | 为此呈现存储 HLS 内容的 S3 前缀的相对路径。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-individual-participant-recording.html)  | 字符串 | 是 | 此呈现的媒体播放列表文件的名称。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-individual-participant-recording.html)  | object | 有条件 | 描述缩略图输出的枚举字段。只有当缩略图配置的 `storage` 字段包含 `SEQUENTIAL` 时，这才可用 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-individual-participant-recording.html)  | 字符串 | 是 | 存储连续缩略图内容的 S3 前缀的相对路径。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-individual-participant-recording.html)  | 对象 | 是 | 元数据对象的呈现数组（缩略图变体）。始终至少有一个呈现。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-individual-participant-recording.html)  | 字符串 | 是 | 为此呈现存储缩略图内容的 S3 前缀的相对路径。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-individual-participant-recording.html)  | object | 有条件 | 描述缩略图输出的枚举字段。只有当缩略图配置的 `storage` 字段包含 `LATEST` 时，这才可用 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-individual-participant-recording.html)  | 字符串 | 是 | 存储 `latest_thumbnail` 的 S3 前缀的相对路径。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-individual-participant-recording.html)  | 对象 | 是 | 元数据对象的呈现数组（缩略图变体）。始终至少有一个呈现。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-individual-participant-recording.html)  | 字符串 | 是 | 为此呈现存储最新缩略图的 S3 前缀的相对路径。 | 
| `version` | 字符串 | 是 | 元数据架构的版本。 | 

### 示例：recording-started.json
<a name="ind-part-rec-json-ex-rec-start"></a>

```
{
   "version": "v1",
   "stage_arn": "arn:aws:ivs:us-west-2:aws_account_id:stage/AbCdef1G2hij",
   "session_id": "st-ZyXwvu1T2s",
   "participant_id": "xYz1c2d3e4f",
   "recording_started_at": "2024-03-13T13:17:17Z",
   "recording_status": "RECORDING_STARTED",
   "media": {
      "hls": {
         "path": "media/hls",
         "playlist": "multivariant.m3u8",
         "renditions": [
            {
               "path": "high",
               "playlist": "playlist.m3u8"
            }
         ]
      },
      "thumbnails": {
         "path": "media/thumbnails",
         "renditions": [
            {
               "path": "high"
            }
         ]
      },
      "latest_thumbnail": {
         "path": "media/latest_thumbnail",
         "renditions": [
            {
               "path": "high"
            }
         ]
      }
   }
}
```

### 示例：recording-ended.json
<a name="ind-part-rec-json-ex-rec-end"></a>

```
{
   "version": "v1",
   "stage_arn": "arn:aws:ivs:us-west-2:aws_account_id:stage/AbCdef1G2hij",
   "session_id": "st-ZyXwvu1T2s",
   "participant_id": "xYz1c2d3e4f",
   "recording_started_at": "2024-03-13T19:44:19Z",
   "recording_ended_at": "2024-03-13T19:55:04Z",
   "recording_status": "RECORDING_ENDED",
   "media": {
      "hls": {
         "duration_ms": 645237,
         "path": "media/hls",
         "playlist": "multivariant.m3u8",
         "renditions": [
            {
               "path": "high",
               "playlist": "playlist.m3u8"
            }
         ]
      },
      "thumbnails": {
         "path": "media/thumbnails",
         "renditions": [
            {
               "path": "high"
            }
         ]
      },
      "latest_thumbnail": {
         "path": "media/latest_thumbnail",
         "renditions": [
            {
               "path": "high"
            }
         ]
      }
   }
}
```

### 示例：recording-failed.json
<a name="ind-part-rec-json-ex-rec-failed"></a>

```
{
   "version": "v1",
   "stage_arn": "arn:aws:ivs:us-west-2:aws_account_id:stage/AbCdef1G2hij",
   "session_id": "st-ZyXwvu1T2s",
   "participant_id": "xYz1c2d3e4f",
   "recording_started_at": "2024-03-13T19:44:19Z",
   "recording_ended_at": "2024-03-13T19:55:04Z",
   "recording_status": "RECORDING_ENDED_WITH_FAILURE",
   "media": {
      "hls": {
         "duration_ms": 645237,
         "path": "media/hls",
         "playlist": "multivariant.m3u8",
         "renditions": [
            {
               "path": "high",
               "playlist": "playlist.m3u8"
            }
         ]
      },
      "thumbnails": {
         "path": "media/thumbnails",
         "renditions": [
            {
               "path": "high"
            }
         ]
      },
      "latest_thumbnail": {
         "path": "media/latest_thumbnail",
         "renditions": [
            {
               "path": "high"
            }
         ]
      }
   }
}
```

## 将录制内容转换为 MP4
<a name="ind-part-rec-convert-rec-mp4"></a>

单个参与者录制以 HLS 格式存储，由播放列表和片段化的 MP4 (fMP4) 分段组成。要将 HLS 录制内容转换为单个 MP4 文件，请安装 FFmpeg 并运行下面的命令：

```
ffmpeg -i /path/to/playlist.m3u8 -i /path/to/playlist.m3u8 -map 0:v -map 1:a -c copy output.mp4
```

# IVS 合成录制 \$1 实时直播功能
<a name="rt-composite-recording"></a>

本文档介绍如何在[服务器端合成](server-side-composition.md)中使用合成录制功能。合成录制允许您使用 IVS 服务器将所有舞台发布者有效地组合到一个视图中，然后将生成的视频保存到 S3 存储桶中，从而生成 IVS 舞台的 HLS 录制。

需要支付标准 S3 存储和请求费用。缩略图不会产生额外 IVS 费用。有关详细信息，请参阅 [Amazon IVS 定价](https://aws.amazon.com/ivs/pricing/)。

## 先决条件
<a name="comp-rec-prerequisites"></a>

要使用合成录制，您必须有一个包含活跃发布者的暂存区以及一个用作录制目标的 S3 存储桶。下面，我们将介绍一种可能的工作流程，它使用 EventBridge 事件将合成录制到 S3 存储桶。或者，您可以根据自己的应用程序逻辑开始和停止合成。

1. 为每个发布者创建 [IVS 舞台](getting-started-create-stage.md)和参与者令牌。

1. 创建 [EncoderConfiguration](https://docs.aws.amazon.com/ivs/latest/RealTimeAPIReference/API_CreateEncoderConfiguration.html)（一个表示应当如何渲染录制视频的对象）。

1. 创建 [S3 存储桶](https://docs.aws.amazon.com/AmazonS3/latest/userguide/creating-bucket.html)和 [StorageConfiguration](https://docs.aws.amazon.com//ivs/latest/RealTimeAPIReference/API_CreateStorageConfiguration.html)（用于存储录制内容）。

   **重要**：如果您使用现有的 S3 存储桶，则**对象所有权**设置必须为**强制存储桶拥有者**或**首选存储桶拥有者**。有关详细信息，请参阅有关[控制对象所有权](https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html)的 S3 文档。

1. [加入舞台并发布到该舞台](getting-started-pub-sub.md)。

1. 当您收到参与者发布的 [EventBridge 事件](eventbridge.md)时，使用 S3 DestinationConfiguration 对象作为目标调用 [StartComposition](https://docs.aws.amazon.com//ivs/latest/RealTimeAPIReference/API_StartComposition.html)

1. 几秒钟后，您应能看到 HLS 分段已保留到您的 S3 存储桶中。

![\[使用服务器端合成将舞台录制到 S3 存储桶。\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/images/Composite_Recording_Workflow.png)


**注意：**发布者参与者在舞台上处于非活动状态 60 秒后，合成执行自动关闭。此时，合成终止，并转换到 `STOPPED` 状态。合成处于 `STOPPED` 状态几分钟后将自动删除。有关详细信息，请参阅*服务器端合成*中的[合成生命周期](ssc-overview.md#ssc-composition-endpoint)。

## 合成录制示例：使用 S3 存储桶目标的 StartComposition
<a name="comp-rec-example"></a>

下例显示了对 [StartComposition](https://docs.aws.amazon.com//ivs/latest/RealTimeAPIReference/API_StartComposition.html) 操作的典型调用，将 S3 指定为合成的唯一目标。合成转换到 `ACTIVE` 状态后，视频片段和元数据将开始写入 `storageConfiguration` 对象指定的 S3 存储桶。要创建具有不同布局的合成，请参阅[服务器端合成](ssc-overview.md#ssc-api-layouts)中的“布局”以及 [IVS Real-Time Streaming API Reference](https://docs.aws.amazon.com//ivs/latest/RealTimeAPIReference/API_LayoutConfiguration.html)。

### 请求
<a name="comp-rec-example-request"></a>

```
POST /StartComposition HTTP/1.1
Content-type: application/json

{
   "destinations": [
      {
         "s3": {
            "encoderConfigurationArns": [
              "arn:aws:ivs:ap-northeast-1:927810967299:encoder-configuration/PAAwglkRtjge"
            ],
            "storageConfigurationArn": "arn:aws:ivs:ap-northeast-1:927810967299:storage-configuration/ZBcEbgbE24Cq",
	    "thumbnailConfigurations": [
	       {
		  "storage": ["LATEST", "SEQUENTIAL"],
		  "targetIntervalSeconds": 30
               }
	    ]
	 }
      }
   ],
   "idempotencyToken": "db1i782f1g9",
   "stageArn": "arn:aws:ivs:ap-northeast-1:927810967299:stage/WyGkzNFGwiwr"
}
```

### 响应
<a name="comp-rec-example-response"></a>

```
{
    "composition": {
        "arn": "arn:aws:ivs:ap-northeast-1:927810967299:composition/s2AdaGUbvQgp",
        "destinations": [
            {
                "configuration": {
                    "name": "",
                    "s3": {
                        "encoderConfigurationArns": [
                            "arn:aws:ivs:ap-northeast-1:927810967299:encoder-configuration/PAAwglkRtjge"
                        ],
                        "recordingConfiguration": {
                            "format": "HLS"
                        },
                        "storageConfigurationArn": "arn:aws:ivs:ap-northeast-1:927810967299:storage-configuration/ZBcEbgbE24Cq",
	                "thumbnailConfigurations": [
	                   {
		              "storage": ["LATEST", "SEQUENTIAL"],
		              "targetIntervalSeconds": 30
                           }
	                ]
                    }
                },
                "detail": {
                    "s3": {
                        "recordingPrefix": "MNALAcH9j2EJ/s2AdaGUbvQgp/2pBRKrNgX1ff/composite"
                    }
                },
                "id": "2pBRKrNgX1ff",
                "state": "STARTING"
            }
        ],
        "layout": null,
        "stageArn": "arn:aws:ivs:ap-northeast-1:927810967299:stage/WyGkzNFGwiwr",
        "startTime": "2023-11-01T06:25:37Z",
        "state": "STARTING",
        "tags": {}
    }
}
```

StartComposition 响应中出现的 `recordingPrefix` 字段可用于确定录制内容的存储位置。

## 录制内容
<a name="comp-rec-contents"></a>

当合成转换为 `ACTIVE` 状态时，HLS 视频片段、元数据文件和缩略图（如果已配置）将开始写入 StartComposition 调用期间指定的 S3 存储桶。此内容可以进行后期处理或作为点播视频播放。

请注意，在合成变成实时后，会发出一个“IVS 合成状态更改”事件，可能需要一些时间才能写入清单文件、视频片段和缩略图。我们建议仅在收到“IVS 合成状态更改（会话结束）”事件后回放或处理录制的流。有关详细信息，请参阅[将 EventBridge 与 IVS 实时直播功能结合使用](eventbridge.md)。

以下是 IVS 实时会话录制的示例目录结构和内容：

```
MNALAcH9j2EJ/s2AdaGUbvQgp/2pBRKrNgX1ff/composite
   events
      recording-started.json
      recording-ended.json
   media
      hls
      thumbnails
      latest_thumbnail
```

`events` 文件夹包含与录制事件相对应的元数据文件。记录开始、成功结束或以失败结束时会生成 JSON 元数据文件：
+ `events/recording-started.json`
+ `events/recording-ended.json`
+ `events/recording-failed.json`

给定 `events` 文件夹将包含 `recording-started.json` 和 `recording-ended.json` 或 `recording-failed.json` 之一。

其中包含与录制会话及其输出格式相关的元数据。JSON 详细信息如下。

`media` 文件夹包含支持的媒体内容。`hls` 子文件夹包含合成会话期间生成的所有媒体和清单文件，并且可使用 IVS 播放器播放。HLS 清单位于 `multivariant.m3u8` 文件夹中。如果已配置，则 `thumbnails` 和 `latest_thumbnail` 子文件夹包含在合成会话期间生成的 JPEG 缩略图媒体文件。

## StorageConfiguration 的存储桶策略
<a name="comp-rec-bucket-policy"></a>

创建 StorageConfiguration 对象后，IVS 将有权将内容写入指定的 S3 存储桶。此访问权限通过修改 S3 存储桶的策略来授予。*如果通过移除 IVS 的访问权限来更改存储桶的策略，则正在进行的录制和新录制都将失败。*

下例显示了允许 IVS 写入到 S3 存储桶的 S3 存储桶策略：

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "CompositeWrite-y1d212y",
            "Effect": "Allow",
            "Principal": {
                "Service": "ivs-composite.ap-northeast-1.amazonaws.com"
            },
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::my-s3-bucket/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                },
                "Bool": {
                    "aws:SecureTransport": "true"
                }
            }
        }
    ]
}
```

------

## JSON 元数据文件
<a name="comp-rec-json"></a>

此元数据采用 JSON 格式，它包含以下信息：


| 字段 | 类型 | 必需 | 描述 | 
| --- | --- | --- | --- | 
| `stage_arn` | 字符串 | 是 | 用作合成来源的舞台的 ARN。 | 
| `media` | 对象 | 是 | 包含可用于此录制的媒体内容的枚举对象的对象。有效值：`"hls"`。  | 
| [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html) | 对象 | 是 | 描述 Apple HLS 格式输出的枚举字段。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | integer | 条件 | 所录制 HLS 内容的时长（以毫秒为单位）。此选项仅在 `recording_status` 为 `"RECORDING_ENDED"` 或 `"RECORDING_ENDED_WITH_FAILURE"` 时可用。如果在完成任何录制之前发生故障，则该值为 0。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | 字符串 | 是 | 存储 HLS 内容的 S3 前缀的相对路径。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | 字符串 | 是 |  HLS 主播放列表文件的名称。  | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | 对象 | 是 | 元数据对象的呈现数组（HLS 变体）。始终至少有一个呈现。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | 字符串 | 是 | 为此呈现存储 HLS 内容的 S3 前缀的相对路径。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | 字符串 | 是 | 此呈现的媒体播放列表文件的名称。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | int | 条件 | 编码视频的像素分辨率高度。仅当呈现包含视频轨道时，此选项才可用。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | int | 条件 | 编码视频的像素分辨率宽度。仅当呈现包含视频轨道时，此选项才可用。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | object | 有条件 | 描述缩略图输出的枚举字段。只有当缩略图配置的 `storage` 字段包含 `SEQUENTIAL` 时，这才可用 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | 字符串 | 是 | 存储连续缩略图内容的 S3 前缀的相对路径。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | 对象 | 是 | 元数据对象的分辨率数组（缩略图变体）。始终至少有一个分辨率。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | 字符串 | 是 | 为此分辨率存储缩略图内容的 S3 前缀的相对路径。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | int | 是 | 缩略图的像素分辨率高度。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | int | 是 | 缩略图的像素分辨率宽度。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | object | 有条件 | 描述缩略图输出的枚举字段。只有当缩略图配置的 `storage` 字段包含 `LATEST` 时，这才可用 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | 字符串 | 是 | 存储 `latest_thumbnail` 的 S3 前缀的相对路径。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | 对象 | 是 | 元数据对象的分辨率数组（缩略图变体）。始终至少有一个分辨率。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | 字符串 | 是 | 为此分辨率存储最新缩略图的 S3 前缀的相对路径。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | int | 是 | 最新缩略图的像素分辨率高度。 | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/ivs/latest/RealTimeUserGuide/rt-composite-recording.html)  | int | 是 | 最新缩略图的像素分辨率宽度。 | 
| `recording_ended_at` | 字符串 | 条件 | 录制结束时的 RFC 3339 UTC 时间戳。此选项仅在 `recording_status` 为 `"RECORDING_ENDED"` 或 `"RECORDING_ENDED_WITH_FAILURE"` 时可用。 `recording_started_at` 和 `recording_ended_at` 是这些事件生成时的时间戳，可能与 HLS 视频片段的时间戳不完全一致。要准确确定录制的持续时间，请使用 `duration_ms` 字段。  | 
| `recording_started_at` | 字符串 | 有条件 | 录制开始时的 RFC 3339 UTC 时间戳。这在 `recording_status` 为 `RECORDING_START_FAILED` 时不可用。 请参阅上面有关 `recording_ended_at` 的注释。  | 
| `recording_status` | 字符串 | 是 | 录制的状态。有效值：`"RECORDING_STARTED"`、`"RECORDING_ENDED"`、`"RECORDING_START_FAILED"`、`"RECORDING_ENDED_WITH_FAILURE"`。 | 
| `recording_status_message` | 字符串 | 条件 | 状态的描述性信息。此选项仅在 `recording_status` 为 `"RECORDING_ENDED"` 或 `"RECORDING_ENDED_WITH_FAILURE"` 时可用。 | 
| `version` | 字符串 | 是 | 元数据架构的版本。 | 

### 示例：recording-started.json
<a name="comp-rec-json-ex-rec-start"></a>

```
{
  "version": "v1",
  "stage_arn": "arn:aws:ivs:ap-northeast-1:123456789012:stage/aAbBcCdDeE12",
  "recording_started_at": "2023-11-01T06:01:36Z",
  "recording_status": "RECORDING_STARTED",
  "media": {
    "hls": {
      "path": "media/hls",
      "playlist": "multivariant.m3u8",
      "renditions": [
        {
          "path": "720p30-abcdeABCDE12",
          "playlist": "playlist.m3u8",
          "resolution_width": 1280,
          "resolution_height": 720
        }
      ]
    },
    "thumbnails": {
      "path": "media/thumbnails",
      "resolutions": [
        {
          "path": "1280x720",
          "resolution_width": 1280,
          "resolution_height": 720
        }
      ]
    },
    "latest_thumbnail": {
      "path": "media/latest_thumbnail",
      "resolutions": [
        {
          "path": "1280x720",
          "resolution_width": 1280,
          "resolution_height": 720
        }
      ]
    }
  }
}
```

### 示例：recording-ended.json
<a name="comp-rec-json-ex-rec-end"></a>

```
{
  "version": "v1",
  "stage_arn": "arn:aws:ivs:ap-northeast-1:123456789012:stage/aAbBcCdDeE12",
  "recording_started_at": "2023-10-27T17:00:44Z",
  "recording_ended_at": "2023-10-27T17:08:24Z",
  "recording_status": "RECORDING_ENDED",
  "media": {
    "hls": {
      "duration_ms": 460315,
      "path": "media/hls",
      "playlist": "multivariant.m3u8",
      "renditions": [
        {
          "path": "720p30-abcdeABCDE12",
          "playlist": "playlist.m3u8",
          "resolution_width": 1280,
          "resolution_height": 720
        }
      ]
    },
    "thumbnails": {
      "path": "media/thumbnails",
      "resolutions": [
        {
          "path": "1280x720",
          "resolution_width": 1280,
          "resolution_height": 720
        }
      ]
    },
    "latest_thumbnail": {
      "path": "media/latest_thumbnail",
      "resolutions": [
        {
          "path": "1280x720",
          "resolution_width": 1280,
          "resolution_height": 720
        }
      ]
    }
  }
}
```

### 示例：recording-failed.json
<a name="comp-rec-json-ex-rec-fail"></a>

```
{
  "version": "v1",
  "stage_arn": "arn:aws:ivs:ap-northeast-1:123456789012:stage/aAbBcCdDeE12",
  "recording_started_at": "2023-10-27T17:00:44Z",
  "recording_ended_at": "2023-10-27T17:08:24Z",
  "recording_status": "RECORDING_ENDED_WITH_FAILURE",
  "media": {
    "hls": {
      "duration_ms": 460315,
      "path": "media/hls",
      "playlist": "multivariant.m3u8",
      "renditions": [
        {
          "path": "720p30-abcdeABCDE12",
          "playlist": "playlist.m3u8",
          "resolution_width": 1280,
          "resolution_height": 720
        }
      ]
    },
    "thumbnails": {
      "path": "media/thumbnails",
      "resolutions": [
        {
          "path": "1280x720",
          "resolution_width": 1280,
          "resolution_height": 720
        }
      ]
    },
    "latest_thumbnail": {
      "path": "media/latest_thumbnail",
      "resolutions": [
        {
          "path": "1280x720",
          "resolution_width": 1280,
          "resolution_height": 720
        }
      ]
    }
  }
}
```

## 播放私有存储桶中的录制内容
<a name="comp-rec-playback"></a>

默认情况下，录制的内容为私有；因此，使用直接 S3 URL 无法访问这些对象。如果您尝试使用 IVS 播放器或其他播放器打开 HLS 多元播放列表（m3u8 文件）进行播放，您将收到错误信息（例如，“您无权访问请求的资源”）。相反，您可以使用 Amazon CloudFront CDN（内容分发网络）播放这些文件。

CloudFront 分配可配置为从私有存储桶提供内容。通常，这比具有公开可访问的存储桶更好，其中读取会绕过 CloudFront 提供的控件。您可以通过创建源访问控制（OAC）将分配设置为从私有存储桶提供服务，OAC 是一个特殊的 CloudFront 用户，具有对私有源存储桶的读取权限。您可以在创建分配后通过 CloudFront 控制台或 API 创建 OAC。请参阅 *Amazon CloudFront 开发人员指南*中的[创建新的源访问控制](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html#create-oac-overview-s3)。

### 在启用 CORS 的情况下使用 CloudFront 设置播放
<a name="comp-rec-playback-setup"></a>

此例介绍开发人员如何在启用了 CORS 的情况下设置 CloudFront 分配，从而允许从任何域播放其录制内容。这在开发阶段特别有用，但是您可以修改下面的示例以满足您的生产需要。

#### 步骤 1：创建 S3 存储桶
<a name="comp-rec-playback-setup-step1"></a>

创建用于存储录制内容的 S3 存储桶。请注意，存储桶需要处于您用于 IVS 工作流程的同一区域。

向存储桶添加宽松 CORS 策略：

1. 在 AWS 控制台中，转到 **S3 存储桶权限**选项卡。

1. 复制下面的 CORS 策略并将其粘贴到**跨源资源共享（CORS）**下。这将在 S3 存储桶上启用 CORS 访问。

   ```
   [
       {
           "AllowedHeaders": [
               "*"
           ],
           "AllowedMethods": [
               "PUT",
               "POST",
               "DELETE",
               "GET"
           ],
           "AllowedOrigins": [
               "*"
           ],
           "ExposeHeaders": [
               "x-amz-server-side-encryption",
               "x-amz-request-id",
               "x-amz-id-2"
           ]
       }
   ]
   ```

#### 步骤 2：创建 CloudFront 分配
<a name="comp-rec-playback-setup-step2"></a>

请参阅 *CloudFront 开发人员指南*中的[创建 CloudFront 分配](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-creating-console.html)。

使用 AWS 控制台，输入以下内容：


| 对于此字段…… | 选择此…… | 
| --- | --- | 
| 源域 | 在上一步中创建的 S3 桶 | 
| 源访问 | 源访问控制设置（推荐），使用默认参数 | 
| 默认缓存行为：查看器协议策略 | 将 HTTP 重定向到 HTTPS | 
| 默认缓存行为：允许的 HTTP 方法 | GET、HEAD 和 OPTIONS | 
| 默认缓存行为：缓存密钥和源请求 | CachingDisabled 策略 | 
| 默认缓存行为：源请求策略 | CORS-S3Origin | 
| 默认缓存行为：响应标头策略 | SimpleCORS | 
| Web 应用程序防火墙 | 启用安全保护 | 

然后保存 CloudFront 分配。

#### 步骤 3：设置 S3 存储桶策略
<a name="comp-rec-playback-setup-step3"></a>

1. 删除您为 S3 存储桶设置的任何 StorageConfiguration。这将删除在为该存储桶创建策略时自动添加的任何存储桶策略。

1. 转到您的 CloudFront 分配，确保所有分配字段均处于上一步中定义的状态，然后**复制存储桶策略**（使用**复制策略**按钮）。

1. 转到您的 S3 桶。在**权限**选项卡上，选择**编辑存储桶策略**，然后粘贴您在上一步中复制的存储桶策略。完成此步骤后，存储桶策略应当只有 CloudFront 策略。

1. 创建 StorageConfiguration，指定 S3 存储桶。

创建 StorageConfiguration 后，您将在 S3 存储桶策略中看到两个项，一个允许 CloudFront 读取内容，另一个允许 IVS 写入内容。[示例：具有 CloudFront 和 IVS 访问权限的 S3 存储桶策略](#comp-rec-playback-example)中显示了最终存储桶策略的示例，具有 CloudFront 和 IVS 访问权限。

#### 步骤 4：播放录制内容
<a name="comp-rec-playback-setup-step4"></a>

成功设置 CloudFront 分配并更新存储桶策略后，您应能够使用 IVS 播放器播放录制内容：

1. 成功启动合成，并确保录制内容存储在 S3 存储桶中。

1. 按照本示例中的步骤 1 到步骤 3 操作后，应可通过 CloudFront URL 获得视频文件。您的 CloudFront URL 是 Amazon CloudFront 控制台的**详细信息**选项卡上的**分配域名**。它应该如下所示：

   `a1b23cdef4ghij.cloudfront.net`

1. 要通过 CloudFront 分配播放录制的视频，请在 S3 存储桶下找到 `multivariant.m3u8` 文件的对象键。它应该如下所示：

   `FDew6Szq5iTt/9NIpWJHj0wPT/fjFKbylPb3k4/composite/media/hls/multivariant.m3u8`

1. 将对象键附加到您的 CloudFront URL 的末尾。您的最终 URL 如下所示：

   `https://a1b23cdef4ghij.cloudfront.net/FDew6Szq5iTt/9NIpWJHj0wPT/fjFKbylPb3k4/composite/media/hls/multivariant.m3u8`

1. 现在，您可以将最终 URL 添加到 IVS 播放器的源属性中，以观看完整录制内容。要观看录制的视频，可以使用 *IVS 播放器开发工具包：Web 指南*的[入门](https://docs.aws.amazon.com//ivs/latest/LowLatencyUserGuide/web-getting-started.html)中的演示。

### 示例：具有 CloudFront 和 IVS 访问权限的 S3 存储桶策略
<a name="comp-rec-playback-example"></a>

下面的代码段演示了一个 S3 存储桶策略，它允许 CloudFront 将内容读取到私有存储桶，并允许 IVS 将内容写入存储桶。**注意：请勿将以下代码段复制并粘贴到自己的存储桶中。您的策略应包含与您的 CloudFront 分配和 StorageConfiguration 相关的 ID。**

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "CompositeWrite-7eiKaIGkC9DO",
      "Effect": "Allow",
      "Principal": {
        "Service": "ivs-composite.ap-northeast-1.amazonaws.com"
      },
      "Action": [
        "s3:PutObject",
        "s3:PutObjectAcl"
      ],
      "Resource": "arn:aws:s3:::eicheane-test-1026-2-ivs-recordings/*",
      "Condition": {
        "StringEquals": {
          "s3:x-amz-acl": "bucket-owner-full-control"
        },
        "Bool": {
          "aws:SecureTransport": "true"
        }
      }
    },
    {
      "Sid": "AllowCloudFrontServicePrincipal",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudfront.amazonaws.com"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::eicheane-test-1026-2-ivs-recordings/*",
      "Condition": {
        "StringEquals": {
          "AWS:SourceArn": "arn:aws:cloudfront::844311324168:distribution/E1NG4YMW5MN25A"
        }
      }
    }
  ]
}
```

------

## 问题排查
<a name="comp-rec-troubleshooting"></a>
+ **合成不会写入 S3 存储桶 —** 确保 S3 存储桶和 StorageConfiguration 对象在同一个区域中创建。还要检查您的存储桶策略以确保 IVS 可以访问该存储桶；请参阅 [StorageConfiguration 的存储桶策略](#comp-rec-bucket-policy)。
+ **执行 *ListCompositions* 时找不到合成 —** 合成是短暂性资源。一旦它们转换到最终状态，将会在几分钟后自动删除。
+ **我的合成自动停止 —** 如果舞台上没有发布者超过 60 秒，合成将自动停止。

## 已知问题
<a name="comp-rec-issues"></a>

由合成录制创建的媒体播放列表在合成正在进行时带有 `#EXT-X-PLAYLIST-TYPE:EVENT` 标签。合成完成后，标签更新为 `#EXT-X-PLAYLIST-TYPE:VOD`。为了获得流畅的播放体验，我们建议您仅在成功完成合成后使用此播放列表。