24

我想从上传到 S3 的视频中制作缩略图,我知道如何使用 Node.js 和 ffmpeg 制作它。

根据这个论坛帖子,我可以添加库:

ImageMagick 是当前默认提供的唯一外部库,但您可以在创建 Lambda 函数时提供的 zip 文件中包含任何其他依赖项。请注意,如果这是本机库或可执行文件,您需要确保它在 Amazon Linux 上运行。

但是如何将静态 ffmpeg 二进制文件放在 aws lambda 上?

我如何使用 AWS Lambda 从 Node.js 调用这个静态二进制文件(ffmpeg)?

我是亚马逊 AWS 和 Linux 的新手

谁能帮我?

4

7 回答 7

39

Naveen 概述的过程是正确的,但它掩盖了一个可能非常痛苦的细节 - 包括 zip 中的 ffmpeg 二进制文件并在您的 lambda 函数中访问它。

我刚刚经历了这个,它是这样的:

  1. 在压缩的 lambda 函数包中包含 ffmpeg 静态二进制文件(我有一个 gulp 任务将其复制到/dist每次构建时)
  2. 当您的函数被调用时,将二进制文件移动到一个/tmp/目录并chmod让您自己访问(2017 年 2 月更新:据报道,这不再需要,回复:@loretoparisi@allen的答案)。
  3. 更新您的 PATH 以包含 ffmpeg 可执行文件(我使用了fluent-ffmpeg,它可以让您设置两个环境变量来更轻松地处理它。

让我知道是否需要更多详细信息,我可以更新此答案。

复制和 chmod(第 2 步)显然不理想......很想知道是否有人找到了更好的方法来处理这个问题,或者这是否是这种架构风格的典型。

(第二次更新,在第一次更新 b/c 之前写它更相关):

正如@Allen 指出的那样,复制+ chmod 步骤不再是必要的——我在Lambda 函数中直接从/var/task/ 执行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

对于大量有用的 lambda 组件:lambduh

以下更新留给后代,但不再需要:

更新更多细节:

我在这里下载了静态 ffmpeg 二进制文件。Amazon 建议启动 EC2 并在其中构建一个二进制文件供您使用,因为该环境将与 Lambda 运行的条件相同。可能是一个好主意,但更多的工作,这个静态下载对我有用。

我只将二进制文件提取ffmpeg到我的项目的待归档/dist文件夹中。

当您将 zip 上传到 lambda 时,它位于/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
    }
  }
)

这应该在你的 lambda 函数中为你提供一个可执行的 ffmpeg 二进制文件——但你仍然需要确保它在你的 $PATH 上。

我放弃了 fluent-ffmpeg 并使用 node 来启动 ffmpeg 命令,转而只在 node 之外启动一个 bash 脚本,所以对我来说,我必须/tmp/在 lambda 函数的顶部添加我的路径:

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运行一系列承诺。

于 2015-03-12T02:50:19.273 回答
8

我创建了一个GitHub 存储库,它正是这样做的(同时调整了视频的大小)。Russ Matney 的回答对于使 FFmpeg 文件可执行非常有帮助。

于 2015-04-12T06:42:28.687 回答
2

我没有将它移动到/tmp. 我chmod 755在我的可执行文件上运行,然后它工作了!我之前将其设置为chmod 777.

于 2015-04-13T06:50:51.827 回答
2

我不确定您将为 ffmpeg 任务使用什么自定义模式库;然而,实现这一目标的步骤是相同的​​。

  1. 为您的 lambda 项目创建一个单独的目录
  2. 在该目录中运行npm install <package name>(这将自动放置 node_modules 和适当的文件)
  3. 在 lambda 项目目录中创建index.js文件,然后使用require(<package-name>)并执行您的主要任务来创建视频缩略图
  4. 完成后,您可以压缩 lambda 项目文件夹并将其上传。我是 AWS 管理控制台并配置索引文件和处理程序。
  5. 其余配置遵循相同的过程,如 IAM 执行角色、触发器、内存和超时规范等。
于 2014-12-30T23:39:59.500 回答
2

在我写的时候,如上所述,不再需要从当前文件夹复制二进制文件,即文件夹var/taskprocess.env['LAMBDA_TASK_ROOT']文件/tmp夹。所以只需要做

chmod 755 dist/ff*

如果你有你的ffmpegffprobe二进制文件。

顺便说一句,以前我浪费 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');

正如此处所述并由模块作者确认,这可以被认为是不需要的,顺便说一下,深入了解 Exploring the Lambda Runtime environment中详细描述的 lambda 运行时(机器)环境是很有趣的。

于 2016-06-16T09:40:47.200 回答
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 回答
0

为了使二进制文件能够在 AWS Lambda 上直接执行(无需先复制到 /tmp 和 chmod),您需要确保二进制文件在添加到 ZIP 文件时具有可执行权限。

这在 Windows 上是有问题的,因为 Windows 无法识别 Linux 二进制文件。如果您使用的是 Windows 10,请使用 Ubuntu Bash shell 创建包。

我在这里专门为此目的创建了一个 Node.js 函数模板。它允许您将一个或多个二进制文件部署到 Lambda,然后执行任意 shell 命令并捕获输出。

于 2017-12-09T09:12:13.990 回答