LoginSignup
2
1

GCS 上の動画を Cloud CDN を経由してストリーミング配信する

Last updated at Posted at 2024-02-23

概要

GCS に HTML ファイル、動画ファイルを配置し、それをクライアントから観れるようにします。
一応ありがちな Cloud CDN を経由するパターンにします。GCS の組み込みキャッシュも効きますが、ここは Cloud CDN で。
ちなみに 2024/02/23 現在 Media CDN は Google にリクエストしないと使えず、U-NEXT が本気で使っている代物で大衆化されてなさそうなので使ってません。

環境

  • Windows 11 Pro
  • Ubuntu 22.04 on WSL2
  • Python 3.10.7

やり方

Python を使うので必要な人は適当なディレクトリを掘って pyenv で local にバージョンを指定してください。以下は一例。

mkdir hls-poc && cd hls-poc
pyenv install 3.10.7
pyenv local 3.10.7
$ cat .python-version
3.10.7

ffmpeg をインストールする

sudo apt -y update
sudo apt install ffmpeg

動画ファイルを取得する

ファイルが入り乱れるのでフォルダ内で作業します。

mkdir resource && cd resource
wget https://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_720p_h264.mov
MOV=big_buck_bunny_720p_h264.mov

Big Buck Bunny(BBB) という動画が公開されています。感謝。ライセンスはご確認を。

ffmpeg でマニフェストとセグメントファイルを作成する

ffmpeg -i $MOV \
-c:v copy -c:a copy \
-f hls \
-hls_time 9 \
-hls_playlist_type vod \
-hls_segment_type fmp4 \
-hls_fmp4_init_filename "init.mp4" \
-hls_segment_filename "seg.%3d.mp4" \
media.m3u8

こんな感じに。元の mov ファイルは削除して大丈夫です。

$ ls
init.mp4     seg.003.mp4  seg.008.mp4  seg.013.mp4  seg.018.mp4  seg.023.mp4  seg.028.mp4  seg.033.mp4  seg.038.mp4  seg.043.mp4  seg.048.mp4  seg.053.mp4  seg.058.mp4  seg.063.mp4
media.m3u8   seg.004.mp4  seg.009.mp4  seg.014.mp4  seg.019.mp4  seg.024.mp4  seg.029.mp4  seg.034.mp4  seg.039.mp4  seg.044.mp4  seg.049.mp4  seg.054.mp4  seg.059.mp4  seg.064.mp4
seg.000.mp4  seg.005.mp4  seg.010.mp4  seg.015.mp4  seg.020.mp4  seg.025.mp4  seg.030.mp4  seg.035.mp4  seg.040.mp4  seg.045.mp4  seg.050.mp4  seg.055.mp4  seg.060.mp4  seg.065.mp4
seg.001.mp4  seg.006.mp4  seg.011.mp4  seg.016.mp4  seg.021.mp4  seg.026.mp4  seg.031.mp4  seg.036.mp4  seg.041.mp4  seg.046.mp4  seg.051.mp4  seg.056.mp4  seg.061.mp4  seg.066.mp4
seg.002.mp4  seg.007.mp4  seg.012.mp4  seg.017.mp4  seg.022.mp4  seg.027.mp4  seg.032.mp4  seg.037.mp4  seg.042.mp4  seg.047.mp4  seg.052.mp4  seg.057.mp4  seg.062.mp4

GCS バケットを用意し、CORS ポリシーを更新する

バケット作成

PROJECT=[YOUR_OWN_PROJECT_ID]
cd ..
gsutil mb gs://$PROJECT

JSON ファイル作成

cors.json
[
    {
      "origin": ["*"],
      "method": ["GET"],
      "responseHeader": ["Content-Type"],
      "maxAgeSeconds": 3600
    }
]

ポリシー適用

gcloud storage buckets update gs://$PROJECT --cors-file=cors.json

resource フォルダをアップロードする

gsutil cp -r resource gs://$PROJECT

index.html をアップロードする

videoSrc は GCS にアップロードした際の media.m3u8 ファイルの GCS パスに変更してください。あとはそのままで OK です。
あと、GCS は外部に公開してください。これ重要です。

<!DOCTYPE html>
<script src="https://cdn.jsdelivr.net/npm/hls.js@1"></script>
<div>
  <h2>HTTP Live Streaming</h2>
  <video id="video" width="640" height="360" controls></video>
</div>
<script>
  var video = document.getElementById("video");
  var videoSrc =
    "https://storage.googleapis.com/[YOUR_OWN_BUCKET_NAME]/resource/media.m3u8";
  if (Hls.isSupported()) {
    var hls = new Hls();
    hls.loadSource(videoSrc);
    hls.attachMedia(video);
  } else if (video.canPlayType("application/vnd.apple.mpegurl")) {
    video.src = videoSrc;
  }
</script>
gsutil cp index.html gs://$PROJECT

いったん、これで GCS にある index.html にアクセスすれば BBB が再生される状態です。確認してみてください。
以下が表示される Web ページです。すでに LB を用意した後の URL ですが、私の場合は http://34.144.254.201/index.html にアクセスしています。(すでにこの IP アドレスは解放しています。アクセスできませんので悪しからず。)
bbb.png

Cloud CDN を有効化しつつ Cloud Load Balacing で公開する

今回は簡易に HTTP で公開します。
が、この手順についてはコンソール上でぽちぽちなり Terraform で管理するなりするための手順が公式ドキュメントにしっかり記載されていますので、こちらをご覧ください。

念のため確認

まずは GCS の index.html に直アクセスした場合の様子です。
200 OK が返ってきています。
devtool1.png

次に、LB 経由で index.html にアクセスした場合の様子です。
一回目は Cloud CDN にキャッシュが保存されていないので、開いたらまず画面更新してください。
すると、以下の結果となるはずです。
devtool2.png

304 Not Modified が返ってきています。

これはキャッシュされたリソースへの暗黙のリダイレクトです。

つまり、一回目のアクセスによって静的コンテンツは Cloud CDN(お近くのエッジキャッシュ)にキャッシュされ、二回目のアクセスは Cloud CDN のキャッシュにアクセスしています。
おめでとうございます 🎉

余談

実は、index.html はキャッシュヒットしていますが、その他の動画コンテンツは下図の通り from disk cache、つまりお使いのブラウザキャッシュから読み込まれています。
devtool3.png

Cloud CDN と言えどそれを支えるのは単なるサーバです。できることならサーバの負荷は減らしたいですし、動画を見る側にとってもなるべく早く観たいはずです。
なので、毎回 Cloud CDN のキャッシュサーバにアクセスするのではなく、可能な範囲でブラウザのキャッシュから読み込むようになっています。
キャッシュに興味のある方は、以下 URL にアクセスしてキャッシュが保存されている場所を確認するなり、Chrome の設定画面よりキャッシュを削除するなりしてください。
chrome://version/

キャッシュなしで試したい場合は開発者ツールの Network タブより Disable cache を選択しましょう。毎回 200 OK で返ってくるようになります。
なぜこのチェックボックスをオンにしたらキャッシュヒットしなくなるの?と思った方、キャッシュの世界へようこそ。

devtool4.png

参考にしたサイト

HLS.js 公式 GitHub リポジトリ

localhost で簡単に HLS 配信を Python でしてみる

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1