Android 上使用命令运行 有直接导入 ffmpeg.c 源码 和 直接编译 ffmpeg 二进制执行文件,两种方式。
这篇介绍 导入 ffmpeg.c 源码的方式

初始化一个 ffmpeg for android 项目

参见:FFmpeg & Mac & AndroidStudio & CMake 环境搭建

拷贝 ffmpeg.c 文件

从 ffmpeg 源码中找到以下文件:

cmdutils.c
cmdutils.h
cmdutils_common_opts.h
config.h
ffmpeg.h
ffmpeg_filter.c
ffmpeg_opt.c

拷贝至 cpp 目录下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
├── AndroidManifest.xml
├── cpp
│   ├── cmdutils.c
│   ├── cmdutils.h
│   ├── cmdutils_common_opts.h
│   ├── ffmpeg.c
│   ├── ffmpeg.h
│   ├── ffmpeg_box.cpp
│   ├── ffmpeg_filter.c
│   ├── ffmpeg_opt.c
├── java
│   └── cn
└── res
├── drawable
└── values

修改代码

ffmpeg.c ffmpeg.h

修改 main 函数,换成其他什么名字随意。我这里修改成 execute

cmdutils.c cmdutils.h

找到 cmdutils.c 中的 exit_program 函数,删掉函数中原来的内容, 添加 return ret;并修改函数的返回类型为 int

编写 jni

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "ffmpeg.h"

JNIEXPORT jint JNICALL
Java_cn_gavinliu_android_ffmpeg_box_FFmpegBox_execute(
JNIEnv *env,
jobject /* this */, jobjectArray commands) {

int argc = env->GetArrayLength(commands);
char *argv[argc];
int i;
for (i = 0; i < argc; i++) {
jstring js = (jstring) env->GetObjectArrayElement(commands, i);
argv[i] = (char *) env->GetStringUTFChars(js, 0);
}
return execute(argc, argv);
}
1
2
3
4
5
6
7
public void execute(String cmd) {
String[] commands = cmd.split("\\s");
execute(commands);
}

execute("ffmpeg -i xx.mp4 xx.3gp");

源码

https://github.com/gavinliu/FFmpegBox

参考

最简单的基于 FFmpeg 的移动端例子:Android 视频转码器