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 を設定します。最後に、VLC Player を使用して、Media CDN 経由でキャッシュに保存されたライブ コンテンツを再生します。また、Media CDN のアクティビティを可視化するための Cloud Monitoring ダッシュボードもセットアップします。

作成するアプリの概要

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

de33cb3e75d52549.png

ラボの一環として次のコンポーネントを設定し、次のタスクを実行します。

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

: このラボでは、ユーザーが 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. 必要なサービス 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
  • 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. 作成してライブ ストリーミング チャンネルを設定する

ライブ ストリーミング チャンネルを作成しましょう。このチャンネルは、前のセクションで作成した入力エンドポイントに関連付けます。次の例では、1 つの高解像度(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 を構成する

このセクションでは、CDN インフラストラクチャである Media 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 ファイルで使用できるさまざまな変数の詳細については、Edge Cache Service 構成ガイドをご覧ください。

エッジ キャッシュ サービスを作成する

エッジ キャッシュ送信元 cme-origin に、ホスト demo.cme.com を使用して、cme-demo という名前のエッジ キャッシュ サービスを作成します。サービスを作成するには、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 を使用して動画をストリーミングできるようにするために、この時点でエッジ キャッシュ サービスの構成を更新することをおすすめします。Edge Cache Service YAML ファイルを使用すると、Edge Cache Service がリクエストを受け入れるすべてのホスト名と IP を一覧表示できます。この時点では、ホストとして demo.cme.com のみを指定しました。このドメインの名前解決を提供するには、クラウドで DNS ゾーンを構成します。簡単な解決策は、yaml ファイルの hosts リストに 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 が表示されていることを確認します。

この時点で、エッジ キャッシュ サービス インスタンスは、"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 を開く

<CTRL+C> を押すまで FFmpeg が永続的に実行されるため、この時点でラボを続行するために新しい 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 の送信元として使用して Media CDN を構成します。

次のセクションでは、エッジ キャッシュ サービスを検証してから、Media CDN エニーキャスト 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

オブジェクトがまだキャッシュに保存されておらず、送信元から読み取られているため、キャッシュ ミスに注目してください。

次に、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 API によって HLS コンテンツにコード変換されたライブ信号の結果を受け取る live-streaming-storage-$LOGNAME というバケットを作成しました。
  • Live Streaming API を設定しました。
  • FFmpeg を使用して、Live Streaming API の入力/チャンネルにフィードする RTMP ライブシグナルを開始しました。
  • ライブシグナルがチャンネルにフィードされていること、およびチャンネルが streaming モードであることを確認しました。
  • その結果、コード変換されたファイル(マニフェスト + TS セグメント)が生成され、live-streaming-storage-$LOGNAME バケットに保存されていることを確認しました。
  • GCS バケット live-streaming-storage-$LOGNAME を送信元として、cme-origin というエッジ キャッシュ送信元が設定されました。
  • cme-origin を送信元として、cme-demo という Edge キャッシュ インスタンスが設定されています。
  • エッジ キャッシュ サービス インスタンスの動作(キャッシュミス、キャッシュ ヒット)を検証しました。

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

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

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

2a2d19abe728d222.png

ノートパソコンに Player をインストールして起動します。以降のステップでは、MacOS X 版のプレーヤーを使用します。

動画を再生するには、[ファイル] に移動します/ "オープン ネットワーク":

f85565301f7c68dc.png

以下を使用して設定します。

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

[開く]をクリックしますコード変換されたライブ動画の再生が開始されます。動画は次のスクリーンショットのようになります。画面上のカウンタが 1 単位で動作し、ビープ音が連続して鳴ります。

これは、FFmpeg で生成され、Live Streaming API によって HLS にコード変換され、Media CDN のキャッシュを介して配信される基本的な RTMP テストライブシグナルです。

28fc359b49d44ec2.png

必要に応じて、他の HLS および MPEG DASH プレーヤーを使用できます。考慮すべき点をいくつか紹介します。

  • Quicktime プレーヤー - Mac にデフォルトでインストールされています。同じ手順: http://34.104.36.157/main.m3u8 へのネットワーク接続を開きます。IP アドレスをエッジ キャッシュ サービス インスタンスのいずれかに置き換えます。

17. Media CDN のモニタリング

Media CDN ダッシュボード テンプレート(https://gist.github.com/elithrar/1c511d00f5cd3736fb2a3897867209c1)が SME チームによって作成されました。

インストールするには、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)")