Cloudflare Streamでオンデマンド動画(VOD)を扱ってみた

Cloudflare Streamに動画ファイルをアップロードすることでVOD配信が可能です。アップロード方法にはURLからのフェッチも準備されており、またAPIでの実行もできます。ライブストリーミングの自動録画の扱いとともに確認してみました。
2022.04.30

はじめに

清水です。Cloudflareの動画配信プラットフォームのサービスCloudflare Streamを試しています。これまでの計4本のエントリではライブストリーミングの機能に焦点を当ててきました。

Cloudflare Streamではライブストリーミングの他にオンデマンド動画(VOD)のストリーミング配信もサポートしています。本エントリではCloudflare Streamでのオンデマンド動画(VOD)の扱いについて確認してみましたのでまとめてみます。

ダッシュボードからオンデマンド動画を確認してみる

まずはダッシュボード(Cloudflareの管理画面)からオンデマンドの動画を確認してみましょう。左側メニューの「Stream」もしくはStreamの中の「ビデオ」を参照するとアップロード用のメニューの下にオンデマンド用の動画(ビデオ)が表示されます。

コンパクト表示にするとこんなかんじです。

さてこのCloudflareのアカウント、実は明示的な動画ファイルのアップロードはこれまでに実施してきていません。それでも現在、9本145分のビデオコンテンツがある状態でした。これらはいずれもライブストリーミングを実施した際、自動録画機能を有効にしていたためCloudflare側に保存され、それがビデオコンテンツとして表示されているというわけですね。

ということでまずは、ライブストリーミングで自動録画されたものがオンデマンド用のビデオコンテンツとして扱われていることを把握しておきましょう。

動画ファイルのアップロード

続いて動画ファイルをCloudflare Streamにアップロードしてビデオコンテンツを準備していきます。アップロードの方法はいくつか準備されていますが、一番簡単なものはメニューのトップに表示されているクイックアップロードと呼ばれるものではないでしょうか。

動画ファイルをそのままドラッグアンドドロップ、もしくは該当部分をクリックするとOSのファイル選択ダイアログが現れますのでアップロードする動画を選択することで、アップロードがはじまります。

vvv実際に動画ファイルをドラッグアンドドロップしてアップロードしてみます。まずはアップロード中のフェーズとなります。

その後、動画一覧に加わり、処理中のフェーズとなります。

「準備ができました」の表示に変わったあと、該当のビデオ部分をクリックしました。このビデオコンテンツの詳細画面に遷移します。ビデオコンテンツには一意のビデオIDが振られています。ビデオ名は変更が可能です。(「IMG_5908.MOV」から「小田原の海」に変えてみました。)

ページを下部にスクロールすると、ビデオコンテンツのプレビューが表示されます。クリックすることで再生可能なほか「ビデオのリンク」部分を押下する とwatch.videodelivery.netドメインでの再生ページが別タブで開きます。

またビデオコンテンツの情報はAPIからも取得可能です。ビデオコンテンツ詳細ページの「JSON」タブにコマンド例が記載されています。

こちらを元に、実際にAPIコマンドで取得してみた情報が以下となります。

 % curl -X GET \
     -H "Authorization: Bearer ${TOKEN}" \
     "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/stream/${VIDEO_UID}"
{
  "result": {
    "uid": "c409xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "creator": null,
    "thumbnail": "https://videodelivery.net/c409xxxxxxxxxxxxxxxxxxxxxxxxxxxx/thumbnails/thumbnail.jpg",
    "thumbnailTimestampPct": 0,
    "readyToStream": true,
    "status": {
      "state": "ready",
      "pctComplete": "100.000000",
      "errorReasonCode": "",
      "errorReasonText": ""
    },
    "meta": {
      "filename": "IMG_5908.MOV",
      "filetype": "video/quicktime",
      "name": "小田原の海",
      "relativePath": "null",
      "type": "video/quicktime"
    },
    "created": "2022-04-30T09:57:30.832975Z",
    "modified": "2022-04-30T10:04:11.871587Z",
    "size": 382466674,
    "preview": "https://watch.videodelivery.net/c409xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "allowedOrigins": [],
    "requireSignedURLs": false,
    "uploaded": "2022-04-30T09:57:30.832929Z",
    "uploadExpiry": "2022-05-01T09:57:30.832922Z",
    "maxSizeBytes": null,
    "maxDurationSeconds": null,
    "duration": 60.9,
    "input": {
      "width": 3840,
      "height": 2160
    },
    "playback": {
      "hls": "https://videodelivery.net/c409xxxxxxxxxxxxxxxxxxxxxxxxxxxx/manifest/video.m3u8",
      "dash": "https://videodelivery.net/c409xxxxxxxxxxxxxxxxxxxxxxxxxxxx/manifest/video.mpd"
    },
    "watermark": null
  },
  "success": true,
  "errors": [],
  "messages": []
}

リンクを使った動画ファイルのアップロード

ダッシュボードからリンクを使ったアップロード

Cloudflare Streamへのオンデマンド動画コンテンツのアップロードは、その他にもいくつか手段が用意されています。ここではリンクを使った方法を確認してみましょう。ダッシュボードの「リンクを使用」タブを開いてみます。先ほどのようにドラッグアンドドロップで手元のPCから動画ファイルをアップロードするのではなく、HTTPSでアクセスできる場所に動画ファイルを配置し、そのURLリンクを指定するというぐあいですね。

実際に動画ファイルを公開設定にしたAmazon S3でホスティングし、Cloudflare Streamのリンクを使った動画のアップロードを試してみます。ビデオ名称はビデオURLの「ファイル名.拡張子」部分がデフォルトで入力されましたが、動画コンテンツの内容にあわせて変えてみました。

アップロードボタンを押下すると、ビデオURLからのダウンロードが開始されます。この時点でビデオIDは割り振られていますね。 その後処理中のフェーズを経て、「準備ができました」になればCloudflare Streamで再生可能となります。

APIからリンクを使ったアップロード

このリンクを使った動画ファイルのアップロードはAPI経由でも可能です。ダッシュボードの「APIを使用」のタブや、ドキュメントの以下の箇所に説明があります。

コマンドは以下となります。フェッチ先のURLとコンテンツ名称をデータとして/copyエンドポイントにPOSTするかたちですね。

curl -X POST \
     -H "Authorization: Bearer ${TOKEN}" \
     --data '{"url":"https://my-bucket.s3.ap-northeast-1.amazonaws.com/IMG_2154.MOV","meta":{"name":"仙台の外が見えるエレベーター"}}' \
    "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/stream/copy"

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

{
  "url": "https://my-bucket.s3.ap-northeast-1.amazonaws.com/IMG_2154.MOV",
  "meta": {
    "name": "仙台の外が見えるエレベーター"
  }
}

以下が実行結果です。

 % curl -X POST \
     -H "Authorization: Bearer ${TOKEN}" \
     --data '{"url":"https://my-bucket.s3.ap-northeast-1.amazonaws.com/IMG_2154.MOV","meta":{"name":"仙台の外が見えるエレベーター"}}' \
    "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/stream/copy"
{
  "result": {
    "uid": "4e25xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "creator": null,
    "thumbnail": "https://videodelivery.net/4e25xxxxxxxxxxxxxxxxxxxxxxxxxxxx/thumbnails/thumbnail.jpg",
    "thumbnailTimestampPct": 0,
    "readyToStream": false,
    "status": {
      "state": "downloading",
      "errorReasonCode": "",
      "errorReasonText": ""
    },
    "meta": {
      "downloaded-from": "https://my-bucket.s3.ap-northeast-1.amazonaws.com/IMG_2154.MOV",
      "name": "仙台の外が見えるエレベーター"
    },
    "created": "2022-04-30T11:05:04.849622Z",
    "modified": "2022-04-30T11:05:04.849622Z",
    "size": 201608589,
    "preview": "https://watch.videodelivery.net/4e25xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "allowedOrigins": [],
    "requireSignedURLs": false,
    "uploaded": "2022-04-30T11:05:04.849598Z",
    "uploadExpiry": null,
    "maxSizeBytes": null,
    "maxDurationSeconds": null,
    "duration": -1,
    "input": {
      "width": -1,
      "height": -1
    },
    "playback": {
      "hls": "https://videodelivery.net/4e25xxxxxxxxxxxxxxxxxxxxxxxxxxxx/manifest/video.m3u8",
      "dash": "https://videodelivery.net/4e25xxxxxxxxxxxxxxxxxxxxxxxxxxxx/manifest/video.mpd"
    },
    "watermark": null
  },
  "success": true,
  "errors": [],
  "messages": []
}

API経由での通常のアップロード

動画コンテンツのアップロード方法としてもう一つ、APIを使った通常の(リンクURLを使わない)アップロード方法についても確認しておきましょう。ドキュメントの以下を参照します。

ドキュメント記載があるとおり、200MBを超える場合はtusプロトコルを利用する必要があるようです。今回はこのtusプロトコルを使った方法は扱わず、200MB以下のファイルのAPI経由でのアップロードを試してみます。curlコマンドの-Fオプションでファイルを指定してPOSTするぐあいですね。

% curl -X POST \
     -H "Authorization: Bearer ${TOKEN}" \
     -F file=@/Users/username/IMG_2439.MOV \
    "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/stream"

{
  "result": {
    "uid": "6fa9xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "creator": null,
    "thumbnail": "https://videodelivery.net/6fa9xxxxxxxxxxxxxxxxxxxxxxxxxxxx/thumbnails/thumbnail.jpg",
    "thumbnailTimestampPct": 0,
    "readyToStream": false,
    "status": {
      "state": "queued",
      "errorReasonCode": "",
      "errorReasonText": ""
    },
    "meta": {
      "name": "IMG_2439.MOV"
    },
    "created": "2022-04-30T11:13:52.958817Z",
    "modified": "2022-04-30T11:13:52.958817Z",
    "size": 43164278,
    "preview": "https://watch.videodelivery.net/6fa9xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "allowedOrigins": [],
    "requireSignedURLs": false,
    "uploaded": "2022-04-30T11:13:52.958811Z",
    "uploadExpiry": null,
    "maxSizeBytes": null,
    "maxDurationSeconds": null,
    "duration": -1,
    "input": {
      "width": -1,
      "height": -1
    },
    "playback": {
      "hls": "https://videodelivery.net/6fa9xxxxxxxxxxxxxxxxxxxxxxxxxxxx/manifest/video.m3u8",
      "dash": "https://videodelivery.net/6fa9xxxxxxxxxxxxxxxxxxxxxxxxxxxx/manifest/video.mpd"
    },
    "watermark": null
  },
  "success": true,
  "errors": [],
  "messages": []
}

アップロードができました!

% curl -X GET \
     -H "Authorization: Bearer ${TOKEN}" \
     "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/stream/${VIDEO_UID}"
{
  "result": {
    "uid": "6fa9xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "creator": null,
    "thumbnail": "https://videodelivery.net/6fa9xxxxxxxxxxxxxxxxxxxxxxxxxxxx/thumbnails/thumbnail.jpg",
    "thumbnailTimestampPct": 0,
    "readyToStream": true,
    "status": {
      "state": "ready",
      "pctComplete": "100.000000",
      "errorReasonCode": "",
      "errorReasonText": ""
    },
    "meta": {
      "name": "IMG_2439.MOV"
    },
    "created": "2022-04-30T11:13:52.958817Z",
    "modified": "2022-04-30T11:14:12.866007Z",
    "size": 43164278,
    "preview": "https://watch.videodelivery.net/6fa9xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "allowedOrigins": [],
    "requireSignedURLs": false,
    "uploaded": "2022-04-30T11:13:52.958811Z",
    "uploadExpiry": null,
    "maxSizeBytes": null,
    "maxDurationSeconds": null,
    "duration": 21.4,
    "input": {
      "width": 1920,
      "height": 1080
    },
    "playback": {
      "hls": "https://videodelivery.net/6fa9xxxxxxxxxxxxxxxxxxxxxxxxxxxx/manifest/video.m3u8",
      "dash": "https://videodelivery.net/6fa9xxxxxxxxxxxxxxxxxxxxxxxxxxxx/manifest/video.mpd"
    },
    "watermark": null
  },
  "success": true,
  "errors": [],
  "messages": []
}

まとめ

Cloudflare Streamでオンデマンド動画(VOD)の扱い、動画ファイルのアップロード方法とライブストリーミングが自動録画されたものがビデオコンテンツとして扱われていることを確認しました。動画ファイルのアップロードには、直接動画ファイルを送信する方法のほか、リンクURLを指定してCloudflare Streamのほうでフェッチする方法があります。またどちらの方法でもAPIを使って実行することができます。ただしリンクURLを使わない方法で200MB以上のファイルサイズの場合に方法が変わる点に注意しておきましょう。