2 FFmpeg4Android:FFmpeg編譯(Windows + Linux)
各操作系統(tǒng)編譯環(huán)境介紹:
- Windows:需要用到MinGW+msys或Cygwin;
- Linux(推薦):有現(xiàn)成的命令可使用,省去很多麻煩(Windows下可裝虛擬機或買云主機);
- Mac:與Linux類似。
在2.1節(jié)與2.2節(jié)分別介紹Windows下與Linux下的編譯,看官可以自行選擇查看。
2.1 在Windows環(huán)境下編譯FFmpeg
這里我使用的Windows編譯環(huán)境為:
開發(fā)工具:Android Studio 2.3.2
操作系統(tǒng):Win7 64位
編譯工具:MinGW + msys
NDK版本:r12b
FFmpeg版本:3.3.6
說明:ffmpeg2.x版本要用NDK r11以下的版本來編,ffmpeg3.x以上的版本一般用r12以上的NDK來編,具體的對應(yīng)關(guān)系還有待研究
2.1.1 安裝編譯工具(MinGW+msys)
step 1:下載MinGW,并安裝,我這里安裝的目錄為D:/MinGW;
安裝完成后彈出一個MinGW安裝管理器,如下圖:

選中左邊的"Basic Setup",在右邊選擇要安裝的編譯工具:
下述"勾選"對應(yīng)的操作為:點擊該選擇Mark for Installation
- mingw-devoloper-toolkit:MinGW可用的msys,勾選;
- mingw32-base:基本MinGW,勾選;
- mingw32-gcc-ada:Ada(一種程序設(shè)計語言)編譯器,不選;
- mingw32-gcc-fortran:FORTRAN編譯器,不選;
- mingw32-gcc-g++:c/c++編譯器,勾選;
- mingw32-objc:Objective-c編譯器,不選;
- msys-base:msys,選上則不需要另外安裝,勾選;
當(dāng)然,嫌麻煩可以全選上,但是不能少選。
選好后,點擊工具欄Installation->Apply Changes,即可安裝。
step 2:配置環(huán)境變量
添加:D:\MinGW\msys\1.0\bin與D:\MinGW\bin到系統(tǒng)Path變量。
step 3:打開MinGW
打開目錄D:/MinGW/mysys/1.0下的msys.bat,彈出如如命令窗口,一會我們會在這里輸入命令進(jìn)行編譯。

到此,MinGW與msys就安裝好了。
2.1.1 下載、安裝NDK
step 1:下載NDK,我這里是android-ndk-r12b版本,解壓到D:\ndk,可不配置環(huán)境變量。
2.1.2 下載FFmpeg源碼、編寫編譯腳本
step 1:下載ffmpeg源碼,我這里下載的是ffmpeg-3.3.6版本,解壓到D:\ffmpeg目錄。

step 3:下載FFmpeg源碼之后,首先需要對源代碼中的configure文件進(jìn)行修改。由于編譯出來的動態(tài)庫文件名的版本號在.so之后(例如“l(fā)ibavcodec.so.5.100.1”),而android平臺不能識別這樣文件名,所以需要修改這種文件名。在configure文件中找到下面幾行代碼:
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)'
替換為下面內(nèi)容:
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'
step 3:在當(dāng)前目錄下新建一個build_android.sh腳本文件
內(nèi)容為:
#!/bin/bash
make clean
export NDK=D:/ndk/android-ndk-r12b
export SYSROOT=$NDK/platforms/android-18/arch-arm/
export TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64
export CPU=arm
export PREFIX=$(pwd)/android/$CPU
export ADDI_CFLAGS="-marm"
./configure --target-os=linux \
--prefix=$PREFIX --arch=arm \
--disable-doc \
--enable-shared \
--disable-static \
--disable-yasm \
--disable-symver \
--enable-gpl \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-doc \
--disable-symver \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
- 對于NDK=D:/ndk/android-ndk-r12b,如果不是這個目錄的,改成自己的目錄;
- 對于TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64,這里是用windows版本,如果是在linux下編譯要寫windows-x86_64。
2.1.3 編譯.so文件
cd到ffmpeg目錄下,運行腳本./build_android.sh,回車后沒有任何反應(yīng),不要驚慌,其實腳本正在運行,等待一段時間會有信息輸出。

如果運行./build_android.sh后報找不到configure.mak,可以先運行./configure --disable-yasm
大約2、3分鐘后會開始編譯。

再過大約10-20分鐘后編譯成功,可以看到在D:\ffmpeg\ffmpeg-3.3.6下生成了一個android目錄,里面就是我們要的.so文件。

如果運行腳本時出錯,一般是你的腳本不對或格式有問題,可以自行baidu解決。
2.2 在Linux環(huán)境下編譯FFmpeg
這里我使用的編譯環(huán)境為:
開發(fā)工具:Android Studio 2.3.2
操作系統(tǒng):Ubuntu 16.04 64位
NDK版本:r10e
FFmpeg版本:2.6.9
當(dāng)然也可以用高版本:
NDK版本:r12以上
FFmpeg版本:3.x以上
說明:ffmpeg2.x版本要用NDK r11以下的版本來編,ffmpeg3.x以上的版本一般用r12以上的NDK來編,具體的對應(yīng)關(guān)系還有待研究
2.2.1 下載、安裝NDK
step 1:下載NDK,我這里是android-ndk-r10e版本,并解壓到/usr/ndk/。
step 2:配置NDK環(huán)境變量:
打開配置文件:vim ~/.bashrc(沒裝vim的“sudo apt-get install vim-gtk”安裝一下,如果 安裝出錯,且看下面的補充),按i切換輸入模式,在文件末尾添加
export NDKROOT=/usr/ndk/android-ndk-r10e
export PATH=$NDKROOT:$PATH
按ESC退出回到命令模式,再按shift + zz(即:ZZ), 保存修改。
更新環(huán)境變量:source ~/.bashrc
輸入ndk-build -version命令,如果出現(xiàn)如下信息,說明NDK安裝成功。

補充:linux基本命令與vim安裝、配置
1)linux基本命令介紹
進(jìn)入編輯模式,i
進(jìn)入命令模式,Esc
命令模式:
shift + :退出;q!強制退出;
shift + z z保存退出;
x刪除,dd刪除行;
2)vim安裝:apt-get install vim-gtk
對于用虛擬機或云主機編譯,并第一次使用apt-get install命令,可能會報錯,需apt-get update更新一下倉庫,再apt-get install vim-gtk安裝即可。
可能還會報用戶名不正確等奇怪的錯,不用怕,這些都比較簡單,自行百度解決即可。
3)vim配置
vim安裝好后,vim /etc/vim/vimrc打開配置文件,在文件末尾添加如下配置:
set nu //行號顯示
set tabstop=4 //tab為4空格(默認(rèn)為8個)
set cursorline //高亮顯示光標(biāo)所在行
set ruler //右下角顯示光標(biāo)坐標(biāo)
2.2.2 下載FFmpeg源碼、編寫編譯腳本
step 1:下載ffmpeg源碼,我這里下載的是ffmpeg-2.6.9版本,unzip ffmpeg-2.6.9.zip解壓到ffmpeg-2.6.9目錄(unzip用sudo apt-get install unzip命令安裝)。
step 2:下載FFmpeg源碼之后,首先需要對源代碼中的configure文件進(jìn)行修改。由于編譯出來的動態(tài)庫文件名的版本號在.so之后(例如“l(fā)ibavcodec.so.5.100.1”),而android平臺不能識別這樣文件名,所以需要修改這種文件名。在configure文件中找到下面幾行代碼:
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)'
替換為下面內(nèi)容:
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'
step 3:在當(dāng)前目錄下新建一個build_android.sh腳本文件
內(nèi)容為:
#!/bin/bash
make clean
export NDK=/usr/ndk/android-ndk-r10e
export SYSROOT=$NDK/platforms/android-9/arch-arm/
export TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64
export CPU=arm
export PREFIX=$(pwd)/android/$CPU
export ADDI_CFLAGS="-marm"
./configure --target-os=linux \
--prefix=$PREFIX --arch=arm \
--disable-doc \
--enable-shared \
--disable-static \
--disable-yasm \
--disable-symver \
--enable-gpl \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-doc \
--disable-symver \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
在這個腳本前面,配置了三個變量(NDK、SYSROOT、TOOLCHAIN),都是指定好NDK的一些工具,目錄的,NDK指定自己所用的NDK安裝路徑。要注意的是在:SYSROOT里面,我編譯的platform是android-9的(過高的版本編譯ffmpeg2.x會報錯,3.x可用android-19),因為NDK對platform有時會有一些影響的,做過深入的NDK開發(fā)的同學(xué)應(yīng)該清楚,所以這個要看具體的需要進(jìn)行更改什么的。
- --enable-static --disable-shared:這兩個是看編譯出來的庫是靜態(tài)庫(.a)還是動態(tài)庫(.so),如果要編譯成動態(tài)庫就--enable-shared --disable-static,或者兩個都編譯出來。
- --disable-ffmpeg:不要ffmpeg這個工具,ffmpeg是一個命令行工具,非常強大,在官網(wǎng)也可以看到,但我們通過代碼開發(fā),就不需要它了
- --disable-ffplay --disable-ffprobe --disable-ffserver:這些都是不需要的工具,當(dāng)然也可以編譯出來看看
- --disable-avdevice:這個庫是用來操作一些硬件設(shè)備的,如攝像頭這些,但Android中感覺不需要它,也可以編譯出來試試能不能使用在Android上
- --disable-doc:取消文檔
- --disable-symver:禁用 symbol versioning
- PREFIX=(pwd)/android/CPU:指定編譯成功的庫所在的目錄,這個配置是:當(dāng)前目錄下的android目錄下的指定的cpu平臺目錄下
動態(tài)庫與靜態(tài)庫:
動態(tài)庫就是只要Android設(shè)備里面有公開這個so,那APP就可以使用,就是只要一次安裝,其他APP就可以使用了,但APP打包進(jìn)去的so都是在當(dāng)前APP的私有目錄下的,不能被其他APP使用的,所以動態(tài)庫的優(yōu)勢就沒有了, 而且就暴露了它的缺點,就是so非常大的時候,就會形成Apk包非常大。
靜態(tài)庫就是會把需要的代碼打包到自己的so里面,所以這樣子就可以解決動態(tài)庫上面的那個缺點
所以這里我們編譯出來的是靜態(tài)庫,因為編譯出來的庫有50多M,所以使用靜態(tài)庫的方式,可以使打包出來的apk最小化。
2.2.3 編譯.so文件
接下來輸入命令:./build_android.sh。
如果build_android.sh文件是在Windows下創(chuàng)建的,編譯會報錯,報錯的原因是因為編碼格式問題,解決方式:
1)用Notepad++打開設(shè)置成“utf-8 無BOM”格式,然后上傳到Linux,并用doc2unix工具(sudo apt-get install doc2unix命令安裝)對腳本格式進(jìn)行轉(zhuǎn)換:doc2unix build_android.sh;
2)在Linux環(huán)境下創(chuàng)建.sh文件,傳輸?shù)絎indows下修改文件內(nèi)容,再上傳到Linux。
因為編譯是比較耗時的,編譯個20分鐘是很正常的,電腦性能好的,會快點,差的可能半小時都正常。
經(jīng)過一段時間的編譯,我們就可以在腳本里面定義的那個目錄里面看到編譯成功的庫了。在當(dāng)前目錄下就會有一個android的目錄,點進(jìn)里面后,就會看到編譯成功的庫了,如下圖:

可以看到有16個.so文件,有帶數(shù)字與不帶數(shù)字的,我們要用的是帶數(shù)字的,共8個,這些數(shù)字是類似與版本號的東西,ffmpeg3.x編出來的.so文字?jǐn)?shù)字會大些。
這樣,我們就把ffmpeg2.6.9編譯好了。