概述
FFmpeg,命令行非常强大。在PC机上,调用一行FFmpeg命令,就可以对视频文件进行剪切、合并、转码等功能。本文将介绍如何在Android中调用FFmpeg命令行。
编译
前面已经有两篇文章介绍FFmpeg的编译:
创建ffmpeg-cmd模块
Step1:目录结构
Step2:导入libffmpeg.so库
在ffmpeg-cmd
模块的build.gradle
中添加配置:
1 | android { |
Step3:导入FFmpeg的相关头文件
Step4: 导入FFmpeg的相关源码文件
在源码目录的
fftools
文件夹内
Step5: 编写CMakeLists.txt文件
1 | cmake_minimum_required(VERSION 3.4.1) |
修改FFmpeg源码
ffmpeg.c
修改main方法:
1
2
3
4
5// 修改前
int main(int argc, char **argv)
// 修改后
int ffmpeg_exec(int argc, char **argv)在
ffmpeg_cleanup
函数执行结束前重新初始化:1
2
3
4
5
6
7
8
9
10static void ffmpeg_cleanup(int ret) {
// 省略其他代码...
nb_filtergraphs = 0;
nb_output_files = 0;
nb_output_streams = 0;
nb_input_files = 0;
nb_input_streams = 0;
}在
print_report
函数中添加代码实现FFmpeg命令执行进度的回调:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time) {
// 省略其他代码...
// 定义已处理的时长
float mss;
secs = FFABS(pts) / AV_TIME_BASE;
us = FFABS(pts) % AV_TIME_BASE;
// 获取已处理的时长
mss = secs + ((float) us / AV_TIME_BASE);
// 调用ffmpeg_progress将进度传到Java层,代码后面定义
ffmpeg_progress(mss);
// 省略其他代码...
}ffmpeg.h
添加
ffmpeg_exec
方法的声明:1
int ffmpeg_exec(int argc, char **argv);
cmdutils.c
修改
exit_program
函数:1
2
3
4
5
6
7
8
9
10void exit_program(int ret) {
if (program_exit)
program_exit(ret);
// 退出线程(该函数后面定义)
ffmpeg_thread_exit(ret);
// 删掉下面这行代码,不然执行结束,应用会crash
//exit(ret);
}
编写JNI调用FFmpeg命令
Note:这部分代码来自开源库 EpMedia
C代码:
ffmpeg_cmd.h
1 |
|
ffmpeg_cmd.c
1 |
|
ffmpeg_thread.h
1 |
|
ffmpeg_thread.c
1 |
|
Java代码:
FFmpegCmd.java
1 | public class FFmpegCmd |
FFmpegUtil.java
1 | // 封装FFmpeg命令的调用 |
CmdList.java
1 | public class CmdList extends ArrayList<String> { |
调用FFmpeg命令
1 | long duration = endTime - startTime; |
源码地址:https://github.com/xch168/VideoEditor