Amazon Elastic TranscoderからAWS Elemental MediaConvertに移行しました
はじめに
インフラコスト削減の一環として、アップロードされた動画ファイルのトランスコードに使っているAWSのサービスをAmazon Elastic TranscoderからAWS Elemental MediaConvertに移行しました。
サービスの紹介
私たちはオンラインサロン・コミュニティ専用サービス「FANTS(ファンツ)」を開発しています。
AWS Elemental MediaConvertとは
移行先のサービスになります。
Amazon Elastic Transcoder(以降、Transcoder)同様、動画を変換・加工することのできるサービスです。Amazon Elastic Transcoderよりもかなり機能が多く、変換にかかる料金単価も基本的にAWS Elemental MediaConvert(以降、MediaConvert)の方が安く設定されています。
移行にあたって検討したこと
移行するにあたって、下記のことを意識して調査や検証をしました。
- 既存のワークロードに大きな変更が入らないか?
- 移行するにあたって、サーバサイドアプリケーションのコードに大きな改修が必要にならないかを調査しました
- 事前調査の結果、TranscoderとMediaConvertはよく似た仕組みで動いていたので、アプリケーションのコードの改修はそこまで大きくありませんでした
- 移行前と後で、対応できなくなるパターンはないか?
- 今までサービスとして提供できていたものが移行によって出来なくなってしまうとユーザ体験が損なわれてしまうため、事前の調査でさまざまな動画ファイルを使って出力結果を確認しました
- さらにコストを下げることはできないか?
- そもそもTranscoderよりもMediaConvertの方が変換にかかる料金単価は半分程度ですが、工夫してさらに下げることができないかを検討しました
- MediaConvertにはQVBRレート制御モードというものがあり、希望する品質レベルに合うようにビットレートを自動で調節してくれる機能があります
- QVBRレート制御モードを使うことで、品質を極力落とさずにビットレートを下げることができ、ネットワーク転送量にかかるインフラコストの節約が望めるため、適用しました
移行作業
FANTS内にアップロードされた動画をトランスコードする導線はサーバサイドアプリケーションのコードで制御していたので、移行作業は下記の順番で実施しました。
- MediaConvert含む移行に必要なAWSインフラ一式のデプロイ
- サーバサイドアプリケーションのトランスコード周りのコードのデプロイ
移行作業では大きな問題は発生せず無事終了しました。
移行した結果
今回はインフラコストの削減が主な目的でした。
サービス移行後、数ヶ月程度CostExplorerで動画のトランスコード関係で発生する費用を比較しました。
2023年11月の下旬ごろにサービスの移行をしています。
Transcoderを使っていた時期に比べて、平均して45%程度のコスト削減に成功しています。
移行にあたってハマった箇所
MediaConvertは高機能かつ多機能なサービスですが、Transcoderに比べて融通が効かない(?)点が結構多かった印象です。
雑にTranscoderに動画ファイルを投げてもTranscoderが内部でうまくやってくれていた部分がMediaConvertではやってくれないケースが多々あり、サービス間の挙動をなくすための調査に時間がかかりました。
ここでは、TranscoderからMediaConvertへ移行するにあたってハマった点をいくつか紹介しようと思います。
AWS SDK for Rubyでのジョブリクエストの方法
いきなりTranscoderと直接関わりのない内容ですが紹介します。
MediaConvertはRuby gemとしてAWS SDK for Rubyが公式で用意されています。
使い方は公式ドキュメントに書かれています。
MediaConvertに対してジョブをリクエストする際には、create_job
を実行する必要があるのですが、このリクエスストパラメータとして渡しているhashがとても複雑です。
ドキュメントを見てみると、パラメータにはそれぞれ専用のRubyのクラスが定義されていて、これを使ってhashを組み立てていく必要があるように一見思います。
調査していて判明したのですが、どうやらこれらのクラスは使わなくても、単純なhashの組み合わせでパラメータで組み立てても同じ挙動になるみたいでした。
なので、一度MediaConvertで対象のジョブを手動で実行して、その結果として出力されるJSONをほぼそのままrubyのhashに置き換えることで解決できました(出力されるJSONのKeyはキャメルケースなのでスネークケースに変換する必要はあります)。
MediaConvertではサムネイルが自動作成されない
Transcoderではトランスコード時にサムネイルも作成してくれていたのですが、MediaConvertではサムネイルは自動では作成してくれません。
公式の移行ガイド(pdf)でも言及されています。
Generating thumbnails works differently in AWS Elemental MediaConvert compared to Amazon Elastic
Transcoder. In Elastic Transcoder, if users attach a video configuration to a preset, they are also required
to attach a thumbnail configuration by default. In AWS Elemental MediaConvert, generating thumbnails is
optional. Users are required to create a file output group, remove the audio from the output, change the
codec to JPEG Frame Capture, and under Output Settings, change the container to ‘No Container’. Users
can then configure the image resolution and interval (framerate controller).
自動作成はされませんが、変換時に作成することは可能です。出力を作成するときに、ソースとなる動画から1フレームだけ使って画像形式でトランスコードすることで実現できます。
生成されるサムネイルですが、TranscoderとMediaCovnertとで命名規則が異なります。
Transcoderでは末尾に-00001.png
といった修飾子がつきますが、MediaConvertでは末尾に000000.png
といった修飾子がつきます。
この修飾子ですが、ジョブの設定時に変更ができないみたいなので注意が必要かもしれません。
MediaConvertはデフォルトでは回転を修正しない
スマートフォンで動画を撮影するときに、画面を横や上下逆にして撮影する場合があると思います。
Transcoderでは、そういった画面の回転を考慮してトランスコードが行われます(例: スマートフォンを上下逆にして撮影をした場合であっても、回転が修正されて出力される)。
一方、MediaConvertでは回転を修正せずにトランスコードが行われるので、上下逆で撮影した動画は上下が逆のまま出力されます。
どうやら、MediaConvertがリリースされてしばらくの間は対応ができなかったようですが、現在ではジョブのパラメータで回転を修正する設定があるので、これで対応できました。
音声ファイルをトランスコードにかけたときにエラーになる
厳密には動画のトランスコードの話ではないのですが、Transcoderはmp3ファイルのような音声ファイルをトランスコードにかけると、画面が真っ暗な音声のみの動画が生成されるという仕組みがあります。
MediaConvertでも同じようなことができるのではないかと思って、動画と同じジョブ設定のリクエストの入力ファイルに音声ファイルを指定すると、リクエストがエラーになります。
Transcoderのように勝手に作ってはくれませんが、MediaConvertでも同じようなことは実現可能です。
ブラックビデオの作成という機能を使って黒画面の音声のみの動画を作成することができます。
ただし、MediaConvertの場合は専用のジョブ設定を用意しないといけないので、そこだけはハンドリングする必要がありそうです。
縦と横両方のサイズを指定すると、縦と横両方に黒い帯が出力される
MediaConvertで、出力ファイルの縦のサイズと横のサイズの両方を固定値にしてトランスコードをかけると、動画再生時に下記のようになります(下記はvideo.jsで再生したもの)[1]。
明確な原因まではわかりませんでしたが、両方の長さを同時に指定せずに、片方のサイズのみを指定すると、指定した方向には黒い帯は表示されなくなります。
MediaConvertはSNS統合されていない
TranscoderはSNSと統合されており、ジョブの進捗に関する情報をSNSで通知することができます。
MediaConvertはSNSと統合はされていません。ただし、MediaConvertのジョブの進捗に関する情報はEventBridgeで追跡可能です。なので、MediaConvertのジョブの進捗に関する情報をEventBridgeで捕捉して、そのターゲットにSNSを設定することでTranscoderと同等の仕組みを構築することができます。
なお、MediaConvertとTranscoderではジョブの進捗に関する内容が若干異なっているので注意が必要です。
まとめ
今回はインフラコスト削減のために、Amazon Elastic TranscoderからAWS Elemental MediaConvertへの移行を行いました。
事前調査の段階では、動画関連の専門用語もよく分かっていない状態でしたが、調査の過程で色々と勉強になりました。
思ったより情報が見つからなかったり、情報の探し方が難しかったりと苦労しましたが、コスト削減効果も大きかったのでよかったです。
-
https://pixabay.com/ja/videos/川-蝶-葉っぱ-サマーカフェ-184427/ より素材をお借りしました ↩︎
Discussion