AWS Lambda制作video缩略图

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

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

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

但是我怎样才能把静态ffmpeg二进制文件放在aws lambda?

我怎样才能使用AWS Lambda从Node.js调用这个静态二进制文件(ffmpeg)?

我是亚马逊AWS和Linux的新手

谁能帮我?

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

我刚刚经历了这个,就这样走了:

  1. 在压缩的lambda函数包中包含ffmpeg静态二进制文件(每次构build时我都有一个复制任务将其复制到/dist
  2. 当你的函数被调用的时候,把二进制文件移动到/tmp/ dir,然后chmod它来给你自己的访问权限 (2017年2月更新:据报道,这已经不再需要了,re: @loretoparisi@allen的答案)。
  3. 更新你的PATH以包含ffmpeg可执行文件(我使用了fluent-ffmpeg ,它可以让你设置两个env vars来更容易的处理。

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

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

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

正如@Allen所指出的那样,copy + chmod步骤不再是必要的 – 我直接从/ var / task /中直接在Lambda函数中执行ffmpeg,此时没有任何问题。 请确保在将任何二进制file upload到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二进制文件。 亚马逊build议启动一个EC2并在那里build立一个二进制文件供你使用,因为这个环境将与Lambda运行的条件相同。 大概一个好主意,但更多的工作,这静态下载为我工作。

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

当您将zipfile upload到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 } } ) 

这很多应该给你一个可执行的ffmpeg二进制在你的lambda函数 – 但你仍然需要确保它在你的$ PATH。

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

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

如果使用fluent-ffmpeg,则可以通过以下方式将path设置为ffmpeg:

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

有点相关/无耻的自我插件:我正在研究一系列模块,以使用Lambduh这个名称更容易地使用可组合模块构buildLambda函数。 可以节省一些时间把这些东西放在一起。 一个简单的例子:用lambduh-execute处理这个场景就像下面这样简单:

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

promisespromises的一系列承诺。

我创build了一个GitHub回购 ,它完全做到了这一点(以及同时调整video的大小)。 Russ Matney的回答对于使FFmpeg文件可执行是非常有用的。

我不知道你将用于ffmpeg任务的自定义模式库; 尽pipe如此,完成这些步骤是相同的​​。

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

我得到这个工作,而不移动到/tmp 。 我运行chmod 755在我的可执行文件,然后它的工作! 当我以前把它设置为chmod 777时,我遇到了问题。

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

chmod 755 dist/ff*

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

顺便说一句,以前我的2美分的解决scheme浪费了两天时间

 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'); 

如此处所述并由模块作者确认 ,现在可以认为这是不需要的,顺便说一下,在浏览Lambda Runtime环境中对Lambda运行时(机器)环境有很好的理解是很有趣的。

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

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

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

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