如何在 AWS Lambda 机器上安装 ffmpeg?

13
我正在尝试在AWS Lambda上运行一个使用ffmpeg的Node.js脚本。为此,我需要在机器上安装ffmpeg。
我查看了文档,但是没有找到如何连接到运行Lambda的机器的方法。

3
抱歉,你不能直接在Lambda中使用ffmpeg。如果你想要使用它,你需要将它和你的代码一起压缩上传,或者在运行时将它下载到Lambda容器的本地文件系统中。如果它被放在ZIP文件的根目录下,那么它应该被安装在/var/task目录下,但是它不会有+x权限,所以你需要在Lambda代码中添加这些权限。在Lambda中运行ffmpeg相对较为困难。有很多Github项目尝试简化在Lambda中使用ffmpeg的过程(例如fluent-ffmpeg),但是没有一个能够解决构建ffmpeg二进制文件并以正确权限进行安装的问题。 - jarmod
2
我已经逐步回答了如何在Lambda实例中包含ffmpeg的问题。别忘了点个赞,伙计:D - alaysd
6个回答

19

在Python中,我用以下方法解决了这个问题:

  1. 此处获取FFmpeg的静态版本,如@Xeroxoid所提到的那样。
  2. 使用tar -zxvf ffmpeg-release-amd64-static.tar.xz解压缩。
  3. 从文件夹中获取ffmpeg(和可选的ffprobe)文件。
  4. 将裸的FFmpeg文件(不含子文件夹)放在与Lambda代码相同的文件夹中。
  5. cd进入此文件夹并使用zip -r -X "../archive.zip" *进行压缩。
  6. 上传压缩文件至AWS Lambda。

像这样设置FFmpeg的正确文件路径:

FFMPEG_STATIC = "/var/task/ffmpeg"
import subprocess
subprocess.call([FFMPEG_STATIC, '-i', input_file, output_file])

1
工作得很好,谢谢!只需要在路径中执行./ffmpeg。 - Bryan Linton
1
为什么这不是最受赞和正确的答案呢?非常好用。此外,这里还有更多信息:https://medium.com/dev-genius/how-to-process-media-in-aws-lambda-ffmpeg-f53491cf8768 - stingMantis
你也要将ffmpeg和ffprobe添加到git吗?git会警告它们是大文件。 - undefined
@Jun 我在提到的工作流程中不使用git。但是,是的,这两个文件都比较大,ffmpeg大约有80MB。所以可能会收到git的警告。然而,你不需要使用git来使ffmpeg在你的AWS Lambda上可用。 - undefined

18

11
你永远不会连接到Lambda运行的“机器”。函数运行的机器不是单一的,而且在第一次调用之前,函数甚至都没有部署。Lambda在一个或多个容器中运行,这些容器会根据请求的到来而创建和删除。你必须将像 ffmpeg 这样的内容包含在 Lambda 的部署包中,这样每次将函数部署到容器时它都会存在。
你在函数的部署包中包含的任何二进制文件都需要为 Lambda 运行的操作系统 Amazon Linux 构建。你可以 使用 EC2 服务器构建二进制文件 或查找已经为 Lambda 打包并提供了 ffmpeg 的人。

8
您也可以在这个酷哥哥的网站上找到针对aws-lambda的预编译版本ffmpeg,链接在这里:https://johnvansickle.com/ffmpeg/。(我选择了x86_64版本。)
提示:不要忘记为二进制文件ffmpeg和可能需要的ffprobe设置正确的+x权限。

你如何将可执行文件所在的目录添加到路径中?我有一个 Lambda,根据上面的链接包含 ffmpeg,但调用 which ffmpeg 返回 null(表示它找不到我的可执行文件)。 - rodrigo-silveira

2

我想在我的Lambda函数中使用FFmpeg,但是当我将其作为Lambda Layer包含或将其包含在源代码包中时,Lambda函数的允许最大大小已经超过了。

使用Docker和Lambda可能是绕过大小限制的好方法,但我的工作流需要重构,所以我决定通过压缩静态amd64 ffmpeg二进制文件并将其放入我的Lambda函数可以访问的存储桶中来实现解决方案。

该函数将从S3中获取zip文件,并将其解压缩到Lambda的/tmp目录中,然后可以通过subprocess.check_output()进行调用。

我将ffmpeg二进制文件压缩在bin/ffmpeg中以供该软件包使用。 你不需要压缩它,只需将二进制文件放在S3上即可。Lambda (/tmp)的存储空间可以在512MB和10,240 MB之间配置。

import logging
from io import BytesIO
from pathlib import Path
from tempfile import TemporaryDirectory
from zipfile import ZipFile

import boto3
from botocore.exceptions import ClientError

from zappa.asynchronous import task

logger = logging.getLogger(__name__)

S3_CLIENT = boto3.client("s3")


def prepare_ffmpeg(bucket: str, key: str) -> Path:
    ffmpeg_binary_path = Path("/tmp/ffmpeg")
    with BytesIO() as bytesbuffer:
        logger.info(f"Downloading package s3://{bucket}/{key} ...")
        try:
            S3_CLIENT.download_fileobj(bucket, key, bytesbuffer)
        except ClientError as e:
            logger.exception(e)
            logger.error(f"Downloading package s3://{bucket}/{key} ... ERROR")
        else:
            logger.info(f"Downloading package s3://{bucket}/{key} ... COMPLETE")
            logger.info(f"Unzipping 'bin/ffmpeg' from {key} to {ffmpeg_binary_path} ...")
            bytesbuffer.seek(0)
            z = ZipFile(bytesbuffer)
            with ffmpeg_binary_path.open("wb") as fileout:
                ffmpeg_content = z.read("bin/ffmpeg")
                fileout.write(ffmpeg_content)
            ffmpeg_binary_path.chmod(0o777)
            logger.info(f"Unzipping 'bin/ffmpeg' from {key} to {ffmpeg_binary_path} ... COMPLETE")
            assert ffmpeg_binary_path.exists()
    return ffmpeg_binary_path

1
我有一个类似的需求,需要在AWS Lambda函数中使用FFmpeg生成视频。由于我的应用程序由于`node_modules`和其他文件的存在而变得庞大,我选择使用AWS Elastic Container Registry(ECR)创建一个Docker镜像,并将其用作Lambda的基础镜像。
以下是我遵循的步骤:
1. 首先,我从这里下载了以zip格式提供的FFmpeg二进制文件。 2. 下载完成后,我解压了zip文件,得到一个包含FFmpeg二进制文件的文件夹。 3. 接下来,我将FFmpeg二进制文件从解压后的文件夹复制到我的项目根目录,即Dockerfile所在的级别。 4. 然后,我修改了我的Dockerfile,将FFmpeg二进制文件复制到`/usr/bin`文件夹中。以下是我的Dockerfile的内容:
```dockerfile # Dockerfile内容 ```
以上。
# Use an official Node.js runtime as a parent image
FROM amazon/aws-lambda-nodejs

# ENV DEBUG="puppeteer:*"

# Copy the FFmpeg binary to /usr/bin
COPY ffmpeg /usr/bin

# Copy package.json and package-lock.json (if available)
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of your application code
COPY index.js ./
COPY *.service.js ./

# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "index.handler" ]

通过按照这些步骤并将FFmpeg二进制文件包含在Docker镜像中,您可以在AWS Lambda函数中无缝使用FFmpeg,而不会遇到任何问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接