Media CDN と Live Streaming API を使用した Google Cloud でのライブ配信

1. はじめに

コンテンツ配信ネットワーク(CDN)は、頻繁にアクセスされるコンテンツをエンドユーザーの近くにキャッシュし、接続をクライアントの近くで終了し、送信元への接続を再利用し、最新のネットワーク プロトコルとカスタマイズを採用することで、ユーザー パフォーマンスを向上させます。ユーザー(および Google のお客様)にとって、これはレイテンシの短縮、信頼性の向上、費用の削減を意味します。これにより、販売の促進、ウェブ エクスペリエンスの向上、ユーザー エクスペリエンスの総合的な向上につながります。現在、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 バケットに保存されます。次に、ライブ動画の Cloud Storage バケットを送信元として Media CDN を設定します。最後に、Media CDN 経由でキャッシュに保存されたライブ コンテンツの再生に VLC Player が使用されます。また、Cloud Monitoring ダッシュボードを設定して、Media CDN のアクティビティを可視化します。

作成するアプリの概要

このラボでは、次のアーキテクチャに基づいて環境を設定します。

de33cb3e75d52549.png

このラボでは、次のコンポーネントを設定し、次のタスクを実行します。

  • ライブ トランスコードされた動画を保存する Google Cloud Storage(GCS)バケットを作成する
  • 動画を複数の形式(HLS + MPEG DASH、SD、HD)にコード変換するように Live Streaming API を構成する
  • ライブ配信コンポーネント(入力/チャンネル)を設定する
  • ライブ配信チャネルを開始する
  • GCS バケットを送信元として Media CDN を設定する
  • FFmpeg を設定してライブ チャンネルをフィードする
  • トランスコードされたライブフィードを動画プレーヤーでストリーミングする
  • Cloud Monitoring ダッシュボードを設定して、Media CDN のアクティビティ(レイテンシ、キャッシュヒット、キャッシュミスなど)をモニタリングする

: このラボでは、ユーザーが Google Cloud コンソールにアクセスでき、プロジェクトがすでに設定されていることを前提としています。また、ユーザーが新しい環境から開始し、このデモ用に何も設定していないことを前提としています。

すべての構成アクションは、Cloud Shell のコマンドラインから行います。コマンドライン経由で構成されたコンポーネントは、コンソールでいつでも確認できます。このラボでは、Google Cloud コンソールを指すポインタが使用されます。

2. 始める前に

Media CDN へのアクセスは制限されています。Media CDN にアクセスするには、アカウント チームにお問い合わせください。お客様に代わってアクセス リクエストを作成できます。Google 社員で、Media CDN を使用したライブ配信をテストしたい場合は、Media CDN の PM に連絡して Media CDN へのアクセスをリクエストしてください。

3. 設定と要件

Cloud Shell の起動

Google Cloud はノートパソコンからリモートで操作できますが、この Codelab では、Google Cloud Shell(Cloud 上で動作するコマンドライン環境)を使用します。

Google Cloud Console で、右上のツールバーにある Cloud Shell アイコンをクリックします。

55efc1aaa7a4d3ad.png

プロビジョニングと環境への接続にはそれほど時間はかかりません。完了すると、次のように表示されます。

7ffe5cbb04455448.png

この仮想マシンには、必要な開発ツールがすべて用意されています。永続的なホーム ディレクトリが 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

次のステップ

  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. 必要な Service 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. 必要な Service API を有効にする

プロジェクトで次の API が有効になっていることを確認する必要があります。

  • Network Services API
  • Certificate Manager API
  • Livestream API
  • Media CDN Edge Cache 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 を作成しました。次の 2 つのセクションでは、次のリソースを作成します。

  • ライブ配信入力: 入力エンドポイントは、エンコーダが入力ストリームを送信するエンドポイントです。入力エンドポイントを使用すると、入力の解像度、入力タイプ、動画の切り抜きなど、ストリーミングの構成を指定できます。
  • ライブ配信チャネル: チャネルは、入力エンドポイントを通じて入力ストリームを取り込み、入力ストリームを複数のコード変換し、特定の場所にある出力形式で特定のライブ ストリームをパブリッシュするリソースです。プライマリ入力ストリームとバックアップ入力ストリームを同じチャネルに含めることができます。

後ほどラボで次のリソースを作成します。

  • エンコーダ: エンコーダは、入力ストリームの送信に使用するプログラムです。このラボでは 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
}

出力には多くの有用な情報が含まれていますが、現時点では次の 2 つのフィールドに注目する必要があります。

  • オペレーション 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. ライブ配信チャンネルを開始する

ライブ配信チャネルを作成したので、チャネルを開始しましょう。このセクションでは、次の操作を行います。

  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. Edge Cache Origin
  2. Edge Cache Service

1. Edge Cache Origin を作成する

エッジ キャッシュ オリジンは、Cloud Storage バケット、サードパーティのストレージ ロケーション、ロードバランサなどのコンテンツのロケーションを表します。CDN の用語では、オリジン(またはオリジン サーバー)は、配信するコンテンツのソース(すべての CSS、JavaScript、HTML、画像など)が配置されている場所です。このラボでは、ラボの開始時に作成した Cloud Storage バケットにマッピングするオリジンを作成します。Edge Cache Origin を 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. Edge Cache Service を作成する

Edge Cache Origin が設定されたので、Edge Cache Service 自体を作成できます。

cme-demo.yaml ファイルを作成する

Edge Cache Service の構成は、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

Edge Cache Service の構成はすべてデフォルトのままにします。上記のファイルには、ユーザーが更新する必要がある 3 つのフィールド値があります。

  • name: Media CDN インスタンスの名前(ここでは cme-demo
  • hosts: この Media CDN サービスによって解決されるドメイン名のリスト(ここでは demo.cme.com)。このデモでは、このモデルを使用します。Media CDN インスタンスの IP アドレスを使用します。
  • Origin:: 前の手順で作成した Edge Cache Origin です。cme-origin(Media CDN 送信元の名前)に設定します。

YAML ファイルで使用できるさまざまな変数の詳細については、Edge Cache Service 構成ガイドをご覧ください。

Edge Cache Service を作成する

Edge Cache Origin cme-origin に、ホスト demo.cme.com を持つ cme-demo という名前の Edge Cache Service を作成します。サービスを作成するには、Cloud Shell で次のコマンドを実行します。

コマンド

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

Edge Cache Service の作成には数分かかることがあります。

出力例

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'

Edge Cache Service インスタンスの ipv4Addresses(ここでは 34.104.36.157)をメモしてコピーします。このファイルを使用して cme-demo.yaml ファイルを更新し、後でコード変換された動画をストリーミングします。

Edge Cache Service を更新する

この時点で、後でサービスの IP を使用して動画をストリーミングできるように、Edge Cache Service の構成を更新することをおすすめします。Edge Cache Service の YAML ファイルを使用すると、Edge Cache Service がリクエストを受信するすべてのホスト名/IP を一覧表示できます。この時点では、ホストとして demo.cme.com のみを指定しています。このドメインの名前解決を提供するには、DNS ゾーンを構成します。ただし、yaml ファイルのホストリストに IP アドレスを追加する方が簡単な解決策です。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 Service インスタンスは、"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 ターミナルで、[入力エンドポイントを作成して構成する] セクションで作成した 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 ウィンドウが開きます。

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 を実行してチャンネルを記述します。出力で、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 を介してバケットにコード変換されます。
  • Media CDN: Media CDN の送信元として Live Streaming ストレージ バケットを使用して Media CDN を構成しました。

以降のセクションでは、Edge Cache Service を検証し、Media CDN の Anycast IP アドレスを使用してトランスコードされた動画をストリーミングします。

15. Edge Cache Service インスタンスが動作していることを確認します。

このセクションでは、Edge Cache Service インスタンスが想定どおりに動作することを確認します。これを行うには、Edge Cache Service サービスの IP アドレスを使用して、Edge Cache Service インスタンスからファイルにアクセスしようとします。オブジェクトに初めてアクセスしたときは、まだキャッシュに保存されていません。キャッシュ 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"

Edge Cache Service インスタンスの IP アドレスを使用して名前を解決する解決に注目してください。demo.cme.com:<IP> を使用します。ここで、IP は、作成した Edge Cache Service インスタンスの 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

出力には、キャッシュ 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 Media Edge Service は想定どおりに動作しています。

16. VLC を使用してコード変換されたライブ シグナル動画をストリーミングする

ここでは、これまでに学んだすべての手順を結び付けます。

  • Live Streaming API によって HLS コンテンツにトランスコードされたライブ シグナルの結果を受信する live-streaming-storage-$LOGNAME というバケットを作成しました。
  • Live Streaming API を設定します。
  • FFmpeg を使用して RTMP ライブ シグナルを開始し、Live Streaming API の入力/チャネルにフィードしました。
  • ライブ シグナルがチャンネルにフィードされ、チャンネルが streaming モードであることを確認しました。
  • 結果として生成されたトランスコード ファイル(マニフェスト + TS セグメント)がバケット live-streaming-storage-$LOGNAME に生成され、保存されていることを確認しました。
  • cme-origin という Edge Cache Origin が、GCS バケット live-streaming-storage-$LOGNAME を送信元として設定されています。
  • cme-demo という名前の Edge Cache インスタンスが、cme-origin を送信元として設定されています。
  • Edge Cache Service インスタンスの動作(キャッシュミス、キャッシュヒット)を確認しました。

これで、動画プレーヤーを使用して、Media CDN キャッシュ経由でコード変換されたライブ シグナルをストリーミングできるようになりました。そのためには、VLC Player を使用します。VLC プレーヤーは、ほとんどのマルチメディア ファイルを再生できる、無料でオープンソースのクロスプラットフォーム マルチメディア プレーヤーとフレームワークです。アダプティブ メディア形式(DASH や HLS など)を再生します。アダプティブ ストリーミングの原理に基づいて、ネットワーク接続の品質と利用可能な帯域幅に応じて、再生する動画の画質を調整します。先ほど行ったコード変換ジョブでは、デフォルトのプリセットを使用して、SD と HD の 2 つの品質のみを生成しました。プレーヤーで動画の再生を開始すると、SD 形式で再生が開始されます。ネットワーク接続が十分に良好な場合は、すぐに HD 形式に切り替わります。

HLS(広くサポートされている Apple の動画形式)にトランスコードされたライブ シグナルをストリーミングします。対応するファイルは main.m3u8 と呼ばれ、HLS マニフェストです。マニフェストは TS 動画セグメントを参照します。

VLC プレーヤーを使用するには、https://www.videolan.org/vlc/ にアクセスし、ノートパソコンのオペレーティング システムに対応したバージョンのプレーヤーをダウンロードします。VLC は、Windows、MacOSX、Linux、Android、iOS で利用できます。

2a2d19abe728d222.png

ノートパソコンに Player をインストールして起動します。次の手順では、MacOSX バージョンのプレーヤーを使用します。

動画を再生するには、[ファイル] / [ネットワークを開く] に移動します。

f85565301f7c68dc.png

次のコマンドで設定します。

  • URL: http://<Replace_With_Edge_Cache_IP>/main.m3u8。これは、ストリーミングする動画の URL です。注意:
  • Media CDN インスタンスの IP: 34.105.35.246。デプロイした Cloud Media Service の IP に置き換えます。
  • マニフェスト動画ファイルのパス: /。これは、live-streaming-storage-$LOGNAME バケットでトランスコードされたライブ シグナル ファイルを保存するために使用したパスです。パスはルートパス「/」です。
  • マニフェスト動画ファイルの名前: HLS マニフェスト ファイル main.m3u8

[開く] をクリックします。トランスコードされたライブ動画が再生を開始します。動画は次のスクリーンショットのようになります。画面上の数値は 1 ずつ増加し、ビープ音が連続して鳴ります。

これは、FFmpeg によって生成された基本的な RTMP テスト ライブ シグナルで、Live Streaming API によって HLS にトランスコードされ、Media CDN キャッシュ経由で配信されます。

28fc359b49d44ec2.png

必要に応じて、他の HLS プレーヤーや MPEG DASH プレーヤーを使用できます。以下に、検討に値するプレーヤーをいくつか示します。

  • Quicktime プレーヤー - Mac にデフォルトでインストールされています。同じ手順で、http://34.104.36.157/main.m3u8 へのネットワーク接続を開きます。IP アドレスは、Edge Cache Service インスタンスの IP アドレスに置き換えます。

17. Media CDN のモニタリング

SME チームが Media 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 コンソールに移動し、3 つのバー > [オペレーション] > [Monitoring] > [ダッシュボード] をクリックします。[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)")