前言:经过前几篇的介绍,我们已经掌握在linux下编译ffmpeg.so。我们编译出so,目的是为了能够使用so达到使用ffmpeg相关功能的目的。本篇介绍如何在android上直接执行ffmpeg命令行。本文要求读者有一定的jni基础。
一、从源码中拷贝文件至项目(首先确保ffmpeg正确导入进ndk项目):
2、从ffmpeg源码中拷贝如上图的几个文件:
这些文件来自:fftools源码目录
3、修改ffmpeg.c里面的源码:
注释掉main()方法里:
exit_program(received_nb_signals ...);
在下面新增:
nb_filtergraphs = 0;
progress_avio = NULL;
input_streams = NULL;
nb_input_streams = 0;
input_files = NULL;
nb_input_files = 0;
output_streams = NULL;
nb_output_streams = 0;
output_files = NULL;
nb_output_files = 0;
4、修改cmdutils.c文件
修改方法:
int exit_program(int ret)
为:
int exit_program(int ret)
{
// if (program_exit)
// program_exit(ret);
//
// exit(ret);
return ret;
}
5、其余文件不需要进行适配修改,只需要解决对应编译时报错就行,比如:
return hw_device_init_from_string(arg, NULL);报错时,直接修改为:
return 1;
二、编写桥接器文件:itrd_ffmpeg_mp4_merage.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libavutil/avutil.h>
#include <libavcodec/avcodec.h>
#include "ffmpeg.h"
#include "itrd_ffmpeg_mp4_merage.h"
#include <android/log.h>
#define LOG "so"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG,__VA_ARGS__) // 定义LOGD类型
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG,__VA_ARGS__) // 定义LOGI类型
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG,__VA_ARGS__) // 定义LOGW类型
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG,__VA_ARGS__) // 定义LOGE类型
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG,__VA_ARGS__) // 定义LOGF类型
int Ffmpeg_Run(unsigned int argc,unsigned char *argv)
{
LOGD("console_print"); //原生打印
return main(argc,argv); //直接调用ffmpeg.h中的可执行方法
}
三、编写natvie方法
...
#include <ffmpeg/itrd_ffmpeg_mp4_merage.h>
...
JNIEXPORT jint JNICALL Java_com_smarthome_impl_NativeMedia_cmdRun(JNIEnv* env, jobject thiz,jobjectArray commands){
int argc = (*env)->GetArrayLength(env, commands);
char *argv[argc];
int i;
for (i = 0; i < argc; i++) {
jstring js = (jstring) (*env)->GetObjectArrayElement(env, commands, i);
argv[i] = (char*) (*env)->GetStringUTFChars(env, js, 0);
}
LOGD("----------begin---------");
Ffmpeg_Run(argc,argv);
return 1;
}
四、java调用
1、申明
public native int cmdRun(String[] commands);
2、调用(以合并多个mp4视频为例)
String txtFile = createFileText(tempRootPath,originHandlers);
String cmd3= "ffmpeg -f concat -i " + txtFile + " -c copy " + recordPath;
String regulation = "[ \\t]+";
Log.d("mergemp4_cmd:",cmd3);
String[] split = cmd3.split(regulation);
NativeMedia.getInstance().cmdRun(split);
后记:本文讲述了常用的改动的地方,如有疏忽,请检查自己的文件,是否有未修改的地方。
好了,本次专辑(六)就讲到这里了,更多内容,请期待下次的讲述
欢迎有问题的伙伴及时留意讨论,有不足之处还望指正
祝大家生活工作愉快~