透過 Media CDN 和 Live Streaming API,在 Google Cloud 上直播

1. 簡介

內容傳遞網路 (CDN) 運用多種方式,將經常存取的內容快取至較靠近使用者的位置、終止較靠近用戶端的連線、重複使用與來源之間的連線,以及採用新型網路通訊協定和自訂項目,藉此改善使用者效能。對使用者 (和我們的客戶) 來說,這代表延遲時間不但縮短、提升穩定性,還能降低成本,進而改善銷售量、網站體驗,並大幅提升使用者體驗。極少數的現代化網站和影片串流平台即使沒有 CDN 也能運作。

課程內容

本研究室將逐步引導您使用 Media CDN (CDN) + Cloud Media Live Streaming API (直播影片轉碼) + Cloud Storage (影片儲存空間) + 影片播放器 (VLC、Google Shaka Player 等 - HLS + MPEG-DASH 支援播放器) 部署直播工作流程環境。

我們會設定 Live Streaming API 元件 (輸入和頻道),並透過 FFmpeg 將即時動態饋給傳送給輸入來源/頻道 (FFmpeg 可以產生即時測試信號)。Live Streaming API 會將即時動態饋給轉碼。經過轉碼的影片資訊清單和片段會儲存在 Cloud Storage 值區中。接著,我們要設定 Media CDN,並以即時影片 Cloud Storage 值區做為來源。最後,VLC 播放器將用於播放透過 Media CDN 快取的直播內容。我們也會設定 Cloud Monitoring 資訊主頁,以視覺化方式呈現 Media CDN 的活動。

建構項目

在本研究室中,我們將依據下列架構設定環境:

de33cb3e75d52549.png

本研究室將設定以下元件,並執行下列工作:

  • 建立 Google Cloud Storage (GCS) 值區,用於儲存即時轉碼影片
  • 設定 Live Streaming API,將影片轉碼成多種格式:HLS + MPEG DASH、SD 和 HD
  • 設定直播元件:輸入/頻道
  • 開始直播頻道
  • 將 Media CDN 設為 GCS 值區做為來源
  • 設定 FFmpeg 將直播頻道傳送給 YouTube
  • 透過影片播放器串流播放經過轉碼的直播動態
  • 設定 Cloud Monitoring 資訊主頁,監控 Media CDN 活動 (延遲、快取命中、快取失敗等)

注意:在本研究室中,我們假設使用者可以存取 Google Cloud 控制台,而且已經設定好專案。同時,我們也假設使用者從全新環境著手,而該示範不需進行任何設定。

所有設定動作都會透過 Cloud Shell 中的指令列完成。我們隨時可以透過控制台中的指令列檢查設定的元件。我們在研究室中全程提供了指標,指向 Google Cloud 控制台。

2. 事前準備

Media CDN 存取權受到限制。如要取得 Media CDN 的存取權,請與帳戶團隊聯絡。他們可以代替您提出存取要求。如果你是 Google 旗下成員,並想透過 Media CDN 測試直播功能,請與 Media CDN 的合作夥伴經理聯絡,要求存取 Media CDN 的存取權。

3. 設定和需求

啟動 Cloud Shell

雖然 Google Cloud 可以從筆記型電腦遠端操作,但在本程式碼研究室中,您將使用 Google Cloud Shell,這是一種在 Cloud 中執行的指令列環境。

Google Cloud 控制台,按一下右上方的工具列上的 Cloud Shell 圖示:

55efc1aaa7a4d3ad.png

佈建並連線至環境的作業只需幾分鐘的時間。完成後,您應該會看到類似下方的內容:

7ffe5cbb04455448.png

這部虛擬機器都裝載了您需要的所有開發工具。提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作,大幅提高網路效能和驗證能力。本程式碼研究室的所有工作都可以在瀏覽器中完成。不必安裝任何程式。

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

後續步驟

  1. 如果 SDK 為 408.0.0 以上版本,請跳至下一部分。
  2. 如果 SDK 版本低於 408.0.0,請執行以下指令更新 SDK。
sudo apt-get update && sudo apt-get install google-cloud-sdk

5. 必要條件

開始設定 GCP 資源前,我們必須進行下列作業:

  1. 設定環境變數
  2. 啟用必要的服務 API

1. 設定環境變數

在這個研究室中,我們將使用幾個變數執行 gcloudcurl 指令。我們需要設定下列環境變數。

  • 專案 ID
  • 專案編號
  • 使用者名稱
  • 區域
  • 輸入 ID
  • 頻道 ID

專案 ID 與使用者名稱

這些環境變數通常已在 Cloud Shell 中預先設定。我們將使用 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
  • Media 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 Edge Cache 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 值區

在本節中,我們將執行下列作業:

  1. 建立 Cloud Storage 值區
  2. 將值區設為可公開存取

在研究室的後續部分,我們會使用這個值區儲存已轉碼的影片檔案。這個值區也會做為 Media 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 鏈的元件架構如下:

96b5d26aedeb89a6.png

我們在上一節建立了 Cloud Storage 值區 live-streaming-storage-$LOGNAME。在接下來的兩節中,我們將建立下列資源:

  • 直播輸入:輸入端點是編碼器將輸入串流傳送至端點的端點。您可以使用輸入端點指定串流設定,例如輸入解析度、輸入類型和影片裁剪。
  • 直播頻道:管道是一種資源,可透過輸入端點擷取輸入串流、將輸入串流轉碼為多個轉譯,以及以特定格式發布指定位置的輸出直播。您可以在同一個管道中加入主要和備份輸入串流。

本研究室的後續部分會建立下列資源:

  • 編碼器:編碼器是一種程式,用於傳送輸入串流。在本研究室中,我們將使用 FFmpeg。

8. 建立及設定輸入端點

建立 input.json 檔案

我們會建立 input.json 檔案,指定直播信號類型。在本研究室中,我們將使用 RTMP 即時訊號。

指令

cat > input.json << EOF
{
  "type": "RTMP_PUSH"
}
EOF

建立輸入端點

截至本文撰寫這個研究室為止,我們不針對 Live Stream API 提供 gcloud 支援。我們將使用 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) 顯示方式組成的 HTTP 即時串流直播。管道會與輸入端點和先前建立的 Cloud Storage 值區建立關聯。

建立 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. 啟動直播頻道

建立直播頻道後,我們開始建立頻道。在本節中,我們將執行下列作業:

  1. 開始直播頻道
  2. 請檢查頻道的狀態,我們需要確認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. 設定 Media CDN

在本節中,我們會部署 Media CDN ( CDN 基礎架構)。我們會建立下列資源:

  1. 邊緣快取來源
  2. 邊緣快取服務

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 的本機檔案。使用 vinano 或任何其他編輯器,然後在 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:Media CDN 執行個體名稱,此處為:cme-demo
  • hosts: 是要由此 Media CDN 服務解析的網域名稱清單:demo.cme.com。我們會在示範過程中使用此功能。我們會使用 Media CDN 執行個體的 IP 位址。
  • Origin: 這是我們在上一步中建立的邊緣快取來源。將其設為 cme-origin - Media CDN 來源名稱。

如要進一步瞭解您可以在 YAML 檔案中使用的不同變數,請參閱邊緣快取服務設定指南

建立邊緣快取服務

我們會在邊緣快取來源 cme-origin 上建立名為 cme-demo 的邊緣快取服務,其中包含 demo.cme.com 主機。如要建立服務,請在 Cloud Shell 中執行下列指令:

指令

gcloud edge-cache services import cme-demo \
    --source=cme-demo.yaml

建立邊緣快取服務可能需要幾分鐘的時間。

輸出內容範例

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 是否出現在主機清單中。

此時,邊緣快取服務執行個體將接受以 "demo.cme.com" 或 IP 位址做為主機的要求。

12. 產生輸入信號

設定所有必要服務後,接著要產生直播輸入信號。在本節中,我們將執行下列作業:

  1. 安裝免費的開放原始碼軟體 FFmpeg
  2. 將測試即時訊號傳送至輸入來源/管道

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 終端機中執行下列指令,請使用我們在「Create and 設定 Input Endpoint」一節中建立的 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 視窗。

b3c7b0be6276c194.png

請在新開啟的 Cloud Shell 視窗中,執行研究室的其餘部分。

設定環境變數

由於這是新的 CloudShell,我們必須重新設定環境變數。我們將使用 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 來描述管道。我們應該在輸出內容中看到 streamState 已從 "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 轉碼成值區
  • Media CDN:將 Media CDN 設為 Media CDN 來源,並將直播儲存空間值區設為來源。

在後續章節中,我們會驗證邊緣快取服務,接著使用 Media CDN anycast IP 位址,串流播放已轉碼的影片。

15. 確認邊緣快取服務執行個體是否正常運作

在本節中,我們會驗證邊緣快取服務執行個體是否正常運作。為此,我們會嘗試使用邊緣快取服務的 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

請注意,快取「miss」,因為物件尚未快取且從來源讀取。

現在,我們會對 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

輸出結果應混用快取 hitmiss。如果您在輸出內容中看到快取命中,表示 Media 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 Medie Edge 服務已正常運作。

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 設為來源。
  • 我們已驗證邊緣快取服務執行個體的行為 (在快取失敗、快取命中)。

目前我們可以使用影片播放器,透過 Media CDN 快取串流傳輸經過轉碼的即時訊號。為此,我們將使用 VLC Player。VLC Player 是免費的開放原始碼跨平台多媒體播放器和架構,可以播放大多數的多媒體檔案。可播放自動調整媒體格式 (例如 DASH 和 HTTP 即時串流)。它採用自動調整式串流原則,會根據網路連線品質和可用頻寬,自動調整影片播放的品質。透過剛才的轉碼工作,我們使用預設預設值,產生兩種「only」:SD 標準畫質與 HD 高畫質。播放器開始播放影片後,應該就會開始播放 SD 標準畫質格式的影片。如果您的網路連線夠正常,即可快速切換至 HD 高畫質格式。

我們會串流播放 HLS (普遍支援 Apple 影片格式) 經過轉碼的即時信號。對應的檔案名為 main.m3u8,也就是 HLS 資訊清單。資訊清單指向 TS 影片片段。

如要使用 VLC Player,請前往 https://www.videolan.org/vlc/,然後下載適用於你筆電作業系統的播放器版本。VLC 適用於 Windows、MacOSX、Linux、Android 和 iOS。

(2a2d19abe728d222.png)

在筆電上安裝 Player 並啟動。接下來的幾個步驟時,我們會使用 MacOSX 版本的播放器。

如要播放影片,請前往「檔案」/ "開放式網路:

f85565301f7c68dc.png

設定以下項目:

  • 網址:http://&lt;Replace_With_Edge_Cache_IP&gt;/main.m3u8。這是我們想要串流播放的影片網址。通知:
  • Media CDN 執行個體的 IP:34.105.35.246。替換為您部署的 Cloud Media 服務 IP。
  • 資訊清單檔案檔案的路徑:「/」。這是我們在 live-streaming-storage-$LOGNAME 值區中用於儲存已轉碼即時信號檔案的路徑。路徑為此處的根路徑:「/」。
  • 資訊清單檔案名稱:HLS 資訊清單檔案 main.m3u8

然後按一下「開啟」完成轉碼的即時影片應該會開始播放。影片應如下方螢幕截圖所示。螢幕上的計數器會以 1 為單位遞增,您應該可以聽到連續嗶聲。

這是由 FFmpeg 產生的基本 RTMP 測試即時信號,並由 Live Streaming API 轉碼為 HLS,並透過 Media CDN 快取放送:

28fc359b49d44ec2.png

您也可以視需要使用任何其他 HLS 和 MPEG DASH 播放器。以下提供幾個建議供您參考:

  • Quicktime Player - Mac 預設會安裝此程式。相同做法:開啟連至 http://34.104.36.157/main.m3u8 的網路連線 - 將 IP 位址替換為其中一個邊緣快取服務執行個體。

17. 監控 Media CDN

Media CDN 資訊主頁範本是由 SME 團隊建立: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 控制台,然後按一下 3 條長條 >營運 >監控 >儀表板。系統應該會顯示名為「Media Edge Metrics」的資訊主頁。按一下即可查看下列指標:

d0821d84a88a928d.png

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)")