初めまして、DELISH KITCHEN 開発部の吉田と申します。この記事ではAWS Elemental MediaConvertを使ってレシピ動画のサムネイルを作成した方法を紹介します。
サムネイル作成の背景
DELISH KITCHEN はレシピを動画でわかりやすく基本的な料理からアレンジまで様々なレシピを公開しています。
スマホでブラウザ版のDELISH KITCHENをみていただいた場合、レシピの各工程は手順の説明とポイントを表示しています。
今回はより工程が分かりやすくなるようここに画像を追加する運びとなりました。
アプリやPCブラウザ版のDELISH KITCHENでは工程の動画が挿入されていることから、動画のサムネイルを工程画像として利用することにしました。 しかしながら現在設定されているサムネイルは動画開始時点のキャプチャになっています。
そのため、動画開始時点のフレームになっているサムネイルをすでに動画の変換処理で利用しているAWS Elemental MediaConvertを用いてレシピごとに適切なフレームで設定できるよう実装を進めました。
AWS Elemental MediaConvertとは
AWS Elemental MediaConvert(以下、MediaConvertとします)はファイルベースの動画処理サービスで、従来のブロードキャストおよびマルチスクリーンデバイスへのインターネットストリーミングに必要な形式にメディアを変換することができます。基盤となるインフラのセットアップや管理、メンテナンスは不要で、必要なビデオ処理設定でジョブを送信するだけで使用を開始することができます。ジョブはトランスコード作業を行うもので、入力ファイルと出力ファイルを指定し、どのようなファイルを作成したいか、どのようなフォーマットで作成したいか等を設定します。 詳しくはこちら
取り組んだこと
サムネイルの作成にはMediaConvertのフレームキャプチャ機能を利用しました。 フレームキャプチャ機能は動画の静止画を作成するための機能になります。
サムネイル作成にあたっては既存で1本のレシピ動画を指定した秒数でクリッピングしているジョブがあるのでそこにフレームキャプチャを組み込むことにしました。
動画のキャプチャタイミングにはフレームレートを指定する必要があります。ドキュメントではコンソールによる設定を例にしていましたが、コンソールでは静的な値しか持つことができません。そのため、レシピごとに指定したいフレームが異なる今回の場合、コンソールによる設定ではなく動的な値を利用できる形で実装する必要がありました。
動的な値を利用するための実装方法は2つです。AWS CLIを使用してJSONによってジョブ仕様を設定する方法、あるいはSDKを使う方法です。今回は既存の実装がAWS CLIを用いていたため、フレームキャプチャのジョブ仕様もJSONで実装することにしました。
今回は弊社でMediaConvertが既に利用されていたこともあり、以下1-3の手順は特に行いませんでしたが、初めて利用する場合は以下の手順を踏む必要があります。
- ファイル用のストレージを作成する
- Amazon S3 コンソールを使用してバケットを作成します。MediaConvert は、Amazon S3 または HTTP か HTTPS を使用するサーバーからの入力ファイルを受け入れます。
- IAM のアクセス許可をセットアップする
- MediaConvert が S3 バケットに対する読み込みと書き込みを実行できるようにするには、それが担う Identity and Access Management (IAM) ロールを作成します。
- 符号化するソースファイルをアップロードする
- Amazon S3 コンソールを使用して、Amazon S3 バケットにソースファイルをアップロードします。
- ジョブを作成する
- ビデオファイルを 1 つ、または複数の出力に変換するための MediaConvert ジョブを作成します。
引用元: AWS Elemental MediaConvert 公式ページ
こちらが作成したJSONです。一部の設定は省略しています。
{ "Settings": { "OutputGroups": [ { ... "Name": "File Group", "Outputs": [ { "ContainerSettings": { "Container": "RAW" }, "VideoDescription": { "Width": <出力キャプチャの幅>, "Height": <出力キャプチャの高さ> "CodecSettings": { ... "Codec": "FRAME_CAPTURE", "FrameCaptureSettings": { "FramerateNumerator": <fps>, "FramerateDenominator": <キャプチャするフレーム番号>, "MaxCaptures": 2, ... } }, ... }, "Extension": "jpg", "NameModifier": <名前修飾子> } ], "OutputGroupSettings": { "Type": "FILE_GROUP_SETTINGS", "FileGroupSettings": { "Destination": <出力ファイルの格納先> } } } ], ... "Inputs": [ { "FileInput": <入力ファイルの格納先> } ] } }
出来上がったサムネイルがこちらです。
実装にあたりつまづいたところ
本実装においては3点つまづいたところがありました。
フレームのキャプチャタイミングは秒数で指定できない
- 当初、キャプチャのタイミングは動画のクリッピングと同様にタイムコードで指定できるのかと思っていたのですが、フレームキャプチャではタイムコードでの指定ができない仕様となっていました。 次に思いついた方法がサムネイルにしたい秒数が動画のスタート時点となるよう元の動画をクリップして0フレーム目をサムネイルに指定する方法です(以下3.参照)。しかしこちらについてもMediaConvertは動画あるいはオーディオの出力があるジョブにおいてのみフレームキャプチャを作成することができフレームキャプチャのみの出力ジョブを作成することはできません。毎回不要な動画が作成されてしまうので断念しました。したがって今回は以下2で紹介するframerateによる設定を採用しました。
framerateの設定
- キャプチャのタイミングを指定するには、framerateを設定します。具体的な設定は「framerate = framerateDenominator / framerateNumerator」となり、framerateDenominatorにはFPS(フレームレート)、framerateNumeratorはキャプチャしたいフレーム番号を指定します。 サムネイル作成時はキャプチャ対象の動画を確認しながら秒数でキャプチャのタイミングを指定していたため、これをフレーム番号に変換する必要があるのですがどうすれば適切に指定した秒数をフレーム番号に指定できるのか苦慮しました。
コンソールで確認するとframerateは以下のように設定することになります。この場合はビデオのフレームレートが30FPSで、50フレームごとに1フレームをJPEGファイルにキャプチャします。 (参考: AWS for M&E Blog)
最大キャプチャ数は2にする必要があること
- MediaConvertは常に動画開始時点のフレームをキャプチャするため、2枚で設定しておかないと欲しいキャプチャは取得できません。
ジョブが完了すると、出力のS3バケットに2つのポスターフレームJPG画像が見つかるので2つ目の画像ファイル(
clip-poster.0000001.jpg
)が指定したフレーム番号のキャプチャ画像になります。
- MediaConvertは常に動画開始時点のフレームをキャプチャするため、2枚で設定しておかないと欲しいキャプチャは取得できません。
ジョブが完了すると、出力のS3バケットに2つのポスターフレームJPG画像が見つかるので2つ目の画像ファイル(
終わりに
本記事ではAWS Elemental MediaConvertを利用して動画のサムネイルを作成する方法を紹介しました。ここまでお読みいただきありがとうございました。