Android NDK開發(fā)(三) 在Linux環(huán)境下編譯FFmpeg

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 下載地址

將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文件

看下生成的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目錄下:

將FFmpeg編譯成一個so文件

4.遇到的問題

NDK路徑錯誤

遇到這個錯誤仔細(xì)檢查一遍設(shè)置的路徑有沒有問題脓诡,我就栽在了這個坑里:

NDK路徑錯誤

android文件夾帶鎖

編譯成功后,android文件夾是帶鎖的媒役,執(zhí)行下面的命令就可以解鎖:

sudo chown 用戶名 android/ -R

5.寫在最后

第一次使用Linux系統(tǒng)和編譯FFmpeg祝谚,一直在網(wǎng)上查命令和各種報錯的解決方案,這篇文章前前后后寫了一個多月酣衷,如有錯誤的地方踊跟,可以給我留言指正,多謝鸥诽!

文中用到的FFmpeg源碼商玫、編譯腳本以及編譯生成的so文件已經(jīng)上傳至GitHub,后續(xù)還會更新牡借,歡迎Start拳昌、Fork!

GitHub傳送門

本篇文章到這里就結(jié)束了钠龙,下一篇文章將會繼續(xù)介紹如何在Android項目中使用FFmepg炬藤,敬請期待!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末碴里,一起剝皮案震驚了整個濱河市沈矿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌咬腋,老刑警劉巖羹膳,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異根竿,居然都是意外死亡陵像,警方通過查閱死者的電腦和手機(jī)就珠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來醒颖,“玉大人妻怎,你說我怎么就攤上這事∨⑶福” “怎么了逼侦?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長腰耙。 經(jīng)常有香客問我榛丢,道長,這世上最難降的妖魔是什么沟优? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任涕滋,我火速辦了婚禮睬辐,結(jié)果婚禮上挠阁,老公的妹妹穿的比我還像新娘。我一直安慰自己溯饵,他們只是感情好侵俗,可當(dāng)我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著丰刊,像睡著了一般隘谣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上啄巧,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天寻歧,我揣著相機(jī)與錄音,去河邊找鬼秩仆。 笑死码泛,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的澄耍。 我是一名探鬼主播噪珊,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼齐莲!你這毒婦竟也來了痢站?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤选酗,失蹤者是張志新(化名)和其女友劉穎阵难,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芒填,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡多望,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年嫩舟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片怀偷。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡家厌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出椎工,到底是詐尸還是另有隱情饭于,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布维蒙,位于F島的核電站掰吕,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏颅痊。R本人自食惡果不足惜殖熟,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望斑响。 院中可真熱鬧菱属,春花似錦、人聲如沸舰罚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽营罢。三九已至赏陵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間饲漾,已是汗流浹背蝙搔。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留考传,地道東北人吃型。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像伙菊,于是被迫代替她去往敵國和親败玉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,834評論 2 345

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