IVS 合成录制 | 实时直播功能
本文档介绍如何在服务器端合成中使用合成录制功能。合成录制允许您使用 IVS 服务器将所有舞台发布者有效地组合到一个视图中,然后将生成的视频保存到 S3 存储桶中,从而生成 IVS 舞台的 HLS 录制。
先决条件
要使用合成录制,您必须有一个包含活跃发布者的暂存区以及一个用作录制目标的 S3 存储桶。下面,我们将介绍一种可能的工作流程,它使用 EventBridge 事件将合成录制到 S3 存储桶。或者,您可以根据自己的应用程序逻辑开始和停止合成。
-
为每个发布者创建 IVS 舞台和参与者令牌。
-
创建 EncoderConfiguration(一个表示应当如何渲染录制视频的对象)。
-
创建 S3 存储桶和 StorageConfiguration(用于存储录制内容)。
重要:如果您使用现有的 S3 存储桶,则对象所有权设置必须为强制存储桶拥有者或首选存储桶拥有者。有关详细信息,请参阅有关控制对象所有权的 S3 文档。
-
当您收到参与者发布的 EventBridge 事件时,使用 S3 DestinationConfiguration 对象作为目标调用 StartComposition
-
几秒钟后,您应能看到 HLS 分段已保留到您的 S3 存储桶中。
注意:发布者参与者在舞台上处于非活动状态 60 秒后,合成执行自动关闭。此时,合成终止,并转换到 STOPPED
状态。合成处于 STOPPED
状态几分钟后将自动删除。有关详细信息,请参阅服务器端合成中的合成生命周期。
合成录制示例:使用 S3 存储桶目标的 StartComposition
下例显示了对 StartComposition 端点的典型调用,将 S3 指定为合成的唯一目标。合成转换到 ACTIVE
状态后,视频片段和元数据将开始写入 storageConfiguration
对象指定的 S3 存储桶。要创建具有不同布局的合成,请参阅服务器端合成中的“布局”以及 IVS Real-Time Streaming API Reference。
请求
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" } } ], "idempotencyToken": "db1i782f1g9", "stageArn": "arn:aws:ivs:ap-northeast-1:927810967299:stage/WyGkzNFGwiwr" }
响应
{ "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" } }, "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
字段可用于确定录制内容的存储位置。
录制内容
当合成转换到 ACTIVE
状态时,您将开始看到 HLS 视频片段和元数据文件正在写入调用 StartComposition 时提供的 S3 存储桶。这些内容可用于后处理或作为按需视频播放。
请注意,在合成变成实时后,会发出一个“IVS 合成状态更改”事件,可能需要一点时间写入清单文件和视频段。我们建议仅在收到“IVS 合成状态更改(会话结束)”事件后回放或处理录制的流。有关详细信息,请参阅将 EventBridge 与 IVS 实时直播功能结合使用。
以下是 IVS 实时会话录制的示例目录结构和内容:
MNALAcH9j2EJ/s2AdaGUbvQgp/2pBRKrNgX1ff/composite events recording-started.json recording-ended.json media hls
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
文件夹中。
StorageConfiguration 的存储桶策略
创建 StorageConfiguration 对象后,IVS 将有权将内容写入指定的 S3 存储桶。此访问权限通过修改 S3 存储桶的策略来授予。如果通过移除 IVS 的访问权限来更改存储桶的策略,则正在进行的录制和新录制都将失败。
下例显示了允许 IVS 写入到 S3 存储桶的 S3 存储桶策略:
{ "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 元数据文件
此元数据采用 JSON 格式,它包含以下信息:
字段 | 类型 | 必需 | 描述 |
---|---|---|---|
|
字符串 | 是 | 用作合成来源的舞台的 ARN。 |
|
对象 | 是 | 包含可用于此录制的媒体内容的枚举对象的对象。有效值: |
|
对象 | 是 | 描述 Apple HLS 格式输出的枚举字段。 |
|
integer | 条件 | 所录制 HLS 内容的时长(以毫秒为单位)。此选项仅在 |
|
字符串 | 是 | 存储 HLS 内容的 S3 前缀的相对路径。 |
|
字符串 | 是 |
HLS 主播放列表文件的名称。 |
|
对象 | 是 | 元数据对象的呈现数组(HLS 变体)。始终至少有一个呈现。 |
|
字符串 | 是 | 为此呈现存储 HLS 内容的 S3 前缀的相对路径。 |
|
字符串 | 是 | 此呈现的媒体播放列表文件的名称。 |
|
int | 条件 | 编码视频的像素分辨率高度。仅当呈现包含视频轨道时,此选项才可用。 |
|
int | 条件 | 编码视频的像素分辨率宽度。仅当呈现包含视频轨道时,此选项才可用。 |
|
字符串 | 条件 | 录制结束时的 RFC 3339 UTC 时间戳。此选项仅在
|
|
字符串 | 条件 | 录制开始时的 RFC 3339 UTC 时间戳。这在 请参阅上面有关 |
|
字符串 | 是 | 录制的状态。有效值: |
|
字符串 | 条件 | 状态的描述性信息。此选项仅在 |
|
字符串 | 是 | 元数据架构的版本。 |
示例:recording-started.json
{ "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 } ] } } }
示例:recording-ended.json
{ "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 } ] } } }
示例:recording-failed.json
{ "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 } ] } } }
播放私有存储桶中的录制内容
默认情况下,录制的内容为私有;因此,使用直接 S3 URL 无法访问这些对象。如果您尝试使用 IVS 播放器或其他播放器打开 HLS 多元播放列表(m3u8 文件)进行播放,您将收到错误信息(例如,“您无权访问请求的资源”)。相反,您可以使用 Amazon CloudFront CDN(内容分发网络)播放这些文件。
CloudFront 分配可配置为从私有存储桶提供内容。通常,这比具有公开可访问的存储桶更好,其中读取会绕过 CloudFront 提供的控件。您可以通过创建源访问控制(OAC)将分配设置为从私有存储桶提供服务,OAC 是一个特殊的 CloudFront 用户,具有对私有源存储桶的读取权限。您可以在创建分配后通过 CloudFront 控制台或 API 创建 OAC。请参阅 Amazon CloudFront 开发人员指南中的创建新的源访问控制。
在启用 CORS 的情况下使用 CloudFront 设置播放
此例介绍开发人员如何在启用了 CORS 的情况下设置 CloudFront 分配,从而允许从任何域播放其录制内容。这在开发阶段特别有用,但是您可以修改下面的示例以满足您的生产需要。
步骤 1:创建 S3 存储桶
创建用于存储录制内容的 S3 存储桶。请注意,存储桶需要处于您用于 IVS 工作流程的同一区域。
向存储桶添加宽松 CORS 策略:
-
在 AWS 控制台中,转到 S3 存储桶权限选项卡。
-
复制下面的 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 分配
请参阅 CloudFront 开发人员指南中的创建 CloudFront 分配。
使用 AWS 控制台,输入以下内容:
对于此字段…… | 选择此…… |
---|---|
源域 | 在上一步中创建的 S3 桶 |
源访问 | 源访问控制设置(推荐),使用默认参数 |
默认缓存行为:查看器协议策略 | 将 HTTP 重定向到 HTTPS |
默认缓存行为:允许的 HTTP 方法 | GET、HEAD 和 OPTIONS |
默认缓存行为:缓存密钥和源请求 | CachingDisabled 策略 |
默认缓存行为:源请求策略 | CORS-S3Origin |
默认缓存行为:响应标头策略 | SimpleCORS |
Web 应用程序防火墙 | 启用安全保护 |
然后保存 CloudFront 分配。
步骤 3:设置 S3 存储桶策略
-
删除您为 S3 存储桶设置的任何 StorageConfiguration。这将删除在为该存储桶创建策略时自动添加的任何存储桶策略。
-
转到您的 CloudFront 分配,确保所有分配字段均处于上一步中定义的状态,然后复制存储桶策略(使用复制策略按钮)。
-
转到您的 S3 桶。在权限选项卡上,选择编辑存储桶策略,然后粘贴您在上一步中复制的存储桶策略。完成此步骤后,存储桶策略应当只有 CloudFront 策略。
-
创建 StorageConfiguration,指定 S3 存储桶。
创建 StorageConfiguration 后,您将在 S3 存储桶策略中看到两个项,一个允许 CloudFront 读取内容,另一个允许 IVS 写入内容。示例:具有 CloudFront 和 IVS 访问权限的 S3 存储桶策略中显示了最终存储桶策略的示例,具有 CloudFront 和 IVS 访问权限。
步骤 4:播放录制内容
成功设置 CloudFront 分配并更新存储桶策略后,您应能够使用 IVS 播放器播放录制内容:
-
成功启动合成,并确保录制内容存储在 S3 存储桶中。
-
按照本示例中的步骤 1 到步骤 3 操作后,应可通过 CloudFront URL 获得视频文件。您的 CloudFront URL 是 Amazon CloudFront 控制台的详细信息选项卡上的分配域名。它应该如下所示:
a1b23cdef4ghij.cloudfront.net
-
要通过 CloudFront 分配播放录制的视频,请在 S3 存储桶下找到
multivariant.m3u8
文件的对象键。它应该如下所示:FDew6Szq5iTt/9NIpWJHj0wPT/fjFKbylPb3k4/composite/media/hls/multivariant.m3u8
-
将对象键附加到您的 CloudFront URL 的末尾。您的最终 URL 如下所示:
https://a1b23cdef4ghij.cloudfront.net/FDew6Szq5iTt/9NIpWJHj0wPT/fjFKbylPb3k4/composite/media/hls/multivariant.m3u8
-
现在,您可以将最终 URL 添加到 IVS 播放器的源属性中,以观看完整录制内容。要观看录制的视频,可以使用 IVS 播放器开发工具包:Web 指南的入门中的演示。
示例:具有 CloudFront 和 IVS 访问权限的 S3 存储桶策略
下面的代码段演示了一个 S3 存储桶策略,它允许 CloudFront 将内容读取到私有存储桶,并允许 IVS 将内容写入存储桶。注意:请勿将以下代码段复制并粘贴到自己的存储桶中。您的策略应包含与您的 CloudFront 分配和 StorageConfiguration 相关的 ID。
{ "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" } } } ] }
故障排除
-
合成不会写入 S3 存储桶 — 确保 S3 存储桶和 StorageConfiguration 对象在同一个区域中创建。还要检查您的存储桶策略以确保 IVS 可以访问该存储桶;请参阅 StorageConfiguration 的存储桶策略。
-
执行 ListCompositions 时找不到合成 — 合成是短暂性资源。一旦它们转换到最终状态,将会在几分钟后自动删除。
-
我的合成自动停止 — 如果舞台上没有发布者超过 60 秒,合成将自动停止。
已知问题
由合成录制创建的媒体播放列表在合成正在进行时带有 #EXT-X-PLAYLIST-TYPE:EVENT
标签。合成完成后,标签更新为 #EXT-X-PLAYLIST-TYPE:VOD
。为了获得流畅的播放体验,我们建议您仅在成功完成合成后使用此播放列表。