FFmpeg編譯4.3.1-ndk(21)

我的ffmpeg開源項(xiàng)目地址Viktor_ffmpeg
該項(xiàng)目主要以學(xué)習(xí)ffmpeg為主,代碼中將ffplay摘抄出來(主要去除了sdl,使用c++的std),用自己的方式實(shí)現(xiàn)(面向?qū)ο?两入。
從該項(xiàng)目中你可以學(xué)到
1.如何使用ffmpeg解碼視頻并播放
2.如何多個(gè)視頻串行播放
該項(xiàng)目是以剪映的功能為目標(biāo)

我的編譯項(xiàng)目地址ffmpeg編譯

該篇基于我前面翻譯的fmpeg-android-maker文章基礎(chǔ)上买优,實(shí)現(xiàn)對(duì)ffmpeg4.3.1版本編譯。沒有看過該篇文章的一定要先看下画拾,內(nèi)容不多,主要是要把編譯shell代碼clone下來。或者clone我的ffmpeg編譯項(xiàng)目(主要加了點(diǎn)echo輸出日志方便排查問題利术、以及更改了ffmpeg目錄下build.sh文件的部分編譯條件以符合自己的編譯需求)

本文編譯產(chǎn)出共享庫(kù)(.so文件)以及頭文件(.h文件),主要針對(duì)android平臺(tái)低矮,使用的ndk是21.3.6528147版本印叁。

之前也是從網(wǎng)上搜各種文章去編譯ffmpeg,到最后不是編譯不過军掂,就是編譯了之后在其他手機(jī)運(yùn)行就崩潰轮蜕,又或者需修改ffmpeg源碼configure文件。
該篇文章基于ffmpeg官網(wǎng)給的git倉(cāng)庫(kù)去修改編譯的(不是修改configure文件蝗锥,是修改clone下來的shell文件跃洛,以符合自己的需求)

編譯環(huán)境基本的要求這里就不啰嗦了。
主要是選擇編譯的系統(tǒng)使用mac或者linux
ndk使用android studio開發(fā)工具下載即可终议,后面會(huì)說到編譯ffmpeg需要使用的基本配置汇竭。

clone下來的都是shell腳本寫的代碼,這里我用的開發(fā)工具是vs code

如果以后要專攻ffmpeg編譯穴张,shell腳本學(xué)習(xí)少不了细燎,想系統(tǒng)學(xué)習(xí)shell腳本看這里
這里介紹一點(diǎn)基礎(chǔ)的shell腳本知識(shí):
A.export 變量=值--->定義環(huán)境變量皂甘,這樣就可以在其他文件中訪問該值了玻驻,類似全局變量,就好比你可以在命令行中執(zhí)行echo $PATH偿枕,訪問.bash_profile定義的變量击狮。
B.$0,$1,$2,$3...$n腳本傳遞的參數(shù)的順序佛析,$0比較特殊代表腳本文件的名稱。
C.$?代表執(zhí)行的結(jié)果彪蓬,shell中非0即為假寸莫,0代表真,例如echo $PATH 執(zhí)行完后再執(zhí)行echo $?輸出0档冬,說明echo $PATH這個(gè)命令執(zhí)行結(jié)果為真膘茎。
D.$*,以一個(gè)單字符串顯示所有向腳本傳遞的參數(shù)
E.$@,與$*相同酷誓,但是使用時(shí)加引號(hào)披坏,并在引號(hào)中返回每個(gè)參數(shù),一般用在for循環(huán)
F.if [[...]] ;then 或者if test ... ;then 都是基本的判斷條件是否成功,具體可以網(wǎng)上搜一搜

先看下fmpeg-android-maker文章中clone下來的編譯代碼基本結(jié)構(gòu)

image.png

結(jié)構(gòu)說明

1.入口文件ffmpeg-android-maker.sh
2.scripts目錄下包括:
------>ffmpeg,三方庫(kù)目錄:打開都是build.sh和download.sh
------>check-host-machine.sh盐数、export-host-variables.sh棒拂、parse-arguments.sh等文件。
當(dāng)運(yùn)行ffmpeg-android-maker.sh文件后:
1.會(huì)自動(dòng)調(diào)起scripts下的sh文件:例如check-host-machine.sh文件檢查android需要sdk,ndk的配置問題等等
2.然后再編譯對(duì)應(yīng)ffmpeg,三方庫(kù)目錄下的download.sh下載源碼玫氢,再執(zhí)行各自的build.sh文件

下面依據(jù)入口文件ffmpeg-android-maker.sh來分析對(duì)ffmpeg的整個(gè)編譯過程帚屉,最后完成編譯輸出.so和.h文件

入口文件ffmpeg-android-maker.sh

建議看該篇文章結(jié)合clone的源碼看
下面是整個(gè)ffmpeg-android-maker.sh文件的代碼,刪去了注釋。
這里會(huì)按照下面的注釋“-----分塊-----”來逐步解釋

#!/usr/bin/env bash

#--------------------分塊1-------start---------------
export BASE_DIR="$( cd "$( dirname "$0" )" && pwd )"

export SOURCES_DIR=${BASE_DIR}/sources

export STATS_DIR=${BASE_DIR}/stats

export SCRIPTS_DIR=${BASE_DIR}/scripts

export OUTPUT_DIR=${BASE_DIR}/output
${SCRIPTS_DIR}/check-host-machine.sh || exit 1
BUILD_DIR=${BASE_DIR}/build
export BUILD_DIR_FFMPEG=$BUILD_DIR/ffmpeg
export BUILD_DIR_EXTERNAL=$BUILD_DIR/external

function prepareOutput() {
  OUTPUT_LIB=${OUTPUT_DIR}/lib/${ANDROID_ABI}
  mkdir -p ${OUTPUT_LIB}
  cp ${BUILD_DIR_FFMPEG}/${ANDROID_ABI}/lib/*.so ${OUTPUT_LIB}

  OUTPUT_HEADERS=${OUTPUT_DIR}/include/${ANDROID_ABI}
  mkdir -p ${OUTPUT_HEADERS}
  cp -r ${BUILD_DIR_FFMPEG}/${ANDROID_ABI}/include/* ${OUTPUT_HEADERS}
}

function checkTextRelocations() {
  TEXT_REL_STATS_FILE=${STATS_DIR}/text-relocations.txt
  ${FAM_READELF} --dynamic ${BUILD_DIR_FFMPEG}/${ANDROID_ABI}/lib/*.so | grep 'TEXTREL\|File' >> ${TEXT_REL_STATS_FILE}

  if grep -q TEXTREL ${TEXT_REL_STATS_FILE}; then
    echo "There are text relocations in output files:"
    cat ${TEXT_REL_STATS_FILE}
    exit 1
  fi
}

rm -rf ${BUILD_DIR}
rm -rf ${STATS_DIR}
rm -rf ${OUTPUT_DIR}
mkdir -p ${STATS_DIR}
mkdir -p ${OUTPUT_DIR}
#--------------------分塊1-------end----------

#--------------------分塊2-------start---------------
source ${SCRIPTS_DIR}/export-host-variables.sh
source ${SCRIPTS_DIR}/parse-arguments.sh

COMPONENTS_TO_BUILD=${EXTERNAL_LIBRARIES[@]}
COMPONENTS_TO_BUILD+=( "ffmpeg" )

for COMPONENT in ${COMPONENTS_TO_BUILD[@]}
do
  SOURCE_DIR_FOR_COMPONENT=${SOURCES_DIR}/${COMPONENT}
  mkdir -p ${SOURCE_DIR_FOR_COMPONENT}
  cd ${SOURCE_DIR_FOR_COMPONENT}

  source ${SCRIPTS_DIR}/${COMPONENT}/download.sh

  COMPONENT_SOURCES_DIR_VARIABLE=SOURCES_DIR_${COMPONENT}
  if [[ -z "${!COMPONENT_SOURCES_DIR_VARIABLE}" ]]; then
     export SOURCES_DIR_${COMPONENT}=${SOURCE_DIR_FOR_COMPONENT}
  fi

  cd ${BASE_DIR}
done

for ABI in ${FFMPEG_ABIS_TO_BUILD[@]}
do
  source ${SCRIPTS_DIR}/export-build-variables.sh ${ABI}

  for COMPONENT in ${COMPONENTS_TO_BUILD[@]}
  do
    echo "Building the component: ${COMPONENT}"
    COMPONENT_SOURCES_DIR_VARIABLE=SOURCES_DIR_${COMPONENT}
    cd ${!COMPONENT_SOURCES_DIR_VARIABLE}
    source ${SCRIPTS_DIR}/${COMPONENT}/build.sh || exit 1

  done
  checkTextRelocations || exit 1

  prepareOutput
done
#--------------------分塊2-------end----------

1.---分塊1---

主要是:
a.定義幾個(gè)環(huán)境變量漾峡,即BASE_DIR攻旦,SOURCES_DIR等全局目錄,沒有就創(chuàng)建("---分塊1---end---"最后幾個(gè)rm -rf 和mdkir -p)
b.定義兩個(gè)方法prepareOutput(將.so和.h文件拷貝到上面創(chuàng)建的OUTPUT_DIR目錄中)、checkTextRelocations(檢查重定向文件text-relocations.txt中是否能檢查到TEXTREL生逸,如果檢查到說明整個(gè)編譯結(jié)果失敗牢屋,退出,具體看fmpeg-android-maker文章末尾介紹)
c.執(zhí)行check-host-machine.sh文件槽袄,檢查sdk烙无、ndk環(huán)境配置

各個(gè)目錄變量具體值可以自己輸出查看,我的輸出結(jié)果:

BASE_DIR:/Users/rain/ffmpeg/ffmpeg-android-custom
SOURCES_DIR:/Users/rain/ffmpeg/ffmpeg-android-custom/sources
STATS_DIR:/Users/rain/ffmpeg/ffmpeg-android-custom/stats
SCRIPTS_DIR:/Users/rain/ffmpeg/ffmpeg-android-custom/scripts
OUTPUT_DIR:/Users/rain/ffmpeg/ffmpeg-android-custom/output
BUILD_DIR_FFMPEG:/Users/rain/ffmpeg/ffmpeg-android-custom/build/ffmpeg
BUILD_DIR_EXTERNAL:/Users/rain/ffmpeg/ffmpeg-android-custom/build/external

BASE_DIR:clone下來的代碼所在的位置遍尺,類似根目錄
SOURCES_DIR:下載ffmpeg,三方庫(kù)源碼存放位置
STATS_DIR:主要用于輸出文本重定位信息text-relocations.txt(具體看fmpeg-android-maker文章末尾介紹)
SCRIPTS_DIR:上面說過了截酷,主要放置ffmpeg,三方庫(kù)各自的download.sh,build.sh和公共sh文件(后面詳細(xì)介紹這些文件)
OUTPUT_DIR:編譯完成后輸出的文件狮鸭,共享庫(kù)(.so文件)以及頭文件(.h文件)
BUILD_DIR_FFMPEG/BUILD_DIR_EXTERNAL:整個(gè)編譯過程中ffmpeg以及三方庫(kù)的build和install所存放的文件

check-host-machine.sh檢查sdk,ndk設(shè)置的環(huán)境變量

${SCRIPTS_DIR}/check-host-machine.sh || exit 1
文件執(zhí)行成功接著往下走合搅,如果失敗直接退出(取check-host-machine.sh執(zhí)行結(jié)果:$? || exit 1)

該文件主要是檢查系統(tǒng)環(huán)境是否配置了ANDROID_SDK_HOMEANDROID_NDK_HOME多搀。
可以自己查看系統(tǒng).bash_profile中是否定義了這兩個(gè)值歧蕉,只要保證check-host-machine.sh和.bash_profile文件中定義的sdk、ndk變量同名即可(如果保持和.bash_profile文件中同名康铭,記得全局搜索ANDROID_SDK_HOME惯退、ANDROID_NDK_HOME,都要修改)从藤。

2.---分塊2---

重點(diǎn)都在這塊了催跪,這塊代碼決定了你能否成功編譯出.so和.h文件锁蠕。
核心是2個(gè)sh文件和2個(gè)for循環(huán)

第1個(gè)sh文件:export-host-variables.sh

source ${SCRIPTS_DIR}/export-host-variables.sh
#!/usr/bin/env bash

# Defining a toolchain directory's name according to the current OS.
# Assume that proper version of NDK is installed
# and is referenced by ANDROID_NDK_HOME environment variable
# 依據(jù)編譯系統(tǒng)確定編譯工具鏈的目錄名字
#macOS  darwin-x86_64
#Linux  linux-x86_64
#32 位 Windows   windows
#64 位 Windows   windows-x86_64
case "$OSTYPE" in
  darwin*)  HOST_TAG="darwin-x86_64" ;;
  linux*)   HOST_TAG="linux-x86_64" ;;
  msys)
    case "$(uname -m)" in
      x86_64) HOST_TAG="windows-x86_64" ;;
      i686)   HOST_TAG="windows" ;;
    esac
  ;;
esac

#檢查當(dāng)前系統(tǒng)輸出cup的個(gè)數(shù),這就是你們經(jīng)常網(wǎng)上看到的那種編譯 make -j8,開啟編譯cpu線程數(shù)
#可以看下scripts/ffmpeg/build.sh最后用到了HOST_NPROC變量
if [[ $OSTYPE == "darwin"* ]]; then
  HOST_NPROC=$(sysctl -n hw.physicalcpu)
else
  HOST_NPROC=$(nproc)
fi

# The variable is used as a path segment of the toolchain path
export HOST_TAG=$HOST_TAG
# Number of physical cores in the system to facilitate parallel assembling
export HOST_NPROC=$HOST_NPROC

# Using CMake from the Android SDK
export CMAKE_EXECUTABLE=${ANDROID_SDK_HOME}/cmake/3.10.2.4988404/bin/cmake
# Using Build machine's Make, because Android NDK's Make (before r21) doesn't work properly in MSYS2 on Windows
export MAKE_EXECUTABLE=$(which make)
# Using Build machine's Ninja. It is used for libdav1d building. Needs to be installed
export NINJA_EXECUTABLE=$(which ninja)
# Meson is used for libdav1d building. Needs to be installed
export MESON_EXECUTABLE=$(which meson)
# Nasm is used for libdav1d and libx264 building. Needs to be installed
export NASM_EXECUTABLE=$(which nasm)
# A utility to properly pick shared libraries by FFmpeg's configure script. Needs to be installed
export PKG_CONFIG_EXECUTABLE=$(which pkg-config)

export-host-variables.sh文件是大的編譯前提實(shí)現(xiàn)的決定性條件懊蒸,先看下我的mac電腦上的輸出:

HOST_TAG:darwin-x86_64
HOST_NPROC:2
CMAKE_EXECUTABLE:/Users/rain/Library/Android/sdk/cmake/3.10.2.4988404/bin/cmake
MAKE_EXECUTABLE:/usr/bin/make
NINJA_EXECUTABLE:/Library/Frameworks/Python.framework/Versions/3.8/bin/ninja
MESON_EXECUTABLE:/Library/Frameworks/Python.framework/Versions/3.8/bin/meson
NASM_EXECUTABLE:/usr/local/bin/nasm
PKG_CONFIG_EXECUTABLE:/usr/local/bin/pkg-config

這幾個(gè)變量的含義:

CMAKE_EXECUTABLE:cmake的絕對(duì)路徑荣倾,用的是sdk下的cmake,scripts/libaom/build.sh中用到了
MAKE_EXECUTABLE:make的絕對(duì)路徑骑丸,所有scripts/目錄/build.sh文件全用到了舌仍,make用來做啥就不用說了吧
NINJA_EXECUTABLE:ninja,主要構(gòu)建三方庫(kù)libdav1d用的
MESON_EXECUTABLE:meson通危,主要構(gòu)建三方庫(kù)libdav1d用的
NASM_EXECUTABLE:nasm铸豁,構(gòu)建libdav1d和libx264用的
PKG_CONFIG_EXECUTABLE:編譯ffmpeg時(shí)從configure腳本文件中選擇共享庫(kù)用的,很重要菊碟!
以上全局變量都可以全局搜索看看都在哪些build.sh文件中用到了节芥,
命令行執(zhí)行:which make/ninja/meson等查看是否安裝了
最好按照網(wǎng)上教程全部安裝!

回到ffmpeg-android-maker.sh文件繼續(xù)分析
第2個(gè)sh文件:parse-arguments.sh

source ${SCRIPTS_DIR}/parse-arguments.sh

parse-arguments.sh文件代碼比較多這里就不貼出來了逆害,可以自己看源碼头镊。該文件就是解析你編譯時(shí)輸入的參數(shù)。
主要是給FFMPEG_ABIS_TO_BUILD忍燥、FFMPEG_SOURCE_TYPE拧晕、FFMPEG_SOURCE_VALUE、FFMPEG_EXTERNAL_LIBRARIES梅垄、DESIRED_ANDROID_API_LEVEL厂捞、DESIRED_BINUTILS
幾個(gè)環(huán)境變量賦值。
我編譯時(shí)輸入的命令:./ffmpeg-android-maker.sh -abis=arm,arm64 -x264

再看下給上面幾個(gè)變量賦值后的值
FFMPEG_ABIS_TO_BUILD:armeabi-v7a arm64-v8a
FFMPEG_SOURCE_TYPE:TAR
FFMPEG_SOURCE_VALUE:4.3.1
FFMPEG_EXTERNAL_LIBRARIES:libx264
DESIRED_ANDROID_API_LEVEL:21
DESIRED_BINUTILS:gnu
我要編譯的就是armeabi-v7a arm64-v8a兩個(gè)ABI队丝,并且支持x264編碼靡馁。
源碼下載的方式我用的是TAR;ffmpeg編譯的版本是4.3.1机久;
androi的API選擇的是21臭墨,沒有選擇更高的版本是我遇到再其他手機(jī)運(yùn)行報(bào)錯(cuò):cannot locate symbol "iconv_close" referenced,可以自行網(wǎng)上搜索這類問題
DESIRED_ANDROID_API_LEVEL主要用來構(gòu)建ffmpeg用到的交叉編譯鏈中用到CC膘盖、CXX胧弛、AS、AR侠畔、NM等用到结缚,具體可以看scripts/export-build-variables.sh文件解析;
DESIRED_BINUTILS代表使用哪個(gè)binutils(gnu或llvm),默認(rèn)是gnu,看scripts/export-build-variables.sh文件中就能找到答案

回到ffmpeg-android-maker.sh文件软棺,這時(shí)COMPONENTS_TO_BUILD的值是libx264 ffmpeg
并且ffmpeg是永遠(yuǎn)放在最后的红竭。

第一個(gè)for循環(huán)

是對(duì)COMPONENTS_TO_BUILD進(jìn)行遍歷,這里是libx264 ffmpeg
核心功能就是下載每個(gè)模塊的源碼,然后將下載的源碼路徑賦值環(huán)境變量 SOURCES_DIR_${COMPONENT}
具體看代碼注釋

for COMPONENT in ${COMPONENTS_TO_BUILD[@]}
do
  #根據(jù)上面創(chuàng)建的SOURCES_DIR目錄創(chuàng)建目錄SOURCE_DIR_FOR_COMPONENT
  #例如ffmpeg:/Users/rain/ffmpeg/ffmpeg-android-custom/sources/ffmpeg
  SOURCE_DIR_FOR_COMPONENT=${SOURCES_DIR}/${COMPONENT}

  #創(chuàng)建SOURCE_DIR_FOR_COMPONENT目錄茵宪,并且進(jìn)入
  mkdir -p ${SOURCE_DIR_FOR_COMPONENT}
  cd ${SOURCE_DIR_FOR_COMPONENT}

  #上一步進(jìn)入之后就執(zhí)行對(duì)應(yīng)模塊的download.sh文件
  #/Users/rain/ffmpeg/ffmpeg-android-custom/scripts/ffmpeg/download.sh
  source ${SCRIPTS_DIR}/${COMPONENT}/download.sh

  #if判斷COMPONENT_SOURCES_DIR_VARIABLE 賦值的SOURCES_DIR_${COMPONENT} 是否已經(jīng)有值
  #沒有的換就進(jìn)入if 并且賦值環(huán)境變量SOURCES_DIR_${COMPONENT}
  #即SOURCES_DIR_ffmpeg=/Users/rain/ffmpeg/ffmpeg-android-custom/sources/ffmpeg
  #主要給下一個(gè)for循環(huán)使用
  COMPONENT_SOURCES_DIR_VARIABLE=SOURCES_DIR_${COMPONENT}
  if [[ -z "${!COMPONENT_SOURCES_DIR_VARIABLE}" ]]; then
     export SOURCES_DIR_${COMPONENT}=${SOURCE_DIR_FOR_COMPONENT}
  fi

  cd ${BASE_DIR}
done

第二個(gè)for循環(huán)是對(duì)在parse-arguments.sh中賦值的環(huán)境變量FFMPEG_ABIS_TO_BUILD:armeabi-v7a arm64-v8a
進(jìn)行遍歷操作最冰,即選擇的不同ABI進(jìn)行編譯。

這里插補(bǔ)下for循環(huán)中export-build-variables.sh文件的解析

source ${SCRIPTS_DIR}/export-build-variables.sh ${ABI}

運(yùn)行export-build-variables.sh文件時(shí)傳入了一個(gè)參數(shù)即:$1=ABI
該文件主要是根據(jù)傳入的ABI和在parse-arguments.sh中定義的環(huán)境變量稀火,
給TOOLCHAIN_PATH暖哨、SYSROOT_PATH,CROSS_PREFIX凰狞、FAM_CC鹿蜀、FAM_CXX等變量賦值,
主要是給每個(gè)模塊build.sh時(shí)用的
該文件什么都不用改動(dòng)服球,如果你感興趣可以輸出某些值看看茴恰,都是和編譯ffmpeg需要的工具鏈相關(guān)的東西。

繼續(xù)第二個(gè)for循環(huán)分析斩熊。經(jīng)過參數(shù)ABI執(zhí)行完export-build-variables.sh后
進(jìn)入第二個(gè)for循環(huán)中的第二個(gè)循環(huán)往枣,其實(shí)就是上面第一個(gè)循環(huán)執(zhí)行不同的命令而已,即執(zhí)行每個(gè)模塊的build.sh文件
最后:第二個(gè)for循環(huán)執(zhí)行完一個(gè)ABI之后粉渠,就執(zhí)行上面說到的----分塊1----中定義的兩個(gè)方法checkTextRelocations分冈,prepareOutput。
可以看到執(zhí)行checkTextRelocations方法時(shí)霸株,如果失敗就退出當(dāng)前ABI的for循環(huán)雕沉。
prepareOutput是將每個(gè)ABI的.so和.h從build/ffmpeg拷貝到output下:

根目錄/build/ffmpeg/armeabi-v7a/lib/.so--->根目錄/output/lib/armeabi-v7a
根目錄/build/ffmpeg/armeabi-v7a/include/
--->根目錄/output/include/armeabi-v7a

第二個(gè)for循環(huán)走完,整個(gè)編譯就已經(jīng)完成了去件,在根目錄的output里面就能看到編譯出的.so和.h坡椒。
這里scripts/ffmpeg/build.sh文件就不詳細(xì)說了,和網(wǎng)上編譯的幾乎一樣尤溜,不過ffmpeg git官網(wǎng)給的分支倔叼,不管是master還是what-the-codec都不是我要的
我是在what-the-codec分支基礎(chǔ)上修改了我的需求,就是支持硬件編碼宫莱,可以對(duì)比看下我的ffmpeg/build.sh內(nèi)容:

./configure \
  --prefix=${BUILD_DIR_FFMPEG}/${ANDROID_ABI} \
  --enable-cross-compile \
  --target-os=android \
  --arch=${TARGET_TRIPLE_MACHINE_BINUTILS} \
  --sysroot=${SYSROOT_PATH} \
  --cc=${FAM_CC} \
  --cxx=${FAM_CXX} \
  --ld=${FAM_LD} \
  --ar=${FAM_AR} \
  --as=${FAM_CC} \
  --nm=${FAM_NM} \
  --ranlib=${FAM_RANLIB} \
  --strip=${FAM_STRIP} \
  --extra-cflags="-O3 -fPIC $DEP_CFLAGS" \
  --extra-ldflags="$DEP_LD_FLAGS" \
  --enable-shared \
  --disable-static \
  --pkg-config=${PKG_CONFIG_EXECUTABLE} \
  ${EXTRA_BUILD_CONFIGURATION_FLAGS} \
  --disable-runtime-cpudetect \
  --disable-programs \
  --disable-avdevice \
  --disable-postproc \
  --disable-doc \
  --disable-debug \
  --disable-network \
  --disable-bsfs \
  --enable-pthreads \
  --enable-asm \
  --disable-neon \
  --enable-jni \
  --enable-mediacodec \
  --enable-decoder=h264_mediacodec \
  $ADDITIONAL_COMPONENTS || exit 1

記住丈攒,開啟mediacodec,一定要開jni,開啟jni也要一定開啟pthreads(如果開啟jni授霸,不開pthreads,會(huì)報(bào)錯(cuò):ERROR: jni not found巡验,可以在ffmpeg源碼configure中全局搜索jni not found就知道答案了)

看下我編譯完成后項(xiàng)目結(jié)構(gòu)情況


image.png

最后

總結(jié)下clone下來代碼之后需要修改的.sh文件有哪些,如果你完全看懂了每個(gè).sh文件就可以隨意修改了

1.check-host-machine.sh文件碘耳,保持文件中ANDROID_SDK_HOME显设、ANDROID_NDK_HOME兩個(gè)變量和系統(tǒng).bash_profile同名即可,
可以全局搜索就能知道哪里用到了這兩個(gè)環(huán)境變量了(如果保持和.bash_profile文件中同名藏畅,記得全局搜索ANDROID_SDK_HOME敷硅、ANDROID_NDK_HOME,都要修改)
2.export-host-variables.sh文件愉阎,什么都不需要修改绞蹦,唯一要注意的就是檢查是否安裝了make、ninja榜旦、meson幽七、nasm、which pkg-config這些編譯時(shí)要用到的工具溅呢,可以在命令行中執(zhí)行要查看的工具澡屡,類似which make等查看即可
3.parse-arguments.sh文件,我只修改了API_LEVEL=21咐旧,其他的SOURCE_TYPE驶鹉、SOURCE_VALUE根據(jù)自己需求修改
4.export-build-variables.sh文件,不做任何修改
5.common-functions.sh文件铣墨,不做任何修改室埋。該文件是每個(gè)模塊的download.sh中會(huì)調(diào)用,就是下載各個(gè)模塊源碼時(shí)使用

上面文件修改完成后伊约,執(zhí)行./ffmpeg-android-maker.sh -abis=arm,arm64 -x264就開始編譯了(更多參數(shù)傳遞看這里)

編譯過程中如果失敗中斷姚淆,一般都會(huì)有錯(cuò)誤日志輸出,看看哪個(gè)模塊失敗了屡律,然后再到對(duì)應(yīng)模塊源碼下查看config.log文件腌逢,
例如:
ffmpeg對(duì)應(yīng)sources/ffmpeg/ffmpeg-4.3.1/ffbuild/config.log文件
libx264對(duì)應(yīng)sources/libx264/x264-cde9adf/config.log文件
一般根據(jù)config.log文件能夠定位解決很多問題,如果還有問題歡迎留言討論超埋!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末搏讶,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子霍殴,更是在濱河造成了極大的恐慌窍蓝,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件繁成,死亡現(xiàn)場(chǎng)離奇詭異吓笙,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)巾腕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門面睛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人尊搬,你說我怎么就攤上這事叁鉴。” “怎么了佛寿?”我有些...
    開封第一講書人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵幌墓,是天一觀的道長(zhǎng)但壮。 經(jīng)常有香客問我,道長(zhǎng)常侣,這世上最難降的妖魔是什么蜡饵? 我笑而不...
    開封第一講書人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮胳施,結(jié)果婚禮上溯祸,老公的妹妹穿的比我還像新娘。我一直安慰自己舞肆,他們只是感情好焦辅,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著椿胯,像睡著了一般筷登。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上哩盲,一...
    開封第一講書人閱讀 52,158評(píng)論 1 308
  • 那天仆抵,我揣著相機(jī)與錄音,去河邊找鬼种冬。 笑死镣丑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的娱两。 我是一名探鬼主播莺匠,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼十兢!你這毒婦竟也來了趣竣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤旱物,失蹤者是張志新(化名)和其女友劉穎遥缕,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宵呛,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡单匣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宝穗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片户秤。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖逮矛,靈堂內(nèi)的尸體忽然破棺而出鸡号,到底是詐尸還是另有隱情,我是刑警寧澤须鼎,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布鲸伴,位于F島的核電站府蔗,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏汞窗。R本人自食惡果不足惜姓赤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望杉辙。 院中可真熱鬧,春花似錦捶朵、人聲如沸蜘矢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)品腹。三九已至,卻和暖如春红碑,著一層夾襖步出監(jiān)牢的瞬間舞吭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工析珊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留羡鸥,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓忠寻,卻偏偏與公主長(zhǎng)得像惧浴,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子奕剃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

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