AWS LambdaとElastic TranscoderでHLS動画を作る


LambdaでElasticTranscoderを使う場合の基本的なやり方は、
[AWS LambdaとElastic Transcoder - Qiita](http://qiita.com/con_mame/items/b58a5e017e7c9ab2356b)

が参考になります。

今回は、HLSを作りたい場合のやり方を説明します。

## HLSとは

HLSはスマホ向けの動画配信などに使われる仕組みです。特徴としては、複数のビットレートに対応することでネットワークの不安定なクライアントもアダプティブにビットレートを選択して視聴することができます。

HLSは、プレイリストファイル(xxx.m3u8)と、動画ファイル(xxx.ts)の２種類のファイルから構成されています。
動画ファイルはビットレート毎にn秒ごとに切られた動画で、プレイリストファイルは、どのビットレートのx秒からy秒までがxxx.ts　というよう動画ファイルへのポインタとなっています。

HLS動画を作る際には、

- どのようなビットレートを用意するか
- その解像度はどうするか
- エンコードには何を使うか
- tsファイルを何秒で区切るか
- 音声のビットレートはどうするか

などを予め決める必要があります。

## TranscoderのPresetを作る

Transcoderでは、Presetという動画をどのように変換するかを決めるレシピのようなものがあります。これを事前に作ります。
デフォルトで用意されているものもあるので、それでよければ作らなくても大丈夫です。

HLSを作るためには、必要なビットレート毎のtsファイルのPresetを作ります。

設定する値は、

- Container
 - tsを選びます
- Codec
	- H.264しか使えません
- ProfileとLevel
	- ここはちょっと説明が複雑になるので詳細は省略します。
	- Profileはスマホ向けならmainでいいと思いますが、かなり古いスマホの対応をするならbaselineになるかもです
	- Levelも3.1か4.1あたりでよいかと。
		- 詳しくは [Wikipedia](https://en.wikipedia.org/wiki/H.264/MPEG-4_AVC#Levels)などを参考にしてください。
- Bitrate
	- キロビット/秒です。ここに出したいビットレートを設定します。
- MaxWidth, MaxHeight, SizingPolicy
	- ここでサイズを決めます
- その他
	- その他の項目はここでは省略します。元の動画にあわせて設定が必要な項目があります。[Elastic Transcoder のプリセットを作成するときに指定する設定 - Amazon Elastic Transcoder](http://docs.aws.amazon.com/ja_jp/elastictranscoder/latest/developerguide/preset-settings.html)を見ながら設定してください。

ここでは、example_720p, example_480p, example_240pの3種類のPresetを作ったとして、次に進みます。

## TranscoderのPipeLineを作る

どのS3bucketからInputして、どのS3Bucketに作るか、の流れを決めます。ここでは省略します。

## LambdaへFunctionの登録

上で作ったPipelineIDを <PipelineID>、3つのPresetIDをそれぞれ、<PresetID_720p>, <PresetID_480p>, <PresetID_240p>とすると、次のような感じに書けます。

```
var aws = require('aws-sdk');
var s3 = new aws.S3({apiVersion: '2006-03-01'});
var ets = new aws.ElasticTranscoder({apiVersion: '2012-09-25', region: 'ap-northeast-1'});

exports.handler = function(event, context) {
   console.log('Received event:');
   console.log(JSON.stringify(event, null, '  '));
   var bucket = event.Records[0].s3.bucket.name;
   var key = event.Records[0].s3.object.key;
   var pipelineId = '<PipeLineID>';
   var presetId720p = '<PresetID_720p>';
   var presetId480p = '<PresetID_480p>';
   var presetId240p = '<PresetID_240p>';
   var fileName = key.split('.')[0];
   ets.createJob({
     PipelineId: pipelineId,
     OutputKeyPrefix: fileName + '/',
     Input: {
       Key: key,
       FrameRate: 'auto',
       Resolution: 'auto',
       AspectRatio: 'auto',
       Interlaced: 'auto',
       Container: 'auto',
     },
     Outputs: [
       {
         Key: 'ts-720p',
         PresetId: presetId720p,
         Rotate: 'auto',
         SegmentDuration: "10"
       },
       {
         Key: 'ts-480p',
         PresetId: presetId480p,
         Rotate: 'auto',
         SegmentDuration: "10"
       },
       {
         Key: 'ts-240p',
         PresetId: presetId240p,
         Rotate: 'auto',
         SegmentDuration: "10"
       },
     ],
     Playlists: [
       {
         Format: 'HLSv3',
         Name: 'master',
         OutputKeys: [
           'ts-720p',
           'ts-480p',
           'ts-240p',
         ],
       },
     ],
   }, function(error, data) {
        if(error) {
            console.log(error);
            context.done('error',error);
        } else {
            console.log('Job submitted');
            context.done(null,'');
        }
    });
};

```

ポイントとしては、Outputsにそれぞれのpresetに対応するOutputを設定します。TSファイルの長さ（秒）をSegmentDurationに指定します。
PlaylistはそれぞれのビットレートのTSをまとめるものです、フォーマットをHLSにします。
Playlistを複数作ることも可能です。

上から3行目の、regionなどが間違っていると動かないので気をつけてください。


## まとめ

残りは [AWS LambdaとElastic Transcoder - Qiita](http://qiita.com/con_mame/items/b58a5e017e7c9ab2356b)と同じように進めれば大丈夫だと思います。

これでS3に動画がアップロードされると、Lambdaからマルチビットレート対応のHLSが作れるようになります。