30.FFmpeg+OpenGLES+OpenSLES播放器实现(四.Android Studio ndk开发环境和CMakeLists脚本编写)

简介: 项目源码FFmpeg开发文档 1.环境配置 ffmpeg库已经编译好了,接下来准备将so引入Android studio进行开发 我们创建一个新的项目,注意在创建过程中这几个选项的勾选 6C~L[SE8UA3Z]JEAFB~CU24.png 勾选添加C++支持,Android studio会自动帮我们做一些配置,后边进行简单的解释 Y%~`T`0D1PM`(`}}$ENC9G2.png C++ Standard:使用哪种 C++ 标准。

项目源码
FFmpeg开发文档

1.环境配置

ffmpeg库已经编译好了,接下来准备将so引入Android studio进行开发
我们创建一个新的项目,注意在创建过程中这几个选项的勾选


img_63bd146ed65b88dba111d66bd1b93d61.png
6C~L[SE8UA3Z]JEAFB~CU24.png

勾选添加C++支持,Android studio会自动帮我们做一些配置,后边进行简单的解释


img_11ccb8adaa9ff48c486098dfe4bb267f.png
Y%~`T`0D1PM`(`}}$ENC9G2.png

C++ Standard:使用哪种 C++ 标准。选择 Toolchain Default 会使用默认的 CMake 设置。有C11和C14两种,我们选择C11

Exceptions Support:如果希望启用对 C++ 异常处理的支持,请选中此复选框。如果启用此复选框,Android Studio 会将 -fexceptions 标志添加到模块级 build.gradle 文件的 cppFlags 中,Gradle 会将其传递到 CMake。

Runtime Type Information Support:(Run-Time Type Identification),通过运行时类型信息程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型。如果希望支持 RTTI,请选中此复选框。如果启用此复选框,Android Studio 会将 -frtti 标志添加到模块级 build.gradle 文件的 cppFlags 中,Gradle 会将其传递到 CMake。

项目创建出来之后,可以看到,项目默认创建了一个调用C++代码的小demo输出一行字符串。在app根目录可以看到一个CMakeLists.txt的文件,这是添加c++支持后默认创建的cmake脚本,我们将使用这个脚本对ffmpeg进行编译

打开app目录下的build.gradle,可以看到下边两项配置

apply plugin: 'com.android.application'

android {
    ...
    defaultConfig {
        ...
        externalNativeBuild {
            cmake {
                //C++标准选择C11之后做的配置
                cppFlags "-std=c++11"
            }
        }
    }
 
    externalNativeBuild {
        cmake {
            //指定的CMakeLists脚本文件的路径
            path "CMakeLists.txt"
        }
    }
}

这是工具自动做好的配置,接下来还需要我们手动做一些处理,来完善ffmpeg编译的环境。
第一. ffmpeg播放视频会涉及到操作内存卡,所以需要配置存储权限,6.0及以上Android版本还要记得动态权限获取的配置,这里不多说

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

第二. 在app main目录下创建jniLibs目录,将我们创建好的so放在这个目录下,或者直接把so放在libs目录下,但是这种方式需要我们在build.gradle中配置路径,这里选用第二种方式


img_49892c35aa8d0df42d15da612be8b5c6.png
dir.png.png

然后打开app下build.gradle文件,在android/defaultConfig节点下添加如下配置,指定so文件的存放目录,默认是jniLibs

      sourceSets{
            //将so放在libs文件夹下,需要指定这个路径,因为默认路径是jniLibs
            main{
                jniLibs.srcDirs=['libs']
            }
        }

还有一点,因为我们只编译了armeabi-v7a版本的ffmpeg,所以需要指定过滤版本,在android/defaultConfig/externalNativeBuild节点中添加

           ndk{
                abiFilters "armeabi-v7a"
            }

此时,整个build.gradle文件应该是这样的(只留下了ndk相关的配置)

apply plugin: 'com.android.application'

android {
    ...
    defaultConfig {
        ...
        externalNativeBuild {
            cmake {
                cppFlags "-std=c++11"
            }
            //默认情况下,Gradle 会针对 [NDK 支持的 ABI](https://developer.android.google.cn/ndk/guides/abis.html?hl=zh-cn#sa) 
            //将原生库构建到单独的 .so文件中,并将其全部打包到 APK 中。如果希望 Gradle 仅构建和打包原生
            //库的特定 ABI 配置,可以在模块级build.gradle文件中使用 ndk.abiFilters标志指定这些配置
            ndk{
                //abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a'
                abiFilters "armeabi-v7a"
            }
        }
        sourceSets{
            //将so放在libs文件夹下,需要指定这个路径,因为默认路径是jniLibs
            main{
                jniLibs.srcDirs=['libs']
            }
        }
    }
    ...
    //将 Gradle 关联到原生库,需要提供一个指向 CMake 或 ndk-build 脚本文件的路径。在构建应用时,Gradle
    //会以依赖项的形式运行 CMake 或 ndk-build,并将共享的库打包到 APK 中
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}

dependencies {
    ...
}

2.CMakeLists.txt脚本文件的编写

CMake 构建脚本是一个纯文本文件,必须将其命名为 CMakeLists.txt,一般放在项目根目录(app的根目录),后边会附上我测试成功的CMakeLists.txt,
CMakeLists Android官方教程

add_library():

该命令用于向CMake构建脚本添加源文件和库,它有三个参数,每个参数的解释如下

add_library(
             //这个参数指定你的源文件被编译或者库被引入后的名字,可以指
             //定任意你觉得合适的名字
             native-lib
             //第二个参数有STATIC 和SHARED两种选择,SHARED表示会编
             //译成动态库,STATIC 表示静态库
             SHARED
             //这个位置用于指定源文件的相对路径(相对于CMakeLists.txt的
             //路径),或者如果你是在引入其他库,那么这里指定IMPORTED
             //属性
             src/main/cpp/native-lib.cpp )
set_target_properties:

如果你add_library引入的是已经编译好的库文件,那么你需要通过set_target_properties指定被引入的库文件的路径

//这两个一一对应,这两个命令结合可以引入一个so库,一个so库对应这两个命令
add_library(
              avcodec 
              SHARED 
              IMPORTED)
set_target_properties(
              //指定是给谁设置属性,这里是上边add的avcodec 
              avcodec 
              //指定是设置什么样的属性,这里是引入的路径,是一个相对路径
              PROPERTIES IMPORTED_LOCATION          
              //这里具体指定相对于脚本文件的路径
              ${FFMPEG_DIR}/libavcodec.so)
include_directories():

通过上边两个命令,库文件会被添加进来,这些库一般会依赖一些头文件,这时我们可以通过include_directories来指定头文件的位置,确保 CMake 在编译时可以定位到头文件

include_directories(
              ${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp/include)

以ffmpeg的编译为例,我们会add很多的so库,add_library了好多次,将所有需要的so添加,我们还add了自己的源文件,最终我们指定了这些源文件被编译成ffmpeg的so

add_library(
            ffmpeg 
            SHARED 
            ${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp/native-lib.cpp )

这些源文件依赖于添加的ffmpeg中的库,所以最终我们要把我们自己编译的库和其他这些so链接到一块,这时就需要命令

target_link_libraries( 
              ffmpeg 
              avcodec 
              avfilter 
              avformat 
              avutil 
              swresample 
              swscale 
              ${log-lib} )

看到这里有个这样的引入${log-lib},这个库是ndk中提供的,通过find_library命令引入

find_library

Android NDK 提供了一套实用的原生 API 和库。通过将NDK 库包含到项目的 CMakeLists.txt脚本文件中,预构建的 NDK 库已经存在于 Android 平台上,因此,无需再构建或将其打包到 APK 中。由于 NDK 库已经是 CMake 搜索路径的一部分,甚至不需要在本地 NDK 安装中指定库的位置 - 只需要向 CMake 提供希望使用的库的名称,并将其关联到自己的原生库上即可。

将 find_library()命令添加到您的 CMake 构建脚本中以定位 NDK 库,并将其路径存储为一个变量。可以使用此变量在构建脚本的其他部分引用 NDK 库。以下示例可以定位Android 特定的日志支持库并将其路径存储在 log-lib 中

find_library( log-lib log )
3.编译ffmpeg的CMakeLists.txt完整脚本
#指定Cmake构建工具的最低版本
cmake_minimum_required(VERSION 3.4.1)

#设置头文件路径
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp/include)

#设置FFmpeg库路径变量
#CMAKE_CURRENT_SOURCE_DIR,指的是当前处理的 CMakeLists.txt 所在的路径,CMAKE_SOURCE_DIR,不论采用何种编译方式,都是工程顶层目录

set(FFMPEG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libs/${ANDROID_ABI})

#添加avcodec
add_library(avcodec SHARED IMPORTED)
set_target_properties(avcodec PROPERTIES IMPORTED_LOCATION ${FFMPEG_DIR}/libavcodec.so)

#添加avfilter
add_library(avfilter SHARED IMPORTED)
set_target_properties(avfilter PROPERTIES IMPORTED_LOCATION ${FFMPEG_DIR}/libavfilter.so)

#添加avformat
add_library(avformat SHARED IMPORTED)
set_target_properties(avformat PROPERTIES IMPORTED_LOCATION ${FFMPEG_DIR}/libavformat.so)

#添加avutil
add_library(avutil SHARED IMPORTED)
set_target_properties(avutil PROPERTIES IMPORTED_LOCATION ${FFMPEG_DIR}/libavutil.so)

#添加swresample
add_library(swresample SHARED IMPORTED)
set_target_properties(swresample PROPERTIES IMPORTED_LOCATION ${FFMPEG_DIR}/libswresample.so)

#添加swscale
add_library(swscale SHARED IMPORTED)
set_target_properties(swscale PROPERTIES IMPORTED_LOCATION ${FFMPEG_DIR}/libswscale.so)

add_library( ffmpeg SHARED ${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp/native-lib.cpp )

find_library( log-lib log )

target_link_libraries( ffmpeg avcodec avfilter avformat avutil swresample swscale ${log-lib} )
相关文章
|
29天前
|
SQL 人工智能 Dart
Android Studio的插件生态非常丰富
Android Studio的插件生态非常丰富
42 1
|
29天前
|
Ubuntu Linux Android开发
Android Studio支持多种操作系统
Android Studio支持多种操作系统
57 1
|
29天前
|
前端开发 数据处理 Android开发
Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍
本文深入探讨了Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍,以及具体操作步骤、常见问题解决、高级调试技巧、团队协作中的调试应用和未来发展趋势,旨在帮助开发者提高调试效率,提升应用质量。
46 8
|
29天前
|
数据可视化 开发工具 Android开发
Android Studio
Android Studio
85 1
|
2月前
|
Java 程序员 开发工具
Android|修复阿里云播放器下载不回调的问题
虽然 GC 带来了很多便利,但在实际编码时,我们也需要注意对象的生命周期管理,该存活的存活,该释放的释放,避免因为 GC 导致的问题。
40 2
|
2月前
|
编译器 Android开发
配置环境变量,使CMakeLists.txt可直接使用Android NDK工具链编译项目
配置环境变量,使CMakeLists.txt可直接使用Android NDK工具链编译项目
|
Android开发 C++
【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )(二)
【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )(二)
229 0
【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )(二)
|
Ubuntu 编译器 Android开发
【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )(一)
【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )(一)
232 0
【Android FFMPEG 开发】Android Studio 工程配置 FFMPEG ( 动态库打包 | 头文件与函数库拷贝 | CMake 脚本配置 )(一)
|
16天前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
40 19
|
16天前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
41 14
下一篇
DataWorks