使用Android NDK編譯ffmpeg

系統(tǒng):macOS High Sierra 10.13.4
NDK:android-ndk-r11c
FFmpeg:ffmpeg-3.3.7

最近基于ffmpeg用c++寫了一個流媒體播放器,支持播放本地/網(wǎng)絡(luò)文件阅仔、rtmp/rtsp流薪伏,想將其移植到Android中,第一步要做的工作就是編譯Android能用的ffmpeg爹殊,之前編譯ffmpeg都是使用NDK直接編譯蜕乡,問題不大,而Android的NDK更新模式就如同Android的Framework更新一樣梗夸,即新版系統(tǒng)中會不斷調(diào)整(優(yōu)化)文件位置层玲,所以做過Android系統(tǒng)開發(fā)的朋友們應(yīng)該時常遇到“No such file or directory”。廢話不多說反症,開始辛块。

1、為何不使用網(wǎng)友直接編譯好的庫铅碍?NO润绵,因為我這個播放器是跨平臺的,而ffmpeg中的AVMediaType與IOS中AVFoundation下的AVMediaType沖突了胞谈,為了兼容IOS尘盼,所以我將ffmpeg源碼中的AVMediaType全局替換成了FFMAVMediaType然后再進行編譯。

sed -i '' "s/AVMediaType/FFMAVMediaType/g" `grep -rl AVMediaType ./ffmpeg-*`
/*如果報錯:sed: RE error: illegal byte sequence
  缺少環(huán)境變量烦绳,在shell輸入:
  export LC_COLLATE='C'
  export LC_CTYPE='C'*/

2悔叽、準(zhǔn)備NDK和FFmpeg源碼,也可以使用Android Studio的SDK Manager一鍵下載NDK爵嗅,更加方便娇澎。

NDK下載地址:https://developer.android.google.cn/ndk/downloads/
FFmpeg下載地址:http://www.ffmpeg.org/download.html

3、下載完成后進入到ffmpeg根目錄創(chuàng)建腳本build-android.sh
3.1 腳本一:一次性編譯所有平臺

#NDK位置
export NDK=/Users/luohan/Library/Android/my_ndk_bundle/android-ndk-r11c

#編譯成功后的產(chǎn)出位置
PREFIX=android
NDK_HOST_PLATFORM=darwin-x86_64

#編譯過程中的臨時文件存放
export TMPDIR=/Users/luohan/ffmpegTemp

#各平臺交叉編譯鏈位置
ARM_LINUX_TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
ARM_LINUX_SYSROOT=$NDK/platforms/android-21/arch-arm

ARM_64_TOOLCHAIN=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64
ARM_64_SYSROOT=$NDK/platforms/android-21/arch-arm64

X86_TOOLCHAIN=$NDK/toolchains/x86-4.9/prebuilt/darwin-x86_64
X86_SYSROOT=$NDK/platforms/android-21/arch-x86

X86_64_TOOLCHAIN=$NDK/toolchains/x86_64-4.9/prebuilt/darwin-x86_64
X86_64_SYSROOT=$NDK/platforms/android-21/arch-x86_64

COMMON_OPTIONS="\
    --prefix=$PREFIX/ \
    --target-os=android \
    --disable-static \
    --enable-shared \
    --enable-small \
    --disable-programs \
    --disable-ffmpeg \
    --disable-ffplay \
    --disable-ffprobe \
    --disable-doc \
    --disable-symver \
    --disable-asm \
    --enable-cross-compile \
    "

function build_android {
    ./configure \
    --libdir=${PREFIX}/libs/armeabi-v7a \
    --incdir=${PREFIX}/includes/armeabi-v7a \
    --pkgconfigdir=${PREFIX}/pkgconfig/armeabi-v7a \
    --arch=arm \
    --cpu=armv7-a \
    --cross-prefix="${ARM_LINUX_TOOLCHAIN}/bin/arm-linux-androideabi-" \
    --sysroot="${ARM_LINUX_SYSROOT}/" \
    --extra-cflags="-march=armv7-a -mfloat-abi=softfp -mfpu=neon -I $ARM_LINUX_SYSROOT/usr/include/" \
    --extra-ldexeflags=-pie \
    ${COMMON_OPTIONS}
    make clean
    make -j8 && make install

    ./configure \
    --libdir=${PREFIX}/libs/arm64-v8a \
    --incdir=${PREFIX}/includes/arm64-v8a \
    --pkgconfigdir=${PREFIX}/pkgconfig/arm64-v8a \
    --arch=aarch64 \
    --cpu=armv8-a \
    --cross-prefix="${ARM_64_TOOLCHAIN}/bin/aarch64-linux-android-" \
    --sysroot="${ARM_64_SYSROOT}/" \
    --extra-libs=-lgcc \
    --extra-cflags="$ARM_64_SYSROOT/usr/include/" \
    --extra-ldexeflags=-pie \
    ${COMMON_OPTIONS} 
    make clean
    make -j8 && make install

    ./configure \
    --libdir=${PREFIX}/libs/x86 \
    --incdir=${PREFIX}/includes/x86 \
    --pkgconfigdir=${PREFIX}/pkgconfig/x86 \
    --arch=x86 \
    --cpu=i686 \
    --cross-prefix="${X86_TOOLCHAIN}/bin/i686-linux-android-" \
    --sysroot="${X86_SYSROOT}/" \
    --extra-cflags="$X86_SYSROOT/usr/include/" \
    --extra-ldexeflags=-pie \
    ${COMMON_OPTIONS} 
    make clean
    make -j8 && make install

    ./configure \
    --libdir=${PREFIX}/libs/x86_64 \
    --incdir=${PREFIX}/includes/x86_64 \
    --pkgconfigdir=${PREFIX}/pkgconfig/x86_64 \
    --arch=x86_64 \
    --cpu=x86_64 \
    --cross-prefix="${X86_64_TOOLCHAIN}/bin/x86_64-linux-android-" \
    --sysroot="${X86_64_SYSROOT}/" \
    --extra-cflags="$X86_64_SYSROOT/usr/include/" \
    --extra-ldexeflags=-pie \
    ${COMMON_OPTIONS}
    make clean
    make -j8 && make install
};

build_android

3.1 腳本二:只針對一種平臺進行編譯

#!/bin/sh
export NDK=/Users/luohan/Library/Android/my_ndk_bundle/android-ndk-r11c
SYSROOT=$NDK/platforms/android-21/arch-arm
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
PREFIX=android
ADDI_CFLAGS="-marm"

function build_one
{
./configure \
--prefix="${PREFIX}/" \
--enable-shared \
--disable-static \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-avdevice \
--disable-doc \
--disable-symver \
--disable-asm \
--cross-prefix="${TOOLCHAIN}/bin/arm-linux-androideabi-" \
--target-os=android \
--arch=arm \
--enable-cross-compile \
--sysroot="${SYSROOT}/" \
--extra-cflags="-mfpu=neon -mfloat-abi=softfp -I $NDK/platforms/android-21/arch-arm/usr/include/" \
--extra-ldflags="$ADDI_LDFLAGS" 

$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
}

build_one
Android版ffmpeg編譯完成睹晒,此腳本支持Android的4個平臺的編譯

說明下為什么這里我要使用舊版的NDK趟庄,因為我們在對ffmpeg進行交叉編譯時需要引用到c庫(--extra-cflags),此前伪很,舊版NDK的c庫目錄位置在“NDK/platforms/android-21/arch-arm64/usr/include/”中戚啥,而新版NDK中所以Android版本下的usr文件夾中都移除了include文件夾,全局搜索了一下發(fā)現(xiàn)锉试,它們被集合放在另一個目錄“NDK/sysroot/usr/include/”猫十,這算是一個優(yōu)化吧,但是引入該目錄后,編譯仍然報找不到c文件拖云,具體原因不明贷笛,最后我直接使用舊版NDK進行編譯,平臺版本選擇android-21宙项,因為android-21中全平臺的c庫都有乏苦,再次編譯,成功尤筐。

舊NDK中c庫與新NDK中c庫的內(nèi)容對比汇荐,我猜想是多版本的集合體

編譯過程中還遇到過其他問題,有時候命令行報錯不清晰盆繁,不能說明問題掀淘,這時就需要打開config.log查看詳細(xì)報錯,能幫助我們迅速對癥下藥油昂,以下我粗略地羅列了幾個問題的解決方案:

/toolchains/aarch64-linux-android-4.9/prebuilt//bin/aarch64-linux-android-gcc is unable to create an executable file.
C compiler test failed.
/*1.gcc交叉編譯文件位置不對(可通過查看config.log獲知)革娄。
  2.沒有制定臨時編譯文件存放目錄,或目錄沒有提權(quán)秕狰。*/
WARNING: /Users/luohan/Library/Android/my_ndk_bundle/android-ndk-r16-beta1/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-pkg-config not found, library detection may fail.
/*警告稠腊,這種警告可直接無視*/
/bin/sh: ranlib/usr/local/lib/libavdevice.a: No such file or directory
make: *** [install-libavdevice-static] Error 127
/*未設(shè)置臨時文件位置所致*/
CC  libavcodec/aacdec.o
/var/folders/6c/zwgcjwzn7y3b5z8wzvd3b8h00000gn/T//ccjyLRuc.s: Assembler messages:
/var/folders/6c/zwgcjwzn7y3b5z8wzvd3b8h00000gn/T//ccjyLRuc.s:16330: Error: selected processor does not support ARM mode `ubfx r1,r2,#0,#4'
/var/folders/6c/zwgcjwzn7y3b5z8wzvd3b8h00000gn/T//ccjyLRuc.s:16331: Error: selected processor does not support ARM mode `ubfx r0,r2,#4,#4'
/var/folders/6c/zwgcjwzn7y3b5z8wzvd3b8h00000gn/T//ccjyLRuc.s:16491: Error: selected processor does not support ARM mode `ubfx r2,r1,#0,#2'
/var/folders/6c/zwgcjwzn7y3b5z8wzvd3b8h00000gn/T//ccjyLRuc.s:16492: Error: selected processor does not support ARM mode `ubfx r7,r1,#2,#2'
/var/folders/6c/zwgcjwzn7y3b5z8wzvd3b8h00000gn/T//ccjyLRuc.s:16494: Error: selected processor does not support ARM mode `ubfx r8,r1,#4,#2'
/var/folders/6c/zwgcjwzn7y3b5z8wzvd3b8h00000gn/T//ccjyLRuc.s:16496: Error: selected processor does not support ARM mode `ubfx r10,r1,#6,#2'
/var/folders/6c/zwgcjwzn7y3b5z8wzvd3b8h00000gn/T//ccjyLRuc.s:16501: Error: selected processor does not support ARM mode `rbit r1,r1'
/var/folders/6c/zwgcjwzn7y3b5z8wzvd3b8h00000gn/T//ccjyLRuc.s:16687: Error: selected processor does not support ARM mode `ubfx r2,r3,#0,#2'
/var/folders/6c/zwgcjwzn7y3b5z8wzvd3b8h00000gn/T//ccjyLRuc.s:16688: Error: selected processor does not support ARM mode `ubfx r1,r3,#2,#2'
/var/folders/6c/zwgcjwzn7y3b5z8wzvd3b8h00000gn/T//ccjyLRuc.s:16690: Error: selected processor does not support ARM mode `ubfx r0,r3,#4,#2'
/var/folders/6c/zwgcjwzn7y3b5z8wzvd3b8h00000gn/T//ccjyLRuc.s:16692: Error: selected processor does not support ARM mode `ubfx lr,r3,#6,#2'
/var/folders/6c/zwgcjwzn7y3b5z8wzvd3b8h00000gn/T//ccjyLRuc.s:16842: Error: selected processor does not support ARM mode `ubfx r2,r3,#0,#4'
/var/folders/6c/zwgcjwzn7y3b5z8wzvd3b8h00000gn/T//ccjyLRuc.s:16843: Error: selected processor does not support ARM mode `ubfx r1,r3,#4,#4'
make: *** [libavcodec/aacdec.o] Error 1
/*.configure中加入–-disable-asm*/
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鸣哀,隨后出現(xiàn)的幾起案子架忌,更是在濱河造成了極大的恐慌,老刑警劉巖我衬,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叹放,死亡現(xiàn)場離奇詭異,居然都是意外死亡挠羔,警方通過查閱死者的電腦和手機井仰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來破加,“玉大人俱恶,你說我怎么就攤上這事》兑ǎ” “怎么了合是?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長锭环。 經(jīng)常有香客問我聪全,道長,這世上最難降的妖魔是什么辅辩? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任难礼,我火速辦了婚禮娃圆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蛾茉。我一直安慰自己讼呢,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布臀稚。 她就那樣靜靜地躺著吝岭,像睡著了一般三痰。 火紅的嫁衣襯著肌膚如雪吧寺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天散劫,我揣著相機與錄音稚机,去河邊找鬼。 笑死获搏,一個胖子當(dāng)著我的面吹牛赖条,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播常熙,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼纬乍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了裸卫?” 一聲冷哼從身側(cè)響起仿贬,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎墓贿,沒想到半個月后茧泪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡聋袋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年队伟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片幽勒。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡嗜侮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出啥容,到底是詐尸還是另有隱情锈颗,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布干毅,位于F島的核電站宜猜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏硝逢。R本人自食惡果不足惜姨拥,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一绅喉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧叫乌,春花似錦柴罐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至排宰,卻和暖如春似芝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背板甘。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工党瓮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人盐类。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓寞奸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親在跳。 傳聞我的和親對象是個殘疾皇子枪萄,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容