在AWS Lambda上部署EC2编译的FFmpeg工具——自定义层的方案

大纲

  • [1 确定Lambda运行时环境](#1 确定Lambda运行时环境)
    • [1.1 Lambda系统、镜像、内核版本](#1.1 Lambda系统、镜像、内核版本)
    • [1.2 运行时](#1.2 运行时)
      • [1.2.1 Python](#1.2.1 Python)
      • [1.2.2 Java](#1.2.2 Java)
  • [2 环境准备](#2 环境准备)
    • [2.1 创建EC2实例](#2.1 创建EC2实例)
  • [3 编译FFmpeg](#3 编译FFmpeg)
    • [3.1 连接EC2](#3.1 连接EC2)
  • [4 编译](#4 编译)
  • [5 上传S3存储桶](#5 上传S3存储桶)
    • [5.1 创建S3桶](#5.1 创建S3桶)
    • [5.2 创建IAM策略](#5.2 创建IAM策略)
    • [5.3 创建IAM角色](#5.3 创建IAM角色)
    • [5.4 EC2关联角色](#5.4 EC2关联角色)
    • [5.5 修改桶策略](#5.5 修改桶策略)
    • [5.6 打包并上传](#5.6 打包并上传)
  • [6 创建Lambda的Layer](#6 创建Lambda的Layer)
  • [7 测试](#7 测试)
    • [7.1 创建Lambda函数](#7.1 创建Lambda函数)
    • [7.2 附加FFmpeg层](#7.2 附加FFmpeg层)
    • [7.3 添加测试代码](#7.3 添加测试代码)
    • [7.4 运行测试](#7.4 运行测试)
  • 参考文献

FFmpeg被广泛应用于音/视频流处理领域。对于简单的需求,我们可以直接运行FFmpeg二进制程序命令就可以完成。但是对于定制性的功能,则需要熟悉系统的代码设计框架,进行二次开发。文本讨论的是在AWS无服务架构的Lambda上,如何通过自定义层部署线下编译的FFmpeg二进制程序。

1 确定Lambda运行时环境

Lambda运行时决定了其运行的CPU架构、操作系统和辅助软件。不同语言的运行时环境不同,相同语言的不同版本的运行时不同,所以这步的确认非常重要,否则会造成FFmpeg与Lambda不兼容的问题。下面是从AWS官方摘录了运行时信息,仅供参考。

1.1 Lambda系统、镜像、内核版本

系统 镜像 Linux 内核
Amazon Linux 镜像 -- amzn-ami-hvm-2018.03.0.20181129-x86_64-gp2 4.14
Amazon Linux 2 自定义 4.14

1.2 运行时

1.2.1 Python

Python 运行时 标识符 AWS Python的软件工具包 操作系统 架构
Python 3.9 python3.9 boto3-1.20.32 botocore-1.23.32 Amazon Linux 2 x86_64,arm64
Python 3.8 python3.8 boto3-1.20.32 botocore-1.23.32 Amazon Linux 2 x86_64,arm64
Python 3.7 python3.7 boto3-1.20.32 botocore-1.23.32 Amazon Linux x86_64
Python 3.6 python3.6 boto3-1.20.32 botocore-1.23.32 Amazon Linux x86_64

1.2.2 Java

Java 运行时 标识符 JDK 作系统 架构
Java 11 java11 amazon-corretto-11 Amazon Linux 2 x86_64,arm64
Java 8 java8.al2 amazon-corretto-11 Amazon Linux 2 x86_64,arm64
Java 8 java8 amazon-corretto-11 Amazon Linux x86_64

本例使用Python3.9版本,其操作系统是Amazon Linux 2,Linux内核是"4.14",架构是"x86_64,arm64"。在这两种CPU架构中,我们选择适用面更广的x86_64。如果选择arm64,后续FFmpeg选择,以及Lambda函数运行时也要做出相应调整。

2 环境准备

2.1 创建EC2实例

选择与Lambda系统匹配的的AMI。架构我们选择比较常见的x86。

使用最低配置的EC2的实例,并创建密钥对。

3 编译FFmpeg

3.1 连接EC2

我们直接在Web端连接EC2就行了。

4 编译

编译时间有点长,需要耐心等待下

bash 复制代码
sudo yum install -y autoconf automake bzip2 bzip2-devel cmake freetype-devel gcc gcc-c++ git libtool make pkgconfig zlib-devel
mkdir ~/ffmpeg_sources

cd ~/ffmpeg_sources
curl -O -L https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.bz2
tar xjvf nasm-2.15.05.tar.bz2
cd nasm-2.15.05
./autogen.sh
./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin"
make
make install

cd ~/ffmpeg_sources
git clone --depth 1 https://github.com/mstorsjo/fdk-aac
cd fdk-aac
autoreconf -fiv
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make
make install

cd ~/ffmpeg_sources
curl -O -L https://downloads.sourceforge.net/project/lame/lame/3.100/lame-3.100.tar.gz
tar xzvf lame-3.100.tar.gz
cd lame-3.100
./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --disable-shared --enable-nasm
make
make install

cd ~/ffmpeg_sources
curl -O -L https://archive.mozilla.org/pub/opus/opus-1.3.1.tar.gz
tar xzvf opus-1.3.1.tar.gz
cd opus-1.3.1
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make
make install

cd ~/ffmpeg_sources
curl -O -L https://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
tar xzvf yasm-1.3.0.tar.gz
cd yasm-1.3.0
./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin"
make
make install

cd ~/ffmpeg_sources
git clone --depth 1 https://chromium.googlesource.com/webm/libvpx.git
cd libvpx
./configure --prefix="$HOME/ffmpeg_build" --disable-examples --disable-unit-tests --enable-vp9-highbitdepth --as=yasm
make
make install

cd ~/ffmpeg_sources
git clone --branch stable --depth 1 https://code.videolan.org/videolan/x264.git
cd x264
PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-static
make
make install

cd ~/ffmpeg_sources
git clone --branch stable --depth 2 https://bitbucket.org/multicoreware/x265_git
cd ~/ffmpeg_sources/x265_git/build/linux
cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" -DENABLE_SHARED:bool=off ../../source
make
make install

cd ~/ffmpeg_sources
curl -O -L https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2
tar xjvf ffmpeg-snapshot.tar.bz2
cd ffmpeg
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure \
  --prefix="$HOME/ffmpeg_build" \
  --pkg-config-flags="--static" \
  --extra-cflags="-I$HOME/ffmpeg_build/include" \
  --extra-ldflags="-L$HOME/ffmpeg_build/lib" \
  --extra-libs=-lpthread \
  --extra-libs=-lm \
  --bindir="$HOME/bin" \
  --enable-gpl \
  --enable-libfdk_aac \
  --enable-libfreetype \
  --enable-libmp3lame \
  --enable-libopus \
  --enable-libvpx \
  --enable-libx264 \
  --enable-libx265 \
  --enable-nonfree
make
make install

5 上传S3存储桶

5.1 创建S3桶

在上述EC2所在的区域中创建一个存储桶。同时记录桶的ARN:arn:aws:s3:::lambda-layers-from-ec2。

5.2 创建IAM策略

使用下面的代码在IAM中创建一个名为ffmpeg-builder-policy的策略。该策略赋予策略拥有者可以对上述创建的S3桶(arn:aws:s3:::lambda-layers-from-ec2)进行任何操作。(实际这步可以将权限设置的粒度更细,更加严格)

xml 复制代码
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::lambda-layers-from-ec2",
                "arn:aws:s3:::lambda-layers-from-ec2/*"
            ]
        }
    ]
}

5.3 创建IAM角色

IAM中创建名为ffmpeg-builder-role的角色,并关联到上一步创建的策略。

5.4 EC2关联角色


5.5 修改桶策略

下面的策略设置,让桶可以被上述创建的角色访问。

xml 复制代码
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::【AccountID】:role/lambda-ffmpeg-role"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::lambda-layers-from-ec2",
                "arn:aws:s3:::lambda-layers-from-ec2/*"
            ]
        }
    ]
}

5.6 打包并上传

在EC2中执行下面指令,将编译完的FFmpeg上传到之前创建的S3桶中。

bash 复制代码
zip -j ffmpeg.zip ~/bin/ffmpeg
aws s3 cp ffmpeg.zip --region us-east-1 s3://lambda-layers-from-ec2/

6 创建Lambda的Layer

我们使用上一步上传到S3桶中的地址提交层的内容。

同时要选择好与上步构建的FFmpeg相同架构的"x86_64"。由于从Python3.6到Python3.9都支持x86_64架构,所以这个层可以给这些版本的Python使用。

最后注意下,在License处填写http://www.ffmpeg.org/legal.html,以确保许可。

7 测试

7.1 创建Lambda函数

选择适用于上述创建层的运行时环境(Python3.9)和架构(x86_64)

7.2 附加FFmpeg层


7.3 添加测试代码

下面的代码通过查询FFmpeg版本号,以测试上述部署的可行性。

python 复制代码
import subprocess
import shlex

def lambda_handler(event, context):
    if not event:
        return {
            'statusCode': 400,
            'body': json.dumps('event error')
        }
        
    ffmpeg_cmd = "/opt/ffmpeg -version"
    command = shlex.split(ffmpeg_cmd)
    p = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    return {
        'statusCode': 200,
        'body': str(p.stdout, encoding='utf-8')
    }

7.4 运行测试

可以看到上述部署是成功的。

参考文献

相关推荐
威联通网络存储8 小时前
基于TS-h3087XU-RP的大型成套空分设备DCS历史趋势数据治理
aws
小殊小殊11 小时前
一文速通GPU版FFmpeg视频转码的安装使用
ffmpeg·音视频·视频编解码
spider_xcxc11 小时前
MySQL备份实战:从小白到熟练使用Percona XtraBackup
mysql·云计算·运维开发·dba
主机哥哥1 天前
2026年腾讯云秒杀活动抢购攻略
云计算·腾讯云
花千烬2 天前
crictl info 连不上 containerd 怎么办?endpoint、socket 与权限一次查清
云计算
blanks20204 天前
ffmpeg 学习笔记 通过命令行采集音频
ffmpeg
AKAMAI5 天前
每百万 Token 成本砍六成,出海 AI 团队开始重算推理这笔账
人工智能·云计算
Mahut8 天前
我用 Electron + FFmpeg 做了一个本地视频处理工作站 ClipForge
前端·ffmpeg·electron
A小辣椒15 天前
AWS Clould Support Engineer就职面试题
aws
tiancaijiben18 天前
阿里云Kubernetes集群托管完全指南:从创建到生产级运维
云计算