AWS Lambda制作视频缩略图

时间:2014-12-30 16:01:07

标签: node.js amazon-web-services ffmpeg aws-lambda

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

根据this forum post我可以添加库:

  

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

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

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

我是亚马逊AWS和Linux的新手

任何人都可以帮助我吗?

7 个答案:

答案 0 :(得分:37)

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

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

  1. 在压缩的lambda函数包中包含ffmpeg静态二进制文件(我有一个gulp任务,每次构建时都将其复制到/dist
  2. 调用您的函数时,将二进制文件移动到/tmp/目录并chmod将其移至(2017年2月更新:据报道已不再是必要的,重新:@loretoparisi@allen的答案)。
  3. 更新您的PATH以包含ffmpeg可执行文件(我使用了fluent-ffmpeg,您可以将two env vars设置为更轻松地处理它。
  4. 如果需要更多详细信息,请告诉我,我可以更新此答案。

    副本和chmod(第2步)显然不太理想....很想知道是否有人找到了更好的方法来解决这个问题,或者这是否适用于这种架构风格。

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

    正如@Allen指出的那样,不再需要copy + chmod步骤 - 我正在/ var / task /中直接在Lambda函数中执行ffmpeg,此时没有任何问题。在将它们上传到Lambda之前,请确保chmod 755任何二进制文件(同样@Allen指出)。

    我不再使用流利的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二进制文件here。亚马逊建议启动EC2并构建一个二进制文件供您在那里使用,因为该环境将与Lambda运行的条件相同。可能是一个好主意,但更多的工作,这个静态下载对我有用。

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

    将zip上传到lambda时,它位于/var/task/。无论出于何种原因,我遇到了尝试在该位置使用二进制文件的访问问题,以及尝试编辑该文件的权限的更多问题。快速解决方法是将二进制文件移动到/tmp/chmod权限。

    在Node中,您可以通过child_process运行shell。我做的是这样的:

    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命令,而只是从节点启动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是要运行的承诺数组。

答案 1 :(得分:6)

我创建了一个GitHub repo来完成此操作(以及同时调整视频大小)。 Russ Matney的回答对于使FFmpeg文件可执行非常有帮助。

答案 2 :(得分:2)

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

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

答案 3 :(得分:2)

我将此工作转移到/tmp。我在我的可执行文件上运行了chmod 755然后就可以了!我之前将其设置为chmod 777时出现问题。

答案 4 :(得分: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');

如此处所述和模块作者的confirmed现在可以认为这不是必需的,因为很好地理解lambda运行时(机器)环境,这在探索{ {3}}

答案 5 :(得分: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;
  })

答案 6 :(得分:0)

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

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

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