首先列出本次編譯所需要的環(huán)境和源碼版本:
- 編譯環(huán)境:VMware-15.5.6 + ubuntu-20.04.2.0
- 編譯工具:android-ndk-r22b
- FFmpeg源碼:ffmpeg-4.1.6
1. 搭建編譯環(huán)境
1.1 安裝Ubuntu
在Windows10電腦安裝VMware市怎,創(chuàng)建新的虛擬機(jī)Ubuntu萍肆,到官網(wǎng)下載需要版本安裝即可,安裝完成后執(zhí)行以下命令:
apt-get update
apt-get install yasm
apt-get install pkg-config
-
apt-get install make
如果安裝失敗选侨,解決辦法根據(jù)提示挂据,加sudo,如:sudo apt-get install make
1.2 下載ndk
在/home下新建ffm文件夾,將ndk下載到 /home/ffm/目錄下:
wget https://dl.google.com/android/repository/android-ndk-r22b-linux-x86_64.zip
下載完成后解壓:
unzip android-ndk-r22b-linux-x86_64.zip
1.3 下載FFmpeg
將FFmpeg下載到 /home/ffm/目錄下:
wget http://www.ffmpeg.org/releases/ffmpeg-4.1.6.tar.gz
下載完成后解壓:
tar -zxvf ffmpeg-4.1.6.tar.gz
2. 編譯FFmpeg
在開(kāi)始編譯FFmpeg之前烛恤,先簡(jiǎn)單介紹下交叉編譯。引自百度百科的定義:交叉編譯是在一個(gè)平臺(tái)上生成另一個(gè)平臺(tái)上的可執(zhí)行代碼余耽,這里即是在Linux平臺(tái)編譯出Android平臺(tái)可以使用的FFmpeg so庫(kù)缚柏。
對(duì)于C/C++的編譯,通常有兩個(gè)工具 GCC 和 CLANG 碟贾。
- GCC币喧,是一個(gè)老牌的編譯工具,不僅可以編譯C/C++袱耽,也可以編譯Java杀餐,Object-C,Go等語(yǔ)言朱巨。
- CLANG史翘,則是一個(gè)效率更高的C/C++編譯工具,并且兼容GCC冀续,Google在很早以前就開(kāi)始建議使用clang進(jìn)行編譯琼讽,并且在ndk17以后,把GCC移除了洪唐,全面推行使用 CLANG 钻蹬。
2.1 新建配置編譯腳本
在ffmpeg-4.1.6源碼根目錄下新建腳本build.sh:vim build.sh
輸入完成后,出現(xiàn)如下界面:
然后按下英文字母i, 底部就會(huì)出現(xiàn)INSERT, 表示當(dāng)前可以輸入文本信息凭需,腳本內(nèi)容如下:
#!/bin/bash
# 目標(biāo)Android版本
API=21
ARCH=arm
CPU=armv7-a
#so庫(kù)輸出目錄
PREFIX=$(pwd)/android/$CPU
# NDK的路徑问欠,根據(jù)自己的NDK位置進(jìn)行設(shè)置
NDK=/home/root1/ffm/android-ndk-r22b
# 編譯環(huán)境
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
# 編譯工具鏈路徑
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin
OPTIMIZE_CFLAGS="-DBIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD -mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
configure()
{
./configure \
--prefix=$PREFIX \
--enable-cross-compile \
--target-os=android \
--arch=$ARCH \
--cpu=$CPU \
--sysroot=$SYSROOT \
--cc=$TOOLCHAIN/armv7a-linux-androideabi$API-clang \
--cxx=$TOOLCHAIN/armv7a-linux-androideabi$API-clang++ \
--cross-prefix=$TOOLCHAIN/arm-linux-androideabi- \
--disable-encoders \
--disable-decoders \
--enable-decoder=h264 \
--enable-decoder=h264_mediacodec \
--enable-decoder=mp3 \
--enable-decoder=aac \
--disable-muxers \
--disable-demuxers \
--enable-demuxer=flv \
--enable-demuxer=sdp \
--enable-demuxer=rtsp \
--disable-filters \
--disable-parsers \
--enable-parser=aac \
--enable-parser=h264 \
--disable-bsfs \
--enable-bsf=aac_adtstoasc \
--enable-bsf=h264_mp4toannexb \
--disable-protocols \
--enable-protocol=file \
--enable-protocol=http \
--enable-protocol=rtmp \
--disable-libsrt \
--enable-neon \
--enable-hwaccels \
--enable-shared \
--enable-jni \
--enable-mediacodec \
--disable-static \
--disable-doc \
--enable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--enable-avdevice \
--disable-doc \
--disable-symver \
--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
}
build()
{
configure
make clean
make
make install
}
build
編輯完成后按Esc鍵退出編輯模式,輸入:wq保存退出粒蜈,可以看到根目錄下多了build.sh文件顺献。
重點(diǎn)關(guān)注幾個(gè)選項(xiàng):
- arch 選擇機(jī)器架構(gòu)
- cpu 選擇最低的cpu
-
target-os 設(shè)置目標(biāo)系統(tǒng)
在舊版本的 FFmpeg 中,對(duì)Android平臺(tái)的支持并不是很完善薪伏,并沒(méi)有android
這個(gè)target滚澜,所以在一些比較老的文章中都會(huì)提到,編譯Android平臺(tái)的so庫(kù),需要對(duì) configure 做以下修改设捐,否則會(huì)按照 linux 標(biāo)準(zhǔn)的方式輸出so庫(kù)借浊,其命名方式和Android的so不一樣,Android是無(wú)法加載的萝招。
SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'
替換為
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'
但是在新版本(至少?gòu)?code>4.0開(kāi)始)的FFmpeg中蚂斤,這個(gè)問(wèn)題已經(jīng)被解決了,F(xiàn)Fmpeg加入了android
這個(gè) target槐沼,不再需要手動(dòng)去修改曙蒸,建議大家盡量使用較新的版本。
-
sysroot 用于配置交叉編譯環(huán)境的
根路徑
岗钩,編譯的時(shí)候會(huì)默認(rèn)從這個(gè)路徑下去尋找usr/include
和usr/lib
這兩個(gè)路徑纽窟,進(jìn)而找到相關(guān)的頭文件和庫(kù)文件。
注意:這里的路徑一定要寫對(duì)兼吓,ndk路徑臂港,包括不同ndk版本下面的頭文件和庫(kù)文件位置可能有所不同,如果找不到就會(huì)編譯失敗视搏。
關(guān)于ndk的路徑审孽,這里有個(gè)坑,本來(lái)設(shè)置/home/ffm/android-ndk-r22b
浑娜,一直提示找不到佑力,編譯失敗,真實(shí)路徑是/home/root1/ffm/android-ndk-r22b
筋遭。大家可以右鍵查看ndk文件夾屬性打颤,即可看到真實(shí)路徑,如下圖所示:
cross-prefix 交叉編譯工具的前綴
cc 指定使用何種C編譯器(默認(rèn)gcc)
cxx 指定使用何種C編譯器(默認(rèn)g++)
FFmpeg 默認(rèn)的編譯工具是gcc
漓滔,ndk老版本中瘸洛,使用的也是gcc
編譯,所以只要設(shè)置cross-prefix即可次和,要保證能找到gcc文件,比如ndk14中配置如下
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
...
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
對(duì)應(yīng)的編譯工具如下
ndk17
以后那伐,改用clang
編譯踏施,需要設(shè)置cc和cxx選項(xiàng),比如本例的ndk22罕邀。
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin
...
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--cc=$TOOLCHAIN/armv7a-linux-androideabi$API-clang \
--cxx=$TOOLCHAIN/armv7a-linux-androideabi$API-clang++ \
對(duì)應(yīng)的編譯工具如下
可以根據(jù)自己的需求對(duì)腳本進(jìn)行修改
查看所有編譯配置選項(xiàng):
./configure --help
查看支持的解碼器:
./configure --list-decoders
查看支持的編碼器:
./configure --list-encoders
查看支持的硬件加速:
./configure --list-hwaccels
2.2 啟動(dòng)編譯
賦予腳本執(zhí)行權(quán)限:chmod +x build.sh
執(zhí)行腳本開(kāi)始編譯:./build.sh
等待編譯完成畅形,將會(huì)在源碼根目錄下的android/armv7-a/lib/下找到我們需要的.so文件了。