Cloud BatchとFFmpegで動画変換を安くできるか検証してみた

Google Cloud
この記事は約9分で読めます。

こんにちは!大嶋です!
前回Transcoder APIとCloud Functions(現Cloud Run関数)を利用して動画変換をするための方法を紹介しました。今回は誰もが気にする料金をできるだけ抑えるために、Cloud BatchとFFmpegを利用して動画変換を安くできるか検証します。

本記事でわかること

  • Cloud BatchでFFmpegを実行する方法
  • 「Cloud BatchとFFmpeg」と「Cloud Run関数とTranscoderAPI」の比較
  • まとめ

Cloud BatchでFFmpegを実行する方法

今回は前回のCloud Function同様、Cloud Storageにデータが格納されたタイミングで自動起動させたかったため、WorkflowsでCloud Batchジョブを起動するよう定義をしていきます。Cloud Batch内で動かすFFmpegは、Cloud Run関数と比較するためにいくつかの解像度へ変換するよう定義しています。細かい手順は、公式ドキュメントをご確認ください。

バッシュファイル(FFmpegによる動画変換)とDockerイメージ

以下はCloud Batch内で起動されるバッシュファイルです。

#!/bin/sh
set -e  # エラーが発生した場合にスクリプトを終了する
set -x  # デバッグモードを有効にする

INPUT_FILE=$1
OUTPUT_DIR=$2

# 一時ファイルのパスを設定
LOCAL_INPUT_FILE="/tmp/input_file"
LOCAL_OUTPUT_DIR="/tmp/output_hls"

# GCSからローカルにファイルをダウンロード
echo "Downloading $INPUT_FILE from GCS..."
gsutil cp $INPUT_FILE $LOCAL_INPUT_FILE

# 解像度のリスト
resolutions="360p:640x360 480p:720x480 720p:1280x720 1080p:1920x1080 1440p:2560x1440"

# 各解像度に変換
for res in $resolutions; do
  res_name=$(echo $res | cut -d':' -f1)
  res_size=$(echo $res | cut -d':' -f2)
  LOCAL_OUTPUT_FILE="${LOCAL_OUTPUT_DIR}_${res_name}.m3u8"
  OUTPUT_FILE="${OUTPUT_DIR}/output_${res_name}.m3u8"
  
  echo "Converting $LOCAL_INPUT_FILE to $LOCAL_OUTPUT_FILE with resolution $res_size..."
  ffmpeg -i $LOCAL_INPUT_FILE -vf "scale=$res_size" -hls_time 10 -hls_playlist_type vod  $LOCAL_OUTPUT_FILE
  
  echo "Uploading $LOCAL_OUTPUT_FILE to $OUTPUT_FILE..."
  gsutil cp ${LOCAL_OUTPUT_DIR}_${res_name}* $OUTPUT_DIR/
done

echo "Conversion completed successfully."

以下は上記バッシュファイルを起動させるためのDockerfileです。

# ベースイメージとしてjrottenberg/FFmpegを使用
FROM jrottenberg/ffmpeg:4.3-alpine

# 必要なパッケージをインストール
RUN apk add --no-cache python3 py3-pip gcc musl-dev libffi-dev python3-dev curl

# Google Cloud SDKのインストール
RUN curl https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.tar.gz > /tmp/google-cloud-sdk.tar.gz \
  && mkdir -p /usr/local/gcloud \
  && tar -C /usr/local/gcloud -xvf /tmp/google-cloud-sdk.tar.gz \
  && /usr/local/gcloud/google-cloud-sdk/install.sh

# PATHにGoogle Cloud SDKを追加
ENV PATH=$PATH:/usr/local/gcloud/google-cloud-sdk/bin

# スクリプトをコンテナにコピー
COPY transcode.sh /usr/local/bin/{バッシュファイル名}.sh

# スクリプトに実行権限を付与
RUN chmod +x /usr/local/bin/{バッシュファイル名}.sh

# エントリーポイントを設定
ENTRYPOINT ["/usr/local/bin/{バッシュファイル名}.sh"]

上記2つをArtifact RegistryリポジトリにDockerイメージとして保存してください。

Workflows(Cloud Batch起動)

WorkflowsでCloud Batchジョブを実行するために、ワークフローを用意しデプロイします。

# workflow.yaml
main:
  params: [event]
  steps:
    - init:
        assign:
          - project: "プロジェクト名"
          - location: "リージョン"
          - inputFile: ${event.data.name}
          - inputBucket: "バケット名"
          - outputBucket: "オブジェクト名"
          - outputFile: ${event.data.name}
    - startBatchJob:
        call: googleapis.batch.v1.projects.locations.jobs.create
        args:
          parent: ${"projects/" + project + "/locations/" + location}
          body:
            taskGroups:
              - taskSpec:
                  runnables:
                    - container:
                        imageUri: ${"Artifact Registryに保存したイメージのURL"}
                        entrypoint: "エントリーポイント"
                        commands:
                          - ${"gs://" + inputBucket + "/" + inputFile}
                          - ${"gs://" + outputBucket + "/" + outputFile}
                  computeResource:
                    cpuMilli: 8000
                    memoryMib: 30720
                taskCount: 1
            allocationPolicy:
              instances:
                policy:
                    machineType: "マシンタイプ"
                installOpsAgent: true
          connector_params:
            timeout: 3600
    - done:
        return: "Batch job started"

上記でCloud Batchのジョブは実行できるようになりました。
あとは任意のタイミングで実行されるように、スケジューラー登録をしてください。

「Cloud BatchとFFmpeg」と「Cloud Run関数とTranscoderAPI」の比較

ここで比較するのは、料金と実行時間です。
今回は5GB程度の動画を利用しています。

まず今回のCloud Batchですが、内部でCompute Engineを呼び出しているため、Compute Engineのマシンタイプとインスタンスの起動時間によって金額は変わってきます。いろいろ試してみましたが、FFmpegの処理能力もあってか、以下に記載のマシンタイプだと1回当たりの起動に対する実行時間は大きくは変わらなかったです。CPUをもう少し下げたときには、30分を超えたりもしたので、「n1-highcpu-32」でほぼ頭打ちでした。

マシンタイプ実行時間(分)料金(円)
n1-highcpu-322082
n1-standard-3220105
g2-standard-2420116
g2-standard-4817231
g2-standard-9617463

続いて、前回のCloud Run関数ですが、Cloud Run関数自体の料金はほぼ0円でTranscoder APIに料金が結構かかりました。料金体系の詳細は、公式ドキュメントをご覧ください。今回はSD、HD(2つ)、UHDの4つを処理した1回あたりの料金を算出しています。まず実行時間はかなり早かった印象です。ただその分Transcoder APIの変換料金は高いですね。

実行時間料金(円)
数秒160

上記で実際に比較してみましたが、動画変換の時間を早める必要がある場合は、Cloud Run関数とTranscoder API、料金重視の場合はCloud BatchとFFmpegがよいという結果になりました。

ただし処理する動画の容量や時間に料金は依存すると思うので、実際に確認してみてください。

まとめ

今回の検証では、Cloud BatchとFFmpegを使ったほうが安く動画変換できることが分かりましたね。もし要件の中でスピードを求めれらている場合は、Cloud Run関数とTranscoder APIを試してみるのも良さそうですね。

おわり。

Google および Google Cloud Platform™ service は Google LLC の商標であり、この記事は Google によって承認されたり、Google と提携したりするものではありません。

コメント

タイトルとURLをコピーしました