web-dev-qa-db-ja.com

ビデオのサムネイルを作成するAWS Lambda

S3にアップロードされた動画からサムネイルを作成したいのですが、Node.jsとffmpegで作成する方法を知っています。

このフォーラムの投稿 によると、ライブラリを追加できます:

ImageMagickは、現在デフォルトで提供されている唯一の外部ライブラリですが、Lambda関数を作成するときに提供するZipファイルに追加の依存関係を含めることができます。これがネイティブライブラリまたは実行可能ファイルである場合は、Amazon Linuxで実行する必要があることに注意してください。

しかし、静的ffmpegバイナリをawsラムダに配置するにはどうすればよいですか?

また、Node.jsからこの静的バイナリ(ffmpeg)をAWS Lambdaで呼び出すにはどうすればよいですか?

私はAmazon AWSとLinuxの初心者です

誰か助けてもらえますか?

22
Jesus

Naveenによって概説されているプロセスは正しいですが、Zip内のffmpegバイナリを含み、ラムダ関数内でそれにアクセスするなど、かなり苦痛である可能性のある詳細を覆い隠しています。

私はこれを通り抜けました、それはこのように行きました:

  1. Ffmpeg静的バイナリを圧縮されたラムダ関数パッケージに含めます(ビルドするたびにこれを/distにコピーするgulpタスクがあります)
  2. 関数が呼び出されたら、バイナリを/tmp/ dirとchmodに移動して、自分自身にアクセス権を与えます。 (2017年2月更新:これは不要であると報告されています。re:@loretoparisiおよび@allenの回答)。
  3. pATHを更新して、ffmpeg実行可能ファイルを含めます(私は fluent-ffmpeg を使用して、より簡単に処理できるように two env vars を設定できます)。

詳細が必要な場合はお知らせください。この回答を更新できます。

コピーとchmod(ステップ2)は明らかに理想的ではありません...これを処理するためのより良い方法を誰かが見つけたかどうか、またはこれがこのアーキテクチャスタイルに典型的かどうかを知りたいと思います。

(2番目の更新、最初の更新の前にそれを書くb/cより関連性があります):

@Allenが指摘したように、copy + chmodステップは不要になりました。この時点では問題なく、/ var/task /から直接Lambda関数でffmpegを実行しています。バイナリをchmod 755にしてから、それらをLambdaにアップロードする前に確認してください(@Allenが指摘したとおり)。

私はもはやfluent-ffmpegを使用して作業を行っていません。むしろ、process.env['LAMBDA_TASK_ROOT']を含めるようにPATHを更新し、単純なbashスクリプトを実行しています。

Lambda関数の上部:

process.env['PATH'] = process.env['PATH'] + "/" + process.env['LAMBDA_TASK_ROOT']

Ffmpegを使用する例: lambda-pngs-to-mp4

多数の便利なラムダコンポーネントの場合: lambduh

以下の更新は後世のために残されましたが、もはや必要ではありません:

より詳細な更新:

静的なffmpegバイナリをダウンロードしました here 。 AmazonはEC2を起動し、そこで使用するためのバイナリを構築することをお勧めします。その環境はLambdaが実行される条件と同じであるためです。おそらく良いアイデアですが、もっと多くの作業が必要で、この静的ダウンロードは私にとってはうまくいきました。

ffmpegバイナリのみをプロジェクトのアーカイブされる/distフォルダーにプルしました。

ラムダにZipをアップロードすると、/var/task/に保存されます。なんらかの理由で、その場所でバイナリを使用しようとするアクセスの問題と、そこでファイルのアクセス許可を編集しようとする問題に遭遇しました。簡単な回避策は、バイナリを/tmp/およびchmod権限に移動することです。

ノードでは、child_processを介してシェルを実行できます。私がしたことは次のようになります:

require('child_process').exec(
  'cp /var/task/ffmpeg /tmp/.; chmod 755 /tmp/ffmpeg;',
  function (error, stdout, stderr) {
    if (error) {
      //handle error
    } else {
      console.log("stdout: " + stdout)
      console.log("stderr: " + stderr)
      //handle success
    }
  }
)

これだけで、ラムダ関数で実行可能なffmpegバイナリが得られるはずですが、それでも$ PATHにあることを確認する必要があります。

ノードからbashスクリプトを起動することを優先して、fluent-ffmpegを放棄し、ノードを使用してffmpegコマンドを起動したので、ラムダ関数の上部にあるパスに/tmp/を追加する必要がありました。

process.env.PATH = process.env.PATH + ':/tmp/'

Fluent-ffmpegを使用する場合は、次を介してffmpegへのパスを設定できます。

process.env['FFMPEG_PATH'] = '/tmp/ffmpeg';

やや関連性があり、恥知らずなセルフプラグイン:私は、一連のモジュールに取り組んでいます Lambduh という名前で、構成可能なモジュールからLambda関数を簡単に作成できるようにします。これらをまとめる時間を節約できるかもしれません。簡単な例:このシナリオを lambduh-execute で処理すると、次のように簡単になります。

promises.Push(execute({
  Shell: "cp /var/task/ffmpeg /tmp/.; chmod 755 /tmp/ffmpeg",
})

ここで、promisesは実行されるpromiseの配列です。

37
Russ Matney

これを正確に行う GitHub repo を作成しました(同時にビデオのサイズを変更します)。 Russ Matneyの回答は、FFmpegファイルを実行可能にするのに非常に役立ちました。

6
BKH

Ffmpegタスクにどのカスタムモードライブラリを使用するかわかりません。それにもかかわらず、それを達成するための手順は同じです。

  1. ラムダプロジェクト用に別のディレクトリを作成する
  2. そのディレクトリ内で_npm install <package name>_を実行します(これにより、node_modulesと適切なファイルが自動的に配置されます)
  3. ラムダプロジェクトディレクトリに_index.js_ファイルを作成し、次にrequire(<package-name>)を使用して、ビデオサムネイルを作成するためのメインタスクを実行します
  4. 完了したら、lambdaプロジェクトフォルダーを圧縮してAWS管理コンソールにアップロードし、インデックスファイルとハンドラーを構成します。
  5. 残りの構成は、IAM実行ロール、トリガー、メモリ、タイムアウト指定などの同じプロセスに従います。
2
Naveen Vijay

これを/tmpに移動せずに動作させました。私は自分の実行可能ファイルでchmod 755を実行しましたが、それでうまくいきました!以前にchmod 777に設定すると問題が発生しました。

2
Allen

私が書いている時点では、上記のように、現在のフォルダーからバイナリをコピーする必要はもうありません。つまり、var/task または process.env['LAMBDA_TASK_ROOT']フォルダから/tmpフォルダ。だからそれを行う必要があるだけです

chmod 755 dist/ff*

ffmpegおよびffprobeバイナリがある場合。

ちなみに、以前は2日間無駄だった2セントのソリューションはこれでした

Configure : function(options, logger) {

        // default options
        this._options = {

          // Temporay files folder for caching and modified/downloaded binaries
          tempDir : '/tmp/',

          /**
           * Copy binaries to temp and fix permissions
           * default to false  - since this is not longer necessary
           * @see http://stackoverflow.com/questions/27708573/aws-lambda-making-video-thumbnails/29001078#29001078
          */
          copyBinaries : false

        };

        // override defaults
        for (var attrname in options) { this._options[attrname] = options[attrname]; }

        this.logger=logger;
        var self=this;

        // add temporary folder and task root folder to PATH
        process.env['PATH'] = process.env['PATH'] + ':/tmp/:' + process.env['LAMBDA_TASK_ROOT']

        if(self._options.copyBinaries)
        {
          var result = {}
          execute(result, {
            Shell: "cp ./ffmpeg /tmp/.; chmod 755 /tmp/ffmpeg", // copies an ffmpeg binary to /tmp/ and chmods permissions to run it
            logOutput: true
          })
          .then(function(result) {
            return execute(result, {
               Shell: "cp ./ffprobe /tmp/.; chmod 755 /tmp/ffprobe", // copies an ffmpeg binary to /tmp/ and chmods permissions to run it
               logOutput: true
             })
          })
          .then(function(result) {
             self.logger.info("LambdaAPIHelper.Configure done.");
          })
          .fail(function(err) {
            self.logger.error("LambdaAPIHelper.Configure: error %s",err);
          });
        } //copyBinaries

      }

良いlambduhモジュールに助けられました:

// lambuh & dependencies
var Q = require('q');
var execute = require('lambduh-execute');

ここで説明しているように、モジュールの作成者は confirmed になっているので、これは不要であると考えることができます。これについては、「探索- Lambdaランタイム環境

2
loretoparisi

上記と同じ問題を経験し、実行が必要なスクリプトを/ tmpディレクトリに移動するのと同じ概念で移動しました。

var childProcess = require("child_process");
var Q = require('q');

私が使用したコードは以下の約束をしています:

.then(function(result) {
    console.log('Move Shell ffmpeg Shell script to executable state and location');
    var def = Q.defer();
    childProcess.exec("mkdir /tmp/bin; cp /var/task/bin/ffmpeg /tmp/bin/ffmpeg; chmod 755 /tmp/bin/ffmpeg",
      function (error, stdout, stderr) {
        if (error) {
          console.log("error: " + error)
        } else {
          def.resolve(result);
        }
      }
    )
    return def.promise;
  })
0
codin

バイナリをAWS Lambdaで直接実行できるようにするには(最初に/ tmpとchmodにコピーする必要がない)、バイナリがZipに追加されるときに実行権限があることを確認する必要がありますファイル

WindowsはLinuxバイナリを認識しないため、これはWindowsで問題になります。 Windows 10を使用している場合は、Ubuntu Bash Shellを使用してパッケージを作成します。

この目的のためにNode.js関数テンプレートを作成しました here 。 1つ以上のバイナリをLambdaにデプロイし、任意のシェルコマンドを実行して出力をキャプチャできます。

0
Hai Phan