Preface
由于Mp3文件是有版权的,所以一般iOS和android都没有提供将音频转换为mp3文件的功能.
这时,我们就需要依赖第三方库,自己进行处理.
Lame库是可以将pcm文件转码为mp3文件的王牌库,就像炒菜要用锅,转换Mp3就要用Lame.
Lame源码的下载地址为:
https://lame.sourceforge.io/
当前最新版本为2017-10更新的3.100
本文主要讲述如何将Lame库编译为so,以及相关话题.
1 ABI
ABI(Application binary interface)应用程序二进制接口,是用来和CPU通信的一套规则,不同的CPU型号会使用不同的ABI.
CPU大都是向前兼容的,但是会按优先级来选择ABI。设计使用的那个ABI效率最高,其他ABI虽然可以用,但是效率比较低.如x86架构的CPU会优先选择x86目录下的.so包,当不存在时,才会选择armeabi-v7a目录下的.so包,如果仍然不存在,最后才会选择armeabi目录下的.so文件。
注:x86设备运行armeabi下的so库时会损失性能。
主流ABI架构
现在主流的ABI架构如下:
查看自己手机的ABI
查看自己手机的abi需要使用adb命令,该命令存在于android sdk中.请确保adb命令已添加到环境变量.
按照以下步骤查看:
adb devices
查看当前链接的设备列表
//查看当前所有的设备列表.
adb devices
List of devices attached
937c7b6a device
emulator-5554 device
小编这里连接了两台,一台是模拟器,一台是真机.
- 使用
adb -s ${devicId} shell getprop ro.product.cpu.abi
命令查看设备abi
可以看到,真机是arm64-v8a的,模拟器是x86的.
2 编译脚本
小编的操作环境为:
os:MacOS Big Sur Version 11.0.1
编译前需要准备好ndk工具,小编的ndk目录为:
~/Library/Android/sdk/ndk/20.0.5594570
是r20的版本.
需要注意的是,网上很多的编译脚本使用的是r10的版本,用的是gcc编译器,不适用于r20的版本.
脚本如下:
#!/bin/sh
# --- 脚本信息 Start ---
version="0.0.1(1)"
author="BinaryBang"
email="GikkiAres@icloud.com"
# --- 脚本信息 End ---
# --- 输入参数指定 Start ---
# lame库目录
libDir="/Users/gikkiares/Desktop/MD_MyData/05_MediaDevelopTool/01_Lame/01_SourceCode/lame-3.100"
# ndk目录
ndkDir="/Users/gikkiares/Library/Android/sdk/ndk/20.0.5594570"
# 输出的库目录
productRootDir="/Users/gikkiares/Desktop/MD_MyData/05_MediaDevelopTool/01_Lame/03_BuildProduct/android"
# 架构
archs="armeabi-v7a arm64-v8a x86 x86_64"
# api等级
androidApiLevel="21"
# --- 输入参数指定 End ---
for arch in ${archs}
do
echo "comile arch: ${arch}"
case $arch in
armeabi-v7a)
archHost="armv7a-linux-androideabi"
crossCompile="arm-linux-androideabi"
;;
arm64-v8a)
archHost="aarch64-linux-android"
crossCompile=${archHost}
;;
x86)
archHost="i686-linux-android"
crossCompile=${archHost}
;;
x86_64)
archHost="x86_64-linux-android"
crossCompile=${archHost}
;;
*) echo "Parameter is not valid."
exit
;;
esac
export CC="${ndkDir}/toolchains/llvm/prebuilt/darwin-x86_64/bin/${archHost}${androidApiLevel}-clang"
export CXX="${ndkDir}/toolchains/llvm/prebuilt/darwin-x86_64/bin/${archHost}${androidApiLevel}-clang++"
prebuilt="${ndkDir}/toolchains/llvm/prebuilt/darwin-x86_64"
export AS=${prebuilt}/bin/${crossCompile}-as
export LD=${prebuilt}/bin/${crossCompile}-ld
export NM=${prebuilt}/bin/${crossCompile}-nm
export STRIP=${prebuilt}/bin/${crossCompile}-strip
export RANLIB=${prebuilt}/bin/${crossCompile}-ranlib
export AR=${prebuilt}/bin/${crossCompile}-ar
productDir="${productRootDir}/${arch}"
rm -rf ${productDir}
mkdir ${productDir}
cd ${libDir}
# config
./configure \
--host=${archHost} \
--enable-shared \
--disable-static \
--target=android \
--disable-frontend \
--enable-static \
--prefix="${productDir}"
# make
make clean
make -j8
make install
done
脚本使用时,需要在输入参数指定部分自行设置相关补录.
3 验证so文件
如何验证编译出来的so文件是正确的abi?
可以使用以下两种方式验证.
file命令验证
使用objdump命令验证
该命令输出内容很多,我们只看前面几行就可以了.