概述
很多做NDK开发的人(像我这样从底层转过来的 >_<!)对于Android app的开发不是很理解,而ffmpeg的NDK开发现在又离不开Andorid app。网上虽然教程虽多,但是很多过时或者与NDK开发需求的不契合,或者ffmpeg与Android Studio一直在更新,从而造成了很多困扰,故写此教程,希望用户可以直接从github上面拉下来就能编译使用,同时一步一步讲解编写过程,对其中的一些大坑进行规避。
Android Studio Version: 3.1.3
ffmpeg Version:4.0
Android Version:O8.1
一. 编译ffmpeg
1. 从https://www.ffmpeg.org/上面下载4.0版本的ffmpeg
2. 编译ffmpeg的环境为:
Ubuntu 16.04 LTS, 64位
ndk version:android-ndk-r14b (需要自己下载)
abi support: armeabi armeabi-v7a arm64-v8a
3. 编写编译脚本,对于不同arm结构的编译脚本不同,对于armeabi-v7a架构的编译脚本,内容如下:
(其中xxx为android-ndk-r14b 的路径)
#!/bin/bash
PLATFORM=/xxx/android-ndk-r14b/platforms/android-19/arch-arm/
TOOLCHAIN=/xxx/android-ndk-r14b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
PREFIX=./android/armeabi-v7a
function build_android
{
./configure
--prefix=$PREFIX
--target-os=android
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi-
--arch=arm
--sysroot=$PLATFORM
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
--nm=$TOOLCHAIN/bin/arm-linux-androideabi-nm
--disable-shared
--disable-ffmpeg
--disable-ffplay
--disable-ffprobe
--disable-doc
--disable-symver
--enable-small
--enable-gpl
--enable-asm
--enable-jni
--enable-mediacodec
--enable-decoder=h264_mediacodec
--enable-hwaccel=h264_mediacodec
--enable-decoder=hevc_mediacodec
--enable-decoder=mpeg4_mediacodec
--enable-decoder=vp8_mediacodec
--enable-decoder=vp9_mediacodec
--enable-nonfree
--enable-version3
--extra-cflags="-Os -fpic $ADDI_CFLAGS -I$PLATFORM/usr/include"
--extra-ldflags="$ADDI_LDFLAGS"
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j8
make install
$TOOLCHAIN/bin/arm-linux-androideabi-ld
-rpath-link=$PLATFORM/usr/lib
-L$PLATFORM/usr/lib
-L$PREFIX/lib
-soname libffmpeg.so -shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o
$PREFIX/libffmpeg.so
libavcodec/libavcodec.a
libavfilter/libavfilter.a
libswresample/libswresample.a
libavformat/libavformat.a
libavutil/libavutil.a
libswscale/libswscale.a
libavdevice/libavdevice.a
libpostproc/libpostproc.a
-lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker
$TOOLCHAIN/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a
}
# arm v7vfp
CPU=arm
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
ADDI_CFLAGS="-marm"
build_android
对于arm64-v8a架构的编译脚本如下:
#/bin/bash
PLATFORM=/xxx/android-ndk-r14b/platforms/android-21/arch-arm64/
TOOLCHAIN=/xxx/android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64
PREFIX=./android/arm64-v8a
function build_android
{
./configure
--prefix=$PREFIX
--target-os=android
--cross-prefix=$TOOLCHAIN/bin/aarch64-linux-android-
--arch=aarch64
--sysroot=$PLATFORM
--cc=$TOOLCHAIN/bin/aarch64-linux-android-gcc
--nm=$TOOLCHAIN/bin/aarch64-linux-android-nm
--disable-shared
--enable-static
--disable-ffmpeg
--disable-ffplay
--disable-ffprobe
--disable-doc
--disable-symver
--enable-small
--enable-gpl
--enable-asm
--enable-jni
--enable-mediacodec
--enable-decoder=h264_mediacodec
--enable-hwaccel=h264_mediacodec
--enable-decoder=hevc_mediacodec
--enable-decoder=mpeg4_mediacodec
--enable-decoder=vp8_mediacodec
--enable-decoder=vp9_mediacodec
--enable-nonfree
--enable-version3
--extra-cflags="-Os -fpic $ADDI_CFLAGS -I$PLATFORM/usr/include"
--extra-ldflags="$ADDI_LDFLAGS"
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j8
make install
$TOOLCHAIN/bin/aarch64-linux-android-ld
-rpath-link=$PLATFORM/usr/lib
-L$PLATFORM/usr/lib
-L$PREFIX/lib
-soname libffmpeg.so -shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o
$PREFIX/libffmpeg.so
libavcodec/libavcodec.a
libavfilter/libavfilter.a
libswresample/libswresample.a
libavformat/libavformat.a
libavutil/libavutil.a
libswscale/libswscale.a
libavdevice/libavdevice.a
libpostproc/libpostproc.a
-lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker
$TOOLCHAIN/lib/gcc/aarch64-linux-android/4.9.x/libgcc.a
}
# arm64-v8a
CPU=arm64-v8a
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -march=$CPU "
build_android
需要注意的是,这两个不同架构的编译脚本中,我都添加了h264_mediacodec硬件解码,这是以后需要讲解的一项内容。
而我这个版本也不是最全的版本,根据自己的需求来编译对应的ffmpeg,还是需要自己学习如何配置编译的,后面也会继续讲ffmpeg configure,暂时可以直接复制我的编译脚本来编译。
同时,这个脚本编译出来的是一个libffmpeg.so库,而不是分开的库,还是为了方便操作。
4. 直接执行./build_android_armeabi-v7a.sh,稍等片刻,就会在ffmpeg/android/armeabi-v7a/目录下生成libffmpeg.so 和 include目录,就是我们所需的lib库和头文件。
二. 将ffmpeg集成到Android Studio中
1. 新建工程,增加C++支持:
然后一路Next,最后可以添加上这两个选项:
点击Finish即可。
2. 这时候也就可以编译执行,放到板子上面执行了,可以看到屏幕上面出现了Hello C++的字符。
其实我们也没做什么,Android Studio就帮我们实现了,实在是太强大了。
3. 切换成Project视图,在main处右键,新建一个jniLibs目录,把刚编译好的lib库和头文件复制到该目录下。需要挑选对应abi的include目录,把里面所有的文件复制过来。(比如,对于armeabi-v7a架构,就把ffmpeg/android/armeabi-v7a/include目录的所有文件复制过去。)
4. 修改build.gradle文件,添加如下内容:
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
如图所示:
5. 修改CMakeLists.txt,把ffmpeg的lib库添加进去:
#CMake版本信息
cmake_minimum_required(VERSION 3.4.1)
#ffmpeg so文件路径
set(lib_src_DIR ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI})
#配置加载native依赖
include_directories(${CMAKE_SOURCE_DIR}/src/main/jniLibs/include)
#动态方式加载ffmepg的so文件 第三方库加载方式
add_library(ffmpeg SHARED IMPORTED)
#引入libffmpeg.so文件
set_target_properties(ffmpeg PROPERTIES IMPORTED_LOCATION
${lib_src_DIR}/libffmpeg.so)
#CPP文件夹下待编译的c文件
add_library(native-lib SHARED ${CMAKE_SOURCE_DIR}/src/main/cpp/native-lib.cpp)
#C 日志 ndk官方库
find_library(log-lib log)
#静态库与动态库进行链接 相当于gcc命令行参数 -l。
target_link_libraries(native-lib
android
ffmpeg
${log-lib})
6. 添加第一个测试代码:
在MainActivity中仿照stringFromJNI,添加一个native方法string2FromJNI,然后点击左侧的红色感叹号,点击Create function xxx 让AS自动生成C++的对应方法,如图所示:
然后就会在 native-lib.cpp文件中,生成如下的函数模板:
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_nxf31081_ffmpeg_1demo_11_MainActivity_string2FromJNI(JNIEnv *env,
jobject instance) {
// TODO
return env->NewStringUTF(returnValue);
}
然后我们对其进行稍加修改,返回ffmpeg的编译信息,如下所示:
JNIEXPORT jstring JNICALL
Java_com_example_nxf31081_ffmpeg_1android_1demo_11_MainActivity_string2FromJNI(JNIEnv *env,
jobject instance) {
// TODO
char info[10000] = {0};
sprintf(info, "%s n", avcodec_configuration());
return env->NewStringUTF(info);
}
然后修改MainActivity.java,把string2FromJNI()函数添加进去,如下所示:
tv.setText(string2FromJNI());
最后,直接编译执行,就可以在APP上看到ffmpeg的编译信息了:
项目下载地址为:https://github.com/ZER0000/ffmpeg_android_demo.git
三. 总结
本篇文章实际的内容不多,主要是详细讲解了操作步骤,为以后的讲解做一个比较详细的铺垫,更主要的目的是为自己做一个记录,谁都知道我写博客的目的就是为了自己,哈哈~
最后
以上就是风趣果汁为你收集整理的基于Android O8.1的ffmpeg NDK 开发 - 1 - Hello World!的全部内容,希望文章能够帮你解决基于Android O8.1的ffmpeg NDK 开发 - 1 - Hello World!所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复