用android ndk编译ffmpeg,AndroidNDK交叉编译FFMPEG
1. 簡介
在進(jìn)行安卓音視頻開發(fā)時(shí),利用安卓NDK工具交叉編譯FFmpeg,生成可供安卓平臺(tái)調(diào)用的FFmpeg庫是最基礎(chǔ)的工作。本篇文章介紹了利用NDK進(jìn)行FFmpeg編譯的具體過程,以及如何在Linux和windows系統(tǒng)下交叉編譯出適用于不同安卓平臺(tái)的FFmpeg庫文件。
2. 編譯前的準(zhǔn)備工作
無論是在Linux還是Windows系統(tǒng)下,進(jìn)行FFmpeg編譯都需要準(zhǔn)備好NDK工具和FFmpeg源碼文件:
NDK下載地址:
https://developer.android.google.cn/ndk/downloads
FFmpeg下載地址:
http://www.ffmpeg.org/download.html
如果是在Windows平臺(tái)下進(jìn)行交叉編譯,還需要準(zhǔn)備MinGW工具。
https://sourceforge.net/projects/mingw-w64/
注意事項(xiàng):
①FFmpge需要下載.zip源碼壓縮文件
②NDK版本和FFmpeg版本要匹配,如果某一個(gè)版本太新或太久可能會(huì)導(dǎo)致后續(xù)交叉編譯出現(xiàn)錯(cuò)誤
下載完成后將兩個(gè)文件夾放到同一路徑下,如下圖是我在Windows系統(tǒng)中的存放形式。
3. 創(chuàng)建并編寫編譯腳本
完成以上準(zhǔn)備工作后,開始撰寫編譯腳本,這也是交叉編譯的關(guān)鍵步驟。首先無論是在Linux系統(tǒng)還是Windows系統(tǒng),都需要在ffmpeg源碼文件夾下創(chuàng)建一個(gè)build_android.sh文件。創(chuàng)建完成后,下面分別介紹如何在Windows和ubuntu系統(tǒng)下編譯用于不同安卓平臺(tái)的FFmpeg庫文件。
windows系統(tǒng)
build_android.sh文件的創(chuàng)建
以在Windows系統(tǒng)下創(chuàng)建一個(gè)適用于X86平臺(tái)的FFmpeg庫為例,打開build_android.sh文件,寫入如下代碼:#!/bin/bash
# 臨時(shí)文件路徑
export TMPDIR=`dirname $0`/tmpdir
# NDK路徑
NDK=C:/FFmpeg/android-ndk-r21e
# API版本(Android API)
API=29
# arm aarch64 i686 x86_64,所屬系統(tǒng)
ARCH=i686
# 編譯針對的平臺(tái),可以根據(jù)自己的需求進(jìn)行設(shè)置
# armv7a aarch64 i686 x86_64
PLATFORM=i686
TARGET=$PLATFORM-linux-android
# 工具鏈的路徑,根據(jù)編譯的平臺(tái)不同而不同
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/windows-x86_64/bin
SYSROOT=$NDK/sysroot
# 編譯文件輸出路徑
PREFIX=`dirname $0`/android_arm/$PLATFORM
CFLAG="-D__ANDROID_API__=$API -U_FILE_OFFSET_BITS -DBIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD -Os -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -marm"
mkdir -p $TMPDIR
build_one()
{
./configure \
--ln_s="cp -rf" \
--prefix=$PREFIX \
--cc=$TOOLCHAIN/$TARGET$API-clang \
--cxx=$TOOLCHAIN/$TARGET$API-clang++ \
--ld=$TOOLCHAIN/$TARGET$API-clang \
--target-os=android \
--arch=$ARCH \
--cpu=$PLATFORM \
--cross-prefix=$TOOLCHAIN/$ARCH-linux-android- \
--disable-asm \
--enable-cross-compile \
--enable-shared \
--disable-static \
--enable-runtime-cpudetect \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-doc \
--disable-symver \
--enable-small \
--enable-gpl --enable-nonfree --enable-version3 --disable-iconv \
--enable-jni \
--enable-mediacodec \
--disable-bsfs \
--disable-indevs --enable-indev=v4l2 \
--disable-outdevs \
--disable-filters \
--disable-postproc \
--extra-cflags="$CFLAG" \
--extra-ldflags="-marm"
}
build_one
make clean
make -j4
make install
其中需要注意NDK的路徑需要修改為你自己電腦中存放NDK的路徑。
運(yùn)行build_android.sh文件
創(chuàng)建完成后,進(jìn)入MinGW的安裝文件夾下,按照路徑/msys/1.0/找到msys.bat文件,雙擊運(yùn)行:然后在命令行中進(jìn)入剛剛創(chuàng)建的build_android.sh文件所在路徑,通過./build_anroid.sh進(jìn)行運(yùn)行(如下圖所示)
等待程序自己運(yùn)行,如果運(yùn)行成功會(huì)在腳本指定的路徑下生成i686文件夾,里面包含了后續(xù)供安卓平臺(tái)調(diào)用的頭文件和共享庫文件。(下圖是我生成的應(yīng)用于x86平臺(tái)的FFmpeg庫文件)
ubuntu系統(tǒng)
ubuntu系統(tǒng)下的交叉編譯相比windows系統(tǒng)下更加方便。這里以編譯一個(gè)適用于armeabi-v7a平臺(tái)的FFmpge庫為例。
build_android.sh文件的創(chuàng)建
同樣在ffmpeg源碼路徑下創(chuàng)建一個(gè)build_andorid.sh文件#!/bin/bash
echo "進(jìn)入編譯ffmpeg腳本"
NDK=/root/ff/android-ndk-r14b
#5.0
PLATFORM=$NDK/platforms/android-21/arch-arm
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
CPU=armv7-a
#輸出路徑
PREFIX=./android/$CPU
function buildFF
{
echo "開始編譯ffmpeg"
./configure \
--prefix=$PREFIX \
--target-os=android \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--arch=arm \
--cpu=$CPU \
--sysroot=$PLATFORM \
--extra-cflags="$CFLAG" \
--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-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-postproc \
--disable-avdevice \
--disable-symver \
--disable-stripping \
$ADD
make -j16
make install
echo "編譯結(jié)束!"
}
###########################################################
echo "編譯支持neon和硬解碼"
CPU=armv7-a
PREFIX=./android/armv7-a-neon-hard
CFLAG="-I$PLATFORM/usr/include -fPIC -DANDROID -mfpu=neon -mfloat-abi=softfp "
ADD="--enable-asm \
--enable-neon \
--enable-jni \
--enable-mediacodec \
--enable-decoder=h264_mediacodec \
--enable-hwaccel=h264_mediacodec "
buildFF
###########################################################
echo "編譯不支持neon和硬解碼"
CPU=armv7-a
PREFIX=./android/$CPU
CFLAG="-I$PLATFORM/usr/include -fPIC -DANDROID -mfpu=vfp -mfloat-abi=softfp "
ADD=
buildFF
運(yùn)行build_android.sh文件
在build_android.sh文件所在路徑下打開命令行工具,直接輸入./build_android.sh回車運(yùn)行
運(yùn)行成功后也會(huì)在指定目錄下生成對應(yīng)的庫文件。
4. 在Android Studio中調(diào)用編譯出的FFmpeg庫
1. 在安卓項(xiàng)目中引入FFmpeg庫
創(chuàng)建一個(gè)的安卓項(xiàng)目,將編譯好的FFmpeg庫放入項(xiàng)目的.../MyApplication/app/src/main/cpp路徑下(包括生成的inclue文件夾和lib文件夾)。按照編譯出的FFmpeg庫版本對lib文件夾進(jìn)行重命名,例如我在Windows下編譯的FFmpeg是針對x86平臺(tái)的,則lib文件夾重命名為x86。
此時(shí),你的cpp路徑下應(yīng)該有如上圖所示的幾個(gè)子文件夾,其中include、CMakeList.txt、native-lib.cpp是必須要有的,其余中armeabi-7v、x86、x86_64可以只有一個(gè),也可以多個(gè)都包含,這取決于你的應(yīng)用所要配置的安卓平臺(tái),如果你只用配置在x86平臺(tái)下,則只包含x86文件夾也可以。
2. 配置CMakeList.txt文件
首先需要在CMakeList.txt中配置include文件夾路徑,由于CMakeList.txt和include在同一文件夾下,所以之間添加如下代碼即可:#添加頭文件路徑(相對于本文件的路徑)
include_directories(include)
然后需要配置ffmpeg動(dòng)態(tài)庫所在路徑,這里分為三步實(shí)現(xiàn):#設(shè)置ffmpeg庫所在路徑的變量
add_library(avcodec SHARED IMPORTED)
set_target_properties(avcodec PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/${ANDROID_ABI}/libavcodec.so)
add_library(avformat SHARED IMPORTED)
set_target_properties(avformat PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/${ANDROID_ABI}/libavformat.so)
add_library(avutil SHARED IMPORTED)
set_target_properties(avutil PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/${ANDROID_ABI}/libavutil.so)
target_link_libraries( # Specifies the target library.
native-lib
avcodec
avformat
avutil
# Links the target library to the log library
# included in the NDK.
${log-lib} )
3. 配置build.gradle文件
在build.gradle中需要進(jìn)行兩項(xiàng)配置,第一項(xiàng)是在externalNativeBuild下添加ndk字段,如下所示:externalNativeBuild {
cmake {
cppFlags "-std=c++11"
}
ndk{
abiFilter "x86"
}
}
第二步是在externalNativeBuild 同級(jí)字段中添加動(dòng)態(tài)庫文件夾所在路徑sourceSets {
main{
jniLibs.srcDirs=['src/main/cpp']
}
}
4. 在native-lib.cpp中進(jìn)行庫調(diào)用
在調(diào)用時(shí)首先需要引入頭文件,這里需要注意,引入頭文件時(shí)需要加上extern "C"關(guān)鍵字extern "C"{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/pixfmt.h"
}
總結(jié)
以上是生活随笔為你收集整理的用android ndk编译ffmpeg,AndroidNDK交叉编译FFMPEG的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android工程jrr版本怎么改,io
- 下一篇: android复选按钮,Android的