1. 简介
内容分发网络 (CDN) 通过以下方式提高用户性能:将经常访问的内容缓存到更靠近最终用户的位置、在更靠近客户端的位置终止连接、重复使用与源站的连接,以及采用现代网络协议和自定义设置。对于用户(以及我们的客户)而言,这意味着延迟时间更短、可靠性更高、成本更低,从而有助于提高销售额、改善 Web 体验,并从整体上提升用户体验。如今,很少有现代网站和视频流平台不使用 CDN。
学习内容
本实验将引导我们完成以下步骤:部署一个包含 Media CDN (CDN) + Cloud Media Live Streaming API(实时视频转码)+ Cloud Storage(视频存储)+ 视频播放器(VLC、Google Shaka Player 等 - 支持 HLS + MPEG-DASH 的播放器)的直播工作流环境。
我们将设置直播 API 组件(输入源、频道),并使用 FFmpeg(FFmpeg 可以生成实时测试信号)启动输入源/频道的直播。Live Streaming API 会对实时 Feed 进行转码。转码后的视频清单和分段将存储在 Cloud Storage 存储分区中。然后,我们将设置媒体 CDN,并将实时视频 Cloud Storage 存储分区作为源。最后,VLC 播放器将用于播放通过 Media CDN 缓存的直播内容。我们还将设置一个 Cloud Monitoring 信息中心,以直观呈现 Media CDN 的活动。
构建内容
在本实验中,我们将根据以下架构设置环境:

在本实验中,我们将设置以下组件并执行以下任务:
- 创建一个 Google Cloud Storage (GCS) 存储分区,用于存储实时转码的视频
- 配置 Live Streaming API 以将视频转码为多种格式:HLS + MPEG DASH、SD 和 HD
- 设置直播组件:输入源/频道
- 启动 Live Stream 频道
- 将 GCS 存储分区设置为源站,设置 Media CDN
- 设置 FFmpeg 以提供直播频道内容
- 使用视频播放器播放转码后的直播源
- 设置 Cloud Monitoring 信息中心以监控 Media CDN 活动(延迟时间、缓存命中、缓存未命中等)
注意:在本实验中,我们假设用户可以访问 Google Cloud 控制台,并且已设置项目。我们还假设用户从全新环境开始,并且没有为此演示设置任何内容。
所有配置操作都将通过 Cloud Shell 中的命令行完成。我们始终可以在控制台中查看通过命令行配置的组件。在整个实验过程中,您会看到指向 Google Cloud 控制台的指针。
2. 准备工作
媒体 CDN 访问权限受限。如需获取媒体 CDN 访问权限,请与您的客户支持团队联系。他们可以代表您创建访问权限申请。如果您是 Google 员工,并且想测试媒体 CDN 的直播功能,请与媒体 CDN 的产品经理联系,申请访问媒体 CDN。
3. 设置和要求
启动 Cloud Shell
虽然可以通过笔记本电脑对 Google Cloud 进行远程操作,但在此 Codelab 中,您将使用 Google Cloud Shell,这是一个在云端运行的命令行环境。
在 Google Cloud 控制台 中,点击右上角工具栏中的 Cloud Shell 图标:

预配和连接到环境应该只需要片刻时间。完成后,您应该会看到如下内容:

这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 5 GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证功能。您在此 Codelab 中的所有工作都可以在浏览器中完成。您无需安装任何程序。
4. Google Cloud SDK 版本
在撰写本文时,408.0.0 是最新的 Google Cloud SDK 版本。本实验中的所有命令均已使用最新版本的 Google Cloud SDK 进行测试。在继续操作之前,请确保 Cloud Shell 使用的是最新版本的 SDK。
检查 SDK 版本
我们将使用 gcloud version 命令来检查 SDK 版本。
命令
gcloud version | grep "Google Cloud SDK"
输出示例
Google Cloud SDK 408.0.0
后续步骤
- 如果 SDK 版本为
408.0.0或更高版本,请跳到下一部分。 - 如果 SDK 版本低于
408.0.0,请运行下列命令来更新 SDK。
sudo apt-get update && sudo apt-get install google-cloud-sdk
5. 前提条件
在开始配置 GCP 资源之前,我们需要执行以下操作:
- 设置环境变量
- 启用必需的服务 API
1. 设置环境变量
在本实验中,我们将运行带有几个变量的 gcloud 和 curl 命令。我们需要配置以下环境变量。
- 项目 ID
- 项目编号
- 用户名
- 区域
- 输入 ID
- 频道 ID
项目 ID 和用户名
这些环境变量通常在 Cloudshell 中预先配置。我们将使用 env 命令进行验证。
命令
env | grep -E 'DEVSHELL_PROJECT_ID=|LOGNAME'
输出示例
DEVSHELL_PROJECT_ID=<YOUR_PROJECT_ID> LOGNAME=<YOUR_USERNAME>
创建 env_variables 文件
使用 cat 命令创建 env_variables.txt 文件。以下命令将在用户的主目录中创建文件 env_variables.txt。
命令
cat > ~/env_variables.txt << EOF export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)") export LOCATION=us-west2 export INPUT_ID=lab-live-input export CHANNEL_ID=lab-live-channel EOF
设置环境变量
我们将使用 source 命令设置环境变量
命令
source ~/env_variables.txt
验证变量是否已设置
我们来验证一下是否已设置所有必需的环境变量。我们应该会在输出中看到总共 6 个环境变量。
命令
env | grep -E 'DEVSHELL_PROJECT_ID=|LOGNAME|PROJECT_NUMBER|LOCATION|INPUT_ID|CHANNEL_ID'
输出示例
LOCATION=us-west2 DEVSHELL_PROJECT_ID=<YOUR_PROJECT_ID> LOGNAME=<YOUR_USERNAME> PROJECT_NUMBER=<YOUR_PROJECT_NUMBER> INPUT_ID=lab-live-input CHANNEL_ID=lab-live-channel
2. 启用必需的服务 API
我们需要确保在项目中启用以下 API。
- Network Services API
- Certificate Manager API
- Livestream API
- 媒体 CDN 边缘缓存 API
启用 Network Services API
如需启用 Network Services API,请运行以下命令:
命令
gcloud services enable networkservices.googleapis.com
启用 Certificate Manager API
如需启用 Certificate Manager API,请运行以下命令:
命令
gcloud services enable certificatemanager.googleapis.com
启用 Live Stream API
如需启用 Live Stream API,请运行以下命令:
命令
gcloud services enable livestream.googleapis.com
启用 Media CDN 边缘缓存 API
如需启用 Media CDN Edge Cache API,请运行以下命令:
命令
gcloud services enable edgecache.googleapis.com
验证 API 是否已启用
运行 gcloud services list 命令以列出所有已启用的 API。我们应该会在输出中看到 4 个 API。
命令
gcloud services list | grep -E 'networkservices|certificatemanager|livestream|edgecache'
输出示例
NAME: certificatemanager.googleapis.com NAME: livestream.googleapis.com NAME: networkservices.googleapis.com NAME: edgecache.googleapis.com
6. 创建 Cloud Storage 存储分区
在本部分中,我们将执行以下操作:
- 创建 Cloud Storage 存储桶
- 将存储分区设为可公开访问
在本实验的后面部分,我们将使用此存储分区来存储转码后的视频文件。此存储分区还将用作媒体 CDN 服务的源存储空间。
1. 创建存储桶
我们将使用 gsutil mb 命令创建存储分区:
命令
gsutil mb gs://live-streaming-storage-$LOGNAME
2. 将存储分区设为可公开访问
我们将使用 gsutil iam 命令公开文件:
命令
gsutil iam ch allUsers:objectViewer gs://live-streaming-storage-$LOGNAME
7. 设置 Live Streaming API 环境
Live Streaming API 链的组件架构如下:

我们在上一部分中创建了 Cloud Storage 存储分区 live-streaming-storage-$LOGNAME。在接下来的两个部分中,我们将创建以下资源:
- 直播输入:输入端点是指编码器向其发送输入直播的端点。您可以使用输入端点为直播指定配置,例如输入分辨率、输入类型和视频裁剪。
- 直播频道:频道是一种资源,可通过输入端点提取输入流,将输入流转码为多种转码版本,并以特定格式在指定位置发布输出直播流。您可以在同一频道中包含主输入源和备用输入源。
我们将在稍后的实验中创建以下资源:
- 编码器:编码器是一种用于发送输入流的程序。在本实验中,我们将使用 FFmpeg。
8. 创建和配置输入端点
创建 input.json 文件
我们将创建一个 input.json 文件来指定直播信号类型。在本实验中,我们将使用 RTMP 直播信号。
命令
cat > input.json << EOF
{
"type": "RTMP_PUSH"
}
EOF
创建输入端点
截至撰写本实验时,gcloud 尚不支持 Live Stream API。我们将使用 curl 命令进行 API 调用。
命令
curl -X POST \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ -H "Content-Type: application/json; charset=utf-8" \ -d @input.json \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/inputs?inputId=$INPUT_ID"
输出示例
{
"name": "projects/PROJECT_NUMBER/locations/us-west2/operations/operation-1661405972853-5e70a38d6f27f-79100d00-310671b4",
"metadata": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
"createTime": "2022-08-25T05:39:32.884030164Z",
"target": "projects/PROJECT_NUMBER/locations/us-west2/inputs/lab-live-input",
"verb": "create",
"requestedCancellation": false,
"apiVersion": "v1"
},
"done": false
}
输出中包含许多实用信息,但目前我们需要重点关注两个字段:
- 操作 ID:从输出中复制并记下操作 ID。以下是输出示例中的操作 ID。您可以在以
"name"开头的输出行中找到此值。"operation-1661405972853-5e70a38d6f27f-79100d00-310671b4" - 状态:我们需要等待状态从
"done": false变为"done": true
检查状态
在继续操作之前,我们需要检查输入端点是否已成功创建并处于就绪状态。
在下面的命令中,将 <OPERATION> 替换为我们刚刚获取的操作的 ID。在此示例中,该网址为 "operation-1661405972853-5e70a38d6f27f-79100d00-310671b4"。
命令
export OPERATION_ID_1=<OPERATION>
命令
curl -X GET \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/operations/$OPERATION_ID_1"
输出示例
{
"name": "projects/PROJECT_NUMBER/locations/us-west2/operations/operation-1661408816982-5e70ae25cea49-617844f0-8fdcb4a1",
"metadata": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
"createTime": "2022-08-25T06:26:57.001530499Z",
"endTime": "2022-08-25T06:26:57.043623522Z",
"target": "projects/PROJECT_NUMBER/locations/us-west2/inputs/lab-live-input",
"verb": "create",
"requestedCancellation": false,
"apiVersion": "v1"
},
"done": true,
"response": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.Input",
"name": "projects/PROJECT_ID/locations/us-west2/inputs/lab-live-input",
"createTime": "2022-08-25T06:26:56.997623672Z",
"updateTime": "2022-08-25T06:26:56.997623672Z",
"type": "RTMP_PUSH",
"uri": "rtmp://34.94.97.220/live/4b7846a1-4a67-44ed-bfd0-d98281b6464a",
"tier": "HD"
}
}
重新运行该命令,直到看到 "done:true",表明输入端点已创建并准备就绪。
保存 URI
在稍后的实验中,我们将使用上一个输出中的 URI。现在,我们为 URI 设置一个环境变量。
命令
export URI=<uri>
将 <uri> 替换为您刚刚在上面记下的 URI。(可选)您还可以使用 GET 方法检索 URI
命令
curl -s -X GET -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/inputs/$INPUT_ID" | jq .uri
9. 创建和配置直播频道
我们来创建直播频道,该频道与我们在上一部分中刚刚创建的输入端点相关联。以下示例创建了一个频道,该频道生成包含单个高清 (1280x720) 转码的 HLS 直播视频流。频道将与输入端点以及我们之前创建的存储分区相关联。
创建 channel.json 文件
在 Cloud Shell 终端中,输入以下命令以创建 "channel.json" 文件:
命令
cat > channel.json << EOF
{
"inputAttachments": [
{
"key": "my-input",
"input": "projects/$PROJECT_NUMBER/locations/$LOCATION/inputs/$INPUT_ID"
}
],
"output": {
"uri": "gs://live-streaming-storage-$LOGNAME"
},
"elementaryStreams": [
{
"key": "es_video",
"videoStream": {
"h264": {
"profile": "high",
"widthPixels": 1280,
"heightPixels": 720,
"bitrateBps": 3000000,
"frameRate": 30
}
}
},
{
"key": "es_audio",
"audioStream": {
"codec": "aac",
"channelCount": 2,
"bitrateBps": 160000
}
}
],
"muxStreams": [
{
"key": "mux_video_ts",
"container": "ts",
"elementaryStreams": ["es_video", "es_audio"],
"segmentSettings": { "segmentDuration": "2s" }
}
],
"manifests": [
{
"fileName": "main.m3u8",
"type": "HLS",
"muxStreams": [
"mux_video_ts"
],
"maxSegmentCount": 5
}
]
}
EOF
创建频道
运行以下 curl 命令以创建渠道:
命令
curl -X POST \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ -H "Content-Type: application/json; charset=utf-8" \ -d @channel.json \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels?channelId=$CHANNEL_ID"
输出示例
{
"name": "projects/PROJECT_NUMBER/locations/us-west2/operations/operation-1661405972853-5e70a38d6f27f-79100d00-310671b4",
"metadata": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
"createTime": "2022-08-25T05:39:32.884030164Z",
"target": "projects/PROJECT_NUMBER/locations/us-west2/channels/lab-live-channel",
"verb": "create",
"requestedCancellation": false,
"apiVersion": "v1"
},
"done": false
}
记下并复制操作 ID。我们将在后续步骤中用到它。您可以在以 "name" 开头的输出行中找到此值。
检查状态
在继续之前,我们需要检查频道是否已成功创建并准备就绪。
在下面的命令中,将 <OPERATION> 替换为我们刚刚获取的操作的 ID。在此示例中,该网址为 operation-1661405972853-5e70a38d6f27f-79100d00-310671b4
命令
export OPERATION_ID_2=<OPERATION>
命令
curl -s -X GET \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/operations/$OPERATION_ID_2"
输出示例
"name": "projects/PROJECT_NUMBER/locations/us-west2/operations/operation-1668666801461-5eda4c3f31852-a4d2229f-0efeef9e",
"metadata": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
"createTime": "2022-11-17T06:33:21.500841488Z",
"endTime": "2022-11-17T06:33:21.529311112Z",
"target": "projects/PROJECT_NUMBER/locations/us-west2/channels/lab-live-channel",
"verb": "create",
"requestedCancellation": false,
"apiVersion": "v1"
},
"done": true,
"response": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.Channel",
"name": "projects/PROJECT_NAME/locations/us-west2/channels/lab-live-channel",
"createTime": "2022-11-17T06:33:21.497818033Z",
"updateTime": "2022-11-17T06:33:21.497818033Z",
"activeInput": "my-input",
"output": {
"uri": "gs://live-streaming-storage-LOGNAME"
},
"elementaryStreams": [
{
"videoStream": {
"h264": {
"widthPixels": 1280,
"heightPixels": 720,
"frameRate": 30,
"bitrateBps": 3000000,
"gopDuration": "2s",
"vbvSizeBits": 3000000,
"vbvFullnessBits": 2700000,
"entropyCoder": "cabac",
"profile": "high"
}
},
"key": "es_video"
},
{
"audioStream": {
"codec": "aac",
"bitrateBps": 160000,
"channelCount": 2,
"sampleRateHertz": 48000
},
"key": "es_audio"
}
],
"muxStreams": [
{
"key": "mux_video_ts",
"container": "ts",
"elementaryStreams": [
"es_video",
"es_audio"
],
"segmentSettings": {
"segmentDuration": "2s"
}
}
],
"manifests": [
{
"fileName": "main.m3u8",
"type": "HLS",
"muxStreams": [
"mux_video_ts"
],
"maxSegmentCount": 5,
"segmentKeepDuration": "60s"
}
],
"streamingState": "STOPPED",
"inputAttachments": [
{
"key": "my-input",
"input": "projects/PROJECT_NUMBER/locations/us-west2/inputs/lab-live-input"
}
],
"logConfig": {
"logSeverity": "OFF"
}
}
}
重新运行该命令,直到看到 "done:true",表明输入端点已创建并准备就绪。
请注意,此时的 "streamingState" 为 "STOPPED";我们将在下一部分中启动渠道。
10. 启动直播频道
现在,我们已经创建了直播频道,接下来开始启动频道。在本部分中,我们将执行以下操作:
- 启动直播频道
- 检查频道的状态,确保
streamingState为"AWAITING INPUT"
1. 创建频道
在 Cloud Shell 中,运行以下 curl 命令来启动频道:
命令
curl -X POST \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ -H "Content-Type: application/json; charset=utf-8" \ -d "" \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels/$CHANNEL_ID:start"
输出示例
{
"name": "projects/PROJECT_NUMBER/locations/LOCATION/operations/operation-1661405972853-5e70a38d6f27f-79100d00-310671b4",
"metadata": {
"@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata",
"createTime": "2022-08-25T05:39:32.884030164Z",
"target": "projects/PROJECT_NUMBER/locations/us-west2/channels/lab-live-channel",
"verb": "start",
"requestedCancellation": false,
"apiVersion": "v1"
},
"done": false
}
2. 查看频道状态
运行以下 curl 命令可获取频道的状态:
命令
curl -s -X GET -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels/$CHANNEL_ID" | grep "streamingState"
输出示例
"streamingState": "AWAITING_INPUT",
重新运行该命令,直到看到“AWAITING_INPUT”,表明渠道正在运行并已准备好接收信号。
11. 配置媒体 CDN
在本部分中,我们将部署 Media CDN(CDN 基础架构)。我们将创建以下资源:
- 边缘缓存来源
- 边缘缓存服务
1. 创建边缘缓存来源
边缘缓存来源表示内容位置,例如 Cloud Storage 存储分区、第三方存储位置或负载平衡器。在 CDN 术语中,源(或源服务器)是指我们要分发的内容的来源所在的位置,例如所有 CSS、JavaScript、HTML、图片等。在本实验中,我们将创建一个映射到我们在实验开始时创建的 Cloud Storage 存储分区的源。我们将边缘缓存来源称为 cme-origin。CDN 的源是指所有源内容在分发到边缘缓存服务器之前存储的位置。
我们将使用 gcloud edge-cache origins create 命令创建来源。此命令需要几分钟才能完成。
命令
gcloud edge-cache origins create cme-origin \ --origin-address="gs://live-streaming-storage-$LOGNAME"
输出示例
Create request issued for: cme-origin Waiting for operation [projects/my-project/locations/global/operations/operation-1612121774168-5ba3759af1919- 3fdcd7b1-99f59223] to complete...done Created origin cme-origin
2. 创建边缘缓存服务
现在,我们已设置边缘缓存来源,接下来可以创建边缘缓存服务本身。
创建 cme-demo.yaml 文件
边缘缓存服务配置通过 YAML 文件完成。在 Cloud Shell 中,创建一个名为 cme-demo.yaml 的本地文件。使用 vi、nano 或任何其他编辑器,并将以下行粘贴到 YAML 文件中:
name: cme-demo
routing:
hostRules:
- hosts:
- demo.cme.com
pathMatcher: routes
pathMatchers:
- name: routes
routeRules:
- headerAction:
responseHeadersToAdd:
- headerName: x-cache-status
headerValue: "{cdn_cache_status}"
matchRules:
- prefixMatch: /
origin: cme-origin
priority: 100
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 3600s
signedRequestMode: DISABLED
- headerAction:
responseHeadersToAdd:
- headerName: x-cache-status
headerValue: "{cdn_cache_status}"
matchRules:
- pathTemplateMatch: /**.m3u8
origin: cme-origin
priority: 25
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 1s
signedRequestMode: DISABLED
- headerAction: {}
matchRules:
- pathTemplateMatch: /**.ts
origin: cme-origin
priority: 50
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 2s
signedRequestMode: DISABLED
我们将保留所有边缘缓存服务配置默认设置。在上述文件中,用户可能需要更新 3 个字段值:
name:媒体 CDN 实例的名称 - 此处为:cme-demohosts:将由此 Media CDN 服务解析的域名列表 - 在此示例中为demo.cme.com。我们将在本次演示中使用此功能。我们将使用媒体 CDN 实例的 IP 地址。Origin:这是我们在上一步中刚刚创建的边缘缓存来源。将其设置为cme-origin- 媒体 CDN 来源的名称。
如需详细了解可在 YAML 文件中使用的不同变量,请参阅 Edge Cache Service 配置指南。
创建边缘缓存服务
我们将在边缘缓存来源 cme-origin 上创建名为 cme-demo 的边缘缓存服务,并使用主机 demo.cme.com。如需创建服务,请在 Cloud Shell 中运行以下命令:
命令
gcloud edge-cache services import cme-demo \
--source=cme-demo.yaml
创建 Edge Cache 服务可能需要几分钟时间。
输出示例
Request issued for: [cme-demo]
Waiting for operation [projects/PROJECT_ID/locations/global/operations/operation-1670476252264-5ef4a0f9f36ce-dd380af5-321be9a0] to complete...done.
createTime: '2022-12-07T18:08:54.403446942Z'
ipv4Addresses:
- 34.104.35.152
ipv6Addresses:
- '2600:1900:4110:d18::'
name: projects/PROJECT_ID/locations/global/edgeCacheServices/cme-demo
routing:
hostRules:
- hosts:
- demo.cme.com
- 34.104.35.152
pathMatcher: routes
pathMatchers:
- name: routes
routeRules:
- headerAction:
responseHeadersToAdd:
- headerName: x-cache-status
headerValue: '{cdn_cache_status}'
matchRules:
- prefixMatch: /
origin: projects/123456789/locations/global/edgeCacheOrigins/cme-origin
priority: '100'
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 3600s
signedRequestMode: DISABLED
- headerAction:
responseHeadersToAdd:
- headerName: x-cache-status
headerValue: '{cdn_cache_status}'
matchRules:
- pathTemplateMatch: /**.m3u8
origin: projects/123456789/locations/global/edgeCacheOrigins/cme-origin
priority: '25'
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 1s
signedRequestMode: DISABLED
- headerAction: {}
matchRules:
- pathTemplateMatch: /**.ts
origin: projects/123456789/locations/global/edgeCacheOrigins/cme-origin
priority: '50'
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 2s
signedRequestMode: DISABLED
updateTime: '2022-12-08T05:11:31.598744308Z'
记下并复制边缘缓存服务实例的 ipv4Addresses - 此处为 34.104.36.157。我们将使用它来更新 cme-demo.yaml 文件,并稍后用于流式传输转码后的视频。
更新边缘缓存服务
此时,最好更新边缘缓存服务配置,以便能够使用服务的 IP 地址在稍后播放视频。借助边缘缓存服务 YAML 文件,我们可以列出边缘缓存服务将接受请求的所有主机名/IP。此时,我们仅将 demo.cme.com 指定为主机。如需为此网域提供域名解析,您可以配置 DNS 区域。不过,更简单的解决方案是将 IP 地址添加到 yaml 文件中的主机列表。再次修改 YAML 文件,使其如下所示:
name: cme-demo
routing:
hostRules:
- hosts:
- demo.cme.com
- IPADDRESS
pathMatcher: routes
pathMatchers:
- name: routes
routeRules:
- headerAction:
responseHeadersToAdd:
- headerName: x-cache-status
headerValue: "{cdn_cache_status}"
matchRules:
- prefixMatch: /
origin: cme-origin
priority: 100
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 3600s
signedRequestMode: DISABLED
- headerAction:
responseHeadersToAdd:
- headerName: x-cache-status
headerValue: "{cdn_cache_status}"
matchRules:
- pathTemplateMatch: /**.m3u8
origin: cme-origin
priority: 25
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 1s
signedRequestMode: DISABLED
- headerAction: {}
matchRules:
- pathTemplateMatch: /**.ts
origin: cme-origin
priority: 50
routeAction:
cdnPolicy:
cacheKeyPolicy: {}
cacheMode: FORCE_CACHE_ALL
defaultTtl: 2s
signedRequestMode: DISABLED
为了反映这些更改,我们只需重新导入 YAML 文件。在 Cloud Shell 终端中,运行以下命令:
命令
gcloud edge-cache services import cme-demo \
--source=cme-demo.yaml
检查命令的输出,并验证该 IP 是否显示在主机列表中。
此时,Edge Cache 服务实例将接受以 "demo.cme.com" 或 IP 地址作为主机的请求。
12. 生成输入信号
现在,我们已配置所有必需的服务,接下来生成直播输入信号。在本部分中,我们将执行以下操作:
- 安装免费的开源软件 FFmpeg
- 向输入源/频道发送测试直播信号
1. 安装 FFmpeg
FFmpeg 是一个免费的开源软件项目,包含一套用于处理视频、音频和其他多媒体文件及流的库和程序。在 Cloud Shell 终端中,使用以下命令安装 FFmpeg:
命令
sudo apt install ffmpeg -y
安装完成后,我们来检查 FFmpeg 的版本,以验证其是否已正确安装:
命令
ffmpeg -version
输出示例
ffmpeg version 4.3.4-0+deb11u1 Copyright (c) 2000-2021 the FFmpeg developers built with gcc 10 (Debian 10.2.1-6) ...
FFmpeg 已正确安装。
2. 启动输入源/频道的直播信号
现在,FFmpeg 已安装完毕,我们将向输入端点发送测试输入流,以生成直播。
在 Cloud Shell 终端中运行以下命令,使用我们在“创建和配置输入端点”部分中创建的 URI 环境变量。
命令
ffmpeg -re -f lavfi -i "testsrc=size=1280x720 [out0]; sine=frequency=500 [out1]" \ -acodec aac -vcodec h264 -f flv $URI
您应该会看到 FFmpeg 发送测试直播信号。该命令不会返回提示。信号将一直生成,直至您停止为止。在完成本实验的剩余部分时,您需要打开一个新的 Cloud Shell 窗口。
13. 打开新的 Cloud Shell
此时,您需要打开一个新的 Cloud Shell 窗口才能继续本实验,因为 FFmpeg 将一直运行,直到您按 <CTRL+C> 停止该命令,从而停止实时信号生成。
点击当前 Cloud Shell 终端名称旁边的“+”号。系统会打开一个额外的 Cloud Shell 窗口。

在新打开的 Cloud Shell 窗口中完成实验的其余部分。
设置环境变量
由于这是新的 Cloud Shell,我们需要再次设置环境变量。我们将使用 source 命令设置环境变量。
命令
source ~/env_variables.txt
验证变量是否已设置
我们来验证一下是否已设置所有必需的环境变量。我们应该会在输出中看到总共 6 个环境变量。
命令
env | grep -E 'DEVSHELL_PROJECT_ID=|LOGNAME|PROJECT_NUMBER|LOCATION|INPUT_ID|CHANNEL_ID'
输出示例
LOCATION=us-west2 DEVSHELL_PROJECT_ID=<YOUR_PROJECT_ID> LOGNAME=<YOUR_USERNAME> PROJECT_NUMBER=<YOUR_PROJECT_NUMBER> INPUT_ID=lab-live-input CHANNEL_ID=lab-live-channel
14. 验证直播信号是否正在转码
我们将运行 curl 来描述频道。我们应该会在输出中看到 streamingState 从 "AWAITING_INPUT" 更改为 "STREAMING"
命令
curl -s -X GET -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels/$CHANNEL_ID" | grep "streamingState"
在输出 JSON 文件响应中,您应该会看到 "streamingState": "STREAMING",这表示频道正在直播,并且直播信号正在转码。
我们还要验证相应存储分区的内容,其中应包含清单文件和多个 TS 视频片段。在 Cloud Shell 中运行以下命令,列出我们在实验开始时创建的存储分区的内容,该存储分区由 Live Streaming API 用于输出转码后的直播信号清单和 TS 视频片段:
命令
gcloud storage ls --recursive gs://live-streaming-storage-$LOGNAME/**
输出示例
gs://live-streaming-storage-$LOGNAME/ gs://live-streaming-storage-$LOGNAME/main.m3u8 gs://live-streaming-storage-$LOGNAME/mux_video_ts/index-1.m3u8 gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000016.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000017.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000018.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000019.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000020.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000021.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000022.ts ...
您应该会看到:
- HLS 清单文件:
main.m3u8 - 相应的 TS 视频片段:一系列编号的文件
segment-000000000X.ts
至此,我们已完成以下操作:
- Live Streaming API:通过 Live Streaming API 生成直播信号并将其转码到存储分区中
- 媒体 CDN:已配置媒体 CDN,并将直播存储分区作为媒体 CDN 的来源。
在接下来的部分中,我们将验证 Edge Cache 服务,然后使用 Media CDN 任播 IP 地址来流式传输转码后的视频。
15. 验证边缘缓存服务实例是否正常运行
在本部分中,我们将验证 Edge Cache Service 实例是否按预期运行。为此,我们将尝试使用边缘缓存服务实例的 IP 地址访问该实例中的文件。首次访问对象时,该对象尚未缓存。我们应该观察到缓存 MISS。对于第一个请求,系统会从源读取对象并将其缓存在边缘。以下所有访问同一文件的尝试都将返回缓存 HIT,因为该对象现在已缓存在边缘。我们来验证一下此行为:
在 Cloud Shell 中运行以下 curl 命令,以访问存储在边缘缓存来源中的转码视频清单文件:
命令
curl -svo /dev/null --resolve demo.cme.com:80:<Replace_With_Edge_Cache_IP> \ "http://demo.cme.com/main.m3u8"
请注意,在解析过程中,我们使用边缘缓存服务实例的 IP 地址来解析其名称。请确保您使用 demo.cme.com:<IP>,其中 IP 是我们刚刚创建的边缘缓存服务实例的 IP。
在输出中查找 x-cache-status 标题。
输出示例
Added demo.cme.com:80:34.104.35.152 to DNS cache
* Hostname demo.cme.com was found in DNS cache
* Trying 34.104.35.152:80...
* Connected to demo.cme.com (34.104.35.152) port 80 (#0)
> GET /main.m3u8 HTTP/1.1
> Host: demo.cme.com
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< x-guploader-uploadid: ADPycdtKtflWt4Kha5YxXNNRwO-Eu6fGSPs-T-XY4HJmNMo46VJyWlD4EAk-8a6SegxjWq3o1gTPqZbpkU_sjW__HPAdDw
< date: Wed, 07 Dec 2022 18:23:46 GMT
< last-modified: Wed, 07 Dec 2022 18:23:45 GMT
< etag: "6bff620ccca4a9849ba4e17fa7c521fb"
< x-goog-generation: 1670437425805400
< x-goog-metageneration: 1
< x-goog-stored-content-encoding: identity
< x-goog-stored-content-length: 193
< content-type: application/x-mpegURL
< x-goog-hash: crc32c=sPO3zw==
< x-goog-hash: md5=a/9iDMykqYSbpOF/p8Uh+w==
< x-goog-storage-class: STANDARD
< accept-ranges: bytes
< content-length: 193
< server: Google-Edge-Cache
< x-request-id: fd25285b-fc1a-4fd4-981a-c50ead2c85ed
< x-xss-protection: 0
< x-frame-options: SAMEORIGIN
< x-cache-status: den;miss
< cache-control: public,max-age=3600
<
{ [193 bytes data]
* Connection #0 to host demo.cme.com left intact
请注意,由于对象尚未缓存,因此会发生缓存未命中,并从源中读取对象。
现在,我们将多次请求 m3u8 文件,如果一切配置正确,Media CDN 应该会开始从其缓存中提供内容。以下命令将发出 10 个 curl 请求,并且仅打印 x-cache-status 标头。
命令
for i in {1..10};do curl -Is --resolve demo.cme.com:80:<Replace_With_Edge_Cache_IP> "http://demo.cme.com/main.m3u8" | grep x-cache-status;done
输出应为缓存 hit 和 miss 的混合。如果您在输出中看到缓存命中,则表示媒体 CDN 正在按预期运行。
输出示例
x-cache-status: den;miss x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit
请注意,由于对象现在已缓存在边缘,因此出现了缓存命中。Cloud Media Edge Service 运行正常。
16. 使用 VLC 流式传输转码后的直播信号视频
接下来,我们将把所有步骤串联起来,将我们目前为止所做的一切联系起来:
- 我们创建了一个名为
live-streaming-storage-$LOGNAME的存储分区,用于接收由 Live Streaming API 转码为 HLS 内容的直播信号的结果。 - 我们设置了 Live Streaming API。
- 我们使用 FFmpeg 启动了 RTMP 直播信号,该信号可馈送 Live Streaming API 输入/频道。
- 我们验证了直播信号已馈送到频道,并验证了频道处于
streaming模式。 - 我们验证了转码后的文件(清单 + TS 片段)已生成并存储在存储分区
live-streaming-storage-$LOGNAME中。 - 已设置一个名为
cme-origin的边缘缓存来源,并将 GCS 存储分区live-streaming-storage-$LOGNAME作为来源。 - 已设置一个名为
cme-demo的边缘缓存实例,其来源为cme-origin。 - 我们验证了边缘缓存服务实例的行为(缓存未命中、缓存命中)。
现在,我们可以使用视频播放器通过媒体 CDN 缓存来流式传输转码后的直播信号。为此,我们将使用 VLC 播放器。VLC 播放器是一款免费的开源跨平台多媒体播放器和框架,可播放大多数多媒体文件。它可播放自适应媒体格式(例如 DASH 和 HLS)。它采用自适应流式传输的原理,即根据网络连接质量和可用带宽,播放器会调整所播放视频的画质。在刚刚完成的转码作业中,我们使用了默认预设,并生成了两种质量的视频:标清和高清。当我们在播放器中开始播放视频时,您应该会看到视频以标清格式开始播放,如果网络连接足够好,则会快速切换到高清格式。
我们将直播经过转码的 HLS(广泛支持的 Apple 视频格式)直播信号。相应的文件称为 main.m3u8,即 HLS 清单。清单指向 TS 视频片段。
如需使用 VLC 播放器,请前往 https://www.videolan.org/vlc/,然后下载适用于笔记本电脑操作系统的播放器版本 - VLC 适用于 Windows、MacOSX、Linux、Android 和 iOS。

在笔记本电脑上安装播放器并启动它。在接下来的几个步骤中,我们将使用 MacOSX 版本的播放器。
如需播放视频,请依次前往“文件”/“打开网络”:

使用以下方式设置:
- 网址:http://<Replace_With_Edge_Cache_IP>/main.m3u8。这是我们想要直播的视频的网址。请注意:
- 媒体 CDN 实例的 IP:
34.105.35.246。替换为您部署的 Cloud Media Service 的 IP。 - 清单视频文件的路径:“
/”。这是我们在live-streaming-storage-$LOGNAME存储分区中用于存储转码后的直播信号文件的路径。此处的路径为根路径“/”。 - 清单视频文件的名称:HLS 清单文件
main.m3u8。
然后点击“打开”。您应该会看到转码后的实时视频开始播放。视频将如以下屏幕截图所示。屏幕上的计数器将以 1 为增量递增,您应该能够听到连续的蜂鸣声。
这是一个由 FFmpeg 生成的基本 RTMP 测试直播信号,由 Live Streaming API 转码为 HLS,并通过媒体 CDN 缓存提供:

如果您愿意,也可以使用任何其他 HLS 和 MPEG DASH 播放器。以下是一些您可能需要考虑的播放器:
- Quicktime 播放器 - 默认安装在 Mac 上。同样,打开与 http://34.104.36.157/main.m3u8
17. 监控媒体 CDN
中小企业团队创建了一个媒体 CDN 信息中心模板 - https://gist.github.com/elithrar/1c511d00f5cd3736fb2a3897867209c1。
如需安装该工具,请在 Cloud Shell 窗口中运行以下命令:
下载 YAML 文件:
curl https://gist.githubusercontent.com/elithrar/1c511d00f5cd3736fb2a3897867209c1/raw/3cb70855304f29e5c06b8d63063196354db0dec3/media-edge-20210208-dashboard --output media-edge-20210208-dashboard.yaml
为 Cloud Monitoring 创建信息中心:
gcloud monitoring dashboards create --config-from-file media-edge-20210208-dashboard.yaml
设置可能需要几分钟的时间。前往 Google Cloud 控制台,然后依次点击三条横线 > Operations > Monitoring > 信息中心。您应该会看到一个名为“Media Edge Metrics”的信息中心。点击该链接,您将看到以下指标:

18. 清理实验环境
恭喜您完成本实验。在本部分中,我们将删除在整个实验过程中创建的所有资源。
停止 FFmpeg 信号:
在运行 FFmpeg 的 Cloud Shell 终端中,按 <CTRL+C>。
停止直播频道:
命令
curl -X POST \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ -H "Content-Type: application/json; charset=utf-8" \ -d "" \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels/$CHANNEL_ID:stop"
删除直播频道:
命令
curl -X DELETE -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels/$CHANNEL_ID"
删除直播输入端点:
命令
curl -X DELETE \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/inputs/$INPUT_ID"
删除 GCS 存储分区:
命令
gsutil rm -r gs://live-streaming-storage-$LOGNAME
删除边缘缓存服务实例:
命令
gcloud edge-cache services delete cme-demo
出现提示时,输入“Y”以确认删除
删除边缘缓存来源:
命令
gcloud edge-cache origins delete cme-origin
出现提示时,输入“Y”以确认删除
删除自定义信息中心
命令
gcloud monitoring dashboards delete $(gcloud monitoring dashboards list --filter="displayName:Media Edge Metrics" --format="value(name)")