24

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

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

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

しかし、どうすれば静的な ffmpeg バイナリを aws ラムダに置くことができますか?

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

Amazon AWS と Linux の初心者です

誰でも私を助けることができますか?

4

7 に答える 7

39

Naveen によって概説されているプロセスは正しいですが、zip 内の ffmpeg バイナリを含め、ラムダ関数内でアクセスするなど、かなり面倒な詳細については触れていません。

私はちょうどこれを経験しました、それは次のようになりました:

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

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

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

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

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

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

Lambda 関数の上部:

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

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

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

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

詳細を更新:

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

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

zip をラムダにアップロードすると、.zip に保存され/var/task/ます。なんらかの理由で、その場所でバイナリを使用しようとするとアクセスの問題が発生し、そこにあるファイルのアクセス許可を編集しようとするとさらに多くの問題が発生しました。簡単な回避策は、バイナリをそこに移動し、そこ/tmp/chmodパーミッションを設定することです。

Node では、シェルを介して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 にあることを確認する必要があります。

私は流暢な ffmpeg を放棄し、ノードを使用して ffmpeg コマンドを起動し、ノードから bash スクリプトを起動するだけにしたので/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 の配列はどこにありますか。

于 2015-03-12T02:50:19.273 に答える
2

に移動せずにこれを機能させました/tmp。実行可能ファイルを実行したところ、うまくいきましchmod 755た!以前に に設定したときに問題が発生しましたchmod 777

于 2015-04-13T06:50:51.827 に答える
2

私が書いている時点では、上記のように、バイナリを現在のフォルダー、つまりフォルダーからフォルダーにコピーする必要はもうあり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');

こちら で説明され、モジュールの作成者によって確認されたように、これは不要であると見なすことができます。ラムダ ランタイム環境の探索 で詳しく説明されているラムダ ランタイム (マシン) 環境をよく理解することは興味深いことです。

于 2016-06-16T09:40:47.200 に答える
2

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

  1. ラムダ プロジェクト用に別のディレクトリを作成する
  2. そのディレクトリ内で実行しますnpm install <package name>(これにより、node_modulesと適切なファイルが自動的に配置されます)
  3. index.jsラムダ プロジェクト ディレクトリにファイルを作成し、 を使用しrequire(<package-name>)てビデオ サムネイル作成の主なタスクを実行します。
  4. 完了したら、ラムダ プロジェクト フォルダーを圧縮してアップロードできます。I'm AWS マネジメント コンソールで、インデックス ファイルとハンドラーを構成します。
  5. 残りの構成は、IAM 実行ロール、トリガー、メモリ、タイムアウトの仕様などと同じプロセスに従います。
于 2014-12-30T23:39:59.500 に答える
0

上記と同じ問題を経験したばかりで、実行が必要なスクリプトを /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;
  })
于 2016-02-02T18:59:10.930 に答える