Cloudflare StreamのStream Connectでライブストリームのサイマル放送をしてみた

Cloudflare Streamのライブストリームを他動画配信プラットフォームに転送できるStream Connectを使ってみました。Cloudflare StreamとYouTube Live、Amazon IVSで同時放送をしてみます。
2022.04.30

はじめに

清水です。Cloudflareの動画配信プラットフォームのサービスCloudflare Streamを試しています。これまでにダッシュボード(管理画面)からのライブストリームやAPI経由でのライブストリームを試してきました。

Cloudflare Streamの機能のひとつにStream Connectというものがあります。ドキュメントではSimulcasting(サイマル放送)と呼ばれているものですね。(Simulcasting · Cloudflare Stream docs)Cloudflare Streamに打ち上げた映像を、そのまま他の動画配信プラットフォームに転送できる機能となります。本エントリではこのCloudflare StreamのStream Connectについて実際に使ってみたのでまとめてみたいと思います。

Stream Connectについて

まずはStream Connectの概要や利点などをおさえておきましょう。機能としては冒頭にも述べたとおり、Cloudflare StreamのLive InputにStreaming Softwareから打ち上げた映像を他の動画配信プラットフォームに転送することができる、というものとなります。プロトコルとしてはRTMP(S)とSRTが利用可能です。Cloudflare StreamがRTMPのハブになるイメージと考えることができるかと思います。

メリットの詳細などはCloudflare公式ブログの以下のエントリが詳しいです。

上記エントリから、機能のメリットをうまく表した図を1枚引用します。

Live stream to multiple platforms with Stream Connect

最近は動画配信プラットフォームも増えてきました。YouTube LiveやFacebook Live、Twitchなどなど、場合によってはこれらの複数で同時に同じ映像をライブストリームするということもあるかと思います。その際にグラウンドつまり映像の打ち上げ元からそれぞれのプラットフォームに映像を打ち上げると、そのプラットフォームぶんのネットワーク帯域が必要になります。打ち上げ元に万全のネットワーク環境が準備できていればそれでもかまいませんがそうではなく、複数の打ち上げ先に個別に打上げることででネットワーク帯域や安定性が問題になるケースも少なくないかと思います。Stream Connectを使用することで、打ち上げ元(グラウンド)からクラウド環境へのネットワーク帯域は映像1本ぶんですみます。またクラウドへの入り口にCloudflareのネットワークが利用できることで、打ち上げ元により近いエンドポイントが利用できるなどのメリットも受けられる、ということになります。

Stream ConnectでライブストリームのSimulcastingをしてみた

簡単に概要がおさえられたところ、実際にStream Connect機能を使ってみます。Cloudflare StreamのLive Input に映像を打ち上げ、Cloudflare Streamとしてライブストリームをしつつ、さらにYouTube Liveへのサイマル放送を行う、というシチュエーションを試してみたいと思います。 v まずはCloudflare StreamのLive Inputを作成し、Streaming Softwareから映像を打ち上げライブストリームを開始します。

Cloudflare Streamでのライブストリームを確認しつつ、YouTube Liveの準備を行います。

YouTube Live側のストリームURLとストリームキーが確認できたら、Cloudflare Stream側の設定を行います。Live Inputの詳細画面、ページ下部の接続情報のあとに「出力」の項目があります。ここの[出力を作成する]ボタンから進みます。

出力の作成画面でプロトコルを選択、ストリームURLとストリームキーをそれぞれ入力して[出力を作成する]ボタンを押下します。

出力部分にYouTube LiveのストリームURLが追加されていますね。

そしてYouTube Live側でもストリームを受け取り、配信準備ができた状態となります。[ライブ配信を開始]ボタンでYouTube Liveのライブ配信を開始しましょう。

Cloudflare Streamのライブストリーム画面とYouTube Liveのライブ配信画面をならべてみました!サイマル放送ができていますね!

APIでもStream ConnectでSimulcastingをやってみる

このStream ConnectによるSimulcasting、もちろんAPIでも設定することができます。以下のCloudflareドキュメントを参考に設定してみます。

APIトークンの取得などは以下ブログエントリの方法で実施済みとして進めます。

APIトークン、アカウントID、そして使用しているLive InputのUIDをシェル変数に格納しておきます。

% TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
% ACCOUNT=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
% LIVE_INPUT_UID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

/live_inputs/${LIVE_INPUT_UID}へのGETリクエストでその(UIDを持つ)Live Inputの詳細情報が取得できます。

% curl -X GET \
    -H "Authorization: Bearer ${TOKEN}" \
    "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/stream/live_inputs/${LIVE_INPUT_UID}"
{
  "result": {
    "uid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "rtmps": {
      "url": "rtmps://live.cloudflare.com:443/live/",
      "streamKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    },
    "srt": {
      "url": "srt://live.cloudflare.com:778",
      "streamId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "passphrase": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    },
    "created": "2022-04-30T05:54:06.151558Z",
    "modified": "2022-04-30T05:54:06.151558Z",
    "meta": {
      "name": "stream-connect-live-input"
    },
    "status": {
      "current": {
        "reason": "connected",
        "state": "connected",
        "statusEnteredAt": "2022-04-30T05:57:07.688Z",
        "statusLastSeen": "2022-04-30T06:22:06.914Z"
      },
      "history": []
    },
    "recording": {
      "mode": "automatic",
      "requireSignedURLs": false,
      "allowedOrigins": null
    }
  },
  "success": true,
  "errors": [],
  "messages": []
}

Simulcastingの出力設定についてはこちらの情報に含まれていませんが、/live_inputs/${LIVE_INPUT_UID}/outputsエンドポイントへのGETリクエストで情報を取得できます。現在はYouTube Liveのみが設定されている状態です。

% curl -X GET \
     -H "Authorization: Bearer ${TOKEN}" \
     "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/stream/live_inputs/${LIVE_INPUT_UID}/outputs"
{
  "result": [
    {
      "uid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "url": "rtmp://a.rtmp.youtube.com/live2",
      "streamKey": "xxxxxxxxxxxxxxxxxxxxxxxx",
      "status": {
        "current": {
          "reason": "connected",
          "state": "connected",
          "statusEnteredAt": "2022-04-30T06:08:04.029Z",
          "statusLastSeen": "2022-04-30T06:22:51.888Z"
        },
        "history": [
          {
            "reason": "new_configuration_accepted",
            "state": "connecting",
            "statusEnteredAt": "2022-04-30T06:08:03.549Z"
          }
        ]
      }
    }
  ],
  "success": true,
  "errors": [],
  "messages": []
}

追加のサイマル放送先として、Amazon Interactive Video Service (Amazon IVS)を使用します。Channelを作成してストリームURL(Ingest Server)ならびにストリームキー(Stream Key)を確認します。

Cloudflare StreamのStream Connect出力の追加は、エンドポイント/live_inputs/${LIVE_INPUT_UID}/outputsヘデータをPOSTすることで行うことができます。

curl -X POST \
     -H "Authorization: Bearer ${TOKEN}" \
     --data '{"url": "rtmps://xxxxxxxxxxxx.global-contribute.live-video.net:443/app","streamKey": "sk_ap-northeast-1_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}' \
     "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/stream/live_inputs/${LIVE_INPUT_UID}/outputs"

送信データのJSONを整形すると以下となります。

{
  "url": "rtmps://xxxxxxxxxxxx.global-contribute.live-video.net:443/app",
  "streamKey": "sk_ap-northeast-1_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

以下が実行結果です。

% curl -X POST \
     -H "Authorization: Bearer ${TOKEN}" \
     --data '{"url": "rtmps://xxxxxxxxxxxx.global-contribute.live-video.net:443/app","streamKey": "sk_ap-northeast-1_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}' \
     "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/stream/live_inputs/${LIVE_INPUT_UID}/outputs"
{
  "result": {
    "uid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "url": "rtmps://xxxxxxxxxxxx.global-contribute.live-video.net:443/app",
    "streamKey": "sk_ap-northeast-1_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "status": null
  },
  "success": true,
  "errors": [],
  "messages": []
}

実行後の状態をダッシュボードでも確認してみましょう。出力先が追加されていますね。

APIでも確認してみます。2つのoutputsが設定されていることがわかります。

% curl -X GET \
     -H "Authorization: Bearer ${TOKEN}" \
     "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/stream/live_inputs/${LIVE_INPUT_UID}/outputs"
{
  "result": [
    {
      "uid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "url": "rtmp://a.rtmp.youtube.com/live2",
      "streamKey": "xxxxxxxxxxxxxxxxxxxxxxxx",
      "status": {
        "current": {
          "reason": "connected",
          "state": "connected",
          "statusEnteredAt": "2022-04-30T06:08:04.029Z",
          "statusLastSeen": "2022-04-30T06:37:50.992Z"
        },
        "history": [
          {
            "reason": "new_configuration_accepted",
            "state": "connecting",
            "statusEnteredAt": "2022-04-30T06:08:03.549Z"
          }
        ]
      }
    },
    {
      "uid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "url": "rtmps://xxxxxxxxxxxx.global-contribute.live-video.net:443/app",
      "streamKey": "sk_ap-northeast-1_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "status": {
        "current": {
          "reason": "connected",
          "state": "connected",
          "statusEnteredAt": "2022-04-30T06:34:38.763Z",
          "statusLastSeen": "2022-04-30T06:37:50.992Z"
        },
        "history": [
          {
            "reason": "new_configuration_accepted",
            "state": "connecting",
            "statusEnteredAt": "2022-04-30T06:34:37.363Z"
          }
        ]
      }
    }
  ],
  "success": true,
  "errors": [],
  "messages": []
}

Amazon IVSについてはAWSマネジメントコンソール経由での視聴となりますが、Cloudflare Stream、YouTube Live、Amazon IVSでそれぞれサイマル放送している状況ができました!

まとめ

Cloudflare StreamのStream Connect機能を使って、ライブストリーミングのサイマル放送(Simulcasting)をやってみました。Live Inputの出力(Output)を作成するだけで簡単にストリームの転送が行なえます。複数の動画配信プラットフォームに映像を打上げる必要がある場合には、是非試してみたい機能だと思いました。なお今回の検証では特に意識していませんが、各ストリーミングプラットフォームでビットレートやKeyframe IntervalなどIngestの最適な条件が設定される点には注意しましょう。