【问题标题】:AWS Lambda making video thumbnailsAWS Lambda 制作视频缩略图
【发布时间】:2015-02-26 19:15:30
【问题描述】:

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

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

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

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

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

我是亚马逊 AWS 和 Linux 的新手

谁能帮帮我?

【问题讨论】:

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


    【解决方案1】:

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

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

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

    如果需要更多细节,请告诉我,我可以更新这个答案。

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

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

    复制 + chmod 步骤不再是必要的,正如@Allen 指出的那样——我在 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 二进制文件here。 Amazon 建议启动 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 命令,转而只在 node 之外启动一个 bash 脚本,所以对我来说,我必须在 lambda 函数顶部的路径中添加/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 是要运行的承诺数组。

    【讨论】:

    • 谢谢,非常好的回应。请添加更详细的过程。
    • @Jesus 更新了更多细节,如果没有点击请大喊。
    • 感谢升级 :)
    • 这是天才。非常感谢!
    • 如何获取 ffmpeg 静态二进制文件。我遇到了问题:stackoverflow.com/questions/39982511/…
    【解决方案2】:

    我创建了一个 GitHub repo 来实现这一点(同时调整视频大小)。 Russ Matney 的回答对于使 FFmpeg 文件可执行。

    【讨论】:

    • 很好的存储库,很容易启动和运行。谢谢!
    【解决方案3】:

    我不确定你会为 ffmpeg 任务使用什么自定义模式库;然而,完成它的步骤是相同的​​。

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

    【讨论】:

      【解决方案4】:

      我没有将其移至 /tmp 就可以正常工作。我在我的可执行文件上运行了chmod 755,然后它工作了!我之前将其设置为 chmod 777 时遇到了问题。

      【讨论】:

      • 能举个详细的例子吗?
      【解决方案5】:

      在我写作的时候,如上所述,不再需要从当前文件夹(即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 Runtime environment 中很好地描述的 lambda 运行时(机器)环境是很有趣的.

      【讨论】:

      • 当我尝试 chmod 二进制文件时出现权限被拒绝错误? fs.chmodSync('/var/task/node_modules/imagemin-mozjpeg/node_modules/mozjpeg/vendor/cjpeg', '755'); “错误:EROFS:只读文件系统,chmod '/var/task/node_modules/imagemin-mozjpeg/node_modules/mozjpeg/vendor/cjpeg'”
      【解决方案6】:

      我刚刚经历了与上述相同的问题,最终以相同的概念将需要执行的脚本移动到 /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;
        })
      

      【讨论】:

        【解决方案7】:

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-12-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-15
          • 2023-04-05
          • 2010-12-13
          • 2012-02-23
          相关资源
          最近更新 更多