如何使用支持MP3的SoX二进制文件来支持具有AWS Linux AMI限制的NodeJS AWS Lambda函数?

M_G*_*M_G 2 linux lambda build amazon-ec2 sox

过去3个月我一直在研究这个问题而且完全陷入困境.

我正在尝试打包我的NodeJS AWS Lambda函数,该函数将使用SoX及其依赖项将音频文件转换为MP3.我可以让我的代码通过以下参考指令识别SOX二进制文件的自定义位置在这里,并在这里.我最后将此代码添加到我的Lambda函数调用的开头,以更新process.env PATH变量以包含自定义二进制文件的路径.

process.env['PATH'] = process.env['PATH'] + ':' 
+ path.join(process.env['LAMBDA_TASK_ROOT'], 'binaries');
Run Code Online (Sandbox Code Playgroud)

这导致我的process.env PATH更新看起来像这样:

/usr/local/lib64/node-v4.3.x/bin:/usr/local/bin:/usr/bin/:/bin:/var/task/binaries
Run Code Online (Sandbox Code Playgroud)

哪个看起来正确,binaries是包含我编译的sox二进制文件的目录.

由于我使用NodeJS,我不得不修改sox-audio NPM模块,因此它使用更新的process.env变量进行child_process execspawn调用.这允许代码找到二进制文件,但我仍然在执行期间收到错误.

Sox process exited with code 127 and signal null
Run Code Online (Sandbox Code Playgroud)

我知道虽然它可以找到我包含的SoX二进制文件,但它无法找到与SoX一起使用的命令,但是没有更多信息我无法分辨它是什么.我在想这是因为我不确定我是否包含了二进制文件所包含的所有文件.

为了创建一个支持MP3的SoX的干净编译版本,我创建了一个新的EC2 linux实例,然后按照这里提供的说明进行操作.

我一行一行地确保能够使它工作,并且在安装了一些依赖项以启用编译(例如开发人员工具)之后,通过导出构建PATH,export PATH=$PATH:/usr/local/bin我能够获得安装了MP3支持的完整版本.我测试了它,它的工作原理与我需要的完全一样.

由于AWS Lambda函数在与AWS EC2实例相同的精简版Linux(Amazon Linux AMI)上运行,理论上,如果我可以导出SoX构建并将其包含在我的Lambda软件包中,那么我应该能够让它工作.

那是我遇到麻烦的地方.构建本身的是什么?有一个SoX linux可执行文件,/usr/local/bin其中有一个单独的文件,但是还有更多的文件似乎与使SoX及其依赖项工作有关.这是/usr/local/bin我工作版本中的文件列表.

/ usr/local/bin中的文件

我试图通过FTP导出所有这些文件,然后将它们导入另一个干净的EC2实例,但即使运行export PATH=$PATH:/usr/local/binSoX也会因为依赖性问题而无法运行.很明显,仅导出这些文件是不够的.

  • 如何导出以及如何导出以将我的工作版本的SoX与支持MP3的EC2实例兼容并将其包含在我的AWS Lambda函数中?
  • 要使MP3工作的安装依赖项的长列表是否会使这变得不可能?
  • 是否有文件不仅仅是/usr/local/bin我需要包含的目录?

我真的不知道还有什么可以用的.请帮忙 :(

M_G*_*M_G 10

我花了3个月才最后发帖,我在同一天弄明白了.

在做了一些更多的研究后,我得出结论,我需要创建一个静态版本的SoX,并具有转换MP3所需的依赖关系.我最后整理了一个脚本来创建基于这篇博文的静态版本,以及这篇博文.

我将两者结合起来的原因是因为我使用的是亚马逊Linux AMI,这是非常准确的.因此,第二篇博客中提到的所有debian和apt-get内容都不太可行.但是,我需要确保安装了编译器,这样我就不会遇到任何错误.以下是我最终运行的内容.我以root身份做了所有事情,因为在EC2 Amazon Linux AMI实例上特权受到相当限制.作为普通用户,唯一需要运行的是最后的PATH导出.

sudo yum update
sudo yum install gcc44 gcc-c++ libgcc44 cmake –y

# now grab sox and its dependencies
mkdir -p deps
mkdir -p deps/unpacked
mkdir -p deps/built
mkdir -p deps/built/libmad
mkdir -p deps/built/sox
mkdir -p deps/built/lame
wget -O deps/sox-14.4.1.tar.bz2 "http://downloads.sourceforge.net/project/sox/sox/14.4.1/sox-14.4.1.tar.bz2?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fsox%2Ffiles%2Fsox%2F14.4.1%2F&ts=1416316415&use_mirror=heanet"
wget -O deps/libmad-0.15.1b.tar.gz "http://downloads.sourceforge.net/project/mad/libmad/0.15.1b/libmad-0.15.1b.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fmad%2Ffiles%2Flibmad%2F0.15.1b%2F&ts=1416316482&use_mirror=heanet"
wget -O deps/lame-3.99.5.tar.gz "http://downloads.sourceforge.net/project/lame/lame/3.99/lame-3.99.5.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Flame%2Ffiles%2Flame%2F3.99%2F&ts=1416316457&use_mirror=kent"

# unpack the dependencies
pushd deps/unpacked
tar xvfpj ../sox-14.4.1.tar.bz2
tar xvfpz ../libmad-0.15.1b.tar.gz
tar xvfpz ../lame-3.99.5.tar.gz
popd

# build libmad, statically
pushd deps/unpacked/libmad-0.15.1b
./configure --disable-shared --enable-static --prefix=$(realpath ../../built/libmad)
# Patch makefile to remove -fforce-mem
sed s/-fforce-mem//g < Makefile > Makefile.patched
cp Makefile.patched Makefile
make
make install
popd

# build lame, statically
pushd deps/unpacked/lame-3.99.5
./configure --disable-shared --enable-static --prefix=$(realpath ../../built/lame)
make
make install
popd

# build sox, statically
pushd deps/unpacked/sox-14.4.1
./configure --disable-shared --enable-static --prefix=$(realpath ../../built/sox) \
    LDFLAGS="-L$(realpath ../../built/libmad/lib) -L$(realpath ../../built/lame/lib)" \
    CPPFLAGS="-I$(realpath ../../built/libmad/include) -I$(realpath ../../built/lame/include)" \
    --with-mad --with-lame --without-oggvorbis --without-oss --without-sndfile --without-flac  --without-gomp
make -s
make install
popd

cp deps/built/sox/bin/sox .
rm -rf deps/built
rm -rf deps/unpacked
Run Code Online (Sandbox Code Playgroud)

在此之后,我以普通用户身份运行以下内容

export PATH=$PATH:/home/ec2-user
Run Code Online (Sandbox Code Playgroud)

然后我可以运行sox!只需在sox终端输入,就可以在终端窗口中显示sox命令列表.

更好的是,我能够下载单个sox linux可执行文件,然后将其上传到全新的EC2实例.我必须在新实例上运行以使其工作的唯一事情如下:

sudo yum update
sudo yum install gcc44 gcc-c++ libgcc44 cmake –y
export PATH=$PATH:/home/ec2-user
Run Code Online (Sandbox Code Playgroud)

我担心我不得不尝试再次构建它而不进行yum更新或yum安装,因为我最终想把它放在Lambda函数中,但这不是必需的!当我将它添加到我的测试Lambda函数并上传时,根据云日志,它没有问题.这必须意味着Lambda容器中使用的Amazon Linux AMI已经安装了yum更新和正确的编译器.