エンジニアレポート

AWS メディアサービスで動画変換のフローを構築する

2019年08月28日

データスタジアムのエンジニア、片岡です。
主にサッカーに関するサービスの開発を担当しています。プロスポーツの現場では、サッカーに限らず強化・分析のために映像が重要な役割を担います。

今回は、当社のいくつかのプロジェクトで利用しているAWSメディアサービスを利用した動画変換処理について書いていきます。

こちらが処理フローのイメージです。

flow

ある動画ファイル(ここではmp4)がS3にアップされたら、Webで扱いやすいHLSに変換してS3に保存し、CloudFront等を通してPCやスマホなどの端末に配信する、という仕組みです。

ここで出てくるAWSサービスはS3LambdaMediaConvertCloudWatchです。

MediaConvertは、AWSメディアサービスの6つあるサービスの1つで、動画ファイルの変換処理や部分カット(クリッピング)、結合(マージ)をサーバーレスで行うものです。
変換後ファイルの映像の解像度と尺によって1分いくらの課金がされます。(東京リージョンでHD映像の場合、0.017USD/分)

MediaConvertジョブテンプレート設定

AWSコンソールのMediaConvertの画面で変換処理設定をしたジョブテンプレートを作成します。

入力と出力の追加ボタンをクリックし、設定していきます。出力は「Apple HLS」を選択します。

非常に多くの設定パラメータがありますが、デフォルトのままでも多くの場合ではOKだと思います。「セグメントの長さ」、「レート制御モード」、「ビットレート (ビット/秒) 」、「最大ビットレート (ビット/秒) 」あたりが主に設定する箇所になります。

JobTemplate

MediaConvert起動用Lambda設定

S3の指定バケットにmp4がアップされたら、そのファイルをMediaConvertでHLS変換する処理です。Lambda(Python)で実装します。


import json
import os
import boto3
import urllib.request

def lambda_handler(event, context):
  try:
    # イベントのソースとなったS3オブジェクト情報
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')

    # MediaConvert起動設定
    src = bucket + '/' + key # 変換元ファイル
    dest = 'testbucketds2019hls/' + key # 変換先ファイル
    baseUrl = 'https://xxxxxx.cloudfront.net' # HLSのm3u8内に記載されるURLベース
    settings = make_settings(src, dest, baseUrl)
    print('settings: ' + str(settings))

    # MediaConvertのクライアント生成    
    # os.environ['mediaconvert_endpoint']はLambda環境変数に設定したMediaConvertのエンドポイント。
    # (AWSコンソールの「アカウント」画面で確認可)
    client = boto3.client('mediaconvert', region_name='ap-northeast-1', endpoint_url=os.environ['mediaconvert_endpoint'])

    # MediaConvertのジョブ作成(=開始)。os.environはLambda環境変数
    result = client.create_job(
      Role=os.environ['mediaconvert_role'], # MediaConvert用ロールのARN
      JobTemplate=os.environ['job_template'], # MediaConvertのジョブテンプレートARN
      Queue=os.environ['queue'], # MediaConvertのキューARN
      Settings=settings
    )
    print('result:' + str(result))
    return {'result': 0}

  except Exception as e:
    return {'result': 9}

def make_settings(src, dest, baseUrl):
  # destには拡張子は不要
  destWithoutExt = dest.split('.')[0]
  settings = {
    "OutputGroups": [
      {
        "Name": "HLS",
        "Outputs": [
          {
            "ContainerSettings": {
              "Container": "M3U8",
              "M3u8Settings": {
              }
            },
          }
        ],
        "OutputGroupSettings": {
          "Type": "HLS_GROUP_SETTINGS",
          "HlsGroupSettings": {
            "MinSegmentLength": 0,
            "SegmentLength": 30,
            "BaseUrl": baseUrl,
            "Destination": f's3://{destWithoutExt}'
          }
        }
      }
    ],
    "Inputs": [
      {
        'FileInput': f's3://{src}'
      }
    ]
  }

  return settings

S3バケット イベント設定

次に、S3のバケットにイベント(トリガー)の設定をして、「S3にアップされたらLambdaを起動する」設定をします。

AWSコンソールでS3の目的のバケットを開き、「プロパティ」タブを開きます。そこで「Events」→「通知の追加」をクリックすると、以下の画面が現れるので、「すべてのオブジェクト作成イベント」にチェックを入れ、送信先に「Lambda 関数」を選択、下のプルダウンで先ほど作成したLambda関数を選択して保存します。

lambda

CloudWatch設定

MediaConvertの処理が終わったタイミングで何かしらの処理を実行したい、という場合は多いと思います。その場合はCloudWatchにてイベントを作成し、Lambda等で処理を実行するようにします。

AWSコンソールでCloudWatchの左メニューの「ルール」から、「ルールを作成」をクリックします。サービス名に「MediaConvert」、イベントタイプに「MediaConvert Job State Change」を選択。さらに「特定の状態」を選択し、COMPLETEとERRORを追加します。

これで、MediaConvertの処理が完了した時とエラー終了した時に発火するイベントが設定できます。

CloudWatch

あとは右側で「ターゲットの追加」からLambda関数を選択して、実行したい関数を指定し、作成を完了すればOKです。

実行してみる

ここまでの設定を行った後、変換元用S3バケットに任意のmp4ファイルをアップしてみると、自動的にMediaConvertの処理が実行され、変換後バケットにHLSのファイルが作成されていきます。

AWSメディアサービスがリリースされる前は、このフローを自前のサーバとプログラムで実行していましたが、その開発と管理・運用コストは大きかったので、メディアサービスの活用は非常に有効でした。

いくつか注意点

  • MediaConvertの同時実行数はデフォルト20まで。AWSに申請すれば拡張可能。
  • 「キュー」という概念があり、ジョブによってキューを分けることができる。例えば同時実行数が20でキューが5つの場合、各キューに均等に同時実行数が割り振られ、各キューの同時実行数は4となる。  →この均等割のルールを知らずにハマりました。
  • まれに処理時間が長くかかることがある。(AWS側の不具合らしい。修正待ち)

エンジニア募集中!

データスタジアムでは一緒に働いていただけるエンジニアを募集しています。野球、サッカー、バスケなどスポーツが好きな方であれば、とても面白い仕事ができる会社です。興味を持たれた方はぜひこちらをご覧ください。

エンジニアトップ エンジニアインタビュー エンジニアレポート

  • 採用情報
  • おしらせ
  • 掲載事例

ページトップヘ