Cloudflare StreamでVOD動画にWatermarkを入れてみた!

Cloudflare StreamではVOD動画ファイルアップロード時にWatermarkを入れることができます。実際にスカしたWatermarkをアップロード時に入れて確認してみます。現在のところ操作がAPIに限定されている点に注意しましょう。
2022.04.30

はじめに

清水です。Cloudflareの動画配信プラットフォームのサービスCloudflare Streamを試しています。Cloudflare Streamではオンデマンド動画(VOD)コンテンツに対して、動画のアップロード時に指定したWatermark(透かし)を入れることができます。本エントリではこちらを試してみました。なお、Watermarkのアップロード(プロファイルの作成)、動画コンテンツアップロード時のWatermarkの適用、いずれもダッシュボードからの操作はできずAPIでの操作が前提となります。以下のドキュメントを参照しながら進めてみました。

動画コンテンツのアップロード方法やCloudflare StreamでのAPIの利用などは以下なども参考にしてください。

Watermark Profileの作成

まずはWatermarkの画像やその他メタ情報をまとめたProfileを作成する必要があります。作成前に、既存のWatermark Profileが存在していないことを確認しておきましょう。

 % curl -X GET \
     -H "Authorization: Bearer $TOKEN" \
     "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/stream/watermarks"
{
  "result": [],
  "success": true,
  "errors": [],
  "messages": []
}

Watermarkの画像として以下を準備しました。

画像のアップロードには、curlコマンドの-Fオプションでファイルを指定する方法のほか、あらかじめHTTPでアクセスできる場所にファイルを配置してそのURLを指定する方法が採れます。今回は後者、URLを渡す方法を用いました。画像ファイルはAmazon S3でホスティングしアクセスできるようにしておきます。

Watermark Profile作成のコマンドは以下となります。/watermarkエンドポイントにデータをPOSTするかたちです。

curl -X POST \
     -H "Authorization: Bearer $TOKEN" \
     -H 'Content-Type: application/json' \
     -d '{
             "url": "https://my-bucket.s3.ap-northeast-1.amazonaws.com/mod_alpha_mono.png",
             "name": "mod_alpha_mono",
             "opacity": 1.0,
v             "padding": 0.05,
             "scale": 0.15,
             "position": "upperRight"
         }' \
    "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT/stream/watermarks"

送信データのJSONを整形すると以下となります。opacity(透かしぐあい)、padding(空白)、scale(サイズ)はデフォルト値と同じですが指定しておきました。position(透かしの位置)もデフォルトと同じupperRight右上を指定しています。

{
  "url": "https://my-bucket.s3.ap-northeast-1.amazonaws.com/mod_alpha_mono.png",
  "name": "mod_alpha_mono",
  "opacity": 1,
  "padding": 0.05,
  "scale": 0.15,
  "position": "upperRight"
}

以下が実行結果です。Watermark profileが作成できましたね。

% curl -X POST \
     -H "Authorization: Bearer $TOKEN" \
     -H 'Content-Type: application/json' \
     -d '{
             "url": "https://my-bucket.s3.ap-northeast-1.amazonaws.com/mod_alpha_mono.png",
             "name": "mod_alpha_mono",
             "opacity": 1.0,
             "padding": 0.05,
             "scale": 0.15,
             "position": "upperRight"
         }' \
    "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT/stream/watermarks"

{
  "result": {
    "uid": "bc8fxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "size": 13938,
    "height": 304,
    "width": 312,
    "created": "2022-04-30T12:35:30.468523Z",
    "downloadedFrom": "https://my-bucket.s3.ap-northeast-1.amazonaws.com/mod_alpha_mono.png",
    "name": "mod_alpha_mono",
    "opacity": 1,
    "padding": 0.05,
    "scale": 0.15,
    "position": "upperRight"
  },
  "success": true,
  "errors": [],
  "messages": []
}

Watermark Profileの一覧でも確認しておきましょう。

 % curl -X GET \
     -H "Authorization: Bearer $TOKEN" \
     "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/stream/watermarks"

{
  "result": [
    {
      "uid": "bc8fxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "size": 13938,
      "height": 304,
      "width": 312,
      "created": "2022-04-30T12:35:30.468522Z",
      "downloadedFrom": "https://my-bucket.s3.ap-northeast-1.amazonaws.com/mod_alpha_mono.png",
      "name": "mod_alpha_mono",
      "opacity": 1,
      "padding": 0.05,
      "scale": 0.15,
      "position": "upperRight"
    }
  ],
  "success": true,
  "errors": [],
  "messages": []
}

Watermark Profileを指定して動画のアップロード

Watermark Profileが作成できました。続いて動画のアップロード時にこのWatermark Profileを指定します。Watermark ProfileのUIDをシェル変数として格納しておきましょう。

% WATERMARK_UID="bc8fxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Watermark Profileを指定した動画のアップロードについては、API経由で行う必要があるほか、現在はSimple Uploadつまりcurlコマンドの-Fオプションを使用した方法(200MB以下のサイズ制限があるもの)はサポートされていないという制限があるようです。そのためリンクURLを使った動画のアップロードか、tusプロトコルでのアップロードを行う必要があります。今回はリンクURLを使ったアップロードをAPIで行います。

コマンドは以下となります。/copyエンドポイントにJSONデータをPOSTするかたちです。送信するデータでWatermark UIDを指定している点に注意しましょう。(シェルでの展開のため、"\"で指定するのに気づくまで苦労しました、、。)

curl -X POST \
     -H "Authorization: Bearer ${TOKEN}" \
     -H "Content-Type: application/json" \
     -d "{
             \"url\": \"https://my-bucket.s3.ap-northeast-1.amazonaws.com/IMG_3435.MOV\",
             \"meta\":{
                 \"name\": \"吉祥寺の駅前with透かし\"
             },
             \"watermark\": {
                 \"uid\": \"${WATERMARK_UID}\"
             }
         }" \
     "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/stream/copy"

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

{
  "url": "https://my-bucket.s3.ap-northeast-1.amazonaws.com/IMG_3435.MOV",
  "meta": {
    "name": "吉祥寺の駅前with透かし"
  },
  "watermark": {
    "uid": "${WATERMARK_UID}"
  }
}

以下が実行結果です。

 % curl -X POST \
     -H "Authorization: Bearer ${TOKEN}" \
     -H "Content-Type: application/json" \
     -d "{
             \"url\": \"https://my-bucket.s3.ap-northeast-1.amazonaws.com/IMG_3435.MOV\",
             \"meta\":{
                 \"name\": \"吉祥寺の駅前with透かし\"
             },
             \"watermark\": {
                 \"uid\": \"${WATERMARK_UID}\"
             }
         }" \
     "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/stream/copy"

{
  "result": {
    "uid": "64e6xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "creator": null,
    "thumbnail": "https://videodelivery.net/64e6xxxxxxxxxxxxxxxxxxxxxxxxxxxx/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_3435.MOV",
      "name": "吉祥寺の駅前with透かし"
    },
    "created": "2022-04-30T13:05:22.351924Z",
    "modified": "2022-04-30T13:05:22.351924Z",
    "size": 336065892,
    "preview": "https://watch.videodelivery.net/64e6xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "allowedOrigins": [],
    "requireSignedURLs": false,
    "uploaded": "2022-04-30T13:05:22.351907Z",
    "uploadExpiry": null,
    "maxSizeBytes": null,
    "maxDurationSeconds": null,
    "duration": -1,
    "input": {
      "width": -1,
      "height": -1
    },
    "playback": {
      "hls": "https://videodelivery.net/64e6xxxxxxxxxxxxxxxxxxxxxxxxxxxx/manifest/video.m3u8",
      "dash": "https://videodelivery.net/64e6xxxxxxxxxxxxxxxxxxxxxxxxxxxx/manifest/video.mpd"
    },
    "watermark": {
      "uid": "bc8fxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "size": 13938,
      "height": 304,
      "width": 312,
      "created": "2022-04-30T12:35:30.468522Z",
      "downloadedFrom": "https://my-bucket.s3.ap-northeast-1.amazonaws.com/mod_alpha_mono.png",
      "name": "mod_alpha_mono",
      "opacity": 1,
      "padding": 0.05,
      "scale": 0.15,
      "position": "upperRight"
    }
  },
  "success": true,
  "errors": [],
  "messages": []
}

アップロード後はダッシュボードのほうで確認してみましょう。サムネイル画像にはWatermarkが入っておらず「あれっ?」となりますが、プレビューしてみるとたしかにWatermarkが入っていますね!

まとめ

Cloudflare Streamでビデオコンテンツ(オンデマンド動画)に対して、Watermark(透かし)が入れられることを確認してみました。現在のところAPIでの操作が前提となりますが、透かしのプロファイルを指定するだけで簡単に動画コンテンツにWatermarkを入れることができます。こだわりのコンテンツには是非ともスカした透かしを入れておきたいですよね、便利な機能があらかじめ実装されており嬉しく感じました。なおWatermarkは動画自体に焼き込まれているようで、透かしを外したり別の透かしを使う、透かしの位置を調整する等の場合は再度ビデオをアップロードする必要がある点にも注意しておきましょう。