概述
导读
对于想要学习音视频开发的android开发者来说,使用NDK对FFmpeg进行交叉编译是一道必须迈过去的坎,网上关于使用NDK对FFmpeg进行交叉编译的教程有很多,
但是不经修改能顺利编译通过的比较少。
其实参照网上的教程不能编译通过很多时候不是人家的教程写的有问题,很多时候更多的是因为环境的差异导致了编译出错,而对于一个入门者来说编译报错了自己却不知道怎么改。
如果对交叉编译不太了解的童鞋们可以先补习下NDK交叉编译基础
NDK编译FFmpeg
今天我们来使用NDK对FFmpeg进行交叉编译并集成到Android Studio中去。
笔者的开发环境是:
电脑系统 Mac OS
NDK 21.1.6352462
FFmpeg源码5.0.1 1、编写编译脚本
首先我们需要下载好对应版本的NDK和FFmpeg源码,然后我们新建一个编译脚本文件build_ffmpeg_android.sh:
#清空上次的编译 make clean #配置你的NDK路径 export NDK=/Users/flyer/Documents/Android/sdk/ndk/21.1.6352462 TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64 function build_android { ./configure --prefix=$PREFIX --disable-postproc --disable-debug --disable-doc --disable-ffmpeg --disable-ffplay --disable-ffprobe --disable-symver --disable-doc --disable-avdevice --disable-static --enable-shared --enable-neon --enable-hwaccels --enable-jni --enable-mediacodec --enable-decoder=h264_mediacodec --enable-decoder=hevc_mediacodec --enable-decoder=mpeg4_mediacodec --enable-hwaccel=h264_mediacodec --cross-prefix=$CROSS_PREFIX --target-os=android --arch=$ARCH --cpu=$CPU --cc=$CC --cxx=$CXX --enable-cross-compile --sysroot=$SYSROOT --extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" --extra-ldflags="$ADDI_LDFLAGS" make clean make -j16 make install echo "============================build android ffmpeg end==========================" } #arm64-v8a 参数配置 ARCH=arm64 CPU=armv8-a API=21 CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++ SYSROOT=$NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android- PREFIX=$(pwd)/android/$CPU OPTIMIZE_CFLAGS="-march=$CPU" # 函数调用 build_android
注意脚本文件中的注释,要把NDK的路径改为自己的NDK路径,尽可能使用与笔者相同版本的NDK,比如使用NDKr23的版本就可能编译不通过,貌似是因为NDKr23的改掉导致了toolchains下一些列工具找不到了。
【学习地址】:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
【文章福利】:免费领取更多音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击1079654574加群领取哦~
2、赋予脚本运行权限
将脚本文件拷贝到下载好的FFmpeg源码目录之下,然后使用命令行chmod +x build_ffmpeg_android.sh赋予脚本可执行权限。
3、运行编译脚本
运行命令行./build_ffmpeg_android.sh即可进行编译,如果编译成功可以在FFmpeg的源码目录下的android文件夹内找到对于的动态库和FFmpeg相关的头文件。
因为上述脚本通过PREFIX=(pwd)/android/CPU配置了编译的输出路径。
注意上述的脚本只编译了arm64-v8a架构的动态库,童鞋们可以尝试下如何编译其他架构的动态库。
集成到Android Studio中
1、 新建Android Studio Native工程
交叉编译成功后,我们通过Android Studio新建一个Native工程,不同的AS版本文件路径可能不一样,比如笔者的项目路径是这样的:
2、拷贝动态库和头文件到工程
然后我们在工程的libs目录下新建一个arm64-v8a目录,然后将我们编译出来的动态库文件拷贝到新建的arm64-v8a目录中去;
然后我们在cpp目录下新建一个ffmpeg_include目录用于存放FFmpeg的头文件,创建好之后我们将交叉编译目录include下头文件拷贝到新建的ffmpeg_include中去。
3、修改CMakeLists.txt
下面修改以下CMakeLists.txt配置文件,主要是配置FFmpeg动态库的搜索路径和头文件的搜索路径:
cmake_minimum_required(VERSION 3.10.2) # 引入FFmpeg的头文件 include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/ffmpeg_include) # 动态链接库或静态链接库的搜索路径 link_directories(${CMAKE_SOURCE_DIR}/libs/${CMAKE_ANDROID_ARCH_ABI}) #找到包含所有的cpp文件 file(GLOB allCpp src/main/cpp/*.*) add_library( # 生成的库的名字 flyffmpeg-lib # 动态库 SHARED # 源文件 ${allCpp} ) target_link_libraries( #目标库 flyffmpeg-lib # 把ffmpeg的动态库依赖进来 avformat avcodec avutil avfilter swscale swresample # NDK中的log库 log )
注意上面的文件修改了最终生成的动态库的名字flyffmpeg-lib
,所以在使用的时候需要注意一下加载正确的动态库。
4、修改build.gradle
这一步的目的主要是为了将libs目录下so文件打包进APK,我们将app目录下build.gradle修改成:
plugins { id 'com.android.application' } android { compileSdk 32 defaultConfig { applicationId "com.fly.ffmpeg.practice" minSdk 21 targetSdk 32 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { cppFlags '-std=c++11' } // abiFilters ndk { abiFilters "arm64-v8a" } } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } externalNativeBuild { cmake { // 指定CMakeLists.txt路径 path file('CMakeLists.txt') version '3.10.2' } } buildFeatures { viewBinding true } sourceSets { main { //将依赖库打进apk,否则可能出现找不到库 jniLibs.srcDirs = ['libs'] } } } dependencies { implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'com.google.android.material:material:1.5.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.3' testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' }
注意注释部分即可。
5、修改native-lib.cpp
最后我们修改以下native-lib.cpp
,在这里返回FFmpeg的配置:
#include <jni.h> #include <string> extern "C"{ #include <libavcodec/avcodec.h> } extern "C" JNIEXPORT jstring JNICALL Java_com_fly_ffmpeg_practice_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { // 返回ffmpeg配置信息 return env->NewStringUTF(avcodec_configuration()); }
运行如果可以能看到正确的配置信息则说明集成成功。
最后
以上就是俏皮咖啡为你收集整理的NDK21编译ffmpeg5.0.1集成到Android Studio中的全部内容,希望文章能够帮你解决NDK21编译ffmpeg5.0.1集成到Android Studio中所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复