Help us understand the problem. What is going on with this article?

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で遊んでみてはいかがでしょうか?

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした