支援対象地域:札幌、仙台、関東、愛知、関西、広島、福岡


はじめに

映画やアニメ、動画など自分で作成したコンテンツを配信したいという方はいらっしゃるでしょう。 そこで今回はAWSのElemental MediaConvertを紹介します。MediaConvertを使えば、サーバーを立てることなく自分の動画をストリーミング形式で配信させることができます。さらにLambdaと連携させることで自動で動画配信をさせることが可能になります。本記事では、MediaConvertとLambdaを連携させた自動動画変換処理の作り方を紹介していきます。

Elemental MediaConertとは?

AWS Elemental MediaConertは、mp4やmovなどの動画ファイルをストリーミング用の動画形式(HLSなど)に変換させるサービスです。AWS上で動画を配信する場合は、以下のようなS3と連携した使い方が可能です。

1.Amazon S3にmp4形式の動画をアップロード。
2.Elemental MediaConertで変換。
3.S3に静的Webページをホスティングして、動画を配信。

S3を使えばサーバーを立てることなくストリーミングを配信させることが可能になります。

料金体系

料金体系はオンデマンド料金とリザーブ料金の2種類から選べます。 オンデマンド料金では、変換させた動画の再生時間×動画の形式や画素数によって課金されるようです。 リザーブ料金は、最低12ヵ月の定期契約となるようです。 私は、今回5分30秒程度の動画をHLSファイルに変換しましたが、0.2USD(20円程)課金されました。 何度か挙動を確認するため一回ではなく、ジョブ実行2、3回、Lambdaを使っての実行1回で合計、3、4回変換させたので、このくらいになったのかと推測しています。

Lambdaを使って自動動画変換処理を作る

Lambdaを使った動画自動配信処理を作成していきます。 やりたいことはS3に動画をアップロードさせると、Lambdaが起動して Media ConvertからHLSファイルに変換させる処理の作成です。 ステップは以下になります。

1.S3にバケット作成
2.MediaConvertでジョブテンプレート作成
3.MediaConvertからS3にアクセスする権限を付与
4.lambdaを作成
5.S3イベントをトリガー設定。

では、1から見ていきます。

 

1.S3にバケットを作成

最初にバケットを用意します。今回用意するのは、入力用のバケットと出力用バケットの二つです。
入力用バケットには、自分のローカルからmp4やmovなどの動画を置きます。
出力用バケットには、MediaConvertが変換した後に転送するバケットになります。
どちらも現状パブリックアクセスブロックは有効にしておいてください。



2.MediaConvertでジョブテンプレート作成

MediaConvertを使って動画を変換する際に、「ジョブ」を作成し実行します。その際、動画の形式やフレームレート、ビットレート、解像度など様々な設定をしなけければなりません。その都度設定するのは大変なので、「ジョブテンプレート」を作成します。



<一般設定>

名前、カテゴリ、説明は任意に決めてください。



<入力>

入力はデフォルトで問題ないです。

<出力>

出力グループは、「Apple HLS」を選択します。



※Apple専用の形式で、SafariとEdge以外のブラウザでは動画をみることができないようです。 私はMacのSafariのみ見れて、EdgeとGoogle Chromeでは見れませんでした。出力の設定は、以下を参考にしてください。

名前修飾子:_hls(変換された動画のファイル名に_hlsが付与されます。)
ビデオコーデック:MPEG-4 AVC (H.264)
解像度:1280 x 720
フレームレート:30fps(1秒間に30回更新されるという意味です。)
ビットレート:5Mbps(1秒間の転送データ量です。)
残りはデフォルトで問題ないです。

<キャプチャーのジョブテンプレート作成>

キャプチャー画像を出力しますので、その設定をします。 「出力グループの追加」を押下します。 形式は「ファイルグループ」にします。以下を参考に設定してください。

名前修飾子:_cap
ビデオコーデック:JPEG へのフレームキャプチャ
最大キャプチャー:1

以上でジョブテンプレート作成完了です。

3.MediaConvertからS3にアクセスする権限を付与

MediaConvertからS3へのアクセスを許可できるようにロールを作成してあげる必要があります。 IAMコンソールから作成します。



「ロールの作成」を押下し、信頼できるエンティティに「MediaConvert」を選択します。すると、「AmazonAPIGatewayInvokeFullAccess」と「AmazonS3FullAccess」のポリシーが付与されます。
タグは特に設定不要です。ロール名は任意につけてください。私は「MediaConvert_Default_Role」にしました。作成されたら、作成されたロールを開きます。



ロールARNが上部に表示されます。MediaConvertでジョブを実行する際にはこのロール名が必要になります。 後ほどLambdaを動かす際に使いますので、どこかに控えておきましょう。また、ジョブテンプレートの名前も必要になりますので、控えておいてください。以上でロールの作成は完了になります。

4.lambdaを作成

Lambdaページに行って、新規に作成します。今回はNode.jsを使います。
名前を任意に決めたら、まずアクセス権限を設定します。ポリシーをアタッチ画面で以下をアタッチします。

AWSElementalMediaConvertFullAccess

これでLambdaからMediaConvertへのアクセスが有効になります。
先程ジョブテンプレートの個所で作成したロールとは別物です。今回の処理では、以下二つのロールが必要になります。

1.Lambda→MediaConvertへのアクセス権
2.MediaConvert→S3へのアクセス権限

以下コードになります。

コード

01. exports.handler = (event, context, callback) => {
02. //AWS-SDK呼び出し、設定
03. var AWS = require('aws-sdk');
04. AWS.config.update({region: 'ap-northeast-1'});
05. AWS.config.mediaconvert = {endpoint : 'エンドポイント名'};
06. //S3アップロード時のイベントよりバケット名とオブジェクト名取得
07. var Bucket = event.Records[0].s3.bucket.name;//イベントよりバケット名取得
08. var ObjKey = event.Records[0].s3.object.key;//イベントよりオブジェクト名取得
09. var RepBucket = Bucket.replace(/\+/g," ");
10. var RepObjKey = ObjKey.replace(/\+/g," ");
11. console.log("RepBucket is:"+RepBucket);
12. console.log("RepObjKey:"+RepObjKey);
13. //MediaConvertパラメータ設定
14. var params = {
15.  "JobTemplate": "ジョブテンプレート名",
16.  "Role":"ロール名",
17.  "Settings":{
18.   "OutputGroups": [
19.   {
20.    "Name": "Apple HLS",
21.    "OutputGroupSettings": {
22.     "Type": "HLS_GROUP_SETTINGS",
23.     "HlsGroupSettings": {
24.      "Destination": "s3://送信先バケット名"
25.      }
26.     }
27.    },
28.   {
29.    "Name": "File Group",
30.    "OutputGroupSettings": {
31.     "Type": "FILE_GROUP_SETTINGS",
32.     "FileGroupSettings": {
33.      "Destination": "s3://送信先バケット名/"
34.     }
35.    }
36.   }
37.  ],
38.   "Inputs": [
39.    {
40.    "FileInput": 's3://'+RepBucket+'/'+RepObjKey
41.    }
42.   ]
43.  }
44. }
45. //MediaConvertのcreatejobメソッド実行
46. var endpointPromise = new AWS.MediaConvert({apiVersion: '2017-08-29'}).createJob(params).promise();
47. //エラーハンドリング
48. endpointPromise.then(
49.  function(data) {
50.   console.log("Job created! ", data);
51.  },
52.  function(err) {
53.   console.log("Error", err);
54.  }
55. );
56. };


ポイント

05.のエンドポイント名は、MediaConvertのアカウントに記載があるものを設定してください。



09.、10.は動画ファイルにスペースが含まれる場合の対策です。ファイル名のスペースが+(プラス)になって出力されるので、Replaceでスペースに変換させます。
14.からパラメータの設定になります。先程作成したジョブテンプレート名とロール名を設定してください。
17.settingには、アウトプットの設定とインプットの設定をします。
アウトプットのdestinationは、自分の送信先のS3バケットを設定してください。
インプットのfileinputは、送信元のS3バケットとオブジェクト名を設定します。 今回は、S3イベントから出力されるバケット名とオブジェクト名を変数代入しておいたものを使います。
46.MediaConvertのCreateメソッドを先程定義したパラメータを引数に実行しています。最後に「promise」メソッドを入れると、実行結果がオブジェクトで返されるのでエラーハンドリングがしやすくなります。
47.以降はpromiseオブジェクトを使ったエラーハンドリングになります。

5.S3イベントをトリガー設定

最後にトリガーを設定します。
S3を選択し、送信元バケットにPUTされるのを引き金にするように設定します。

実行

ではS3に動画をアップロードしてみましょう。
すると送信先のバケットにtsファイルとm3u8ファイルが作成されます。
HLSファイルは、tsファイル(動画を細かく分けたファイル、セグメントと呼びます。)とm3u8ファイル(セグメントのプレイリストファイル)で構成されます。



写真のようにtsファイルとm3u8ファイルが出来ていれば成功です。

最後に

いかがでしたでしょうか? 今回は紹介しませんでしたが、作成されたHLSファイルをストリーミングとして視聴可能にするためには、 動画プレイヤーを呼び出す記述をHTMLに記述し、そのファイルをIndexとしてWebページをホスティングする必要があります。 興味がある方は是非やってみてください。