ubuntu下編譯FFmpeg so庫(kù)

首先列出本次編譯所需要的環(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/includeusr/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文件了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末诉探,一起剝皮案震驚了整個(gè)濱河市日熬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌肾胯,老刑警劉巖竖席,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耘纱,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡毕荐,警方通過(guò)查閱死者的電腦和手機(jī)束析,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)憎亚,“玉大人员寇,你說(shuō)我怎么就攤上這事〉诿溃” “怎么了蝶锋?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)什往。 經(jīng)常有香客問(wèn)我扳缕,道長(zhǎng),這世上最難降的妖魔是什么恶守? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任第献,我火速辦了婚禮,結(jié)果婚禮上兔港,老公的妹妹穿的比我還像新娘庸毫。我一直安慰自己,他們只是感情好衫樊,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布飒赃。 她就那樣靜靜地躺著,像睡著了一般科侈。 火紅的嫁衣襯著肌膚如雪载佳。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天臀栈,我揣著相機(jī)與錄音蔫慧,去河邊找鬼。 笑死权薯,一個(gè)胖子當(dāng)著我的面吹牛姑躲,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播盟蚣,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼黍析,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了屎开?” 一聲冷哼從身側(cè)響起阐枣,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后蔼两,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體甩鳄,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年宪哩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了娩贷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡锁孟,死狀恐怖彬祖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情品抽,我是刑警寧澤储笑,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站圆恤,受9級(jí)特大地震影響突倍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜盆昙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一羽历、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧淡喜,春花似錦秕磷、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至瘟芝,卻和暖如春易桃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背锌俱。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工晤郑, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贸宏。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓贩汉,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親锚赤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

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