FFmpeg是一套可以用來記錄捡鱼、轉(zhuǎn)換數(shù)字音頻、視頻岩遗,并能將其轉(zhuǎn)化為流的開源計算機(jī)程序。它提供了錄制凤瘦、轉(zhuǎn)換以及流化音視頻的完整解決方案宿礁。
1.環(huán)境搭建
操作系統(tǒng):Ubuntu 16.04 64bit
NDK版本:android-ndk-r14b-linux-x86_64
FFmpeg版本:3.4.2
將NDK和FFmpeg源碼解壓至指定目錄,文中解壓在了Home > ffmpeg目錄下蔬芥,注意NDK的版本一定要選擇Linux版的窘拯,在編譯的時候我就犯了這個錯誤,使用了Windows版的NDK坝茎,一直報錯也找不到原因涤姊,切記切記!
2.編譯FFmpeg
在ffmpeg-3.4.2目錄下創(chuàng)建build_android.sh編譯腳本嗤放,文件名可以隨便取思喊,這個腳本是本文中最關(guān)鍵的內(nèi)容,一起來看下:
#!/bin/bash
# 設(shè)置臨時文件夾次酌,需要提前手動創(chuàng)建
export TMPDIR="/home/yangle/ffmpeg/ffmpeg-3.4.2/ffmpegtemp"
# 設(shè)置NDK路徑
NDK=~/ffmpeg/android-ndk-r14b
# 設(shè)置編譯針對的平臺恨课,可以根據(jù)實際需求進(jìn)行設(shè)置
# 當(dāng)前設(shè)置為最低支持android-14版本,arm架構(gòu)
SYSROOT=$NDK/platforms/android-14/arch-arm
# 設(shè)置編譯工具鏈岳服,4.9為版本號
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
function build_one
{
./configure \
--enable-cross-compile \
--enable-shared \
--disable-static \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-avdevice \
--disable-doc \
--disable-symver \
--prefix=$PREFIX \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--target-os=android \
--arch=arm \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
}
# 設(shè)置編譯后文件的輸出目錄
CPU=arm
PREFIX=$(pwd)/android/$CPU
ADDI_CFLAGS="-marm"
build_one
前四項配置按照你本機(jī)的實際路徑修改就可以了剂公,注意ffmpegtemp這個臨時文件夾需要提前手動創(chuàng)建仑鸥,【~/】 在Linux上代表 【/home/用戶名/】纫雁,看下build_one這個方法,enable您觉、disable分別代表打開和關(guān)閉一些功能璃搜,重點看下下面幾個配置:
--enable-shared
--disable-static
編譯動態(tài)庫拖吼,shared和static的開關(guān)是相對的。
--prefix=$PREFIX
CPU=arm
PREFIX=$(pwd)/android/$CPU
設(shè)置編譯后文件的輸出目錄这吻,$(pwd)代表當(dāng)前目錄吊档,所以文件的輸出路徑為:ffmpeg-3.4.2/android/arm
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi-
設(shè)置交叉編譯器,按照實際路徑修改就可以了唾糯。
--target-os=android
設(shè)置編譯針對的系統(tǒng)怠硼,網(wǎng)上查到很多資料說編譯前需要修改configure文件鬼贱,設(shè)置這項后就不用修改了,系統(tǒng)會自動為我們修改香璃,效果一樣这难。
--arch=arm
設(shè)置編譯so庫的架構(gòu),當(dāng)前設(shè)置為arm增显,可以根據(jù)實際需求修改。
--sysroot=$SYSROOT
設(shè)置編譯針對的平臺脐帝,可以根據(jù)實際需求進(jìn)行設(shè)置同云,當(dāng)前設(shè)置為最低支持android-14版本,arm架構(gòu)堵腹。
--extra-cflags="-Os -fpic $ADDI_CFLAGS"
ADDI_CFLAGS="-marm"
還沒有完全理解這幾個參數(shù)的作用炸站,有知道的同學(xué)可以給我留言啊,謝謝疚顷!
到這里旱易,編譯腳本就寫完了,在當(dāng)前目錄下打開終端窗口腿堤,執(zhí)行腳本阀坏,加上管理員權(quán)限,以防權(quán)限不足:
$ sudo ./build_android.sh
回車提示輸入密碼笆檀,密碼不會顯示出來或者顯示成*號忌堂,直接輸完然后回車就可以了,看下執(zhí)行效果:
編譯中:
如果一切順利的話酗洒,大概十多分鐘就可以編譯完成:
編譯完成后士修,在當(dāng)前目錄下(ffmpeg-3.4.2)會生成一個android目錄,so文件就在android > arm > lib目錄下:
看下生成的so包是做什么用的:
libavcodec:用于各種類型聲音樱衷、圖像編解碼棋嘲。
libavformat:用于各種音視頻封裝格式的生成和解析,讀取音視頻幀等功能矩桂。
libavutil:包含一些公共的工具函數(shù)沸移。
libavfilter:提供了各種音視頻過濾器。
libswresample:用于音頻重采樣侄榴,采樣格式轉(zhuǎn)換和混合阔籽。
libswscale:用于視頻場景比例縮放、色彩映射轉(zhuǎn)換牲蜀。
3.將FFmpeg編譯成一個so文件
在上文中我們成功的編譯了FFmpeg笆制,但是編譯出來的so文件一共有6個,如果覺的使用起來比較麻煩涣达,可以編譯成一個so文件在辆,下面我們來修改下腳本:
#!/bin/bash
# 設(shè)置臨時文件夾证薇,需要提前手動創(chuàng)建
export TMPDIR="/home/yangle/ffmpeg/ffmpeg-3.4.2/ffmpegtemp"
# 設(shè)置NDK路徑
NDK=~/ffmpeg/android-ndk-r14b
# 設(shè)置編譯針對的平臺,可以根據(jù)自己的需求進(jìn)行設(shè)置
# 當(dāng)前設(shè)置為最低支持android-14版本匆篓,arm架構(gòu)
SYSROOT=$NDK/platforms/android-14/arch-arm
# 設(shè)置編譯工具鏈浑度,4.9為版本號
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
function build_one
{
./configure \
--enable-cross-compile \
--enable-static \
--disable-shared \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-avdevice \
--disable-doc \
--disable-symver \
--prefix=$PREFIX \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--target-os=android \
--arch=arm \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
# 合并生成的靜態(tài)庫
$TOOLCHAIN/bin/arm-linux-androideabi-ld \
-rpath-link=$SYSROOT/usr/lib \
-L$SYSROOT/usr/lib \
-L$PREFIX/lib \
-soname libffmpeg.so -shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o \
$PREFIX/libffmpeg.so \
libavcodec/libavcodec.a \
libavfilter/libavfilter.a \
libswresample/libswresample.a \
libavformat/libavformat.a \
libavutil/libavutil.a \
libswscale/libswscale.a \
-lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker \
$TOOLCHAIN/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a
}
# 設(shè)置編譯后的文件輸出目錄
CPU=arm
PREFIX=$(pwd)/android/$CPU
ADDI_CFLAGS="-marm"
build_one
看下和編譯單個so文件的腳本有什么區(qū)別:
生成靜態(tài)庫:
--disable-static
--enable-shared
修改為:
--enable-static
--disable-shared
增加下面的指令,將生成的靜態(tài)庫合并成一個動態(tài)庫:
$TOOLCHAIN/bin/arm-linux-androideabi-ld \
-rpath-link=$SYSROOT/usr/lib \
-L$SYSROOT/usr/lib \
-L$PREFIX/lib \
-soname libffmpeg.so -shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o \
$PREFIX/libffmpeg.so \
libavcodec/libavcodec.a \
libavfilter/libavfilter.a \
libswresample/libswresample.a \
libavformat/libavformat.a \
libavutil/libavutil.a \
libswscale/libswscale.a \
-lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker \
$TOOLCHAIN/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a
重點看下下面兩個配置:
-soname libffmpeg.so
指定動態(tài)庫鸦概,也就是so文件的名稱箩张。
$TOOLCHAIN/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a
設(shè)置編譯器的路徑,根據(jù)實際路徑進(jìn)行修改窗市,編譯前一定要檢查一遍路徑是否正確先慷!
腳本中還涉及到一些編譯指令,都可以在網(wǎng)上查到作用咨察,在這里就不再一一說明了论熙,OK,開始執(zhí)行編譯腳本:
$ sudo ./build_android_all.sh
編譯完成后摄狱,生成的libffmpeg.so就在android > arm目錄下:
4.遇到的問題
NDK路徑錯誤
遇到這個錯誤仔細(xì)檢查一遍設(shè)置的路徑有沒有問題脓诡,我就栽在了這個坑里:
android文件夾帶鎖
編譯成功后,android文件夾是帶鎖的媒役,執(zhí)行下面的命令就可以解鎖:
sudo chown 用戶名 android/ -R
5.寫在最后
第一次使用Linux系統(tǒng)和編譯FFmpeg祝谚,一直在網(wǎng)上查命令和各種報錯的解決方案,這篇文章前前后后寫了一個多月酣衷,如有錯誤的地方踊跟,可以給我留言指正,多謝鸥诽!
文中用到的FFmpeg源碼商玫、編譯腳本以及編譯生成的so文件已經(jīng)上傳至GitHub,后續(xù)還會更新牡借,歡迎Start拳昌、Fork!
本篇文章到這里就結(jié)束了钠龙,下一篇文章將會繼續(xù)介紹如何在Android項目中使用FFmepg炬藤,敬請期待!