【问题标题】:FFMPEG failing in AWS LambdaFFMPEG 在 AWS Lambda 中失败
【发布时间】:2019-02-14 12:45:43
【问题描述】:

我正在尝试为短视频创建转码功能。该函数托管在 AWS Lambda 上。问题是 AWS lambda 似乎缺少 FFMPEG 需要的东西,至少根据亚马逊的说法。

我之前联系过亚马逊,这是他们对这个问题的回应:

我们发现 FFMPEG 操作至少需要 libx264 和一个 acc 库,它们都有自己的依赖项。到 解决问题,这将涉及更深入地深入研究 依赖链。我们可以看到它在 Amazon Linux 中运行 环境然而,环境是相似的,但不完全相同 lambda 环境。可能存在一些依赖项 Amazon Linux 但不在 lambda 环境中,因为 Lambda 在 容器。在这里,由于 FFmpeg 是第三方软件,因此深入研究 进入依赖链并验证版本兼容性是 很难做到。不幸的是,更进一步,这必然会进入 架构和代码支持超出 AWS Support 范围 1。一世 希望您了解我们的局限性。但是FFmpeg应该支持吗 对 Lambda 平台有任何疑问,请告诉我们 知道,我们将很乐意为您提供帮助。我们将处于更好的位置 一旦您收到来自 FFmpeg 支持的更新,请进一步调查 从 Lambda 端提出一个问题。

根据 AWS 的建议,我联系了开发人员邮件列表上的 FFMPEG,我的邮件被拒绝了,原因是它比开发人员更适合 ffmpeg 用户邮件列表。一周前我向“ffmpeg-user@ffmpeg.org”发送了一封电子邮件,但尚未收到任何回复。

然后我构建了一个动态链接的 ffmpeg 版本,确保打包所有库,检查每个库的 ddl,然后创建一个小的 lambda 函数,循环遍历所有二进制文件并对每个文件进行 ddl,与我的输出相比从 Amazon Linux 获取,并且 lambda 和 AWS Linux 实例上存在相同的依赖项/版本,但 ffmpeg 在 lambda 上仍然失败。

您可以在此处找到详细的日志文件:https://www.datafilehost.com/d/6e5e21bb

这是我得到的错误示例,在整个日志文件中重复:

2018-08-14T12:27:10.874Z [h264 @ 0x65c2fc0] 隐藏 2628 DC, 2628 AC,P帧2628个MV错误

2018-08-14T12:27:10.874Z [aac @ 0x65d2f00] 通道元素 2.11 不是 已分配

2018-08-14T12:27:10.874Z 解码流 #0:1 时出错:无效 处理输入时找到的数据

2018-08-14T12:27:10.874Z [h264 @ 0x67e86c0] NAL 单元大小无效 (108085662 > 1649)。

2018-08-14T12:27:10.874Z [h264 @ 0x67e86c0] 拆分输入时出错 转换为 NAL 单元。

2018-08-14T12:27:10.874Z [aac @ 0x65d2f00] 通道元素 2.0 不是 已分配

2018-08-14T12:27:10.874Z 解码流 #0:1 时出错:无效 处理输入时找到的数据

2018-08-14T12:27:10.874Z [h264 @ 0x68189c0] NAL 单元大小无效 (71106974 > 1085)。

2018-08-14T12:27:10.874Z [h264 @ 0x68189c0] 拆分输入时出错 转换为 NAL 单元。

2018-08-14T12:27:10.874Z [aac @ 0x65d2f00] 不允许使用脉冲工具 八个短序列。

尝试对此文件执行 HLS 转码时会生成此日志:https://www.datafilehost.com/d/999a4492

请注意,该问题与该文件无关,也与 HLS 无关,它一般发生在所有视频和任何试图寻找流的 ffmpeg 命令上,甚至尝试使用可能的最简单形式,例如:ffmpeg -ss 00:00:02 -I file.mp4 -vframes 1 -y output.jpg 也会失败,并在日志文件中显示相同的错误。

不确定如何进一步调试。尝试使用“-loglevel debug”启用调试日志,但没有给我任何额外信息。任何帮助或建议

【问题讨论】:

  • 不查找时运行正常吗?
  • 另外,您确实收到了关于 ffmpeg-user 的回复,但您还没有跟进:lists.ffmpeg.org/pipermail/ffmpeg-user/2018-September/…
  • @Gyan 唯一能正常运行的是调用ffmpeg -i file.mp4 任何试图读取视频的操作都失败
  • 源文件实际上是如何进入 Lambda 容器的?它是在调用请求有效负载中传递的吗?如果是这样,除非您将其作为 base64 传递,否则您可能会损坏它。 Lambda API 是 JSON,它不支持任意二进制数据,有效载荷中的任何无效 utf-8 几乎肯定会被强制转换为 utf-8 替换为 � (U+FFFD/hex 0xEF 0xBF 0xBD)代替不是实际有效字符的字节。将 base64 用于二进制有效负载可以解决此问题。这些错误给人的印象是数据损坏,而不是依赖问题。
  • @Michael-sqlbot 该文件已下载并存储在 lambda 的磁盘上。起初,在计算下载文件的 MD5 时,我认为同样的事情是正确的。除了 MD5 之外,我尝试在下载后将文件重新上传到 S3 并保留二进制文件。

标签: amazon-web-services ffmpeg aws-lambda h.264 aac


【解决方案1】:

我今天遇到了完全相同的问题并花了几个小时。但最后我遇到了这个SO answer 并找到了解决方案。

基本上,您需要确保没有将 STDIN 传递给 FFmpeg 进程。 re:Invent 演讲中提到了这一点 on this slide

【讨论】:

    【解决方案2】:

    如果您在使用 ffmpeg 时遇到问题,请尝试使用 avconv。 avconv 是 ffmpeg 的一个分支,可以以相同的方式调用。尝试在 lambda 环境中解码 aac 音频流时,我遇到了与使用 ffmpeg 相同的问题,但 John Van Sickle 的 avconv 静态构建对我来说按预期工作。

    另外,请确保为您的 lambda 函数分配足够的 RAM。静态 ffmpeg 二进制文件很大,编码需要大量 RAM,尤其是在编码视频时。

    【讨论】:

    • 也许你的 ffmpeg 很古老。
    • @LordNeckbeard:我使用了不到一个月前发布的 ffmpeg 4.1(John van Sickle 的静态构建),它在我的本地 debian 机器上完美运行。
    • 所以 4.1 在本地 debian 机器上使用相同的输入文件可以正常工作,但相同的版本在 lambda 上不起作用?很高兴能深入了解这一点。
    • 是的,确实如此。使用相同的 ffmpeg 4.1 静态二进制文件和相同的输入文件,从 aac 到 wav 的转换在 Lambda 上失败,但在我的本地 Debian 机器上工作。如果我用 avconfig 12.1 的静态构建(同样是 John van Sickle 的静态构建)替换 ffmpeg,那么我在 Lambda 中没有任何问题。我也想知道我们如何才能理解那里出了什么问题。
    【解决方案3】:

    您是否尝试过使用静态编译的 ffmpeg?

    这对我有用:

    1. https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-64bit-static.tar.xz 抓取了一个静态构建的 ffmpeg
    2. 提取并丢弃除ffmpeg 二进制文件本身之外的所有内容。 chmod 这个二进制文件以允许执行并放入部署文件夹内的bin/ffmpeg(在我的情况下,该文件夹将由 zappa 压缩和部署)
    3. /tmp 中复制了ffmpeg 二进制文件。 (如果从/var/task/bin 执行 ffmpeg,我会遇到操作不允许错误,我对 ffmpeg 本身的了解是有限的,但我的假设是 ffmpeg 将在处理过程中创建临时文件,并且由于 lambda 具有只读文件系统,这只能在/tmp 内完成,在我的情况下,我正在将 caf 转换为 mp4)
    4. 在搜索路径中添加了/tmp,因此ffmpeg 将在路径中可用。 (在使用一些封装了 ffmpeg 调用的 3rd 方时需要,例如 pydub

    这里是相关的 python 代码,因为 lambda 容器将被重用,/tmp 可能已经包含复制的 ffmpeg。

    from os import environ, path
    from shutil import copy2
    
    # check if we have ffmpeg inside /tmp, if we do, no need to copy
    # otherwise copy ffmpeg from /var/task/bin to /tmp
    if environ.get('AWS_EXECUTION_ENV', '').startswith('AWS_Lambda_') and not path.isfile('/tmp/ffmpeg'):
        copy2(path.join(PROJECT_ROOT, 'bin/ffmpeg'), '/tmp/ffmpeg')
    
    # add /tmp to search paths if it's not there
    # so ffmpeg executed from pydub will be found
    custom_deps_bin_path = '/tmp/'
    if environ.get('AWS_EXECUTION_ENV', '').startswith('AWS_Lambda_') and custom_deps_bin_path not in environ['PATH']:
        environ['PATH'] += ":" + custom_deps_bin_path
    

    也很少有相关的第三方:

    1. binoculars/aws-lambda-ffmpeg
    2. ubergarm/zappa-ffmpeg

    【讨论】:

      猜你喜欢
      • 2022-06-14
      • 2023-01-17
      • 2017-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-30
      • 2019-05-16
      相关资源
      最近更新 更多