我是靠谱客的博主 风趣果汁,最近开发中收集的这篇文章主要介绍基于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 的路径)

#!/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!所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部