Edited at

AWS LambdaとElastic Transcoder

More than 3 years have passed since last update.


AWS Lambda

AWS Lambdaはre:Inventで発表されたクラウド上でコードスニペットをイベントドリブンで実行出来るプラットフォームです。

S3 EventNotificationやDynamoDB、Kinesisと連携することが出来ます。例えば、S3にファイルがPUTされたら、そのイベントをトリガーにしてDynamoDBに情報を書き込んだり、AWS SDKを利用して他のAWSサービスを呼び出すことも可能です。現在のところ、LambdaではNode.jsがサポートされています。サードパーティモジュールもnpm_modulesディレクトリも含めてzipでUploadすることで利用することが可能です。

http://aws.amazon.com/lambda/


Amazon Elastic Transcoder

Amazon Elastic Transcoderは動画や音声を簡単にエンコードが行えるフルマネージドサービスです。リリース時に書いたBlogですが、http://d.conma.me/entry/2013/01/30/002445 に概要をまとめています。

Amazon Elastic Transcoderもリリース後機能追加や性能改善が行われており、SmoothStreamingやSSE対応などが直近で行われた追加です。


組み合わせてみる

今回は、AWS Lambdaを簡単に使ってみる例としてS3の特定のバケットに動画がアップロードされたら、S3のEvent NotificationからLambdaを呼び出して、Elastic TranscoderにエンコードJobを登録するというsnippetです。


Amazon Elastic Transcoderの作成

Amazon Elastic TranscoderのPiplineの作成は割愛します。http://d.conma.me/entry/2013/01/30/002445

に簡単にですが書いてありますのでご参照下さい。


LambdaへFunctionの登録

var aws = require('aws-sdk');

var s3 = new aws.S3({apiVersion: '2006-03-01'});
var ets = new aws.ElasticTranscoder({apiVersion: '2012-09-25', region: 'us-east-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 = key.split('/')[0];
var presetId = key.split('/')[1];
var fileName = (key.split('/')[2]).split('.')[0];
ets.createJob({
PipelineId: pipelineId,
OutputKeyPrefix: 'demo/',
Input: {
Key: key,
FrameRate: 'auto',
Resolution: 'auto',
AspectRatio: 'auto',
Interlaced: 'auto',
Container: 'auto',
},
Output: {
Key: fileName + '.mp4',
ThumbnailPattern: fileName + '-thumbs-{count}',
PresetId: presetId,
Rotate: 'auto'
}
}, function(error, data) {
if(error) {
console.log(error);
context.done('error',error);
} else {
console.log('Job submitted');
context.done(null,'');
}
});
};

このような簡単なsnippetを登録しておきます。

あくまで参考ということで、エラーハンドリングや重複処理が甘い、mp4以外のpresetへ未対応なコードとなっていますが、LambdaをとS3 Notificationを使うイメージを掴んでいただければと思います。

1点だけ注意ですが、functionを作成する際に、Roleを作成します。こちらはLambdaに設定されるIAM Roleですが、標準のままだと

{

"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:*"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::*"
]
}
]
}

のようにS3に対する権限のみついているシンプルなものが付与されるため、Elastic TranscoderにJobをSubmit出来る権限をつけます。

IAMの画面からRolesの中に先ほど作成されたlambda_exec_role(デフォルト名)があるので、それに権限を付与します。もちろん、Lambdaのfunction作成時に一緒に権限を付与してしまう事も可能です。

後から付与する場合は、先ほどのIAM Rolesから選択したRole中のAttache Role PolicyからSelect Policy Template内のAmazon Elastic Transcoder Jobs Submitterを付与します。

function毎に必要な権限を追加してRoleを作成することをオススメします。


S3の準備

動画をアップロードする用とエンコード済み動画を格納するバケットをそれぞれ作成しておきます。動画をアップロードするためのバケットのEventsタブで

S3_Management_Console.png

今回は動画ということで、マルチパートアップロード前提でマルチパートアップロードが完了した場合に通知するCompleteMultiPartUploadをEventに指定し、先ほど作成したLambdaのfunctionを呼び出すように設定します。(通常のPutを使う場合はEventでPutを指定します)

Invocation roleはIAM Roleで

{

"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": [
"*"
],
"Action": [
"lambda:InvokeFunction"
]
}
]
}

このような権限を設定します。Lambdaの画面からS3にConfigure Event SouceでS3に関連付けると自動的にこのロールを作る事が可能です。


エンコードしてみる

Elastic TranscoderにはPipline IDと呼ばれる識別子とエンコード動画形式を指定するPreset IDと呼ばれるものがあります。Jobを登録する際はこちら双方のIDが必要になるのですがsnippetに埋め込むのも変更しづらいので、Objectのkey prefixとして指定するようにしてみました。

形式は

Pipline ID/preset ID/ファイル名

この順番でディレクトリを切って、ファイルをアップロードするといい感じにエンコードをしてくれると思います。


まとめ

今回は簡単にS3とElastic Transcoderが連携出来るのがわかっていただけたと思います。短いコードでS3にアップロードしてエンコードまでがすぐに出来るようになりました。今までだと、S3をポーリングするか別途APIサーバにエンコード要求を送るなどしていたかと思います。この構成にCloud FrontをS3の前面に置くことでCognitoなどもつかうと、EC2インスタンスを一切たてること無く、動画のアップロードからエンコードして、CDN経由で配信まで可能になります。もちろん認証付きです。

また発展系として、DynamoDBに再生数やLike数などを入れて、DynamoDBとSNS Mobile Pushと組み合わせると、動画がアップロードされたりLikeが一定数ついたらPush通知を送るという応用も出来ると思います。

是非、AWS Lambdaで遊んでみてはいかがでしょうか?

こちらは個人の意見で会社とは関係ありません。お約束です。