Android集成FFmpeg
参考:https://www.jianshu.com/p/2c9918546edc
上一篇文章我们在mac下编译出了供Android平台使用的FFmpeg产物,这篇文章继续讲怎么在Android平台上集成FFmepg。
本文是参考别的文章写的,出处已在文首和文末处说明。之所以说只参考,而不是转载,一是我对原文进行了精简,二是因为我在自己尝试时发现了两个问题,并解决了这两个问题,可以说是一种补充吧。
实现步骤
一、新建工程
在Android Studio中选择新建Native C++功能,我的Android Studio版本是4.1.2
二、导入FFmepg文件
-
在main下新建nativeLibs/armeabi-v7a 目录,将上篇文章的so导入 为什么是nativeLibs而不是jniLibs,是因为我按原文新建jniLibs后编译报错。后经搜索发现在AS升级4.0.1后会有报Android Studio带C++项目提示More than one file was found with OS independent path问题 详见:https://blog.k-res.net/archives/2592.html -
导入头文件 在cpp文件夹下新建ffmpeg/include 目录在其中导入上篇文章中的include文件下的所有文件夹 -
修改CMakeList.txt 注意so文件的目录,本文是nativeLibs
cmake_minimum_required(VERSION 3.10.2)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
set(ffmpeg_lib_dir ${CMAKE_SOURCE_DIR}/../nativeLibs/${ANDROID_ABI})
set(ffmpeg_head_dir ${CMAKE_SOURCE_DIR}/ffmpeg)
include_directories(${ffmpeg_head_dir}/include)
add_library( avutil
SHARED
IMPORTED )
set_target_properties( avutil
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libavutil.so )
add_library( swresample
SHARED
IMPORTED )
set_target_properties( swresample
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libswresample.so )
add_library( avcodec
SHARED
IMPORTED )
set_target_properties( avcodec
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libavcodec.so )
add_library( avfilter
SHARED
IMPORTED)
set_target_properties( avfilter
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libavfilter.so )
add_library( swscale
SHARED
IMPORTED)
set_target_properties( swscale
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libswscale.so )
add_library( avformat
SHARED
IMPORTED)
set_target_properties( avformat
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libavformat.so )
add_library( avdevice
SHARED
IMPORTED)
set_target_properties( avdevice
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libavdevice.so )
find_library(
log-lib
log )
add_library(
native-lib
SHARED
native-lib.cpp
)
target_link_libraries(
native-lib
avutil
swresample
avcodec
avfilter
swscale
avformat
avdevice
${log-lib} )
-
新建测试方法 在nateive-lib.cpp中添加测试方法 这里是我遇到的第二个问题,原文中使用的方法av_codec_next在我这个环境中已经失效了,于是搜索后,找到解决方案:https://www.coder.work/article/1988131 #include <jni.h>
#include <string>
#include <unistd.h>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavfilter/avfilter.h>
#include <libavcodec/jni.h>
JNIEXPORT jstring JNICALL
Java_com_hdym_myapplication_MainActivity_ffmpegInfo(JNIEnv *env, jobject /* this */) {
char info[40000] = {0};
const AVCodec *c_temp = nullptr;
void *i = 0;
while ((c_temp = av_codec_iterate(&i))) {
if (c_temp->decode != NULL) {
sprintf(info, "%sdecode:", info);
switch (c_temp->type) {
case AVMEDIA_TYPE_VIDEO:
sprintf(info, "%s(video):", info);
break;
case AVMEDIA_TYPE_AUDIO:
sprintf(info, "%s(audio):", info);
break;
default:
sprintf(info, "%s(other):", info);
break;
}
sprintf(info, "%s[%10s]\n", info, c_temp->name);
} else {
sprintf(info, "%sencode:", info);
}
}
return env->NewStringUTF(info);
}
}
-
测试使用 import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
companion object {
init {
System.loadLibrary("native-lib")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val tv = findViewById<TextView>(R.id.sample_text)
tv.text = ffmpegInfo()
}
private external fun ffmpegInfo(): String
}
-
运行结果 
以上
参考:https://www.jianshu.com/p/2c9918546edc
|