Cloudflare Stream がオリジンプロキシー型(Transform)にも対応

に公開

はじめに

これまで Cloudflare Stream での動画変換・配信は

を対象にしていました。

ここに Transform 機能が追加され、オリジンサーバーに配置した動画を Stream 経由で変換・配信することができるようになります。

通信フロー

大まかなフローは以下になります。

Eyeball(ユーザー)は以下のような URL で接続します。
オリジンサーバーと変換パラメータ(OPTIONS)をパスで伝えています。

https://example.com/cdn-cgi/media/mode=video,time=5s,duration=5s,width=500,fit=crop,audio=false/https://pub-8.r2.dev/aus-mobile-demo.mp4
scheme host path 補足
https Stream Transformations を Enable にしたゾーンで
プロキシー中のホスト
/cdn-cgi/media/OPTIONS/SOURCE-VIDEO OPTIONS
変換パラメータ
SOURCE-VIDEO
オリジンの URL

設定

ダッシュボードは Stream Transformations を有効にしたいゾーンを選ぶだけです。

Transformations = Disable というのが有効になっている状況です。
(Disable をクリックすれば Disable になる。ちょっとわかりにくい。)
あとは URL に OPTIONS の指定をしてオリジンから動画を取ってくれば動きます。

OPTIONS 決め

まず、出力形式を決めます。

動画・静止画・静止画の連続、どれかになります。
関連するパラメータを追加で指定可能です。

  • mode 出力形式
    • video ➜ H.264/AAC の MP4
      • audio true | false
      • time 開始時間
      • duration 再生期間
    • frame ➜ 静止画
      • format jpg | png
      • time 取得時間
    • spritesheet ➜ 静止画の連続(JPEG)
      • time 開始時間
      • duration 再生期間
mode=spritesheet の例

次に出力領域(height, width)と、そこにどう絵を収めるのか(fit)を決めます。

  • fit
    • contain 領域の範囲内に、縦横比を尊重し、拡大・縮小
    • scale-down contain と同じだが拡大はしない
    • cover 縦横比を尊重しつつ、height, width の面を全部埋める(真ん中を中心に抜き出し)
  • heightwidth 縦と横
    • contain,scale-down の場合
      • height, width どちらかを指定すれば、縦横比を維持し拡縮。
      • 両方指定の場合、height 観点、width 観点、絵が小さい方で拡縮。
    • cover の場合
      • height, width どちらも指定
      • height 観点、width 観点、絵が大きい方に変換、領域を抜き出す。

fit, hight, width

mode=frame にし、fit と height, width の関係を見てみます。

mode=frame
出力 ➜ 640 x 340(オリジナル)

mode=frame,width=320
出力 ➜ 320 x 180

mode=frame,width=320,height=113
出力 ➜ 202 x 114(width は 1/2、height は 1/3 ➜ 後者を選択)

mode=frame,width=320,height=113,fit=cover
出力 ➜ 320 x 112(width は 1/2、height は 1/3 ➜ 前者を選択 ➜ 枠を埋めるよう切り取る)

URL 変換

Snippets を使って固定の OPTIONS を仕込んだり、クエリーパラメータで渡すようにすれば、ユーザーがアクセスする URL を簡素化出来そうです。(URL Rewrite Rules ではうまく動かせず。。GA 待ちなのか、なんか間違ってたのか。。。)

snippets 抜粋
    const pathLabel = url.pathname.split('/')
    const movieName = pathLabel.filter(label => label.length > 0).pop()
    const transOptions = 'width=300,audio=false,time=10s,duration=5s'
    const nUrl = 'https://' + url.hostname + '/cdn-cgi/media/' +  transOptions + '/' + bucketUrl + movieName
    return await fetch(nUrl);

最後に

将来的には GA とともに Images の Transform のような機能が追加され、同様の使用感を享受できるのではないかと想像しています。
Beta の段階では無料とのことなので R2 に MP4 を置いてお試ししてはいかがでしょうか。

Discussion