MediaConvertを利用した動画の自動変換環境をCFnでつくってみた

MediaConvertにて自動で動画変換(mp4→HLS)する環境をまるっと作成するCFnテンプレートです。
2021.09.27

MediaConvertの検証環境がほしくCFnで構築してみましたのでそのアウトプットです。今回はS3にmp4形式の動画ファイルのPUTで、MediaConvertでHLS形式に自動変換する構成をテンプレートにしました。

sa20210926-01

上記、構成を作成するテンプレートは以下になります。CFnの拡張であるAWS SAMを利用していますが、本ブログではCFnと一括りで表現し、SAMの利用方法等についても割愛しています。

VoD動画配信環境については、AWSからソリューションが提供されていますが、MediaConvertに限定した検証を行いたかったので作成しました。

前提

  • SAM CLI, version 1.31.0
  • Python 3.8

テンプレートの説明

CFnテンプレートのフォルダ構成は以下になります。

.
├── functions
│   └── start-media-convert-job
│       ├── app.py                  … Lambda Functionのコード
│       └── job.json                … MediaConvertジョブ定義
├── job-template
│   └── settings.json               … MediaConvertジョブテンプレート定義
└── template.yml                    … CFnテンプレート

各ファイルについて簡単に説明します。

template.yml

論理IDのInputBucketOutputBucketでMediaConvertの入出力で利用するS3バケットを作成しています。LogBucketは作成されたS3バケットのサーバアクセスログを保管するバケットになります。

LambdaFunctionは、S3トリガーで呼び出しされるLambda Functionとなります。コードはfunctionsディレクトリ配下のapp.pyとなります。環境固有の情報については、環境変数で定義しています。

MediaConvertServiceRoleMediaConvertJobPolicyは、MediaConvertのロール、ポリシーを作成しています。ポリシーは入出力ファイルが保存されているS3へのアクセス権限を与え、Resourceエレメントを定義し該当のS3バケットのみに制限しています。

LambdaFunctionRoleMediaConvertJobExecutePolicyでは、Lambda Functionのロール、ポリシーを作成しています。MediaConvertのジョブを実行するCreateJob権限を与えています。また、ジョブ実行時には、MediaConvertにロールを渡す必要がありますので、PassRole権限も付与しています。

MediaConvertJobTemplateでは、MediaConvertのジョブテンプレートを作成しています。Lambda FunctionはMediaConvertのジョブを実行しますが、再実行(ジョブ定義の再利用)を想定し、ジョブテンプレートにしています。

SettingsJsonプロパティは、ジョブテンプレートのトランスコーディングジョブ設定(別の形式に変換する設定)をJSON形式で指定します。設定をテンプレート内に直接書いてもよかったのですが、CFnの組み込み関数を利用して、ジョブテンプレートの定義を別ファイル(job-template/settings.json)に記述しました。

job.json

ジョブ実行に関する設定です。ジョブテンプレートで指定していない設定(ジョブ実行時に可変となる部分)をこちらで定義しています。Inputsが入力設定となりFileInputは空で定義し、ジョブ実行時にLambda Functionにて指定しています。OutputGroupsが出力グループの設定になり、入力設定同様、Destinationはジョブ実行時に指定します。ジョブ設定のJSONについては以下が参考になります。

JSON設定を作成する際は、有効なJSONがインタラクティブに生成できる、MediaConvertコンソールの利用が推奨されています。

settings.json

ジョブテンプレートの設定です。JSON設定の仕様については、あまりドキュメントが見当たりませんので、ジョブ定義同様MediaConvertコンソールの利用してのJSON作成をお勧めします。

app.py

Lambda Functionのコード定義です。以下ドキュメント等を参考にしました。

環境固有の情報は、ハンドラーに渡されるイベントデータ、環境変数から取得しています。ジョブテンプレートを読み込み、ジョブ実行に必要な情報を指定しcreate_jobでジョブを実行しています。

やってみた

環境構築

こちらのテンプレートをデプロイして環境を構築しました。

sam deploy(一部マスクしてます)
$ sam deploy --guided
Configuring SAM deploy
======================


        Looking for config file [samconfig.toml] :  Not found
    
        Setting default arguments for 'sam deploy'
        =========================================
        Stack Name [sam-app]: test-sam-app
        AWS Region [us-east-1]: ap-northeast-1
        Parameter SystemName [test]: 
        Parameter EnvType [dev]: 
        Parameter EndPointUrl [https://xxxxxxxxx.mediaconvert.ap-northeast-1.amazonaws.com]: https://ooooooooo.mediaconvert.ap-northeast-1.amazonaws.com
        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
        Confirm changes before deploy [y/N]: 
        #SAM needs permission to be able to create roles to connect to the resources in your template
        Allow SAM CLI IAM role creation [Y/n]: n
        Capabilities [['CAPABILITY_IAM']]: CAPABILITY_NAMED_IAM
        Save arguments to configuration file [Y/n]: 
        SAM configuration file [samconfig.toml]: 
        SAM configuration environment [default]: 
    
        Looking for resources needed for deployment:
         Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-1serkyaxr8xb6
         A different default S3 bucket can be set in samconfig.toml
    
        Saved arguments to config file
        Running 'sam deploy' for future deployments will use the parameters saved above.
        The above parameters can be changed by modifying samconfig.toml
        Learn more about samconfig.toml syntax at 
        https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html

Uploading to test-sam-app/a9e4df5ce784687eca221f70df32ae3c  1670 / 1670  (100.00%)
Uploading to test-sam-app/c6d7744d20981a1572d50abfdd75a872  1359 / 1359  (100.00%)

        Deploying with following values
        ===============================
        Stack name                   : test-sam-app
        Region                       : ap-northeast-1
        Confirm changeset            : False
        Deployment s3 bucket         : aws-sam-cli-managed-default-samclisourcebucket-1serkyaxr8xb6
        Capabilities                 : ["CAPABILITY_NAMED_IAM"]
        Parameter overrides          : {"SystemName": "test", "EnvType": "dev", "EndPointUrl": "https://ooooooooo.mediaconvert.ap-northeast-1.amazonaws.com"}
        Signing Profiles             : {}

Initiating deployment
=====================

Uploading to test-sam-app/ec04f3ded743b1dcaa5ce47ccd401e58.template  5896 / 5896  (100.00%)

Waiting for changeset to be created..

CloudFormation stack changeset
-----------------------------------------------------------------------------------------------------------------------------

Operation                       LogicalResourceId               ResourceType                    Replacement                   
-----------------------------------------------------------------------------------------------------------------------------

+ Add                           InputBucket                     AWS::S3::Bucket                 N/A                           
+ Add                           LambdaFunctionRole              AWS::IAM::Role                  N/A                           
+ Add                           LambdaFunctionS3EventPermissi   AWS::Lambda::Permission         N/A                           
      on                                                                                            
+ Add                           LambdaFunction                  AWS::Lambda::Function           N/A                           
+ Add                           LogBucket                       AWS::S3::Bucket                 N/A                           
+ Add                           MediaConvertJobExecutePolicy    AWS::IAM::ManagedPolicy         N/A                           
+ Add                           MediaConvertJobPolicy           AWS::IAM::ManagedPolicy         N/A                           
+ Add                           MediaConvertJobTemplate         AWS::MediaConvert::JobTemplat   N/A                           
      e                                                             
+ Add                           MediaConvertServiceRole         AWS::IAM::Role                  N/A                           
+ Add                           OutputBucket                    AWS::S3::Bucket                 N/A                           

-----------------------------------------------------------------------------------------------------------------------------

Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:changeSet/samcli-deploy1632658732/77769df7-e9d2-4bd4-9b45-959f295830b4


2021-09-26 21:19:03 - Waiting for stack create/update to complete

CloudFormation events from changeset
-----------------------------------------------------------------------------------------------------------------------------

ResourceStatus                  ResourceType                    LogicalResourceId               ResourceStatusReason          
-----------------------------------------------------------------------------------------------------------------------------

CREATE_IN_PROGRESS              AWS::IAM::ManagedPolicy         MediaConvertJobPolicy           -                             
CREATE_IN_PROGRESS              AWS::IAM::ManagedPolicy         MediaConvertJobExecutePolicy    -                             
CREATE_IN_PROGRESS              AWS::S3::Bucket                 LogBucket                       -                             
CREATE_IN_PROGRESS              AWS::MediaConvert::JobTemplat   MediaConvertJobTemplate         -                             
                                e                                                                                             
CREATE_IN_PROGRESS              AWS::S3::Bucket                 LogBucket                       Resource creation Initiated   
CREATE_IN_PROGRESS              AWS::IAM::ManagedPolicy         MediaConvertJobExecutePolicy    Resource creation Initiated   
CREATE_IN_PROGRESS              AWS::IAM::ManagedPolicy         MediaConvertJobPolicy           Resource creation Initiated   
CREATE_COMPLETE                 AWS::IAM::ManagedPolicy         MediaConvertJobExecutePolicy    -                             
CREATE_COMPLETE                 AWS::IAM::ManagedPolicy         MediaConvertJobPolicy           -                             
CREATE_IN_PROGRESS              AWS::IAM::Role                  LambdaFunctionRole              -                             
CREATE_IN_PROGRESS              AWS::IAM::Role                  MediaConvertServiceRole         -                             
CREATE_IN_PROGRESS              AWS::IAM::Role                  LambdaFunctionRole              Resource creation Initiated   
CREATE_IN_PROGRESS              AWS::IAM::Role                  MediaConvertServiceRole         Resource creation Initiated   
CREATE_COMPLETE                 AWS::S3::Bucket                 LogBucket                       -                             
CREATE_IN_PROGRESS              AWS::S3::Bucket                 OutputBucket                    -                             
CREATE_IN_PROGRESS              AWS::S3::Bucket                 OutputBucket                    Resource creation Initiated   
CREATE_IN_PROGRESS              AWS::MediaConvert::JobTemplat   MediaConvertJobTemplate         Resource creation Initiated   
                                e                                                                                             
CREATE_COMPLETE                 AWS::MediaConvert::JobTemplat   MediaConvertJobTemplate         -                             
                                e                                                                                             
CREATE_COMPLETE                 AWS::IAM::Role                  LambdaFunctionRole              -                             
CREATE_COMPLETE                 AWS::IAM::Role                  MediaConvertServiceRole         -                             
CREATE_COMPLETE                 AWS::S3::Bucket                 OutputBucket                    -                             
CREATE_IN_PROGRESS              AWS::Lambda::Function           LambdaFunction                  -                             
CREATE_IN_PROGRESS              AWS::Lambda::Function           LambdaFunction                  Resource creation Initiated   
CREATE_COMPLETE                 AWS::Lambda::Function           LambdaFunction                  -                             
CREATE_IN_PROGRESS              AWS::Lambda::Permission         LambdaFunctionS3EventPermissi   -                             
                                                                on                                                            
CREATE_IN_PROGRESS              AWS::Lambda::Permission         LambdaFunctionS3EventPermissi   Resource creation Initiated   
                                                                on                                                            
CREATE_COMPLETE                 AWS::Lambda::Permission         LambdaFunctionS3EventPermissi   -                             
                                                                on                                                            
CREATE_IN_PROGRESS              AWS::S3::Bucket                 InputBucket                     -                             
CREATE_IN_PROGRESS              AWS::S3::Bucket                 InputBucket                     Resource creation Initiated   
CREATE_COMPLETE                 AWS::S3::Bucket                 InputBucket                     -                             

CREATE_COMPLETE                 AWS::CloudFormation::Stack      test-sam-app                    -                             
-----------------------------------------------------------------------------------------------------------------------------

Successfully created/updated stack - test-sam-app in ap-northeast-1

正常にデプロイできるとリソースが作成されます。

MediaConvert

sa20210926-03

S3

sa20210926-02

Lambda Function

sa20210926-04

IAM

sa20210926-05

動作確認

動画ファイルがPUTされるバケット(test-dev-media-convert-input-xxxxxxxxxxxx)と、変換後のファイルが格納されるバケット(test-dev-media-convert-output-xxxxxxxxxxxx)を確認しました。空の状態です。

$ aws s3 ls s3://test-dev-media-convert-input-xxxxxxxxxxxx
$ aws s3 ls s3://test-dev-media-convert-output-xxxxxxxxxxxx
$

mp4形式の動画ファイルをS3バケットにPUTします。

$ aws s3 cp ~/tmp/test.mp4 s3://test-dev-media-convert-input-xxxxxxxxxxxx
upload: ../../../../tmp/test.mp4 to s3://test-dev-media-convert-input-xxxxxxxxxxxx/test.mp4  
$ aws s3 ls s3://test-dev-media-convert-input-xxxxxxxxxxxx
2021-09-26 22:24:45     805306 test.mp4

S3トリガーでLambda Functionが起動され、MediaConvertのジョブが完了しました。

sa20210926-06 sa20210926-07

MediaConvertによりHLS形式に自動変換されたことが確認できました。

$ aws s3 ls s3://test-dev-media-convert-output-xxxxxxxxxxxx
2021-09-26 22:24:54        196 test.m3u8
2021-09-26 22:24:54        143 test_hls.m3u8
2021-09-26 22:24:54     159612 test_hls_00001.ts

さいごに

MediaConvertを一時的に利用したく、ソリューション以外でS3へのPUTで自動変換するようなテンプレートが見当たらなかったので作ってみました。今回はジョブのエラー等はあまり考慮していないので、こちらのテンプレートを利用してまた別の機会にアウトプットしたいと思います。誰かのお役に立てれば幸いです。