本页介绍了如何使用 Live Stream API 从直播中创建点播视频 (VOD) 剪辑。VOD 剪辑由从直播中保存的 HLS 清单文件和片段文件组成。仅支持 HLS 清单。
VOD 片段和 DVR 会话之间的区别
VOD 剪辑(也称为频道剪辑)与 DVR 会话类似,但存在以下主要区别:
- DVR 会话:
- 该 API 会将 DVR 清单保存在与直播片段相同的位置,因此无需额外复制到 Cloud Storage。DVR 清单与直播清单类似,但更长。保留期限到期后,清单会随分段文件一同删除。
- 您可以为过去、现在和未来的内容创建 DVR 会话。例如,DVR 会话可以跟随直播,您也可以安排 DVR 会话在未来某个时间开始和停止。
- DVR 会话的一个典型用例是为直播活动支持 DVR 功能。例如,观看者可以在直播开始一小时后加入直播,并以一小时的延迟时间观看内容(或跳过部分内容)。
- 频道剪辑:
- Live Stream API 会将剪辑清单和关联的片段文件复制到用户指定的目录,以便在保留期限结束时不被删除。您可以完全控制剪辑。
- 只能剪辑过往内容。不支持直播剪辑和安排未来的剪辑。
- 剪辑的一个典型用例是归档直播,使直播以 VOD 文件的形式无限期提供。
如需详细了解 DVR 会话,请参阅创建 DVR 会话。
设置 Google Cloud 项目和身份验证
如果您尚未创建 Google Cloud 项目和凭据,请参阅开始前须知。创建输入端点
如需创建输入端点,请使用 projects.locations.inputs.create 方法。
在使用任何请求数据之前,请先进行以下替换:
PROJECT_NUMBER:您的 Google Cloud 项目编号;此值位于 IAM 设置页面上的“项目编号”字段中LOCATION:用于创建输入端点的位置;请使用某个受支持的地区显示位置us-central1us-east1us-east4us-west1us-west2northamerica-northeast1southamerica-east1asia-east1asia-east2asia-south1asia-northeast1asia-southeast1australia-southeast1europe-north1europe-west1europe-west2europe-west3europe-west4
INPUT_ID:要创建的新输入端点(您将输入数据流发送到该端点)的用户定义标识符。此值必须为 1-63 个字符,以[a-z0-9]开头和结尾,并且字符之间可以包含短划线 (-)。例如my-input。
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
{
"name": "projects/PROJECT_NUMBER/locations/LOCATION/operations/OPERATION_ID",
"metadata": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
"createTime": CREATE_TIME,
"target": "projects/PROJECT_NUMBER/locations/LOCATION/inputs/INPUT_ID",
"verb": "create",
"requestedCancellation": false,
"apiVersion": "v1"
},
"done": false
}
此命令会创建一个长时间运行的操作 (LRO),您可以使用该操作来跟踪请求的进度。如需了解详情,请参阅管理长时间运行的操作 。
获取输入端点详情
如需获取输入端点的详细信息,请使用 projects.locations.inputs.get 方法。
在使用任何请求数据之前,请先进行以下替换:
PROJECT_NUMBER:您的 Google Cloud 项目编号;此值位于 IAM 设置页面上的“项目编号”字段中LOCATION:输入端点所在的位置;请使用某个受支持的地区显示位置us-central1us-east1us-east4us-west1us-west2northamerica-northeast1southamerica-east1asia-east1asia-east2asia-south1asia-northeast1asia-southeast1australia-southeast1europe-north1europe-west1europe-west2europe-west3europe-west4
INPUT_ID:输入端点的用户定义标识符
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
{
"name": "projects/PROJECT_NUMBER/locations/LOCATION/inputs/INPUT_ID",
"createTime": CREATE_TIME,
"updateTime": UPDATE_TIME,
"type": "RTMP_PUSH",
"uri": "INPUT_STREAM_URI", # For example, "rtmp://1.2.3.4/live/b8ebdd94-c8d9-4d88-a16e-b963c43a953b",
"tier": "HD"
}
找到 uri 字段,然后复制返回的 INPUT_STREAM_URI,以便稍后在发送输入流部分中使用。
创建频道
如需创建渠道,请使用 projects.locations.channels.create 方法。以下示例会创建一个用于生成 HLS 直播的频道。直播由单个高清 (1280x720) 版本组成。
如需启用 VOD 剪辑的创建,请将 retentionConfig 对象添加到频道配置中。
"retentionConfig": {
"retentionWindowDuration": {
"seconds": 86400
}
},
为直播频道启用保留功能后,系统会保留直播片段和清单,以便制作视频点播剪辑。retentionWindowDuration 对象用于指定直播输出在上传到 Cloud Storage 后保存的时长。保留期限从在 Cloud Storage 中创建数据段时开始。
保留期不得超过 30 天。保留期限过后,系统会自动从 Cloud Storage 中删除直播片段文件和清单文件。(VOD 剪辑清单及其关联的片段文件不会自动删除。)您无法使用已删除的片段创建 VOD 剪辑。删除过程是异步的,最长可能需要 24 小时才能完成。
为清单指定一个键,以启用 VOD 剪辑创建功能。您可以在实际创建剪辑时引用此键。仅支持 HLS 清单。
"manifests": [
{
...
"key": "manifest_hls"
}
在使用任何请求数据之前,请先进行以下替换:
PROJECT_NUMBER:您的 Google Cloud 项目编号;此值位于 IAM 设置页面上的“项目编号”字段中LOCATION:创建渠道的地理位置;请使用某个受支持的地区显示位置us-central1us-east1us-east4us-west1us-west2northamerica-northeast1southamerica-east1asia-east1asia-east2asia-south1asia-northeast1asia-southeast1australia-southeast1europe-north1europe-west1europe-west2europe-west3europe-west4
CHANNEL_ID:要创建的渠道的用户定义标识符;此值必须为 1-63 个字符,以[a-z0-9]开头和结尾,并且字符之间可以包含短划线 (-)INPUT_ID:输入端点的用户定义标识符BUCKET_NAME:您创建的用于存储直播清单和片段文件的 Cloud Storage 存储分区的名称
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
{
"name": "projects/PROJECT_NUMBER/locations/LOCATION/operations/OPERATION_ID",
"metadata": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
"createTime": CREATE_TIME,
"target": "projects/PROJECT_NUMBER/locations/LOCATION/channels/CHANNEL_ID",
"verb": "create",
"requestedCancellation": false,
"apiVersion": "v1"
},
"done": false
}
此命令会创建一个长时间运行的操作 (LRO),您可以使用该操作来跟踪请求的进度。如需了解详情,请参阅管理长时间运行的操作 。
启动频道
如需启动渠道,请使用 projects.locations.channels.start 方法。
在使用任何请求数据之前,请先进行以下替换:
PROJECT_NUMBER:您的 Google Cloud 项目编号;此值位于 IAM 设置页面上的“项目编号”字段中LOCATION:频道所在的位置;请使用某个受支持的地区显示位置us-central1us-east1us-east4us-west1us-west2northamerica-northeast1southamerica-east1asia-east1asia-east2asia-south1asia-northeast1asia-southeast1australia-southeast1europe-north1europe-west1europe-west2europe-west3europe-west4
CHANNEL_ID:用户定义的渠道标识符
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
{
"name": "projects/PROJECT_NUMBER/locations/LOCATION/operations/OPERATION_ID",
"metadata": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
"createTime": CREATE_TIME,
"target": "projects/PROJECT_NUMBER/locations/LOCATION/channels/CHANNEL_ID",
"verb": "start",
"requestedCancellation": false,
"apiVersion": "v1"
},
"done": false
}
此命令会创建一个长时间运行的操作 (LRO),您可以使用该操作来跟踪请求的进度。如需了解详情,请参阅管理长时间运行的操作 。
发送输入流
打开一个新终端窗口。使用获取输入端点详情部分中的 INPUT_STREAM_URI 运行以下命令:
ffmpeg -re -f lavfi -i "testsrc=size=1280x720 [out0]; sine=frequency=500 [out1]" \
-acodec aac -vcodec h264 -f flv INPUT_STREAM_URI
创建 VOD 剪辑
如需创建 VOD 剪辑,请使用 projects.locations.channels.clips.create 方法。
使用 outputUri 字段指定要将剪辑和剪辑清单文件保存在 Cloud Storage 中的具体位置。您可以使用为直播清单创建的存储分区,也可以使用其他存储分区。您还可以将目录名称附加到存储分区名称(例如 my-bucket/vod-clip)。
使用 clipManifests 数组中的 manifestKey 字段指定要从中保存剪辑的清单。在本页上的示例渠道配置中,此键设置为 manifest_hls。
使用 outputType 字段指定以下任一受支持的剪辑输出格式:MANIFEST(默认)或 MP4。在本页的示例频道配置中,此字段设置为 MANIFEST,这会生成与频道输出类似的 VOD 清单。
您可以通过向 slices 数组添加 timeSlice 对象,将直播中的多个时间段合并到一个剪辑中。
"outputUri": "gs://my-bucket",
"clipManifests":[
{
"manifestKey": "manifest_hls"
}
],
"slices":[
{
"timeSlice": {
"markinTime": "2022-07-08T23:03:20.000Z",
"markoutTime": "2022-07-08T23:04:20.000Z"
}
},
{
"timeSlice": {
"markinTime": "2022-07-08T23:05:20.000Z",
"markoutTime": "2022-07-08T23:06:20.000Z"
}
}
]
请注意以下几点:
- 每个剪辑都必须在
slices中包含至少一个timeSlice。 clipManifests.manifestKey字段必须引用剪辑父频道中定义的 HLS 清单。如果剪辑作业创建请求成功,则clipManifests.outputUri字段中会返回生成的剪辑清单的 URI。此 URI 位于剪辑的outputUri字段指定的路径中。clipManifests数组每个请求仅支持一个清单。如果您想为同一剪辑作业生成多个清单,则需要将清单拆分为多个剪辑作业请求。- 剪辑片段必须是同质的;每个元素都必须是
timeSlice类型。 - 一组
timeSlice对象不得重叠,且必须按时间顺序排列。每个timeSlice中的markinTime都必须早于markoutTime。 - 如果剪辑的最新
markinTime早于频道开始时间或留存期开始时间,则标记时间设置为这两个时间中的较晚者。 - 如果剪辑的最新
markoutTime晚于频道停止时间,则将其设置为频道停止时间。如果剪辑的最新markoutTime晚于当前系统壁挂时钟时间,则将其设置为 API 实际启动剪辑任务的时间。 - 对于
MANIFEST输出类型的剪辑,时长上限为 24 小时。对于MP4输出类型的剪辑,时长上限为 6 小时。
在使用任何请求数据之前,请先进行以下替换:
PROJECT_NUMBER:您的 Google Cloud 项目编号;此值位于 IAM 设置页面上的“项目编号”字段中LOCATION:频道所在的位置;请使用某个受支持的地区显示位置us-central1us-east1us-east4us-west1us-west2northamerica-northeast1southamerica-east1asia-east1asia-east2asia-south1asia-northeast1asia-southeast1australia-southeast1europe-north1europe-west1europe-west2europe-west3europe-west4
CHANNEL_ID:用户定义的渠道标识符CLIP_ID:视频点播剪辑的用户定义标识符MARK_IN_TIME:原始直播流清单中的标记时间(与 Unix 计时原点之间相隔的时间);使用 RFC3339 UTC“Zulu”格式的时间戳(例如2014-10-02T15:01:23Z)MARK_OUT_TIME:原始直播流清单中的标记时间戳(Unix 纪年时间戳);使用 RFC3339 UTC“Zulu”格式的时间戳(例如2014-10-02T15:01:23Z)BUCKET_NAME:您创建的用于存储 VOD 剪辑清单和片段文件的 Cloud Storage 存储分区的名称;您可以使用为直播清单创建的存储分区,也可以使用其他存储分区;您还可以将目录名称附加到存储分区名称(例如my-bucket/vod-clip)
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
{
"name": "projects/PROJECT_NUMBER/locations/LOCATION/operations/OPERATION_ID",
"metadata": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
"createTime": CREATE_TIME,
"target": "projects/PROJECT_NUMBER/locations/LOCATION/channels/CHANNEL_ID/clips/CLIP_ID",
"verb": "create",
"requestedCancellation": false,
"apiVersion": "v1"
},
"done": false
}
此命令会创建一个长时间运行的操作 (LRO),您可以使用该操作来跟踪请求的进度。如需了解详情,请参阅管理长时间运行的操作 。
获取 VOD 剪辑
如需获取 VOD 剪辑,请使用 projects.locations.channels.clips.get 方法。
在使用任何请求数据之前,请先进行以下替换:
PROJECT_NUMBER:您的 Google Cloud 项目编号;此值位于 IAM 设置页面上的“项目编号”字段中LOCATION:渠道所在的位置;请使用某个受支持的地区显示位置us-central1us-east1us-east4us-west1us-west2northamerica-northeast1southamerica-east1asia-east1asia-east2asia-south1asia-northeast1asia-southeast1australia-southeast1europe-north1europe-west1europe-west2europe-west3europe-west4
CHANNEL_ID:用户定义的渠道标识符CLIP_ID:视频点播剪辑的用户定义标识符
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
{
"name": "projects/PROJECT_NUMBER/locations/LOCATION/channels/CHANNEL_ID/clips/CLIP_ID",
"createTime": CREATE_TIME,
"startTime": START_TIME,
"updateTime": UPDATE_TIME,
"state": "SUCCEEDED",
"outputUri": "gs://BUCKET_NAME",
"slices": [
{
"timeSlice": {
"markinTime": "MARK_IN_TIME",
"markoutTime": "MARK_OUT_TIME"
}
}
],
"features": {},
"clipManifests": [
{
"manifestKey": "manifest_hls",
"outputUri": "gs://BUCKET_NAME/main.m3u8"
}
]
}
生成的清单位于 clipManifests.outputUri 字段中指定的 URI 中。清单文件名与父级渠道的 manifests.fileName 字段值相同。
响应应包含以下内容:
{
...
"state": "SUCCEEDED"
...
}
使用 projects.locations.channels.clips.get 方法时,每个频道只有最近的 1,000 条剪辑作业记录可用。系统会移除超出此上限的所有剪辑作业记录。您必须管理 outputUri 指定的生成的剪辑文件;Live Stream API 不会从 Cloud Storage 中删除这些文件。
验证存储分区内容
打开剪辑的 outputUri 字段中指定的 Cloud Storage 存储分区。验证该文件夹是否包含以下文件和目录:
- 剪辑的顶级清单,其名称与频道配置中指定的
manifests.fileName相同(例如main.m3u8);您可以使用在线媒体播放器播放此清单 - 渠道中指定的每个
muxStreams.key的目录(例如mux_video_ts)- 剪辑的播放列表(例如
index-1.m3u8) - 使用
YYYYMMDDTHHMMSSZ格式(例如20220708T203309Z/)命名的目录;此目录用于存储 VOD 剪辑片段- 构成 VOD 剪辑的多个片段
segment-number.ts文件
- 构成 VOD 剪辑的多个片段
- 剪辑的播放列表(例如
播放 VOD 片段
如需在 Shaka Player 中播放生成的媒体文件,请完成以下步骤:
- 请将 Cloud Storage 存储分区设为可公开读取。
- 如需在 Cloud Storage 存储分区上启用跨域资源共享 (CORS),请执行以下操作:
- 创建一个包含以下代码的 JSON 文件:
[ { "origin": ["https://shaka-player-demo.appspot.com/"], "responseHeader": ["Content-Type", "Range"], "method": ["GET", "HEAD"], "maxAgeSeconds": 3600 } ] -
将
JSON_FILE_NAME替换为您在上一步中创建的 JSON 文件的名称,然后运行以下命令:gcloud storage buckets update gs://BUCKET_NAME --cors-file=JSON_FILE_NAME.json
- 创建一个包含以下代码的 JSON 文件:
- 在 Cloud Storage 存储分区中,找到生成的文件。在该文件的公开访问权限列中,点击复制网址。
- 导航到在线直播播放器 Shaka Player。
- 点击顶部导航栏中的自定义内容。
- 点击 + 按钮。
将文件的公开网址粘贴到清单网址框中。

在名称框中输入一个名称。
点击保存。
点击播放。
您应该会看到测试模式以直播形式播放。
广告插播时间点和广告信息板事件
如果您为直播创建了广告插播时间点,则 VOD 剪辑中不会包含广告。该 API 会生成一个播放列表,其中广告插播点会替换为以下代码:
#EXT-X-CUE-OUT: AD_BREAK_DURATION
#EXT-X-CUE-IN
VOD 剪辑开头或结尾显示的片头片尾字幕会自动移除。在直播中显示且被直播内容环绕的片头片尾信息会保留在生成的视频点播剪辑中。