我是靠谱客的博主 风趣果汁,这篇文章主要介绍基于Android O8.1的ffmpeg NDK 开发 - 1 - Hello World!,现在分享给大家,希望可以做个参考。

 

很多做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 的路径)

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/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架构的编译脚本如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#/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文件,添加如下内容:

复制代码
1
2
3
ndk { abiFilters 'armeabi-v7a', 'arm64-v8a' }

如图所示:

5. 修改CMakeLists.txt,把ffmpeg的lib库添加进去:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#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文件中,生成如下的函数模板:

复制代码
1
2
3
4
5
6
7
8
9
10
extern "C" JNIEXPORT jstring JNICALL Java_com_example_nxf31081_ffmpeg_1demo_11_MainActivity_string2FromJNI(JNIEnv *env, jobject instance) { // TODO return env->NewStringUTF(returnValue); }

然后我们对其进行稍加修改,返回ffmpeg的编译信息,如下所示:

复制代码
1
2
3
4
5
6
7
8
9
10
11
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()函数添加进去,如下所示:

复制代码
1
tv.setText(string2FromJNI());

最后,直接编译执行,就可以在APP上看到ffmpeg的编译信息了:

 

项目下载地址为:https://github.com/ZER0000/ffmpeg_android_demo.git

 

三. 总结

本篇文章实际的内容不多,主要是详细讲解了操作步骤,为以后的讲解做一个比较详细的铺垫,更主要的目的是为自己做一个记录,谁都知道我写博客的目的就是为了自己,哈哈~

最后

以上就是风趣果汁最近收集整理的关于基于Android O8.1的ffmpeg NDK 开发 - 1 - Hello World!的全部内容,更多相关基于Android内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部