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函数中访问它。
我刚刚经历了这个,就这样走了:
- 在压缩的lambda函数包中包含ffmpeg静态二进制文件(每次构build时我都有一个复制任务将其复制到
/dist
) -
当你的函数被调用的时候,把二进制文件移动到(2017年2月更新:据报道,这已经不再需要了,re:/tmp/
dir,然后chmod
它来给你自己的访问权限@loretoparisi
和@allen
的答案)。 - 更新你的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", })
promises
是promises
的一系列承诺。
我创build了一个GitHub回购 ,它完全做到了这一点(以及同时调整video的大小)。 Russ Matney的回答对于使FFmpeg文件可执行是非常有用的。
我不知道你将用于ffmpeg任务的自定义模式库; 尽pipe如此,完成这些步骤是相同的。
- 为您的lambda项目创build一个单独的目录
- 在该目录内运行
npm install <package name>
(这会自动放置node_modules和相应的文件) - 在lambda项目目录中创build
index.js
文件,然后使用require(<package-name>)
并执行您的主要任务以创buildvideo缩略图 - 一旦你完成了,你可以压缩lambda项目文件夹并上传它我是AWSpipe理控制台和configuration索引文件和处理程序。
- 其余configuration遵循IAM执行angular色,触发器,内存和超时规范等相同的过程。
我得到这个工作,而不移动到/tmp
。 我运行chmod 755
在我的可执行文件,然后它的工作! 当我以前把它设置为chmod 777
时,我遇到了问题。
在我写的时候,如上所述,不需要将当前文件夹的二进制文件,即var/task
或process.env['LAMBDA_TASK_ROOT']
文件夹复制到/tmp
文件夹。 所以这是必要的
chmod 755 dist/ff*
如果你有你的ffmpeg
和ffprobe
二进制文件。
顺便说一句,以前我的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命令并捕获输出。