はじめに
本記事では動画のアップロードをトリガーとして, MediaConvertのジョブテンプレートからジョブを生成し, HLS形式へと変換するフローを解説します.
S3バケットの作成
まずはmp4ファイルを格納するバケットと変換されたファイル群を格納するバケットを作成しましょう
(ここではあえてバケットを分けていますが,分けなくても問題ありません.)
IAMの作成
MediaConvert用のロール
AmazonS3FullAccess, AmazonAPIGatewayInvokeFullAccessをアタッチ.
Lambda用のロール
LambdaからMediaConvertを呼び出すためのカスタムポリシーを作成します.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "iam:PassRole",
                "mediaconvert:CreateJob"
            ],
            "Resource": "*"
        }
    ]
}
上記で作成したポリシーに加えAmazonS3ReadOnlyAccess, AWSLambdaBasicExecutionRoleをアタッチ.
ジョブテンプレート作成
動画の設定
テンプレート名を入力し,出力グループの「追加」からApple HLSを選択.
送信先に変換後のファイル群を入れるバケットを指定, 出力の項目の名前修飾子に_hlsと適当なサフィックスを指定してください.
Output 1にてコーデックやフレームレートの設定をしていきます.
ここではフレームレート30, ビットレート5000000としています.解像度はお好みで.
サムネイルの設定
出力グループの「追加」からファイルグループを選択します.
こちらも送信先に変換後のjpgファイルを入れるバケットを指定し,拡張子は.jpgとしてください.
Output 1にてエンコード設定を行います
ここではコンテナを使用しないのでNoContainerを選択します.
サムネイルなので最大キャプチャは1を入力し,Audioの設定は削除しておきましょう.
以上でジョブテンプレートの設定は完了です.
動作確認
作成したジョブテンプレートの詳細画面から「ジョブの作成」を選択.
変換対象のmp4ファイルをここで指定します.
次に「設定」にて,先ほど作成したMediaConvert用のIAMロールを指定し, ジョブを作成.
ジョブが完了すると送信先に指定したバケットにエンコードされたファイル群が入っているかと思います.
Lambda関数の実装
IAMロールの指定
ここで設定するIAMロールは先ほど作成したLambda用のロールを指定してください.
S3トリガーの設定
設定は以下の通りになります
.mp4のサフィックスが付いているファイルのアップロードをトリガーとします.
入出力のバケットを分けずに行う場合この指定をしておかないと無限ループに陥る可能性が出てくるので要注意.
実装!
import json
import urllib.parse
import boto3
import os
 
s3 = boto3.client('s3')
mediaconvert =  boto3.client('mediaconvert', region_name='ap-northeast-1', endpoint_url=os.environ['MEDIACONVERT_ENDPOINT'])
 
def lambda_handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    inputFile = "s3://" + bucket + "/" + key
    outputKey = os.environ['OUTPUT_BUCKET'] + "/" + key.replace(".mp4", "")
 
    try:
        with open("job.json", "r") as jsonfile:
            job_object = json.load(jsonfile)
        job_object["OutputGroups"][0]["OutputGroupSettings"]["HlsGroupSettings"]["Destination"] = outputKey
        job_object["OutputGroups"][1]["OutputGroupSettings"]["FileGroupSettings"]["Destination"] = outputKey
        job_object["Inputs"][0]["FileInput"] = inputFile
 
        response = mediaconvert.create_job(
          JobTemplate=os.environ['JOB_TEMPLATE'],
          Queue=os.environ['QUEUE'],
          Role=os.environ['MEDIACONVERT_ROLE'],
          Settings=job_object
        )
    except Exception as e:
        print(e)
        print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
        raise e
{
  "OutputGroups": [
    {
        "Name": "Apple HLS",
        "OutputGroupSettings": {
          "Type": "HLS_GROUP_SETTINGS",
          "HlsGroupSettings": {
            "Destination": ""
        }
      }
    },
    {
      "Name": "File Group",
      "OutputGroupSettings": {
        "Type": "FILE_GROUP_SETTINGS",
        "FileGroupSettings": {
          "Destination": ""
        }
      }
    }
  ],
  "Inputs": [
    {
      "FileInput": ""
    }
  ]
}
環境変数について
OUTPUT_BUCKET = s3://バケット名
MEDIACONVERT_ENDPOINT = https://xxxx.mediaconvert.ap-northeast-1.amazonaws.com
JOB_TEMPLATE = arn:aws:mediaconvert:ap-northeast-1:xxxxxxxx:jobTemplates/ジョブテンプレート名
QUEUE = arn:aws:mediaconvert:ap-northeast-1:xxxxxxxx:queues/Default
MEDIACONVERT_ROLE = arn:aws:iam::xxxxxxxx:role/MediaConvertのロール
自動変換の動作確認
対象バケットにmp4ファイルをアップロードし,
Lambda関数が実行され
HLS用のバケットに変換されたファイル群があれば成功です
さいごに
シンプルにストリーミング配信用の動画エンコードができました.
簡単ですね!
今後はアダプティブビットレートの対応やDRMなどにも挑戦していきたいです.
