😃

[AWS Elemental MediaConvert × Laravel]動画変換の基本

2022/08/28に公開

前置き

経緯

動画ファイルのmovをmp4に変換したかったのですが、ffmpegなどはサーバーのリソースを圧迫するため、インスタンスがEC2に存在するということもあり、AWS Elemental MediaConvertを使用しました。
ただ、実装した際に参考となる資料が少なかったので、メモとして残します。

そもそもAWS Elemental MediaConvertとは?

AWSが提供する動画変換・配信などをサポートするためのサービス。。。。らしい
https://aws.amazon.com/jp/mediaconvert/

動画変換の手順

パッケージ追加

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に保存したり、動画を取得するなど、使いやすい形で使ってください。

最後に

今回紹介したのはあくまで基本的な動画変換部分だけで、他にもストリーミングに使おうとすると色々と設定がいるみたいなのですが、動画変換を行うだけであれば、比較的簡単に実装を行うことができます。

参考文献

https://www.wenyanet.com/opensource/ja/618425364542c3076700db62.html

Discussion