我是靠谱客的博主 称心烧鹅,这篇文章主要介绍android 引入ffmpeg,现在分享给大家,希望可以做个参考。

上篇介绍了如何 在 mac 系统下打包 ffmpeg 的 so

这篇介绍如何引入 so 到项目中

开发环境:

复制代码
1
2
3
4
macos android studio 3.2.1 ndk: 15.2.4203891

新建一个工程

新建工程时,勾选 c++支持

20190114171810.png

将文件复制到项目内

需要复制的文件

复制代码
1
2
3
.h 头文件 so文件

20190114172127.png

20190114172229.png

在 cpp 中新建一个文件夹include/ffmpeg 把 include 中的文件夹复制到 ffmpeg 下

在 main 下新建文件夹jniLibs,把 so 文件复制到其中
20190114172435.png

修改 CMakeList

完整的CMakeList.txt 如下

复制代码
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# For more information about using CMake with Android Studio, read the # documentation: https://d.android.com/studio/projects/add-native-code.html # Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds them for you. # Gradle automatically packages shared libraries with your APK. # # set(distribution_DIR ${CMAKE_SOURCE_DIR}/src/main/jniLibs) # #set(FFDIR /Users/cai/code/c/ffmpeg-3.3.6/android/arm/lib) include_directories( src/main/cpp/include/ffmpeg ) # ffmpeg 的library add_library( avcodec SHARED IMPORTED ) set_target_properties( avcodec PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavcodec-57.so ) add_library( avdevice SHARED IMPORTED ) set_target_properties( avdevice PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavdevice-57.so ) add_library( avfilter SHARED IMPORTED ) set_target_properties( avfilter PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavfilter-6.so ) add_library( avformat SHARED IMPORTED ) set_target_properties( avformat PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavformat-57.so ) add_library( avutil SHARED IMPORTED ) set_target_properties( avutil PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavutil-55.so ) add_library( swresample SHARED IMPORTED ) set_target_properties( swresample PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswresample-2.so ) add_library( swscale SHARED IMPORTED ) set_target_properties( swscale PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswscale-4.so ) # ffmpeg 的library end # Searches for a specified prebuilt library and stores the path as a # variable. Because CMake includes system libraries in the search path by # default, you only need to specify the name of the public NDK library # you want to add. CMake verifies that the library exists before # completing its build. find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log) add_library( # Sets the name of the library. native-lib # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). src/main/cpp/native-lib.cpp ) # Specifies libraries CMake should link to your target library. You # can link multiple libraries, such as libraries you define in this # build script, prebuilt third-party libraries, or system libraries. target_link_libraries( # Specifies the target library. native-lib # ffmpeg 相关库 avcodec avdevice avfilter avformat avutil swresample swscale # # Links the target library to the log library # included in the NDK. ${log-lib})

简单解释下:

复制代码
1
2
3
# 设置so文件的目录 set(distribution_DIR ${CMAKE_SOURCE_DIR}/src/main/jniLibs)
复制代码
1
2
3
4
5
# 引入头文件 include_directories( src/main/cpp/include/ffmpeg )
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#视为一组 # 第一个为库名称,类型,已导入 add_library( avcodec SHARED IMPORTED ) # 库名称, 属性名称, 文件路径 set_target_properties( avcodec PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavcodec-57.so )
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 这两个是新建项目时自带的, 这个应该是ndk中的库 find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log) add_library( # Sets the name of the library. native-lib # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). src/main/cpp/native-lib.cpp )
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 最后是连接到项目中 target_link_libraries( # Specifies the target library. native-lib # ffmpeg 相关库 avcodec avdevice avfilter avformat avutil swresample swscale # # Links the target library to the log library # included in the NDK. ${log-lib})

作用解释没有那么准确,大概理解意思就行

修改 cpp/kotlin 文件

新建项目时会有一个 cpp 文件,

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <jni.h> #include <string> // 这里的导入是我们新建的 extern "C" { #include <libavutil/log.h> #include <libavformat/avformat.h> } extern "C" JNIEXPORT jstring JNICALL Java_top_kikt_ffmpegandroidexample_MainActivity_stringFromJNI( JNIEnv *env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); } // 这里是我们自己新建的方法 extern "C" JNIEXPORT jint JNICALL Java_top_kikt_ffmpegandroidexample_MainActivity_dumpInfo( JNIEnv *env, jobject) { av_log_set_level(AV_LOG_DEBUG); av_register_all(); return 1; }

有 2 个方法,第二个是我们自定义的, 导包部分引入了 avutil 和 avformat 的头文件

这里有一点要格外注意 extern "C" 我们必须要用这个,这个是在 cpp 中使用 c 文件的必备方法

不然在运行时会报错,当然如果你本身是 c 文件就不存在这个问题了


然后修改 kotlin 文件

复制代码
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
package top.kikt.ffmpegandroidexample import android.os.Bundle import android.support.v7.app.AppCompatActivity import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Example of a call to a native method sample_text.text = stringFromJNI() sample_text.text = dumpInfo().toString() } /** * A native method that is implemented by the 'native-lib' native library, * which is packaged with this application. */ external fun stringFromJNI(): String external fun dumpInfo(): Int companion object { // Used to load the 'native-lib' library on application startup. init { System.loadLibrary("native-lib") System.loadLibrary("avformat") System.loadLibrary("avutil") } } }

这里可以看到我们输出的内容来源于自己新建的内容 dumpInfo 会调用到刚刚在 cpp 中定义的第二个方法,并且运行时 loadLibrary 也没有报找不到 so 的异常, 这就说明成功了

后记

本篇在 android 项目中引入了 ffmpeg ,完成了这一步的跨越后,很多 ffmpeg 的功能就可以自己写 jni 方法来调用了!

比如直播,滤镜,yuv 处理等等,依托于 ffmpeg 强大的生态,音视频领域可以说有大半可做了!

最后

以上就是称心烧鹅最近收集整理的关于android 引入ffmpeg的全部内容,更多相关android内容请搜索靠谱客的其他文章。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部