9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RUNTEQAdvent Calendar 2019

Day 16

RUNTEQの動画配信基盤-HLSエンコード編-

Posted at

はじめに

本記事では動画のアップロードをトリガーとして, 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を選択.
Screenshot from Gyazo
送信先に変換後のファイル群を入れるバケットを指定, 出力の項目の名前修飾子に_hlsと適当なサフィックスを指定してください.
Output 1にてコーデックやフレームレートの設定をしていきます.
Screenshot from Gyazo
ここではフレームレート30, ビットレート5000000としています.解像度はお好みで.

サムネイルの設定

出力グループの「追加」からファイルグループを選択します.
Screenshot from Gyazo
こちらも送信先に変換後のjpgファイルを入れるバケットを指定し,拡張子は.jpgとしてください.
Output 1にてエンコード設定を行います
Screenshot from Gyazo
ここではコンテナを使用しないのでNoContainerを選択します.
サムネイルなので最大キャプチャは1を入力し,Audioの設定は削除しておきましょう.

以上でジョブテンプレートの設定は完了です.

動作確認

作成したジョブテンプレートの詳細画面から「ジョブの作成」を選択.
変換対象のmp4ファイルをここで指定します.
Screenshot from Gyazo
次に「設定」にて,先ほど作成したMediaConvert用のIAMロールを指定し, ジョブを作成.

ジョブが完了すると送信先に指定したバケットにエンコードされたファイル群が入っているかと思います.

Lambda関数の実装

今回はAWSで用されている設計図を元に実装していきます.
Screenshot from Gyazo

IAMロールの指定

ここで設定するIAMロールは先ほど作成したLambda用のロールを指定してください.
Screenshot from Gyazo

S3トリガーの設定

設定は以下の通りになります
.mp4のサフィックスが付いているファイルのアップロードをトリガーとします.
入出力のバケットを分けずに行う場合この指定をしておかないと無限ループに陥る可能性が出てくるので要注意.
Screenshot from Gyazo

実装!

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用のバケットに変換されたファイル群があれば成功です:tada:
Screenshot from Gyazo

さいごに

シンプルにストリーミング配信用の動画エンコードができました.
簡単ですね!

今後はアダプティブビットレートの対応やDRMなどにも挑戦していきたいです.

9
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?