最新靠譜可用的 Mac 環(huán)境下 FFmpeg 環(huán)境搭建

大家好洗显,我是光源搔耕。

最近在嘗試搭建 FFmpeg 開(kāi)發(fā)環(huán)境時(shí)遇到一個(gè)蛋疼的事阵幸,Google 了 N 篇文章竟然沒(méi)有一篇是可以跑起來(lái)的臊诊!

少部分教程是給出了自我矛盾的配置(是的癞埠,按照貼出來(lái)的代碼和配置状原,他自己都跑不起來(lái))聋呢,大部分教程是看著挺全但忽略了某幾個(gè)關(guān)鍵的點(diǎn)導(dǎo)致跑不起來(lái),更蛋疼的是碰到報(bào)錯(cuò)后錯(cuò)誤相關(guān)的文章也很少颠区,當(dāng)然還有一些是年代久遠(yuǎn)過(guò)時(shí)了削锰。

于是在成功跑起來(lái)后,我將整個(gè)搭建過(guò)程整理出來(lái)毕莱,希望可以幫到后面的人器贩。

本文基于 Mac OS X + Android Studio 3.2 + FFmpeg 3.3 + CMake。

文章會(huì)分為兩部分朋截,第一部分是總結(jié)一下碰到的幾個(gè)坑蛹稍,這樣只是因?yàn)閳?bào)錯(cuò)而無(wú)法繼續(xù)的朋友可以先看看是否可以解決問(wèn)題;第二部分是搭建過(guò)程的完整描述(我特意用另一臺(tái)電腦測(cè)試過(guò)部服,可以完美跑起來(lái))唆姐。

一、FFmpeg 搭建的常見(jiàn)問(wèn)題

1. NDK 的問(wèn)題

在編譯之前廓八,教程都會(huì)讓我們修改命令中 NDK 的地址為自己本地的地址奉芦,我們當(dāng)然自然而然地改成了 Android Studio 自帶的 ndk-bundle。

然后編譯的時(shí)候就發(fā)現(xiàn)會(huì)出現(xiàn)errno.h: No such file or directory字樣的error剧蹂。

這是因?yàn)?Android Studio 自帶的 NDK 缺少相關(guān)的 .h 文件声功,從網(wǎng)上額外下載 NDK 然后編譯時(shí)使用就可以解決問(wèn)題。(基于 FFmpeg 3.3)

2. 編譯命令的問(wèn)題

報(bào)錯(cuò)信息形如:

ffmpeg_build.sh: line 14: ./configure: No such file or directory

ffmpeg_build.sh: line 20: --extra-cflags=-Os -fpic -marm: command not found

之類的宠叼,請(qǐng)檢查一下 Android 編輯腳本的 “/” 后是否有空格减噪。

由于不同系統(tǒng)存在差異,最好找對(duì)應(yīng)系統(tǒng)下他人驗(yàn)證可行的編譯命令车吹。

3. 編譯相關(guān)的版本

編譯過(guò)程有 NDK 版本、Android 版本醋闭、FFmpeg 版本窄驹、Android Studio 版本等,不同版本存在差異证逻,最好是完全使用教程描述時(shí)的版本乐埠。

比如編譯命令中包含的 Android 版本

export SYSROOT=$NDK/platforms/android-21/arch-arm/

這里的 android-21 改成 26 就不行,因?yàn)樗阉髁诉@兩個(gè)文件夾只有 21 中有需要的 .h 文件囚企。

4. 項(xiàng)目構(gòu)建配置

需要將相關(guān)的 .so 文件和 include 文件夾(里面包含一些頭文件)都放入 libs 文件夾中丈咐,并在 gradle 文件夾中指定 jni 目錄,最后編寫 CMake 文件龙宏,缺少一步就報(bào)錯(cuò)

二棵逊、FFmpeg 環(huán)境配置最佳實(shí)踐

1. 下載 FFmpeg 源碼

git clone https://git.ffmpeg.org/ffmpeg.git

再切到 3.3 分支

git checkout -b 3.3 remotes/origin/release/3.3

2. 修改 configure 文件

在下載好的 ffmpeg 文件夾內(nèi)可以找到一個(gè) 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)'

修改成

SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'  
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'  
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'  
SLIB_INSTALL_LINKS='$(SLIBNAME)'

3. 下載 NDK

就如上文所述银酗,Android Studio 自帶的 NDK 缺少部分 .h 文件辆影,不確定是否跟 Android Studio 的 版本或者 NDK 版本有關(guān)徒像,也不確定是否所有人都這樣。但為了簡(jiǎn)單蛙讥,還是下載吧(下載下來(lái)的的這個(gè) NDK 只為了編譯 FFmpeg锯蛀,不影響之前的 NDK)。

可以選擇去官網(wǎng)下載次慢,我找了個(gè)國(guó)內(nèi)的 Android NDK下載(r10d r13b r14b)

下載適用于 Mac OS X 的 android-ndk-r14b-darwin-x86_64.zip 文件旁涤。

4. 編寫編譯腳本

在 ffmpeg 文件夾根目錄下創(chuàng)建一個(gè) ffmpeg_build.sh 文件(名稱跟配置不相關(guān),想改可以改)迫像,具體內(nèi)容如下:

#!/bin/bash
make clean
# NDK的路徑劈愚,根據(jù)自己的安裝位置進(jìn)行設(shè)置
export NDK=/Users/yanzhenghui/Downloads/android-ndk
export SYSROOT=$NDK/platforms/android-21/arch-arm/
export TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
export CPU=arm
export PREFIX=$(pwd)/android/$CPU
export ADDI_CFLAGS="-marm"
function build_one
{
./configure \
    --prefix=$PREFIX \
    --target-os=linux \
    --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
    --arch=arm \
    --sysroot=$SYSROOT \
    --extra-cflags="-Os -fpic $ADDI_CFLAGS" \
    --extra-ldflags="$ADDI_LDFLAGS" \
    --cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
    --nm=$TOOLCHAIN/bin/arm-linux-androideabi-nm \
    --enable-shared \
    --enable-runtime-cpudetect \
    --enable-gpl \
    --enable-small \
    --enable-cross-compile \
    --disable-debug \
    --disable-static \
    --disable-doc \
    --disable-asm \
    --disable-ffmpeg \
    --disable-ffplay \
    --disable-ffprobe \
    --disable-ffserver \
    --enable-postproc \
    --enable-avdevice \
    --disable-symver \
    --disable-stripping \
$ADDITIONAL_CONFIGURE_FLAG
sed -i '' 's/HAVE_LRINT 0/HAVE_LRINT 1/g' config.h
sed -i '' 's/HAVE_LRINTF 0/HAVE_LRINTF 1/g' config.h
sed -i '' 's/HAVE_ROUND 0/HAVE_ROUND 1/g' config.h
sed -i '' 's/HAVE_ROUNDF 0/HAVE_ROUNDF 1/g' config.h
sed -i '' 's/HAVE_TRUNC 0/HAVE_TRUNC 1/g' config.h
sed -i '' 's/HAVE_TRUNCF 0/HAVE_TRUNCF 1/g' config.h
sed -i '' 's/HAVE_CBRT 0/HAVE_CBRT 1/g' config.h
sed -i '' 's/HAVE_RINT 0/HAVE_RINT 1/g' config.h
make clean
# 這里是定義用幾個(gè)CPU編譯,我用4個(gè)侵蒙,一般在5分鐘之內(nèi)編譯完成
make -j4
make install
}
build_one

需要更改的是這個(gè):

# NDK的路徑造虎,根據(jù)自己的安裝位置進(jìn)行設(shè)置
export NDK=/Users/yanzhenghui/Downloads/android-ndk

改成你本地的路徑。

5.執(zhí)行腳本

從命令行進(jìn)入 ffmpeg 文件夾后纷闺,先執(zhí)行

chmod +x ffmpeg_build.sh

命令給腳本開(kāi)啟權(quán)限算凿,再執(zhí)行編譯腳本:

./ffmpeg_build.sh

等待編譯完成,即可在 ffmpeg 文件夾內(nèi)看到 android 文件夾犁功,里面包含了我們需要的 .so 文件和對(duì)應(yīng)的頭文件

圖一

6.配置 ffmpeg 項(xiàng)目

這部分 Android - FFmpeg & Mac & AndroidStudio & CMake 環(huán)境搭建 這篇文章寫得足夠好氓轰,我就不重復(fù)造輪子了,下面摘抄部分權(quán)當(dāng)轉(zhuǎn)載了浸卦。(當(dāng)然署鸡,我也全部測(cè)試過(guò)能跑起來(lái))

6.1 新建項(xiàng)目

新建一個(gè)以 CMake 方式構(gòu)建的 C++ 項(xiàng)目(記得勾選 Include C++ Support)

屏幕快照 2018-05-13 下午1.26.56.png

6.2 拷貝文件到 libs 目錄下

將編譯好的 .so 和頭文件拷貝到 libs 目錄下:

屏幕快照 2018-05-13 下午7.07.51.png

6.3 指定 jniLibs 路徑

android {
    ...
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
}

6.4 配置 abiFilters

因?yàn)槲覀冎痪幾g出 armeabi-v7a 的 so,所以需要特別指定一下 abi

android {
    ...
    defaultConfig {
      ...
      idk {
          abiFilters 'armeabi-v7a'
      }
    }
}

6.5 編寫 CMakeLists

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library.
             native-lib
             # Sets the library as a shared library.
             SHARED
             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp )
add_library( avcodec-57
             SHARED
             IMPORTED )
set_target_properties( avcodec-57
                       PROPERTIES IMPORTED_LOCATION
                       ../../../../libs/armeabi-v7a/libavcodec-57.so )
add_library( avfilter-6
             SHARED
             IMPORTED )
set_target_properties( avfilter-6
                       PROPERTIES IMPORTED_LOCATION
                       ../../../../libs/armeabi-v7a/libavfilter-6.so )
add_library( avformat-57
             SHARED
             IMPORTED )
set_target_properties( avformat-57
                       PROPERTIES IMPORTED_LOCATION
                       ../../../../libs/armeabi-v7a/libavformat-57.so )
add_library( avutil-55
             SHARED
             IMPORTED )
set_target_properties( avutil-55
                       PROPERTIES IMPORTED_LOCATION
                       ../../../../libs/armeabi-v7a/libavutil-55.so )
add_library( swresample-2
             SHARED
             IMPORTED )
set_target_properties( swresample-2
                       PROPERTIES IMPORTED_LOCATION
                       ../../../../libs/armeabi-v7a/libswresample-2.so )
add_library( swscale-4
             SHARED
             IMPORTED )
set_target_properties( swscale-4
                       PROPERTIES IMPORTED_LOCATION
                       ../../../../libs/armeabi-v7a/libswscale-4.so )
include_directories( libs/include )
find_library( # Sets the name of the path variable.
              log-lib
              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
                       native-lib
                       avcodec-57
                       avfilter-6
                       avformat-57
                       avutil-55
                       swresample-2
                       swscale-4
                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

6.6 Java 引入 so 庫(kù)

static {
    System.loadLibrary("native-lib");
    System.loadLibrary("avcodec-57");
    System.loadLibrary("avfilter-6");
    System.loadLibrary("avformat-57");
    System.loadLibrary("avutil-55");
    System.loadLibrary("swresample-2");
    System.loadLibrary("swscale-4");
}

最后運(yùn)行測(cè)試下限嫌,即配置完成靴庆。

參考資料

  1. Android - FFmpeg & Mac & AndroidStudio & CMake 環(huán)境搭建
  2. FFmpeg-3.3.1移植到Android平臺(tái)(Mac編譯)
  3. Mac 環(huán)境下ffmpeg編譯出現(xiàn) errno.h: No such file or directory 錯(cuò)誤問(wèn)題
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市怒医,隨后出現(xiàn)的幾起案子炉抒,更是在濱河造成了極大的恐慌,老刑警劉巖稚叹,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件焰薄,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡扒袖,警方通過(guò)查閱死者的電腦和手機(jī)塞茅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)季率,“玉大人野瘦,你說(shuō)我怎么就攤上這事§海” “怎么了缅刽?”我有些...
    開(kāi)封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵啊掏,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我衰猛,道長(zhǎng)迟蜜,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任啡省,我火速辦了婚禮娜睛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘卦睹。我一直安慰自己畦戒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布结序。 她就那樣靜靜地躺著障斋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪徐鹤。 梳的紋絲不亂的頭發(fā)上垃环,一...
    開(kāi)封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音返敬,去河邊找鬼遂庄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛劲赠,可吹牛的內(nèi)容都是我干的涛目。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼凛澎,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼霹肝!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起塑煎,我...
    開(kāi)封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤沫换,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后轧叽,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡刊棕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年炭晒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甥角。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡网严,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出嗤无,到底是詐尸還是另有隱情震束,我是刑警寧澤怜庸,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站垢村,受9級(jí)特大地震影響割疾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜嘉栓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一宏榕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧侵佃,春花似錦麻昼、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至迈螟,卻和暖如春叉抡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背井联。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工卜壕, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人烙常。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓轴捎,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蚕脏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子侦副,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

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