😃
[AWS Elemental MediaConvert × Laravel]動画変換の基本
前置き
経緯
動画ファイルのmovをmp4に変換したかったのですが、ffmpegなどはサーバーのリソースを圧迫するため、インスタンスがEC2に存在するということもあり、AWS Elemental MediaConvertを使用しました。
ただ、実装した際に参考となる資料が少なかったので、メモとして残します。
そもそもAWS Elemental MediaConvertとは?
AWSが提供する動画変換・配信などをサポートするためのサービス。。。。らしい
動画変換の手順
パッケージ追加
compsoerで動画変換用のパッケージを追加する
composer require meema/laravel-media-converter
構成ファイルの作成
MediaConvertを使用するための構成ファイルを作成する
実行するとconfigディレクトリにmedia-converter.phpという構成ファイルが作成される
php artisan vendor:publish --provider="Meema\MediaConverter\Providers\MediaConverterServiceProvider" --tag="config"
動画書き出し用のIAMロールを作成
動画変換時に使用する権限をIAMロールに作成する
- AmazonS3FullAccess
- AmazonAPIGatewayInvokeFullAccess
上記の権限でロールが作成できたら、作成したロールのARNをメモしておく
(フルアクセスで持たせていますが、全て必要なわけではないので注意)
デフォルトのキューを作成
1.MediaConvrtの管理ページの左ナビゲーションペインで「キュー」を選択し、遷移する
2. オンデマンドキューの「キュー作成」からデフォルト用にキューを作成
3. キューが作成できたら、作成したキューの詳細画面からARNをメモっておく
AWSの設定を追加
.envファイルにAWSの設定を追記する
// AWSアクセスキー
AWS_ACCESS_KEY_ID=xxxxxxx
// AWSシークレットキー
AWS_SECRET_ACCESS_KEY=xxxxxxx
// AWS リージョン
AWS_DEFAULT_REGION=ap-northeast-1
// 「https://リージョン名.console.aws.amazon.com/mediaconvert/home?region=リージョン名#/account」にアクセスし、AWS_MEDIACONVERT_ACCOUNT_URLを確認する
AWS_MEDIACONVERT_ACCOUNT_URL=https://xxxxxxxxx.mediaconvert.us-east-1.amazonaws.com
// 先に作成していたIAM RoleのARN
AWS_IAM_ARN=arn:aws:iam::xxxxxxx:role/MediaConvert_Default_Role
// 先に作成していたデフォルトキューのARN
AWS_QUEUE_ARN=arn:aws:mediaconvert:us-east-1:xxxxxxx:queues/Default
変換処理の実装
実行ファイルを記載する場所はコントローラーでも、共通クラスを置いている場所でも大丈夫ですので、やりやすい場所においてください。
use Meema\MediaConverter\Facades\MediaConvert;
use Meema\MediaConverter\Jobs\CreateVideoConversion;
use Illuminate\Support\Facades\Storage;
$file = "変換したいファイル"
// ファイル名 (拡張子抜き)を取得
$basename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
$file_name = $file->getClientOriginalName();
// 動画の保存先
$dir = 'media_convert/' . auth()->user()->id . '/' . date("Y-m-d H:i:s");
// 変換前のファイル名をS3に保存
$original_file_path = '/'. Storage::disk('ディスク名')->putFileAs($dir, $file, $file_name);
// 変換後のファイルルート
$convert_file_path = '/'. $dir . '/' . $basename . '.mp4';
// 変換後のファイルパス
$convert_mp4_path = $dir . '/' . $basename . '.mp4/mp4/' . $basename . '.mp4';
// withThumbnails()のパラメータの詳細については「https://docs.aws.amazon.com/mediaconvert/latest/apireference/mediaconvert-api.pdf」を確認
$media_setting= MediaConvert::path($original_file_path,変換したい動画ファイルが保存されているバケット名)
->optimizeForWeb()
->withThumbnails(60000, 1001, 1, 1080, null, 80)
->saveTo('/'.$convert_file_path,変換したファイルを保存するバケット名);
// 縦向きの動画の場合に自動回転させる設定を追加
$media_setting->jobSettings['Inputs'][0]['VideoSelector']['Rotate'] = "AUTO";
// movからmp4に変換するためのジョブを作成
$result = $media_setting->createJob();
// 動画のエンコードが終わるまで待機
while ($result['Job']['Status'] == 'SUBMITTED' or $result['Job']['Status'] == 'PROGRESSING') {
// ジョブの情報を取得
$result = MediaConvert::getJob($result['Job']['Id']);
// 3秒まつ
sleep(3);
}
// 動画の変換に失敗した場合はエラーを発生させる
if($result['Job']['Status'] == 'ERROR'){
throw new \Exception("動画の変換に失敗しました。時間をおいていただくか、別のファイルを選択してください。");
}
変換後のファイルパスは$convert_mp4_pathから取得することができまるため、DBに保存したり、動画を取得するなど、使いやすい形で使ってください。
最後に
今回紹介したのはあくまで基本的な動画変換部分だけで、他にもストリーミングに使おうとすると色々と設定がいるみたいなのですが、動画変換を行うだけであれば、比較的簡単に実装を行うことができます。
参考文献
Discussion