有一段时间没有更新博客了。

最近有人在我的博客中跟我说mp4Parse不能裁剪mov视频,问我有没有其他的解决方案,所以这次我更新了一下自己的项目:Android-Video-Trimmer,使用ffmpeg来实现视频的裁剪。

FFmpeg是为大家所熟悉的处理视频的一个跨平台的开源库,支持android、ios。我们可以自己手动编译不同平台的lib库,从何集成到我们的项目中去。但是FFmpeg是一个C/C++的库,对于熟悉Java开发的Android同学来说,更希望是Java层面的调用。

在我的项目中,集成了一个FFmpegAndroid开发库,这个库优点是我们可以直接用Java的API来执行ffmpge的命令,缺点是该库比较大(大概19M),没办法对库做瘦身缩减工作。下面是我集成这个库的几个步骤。

1. 引入库的方式有两种:aar或者源码依赖

aar依赖:

dependencies {

compile 'com.writingminds:FFmpegAndroid:0.3.2'

}

源码依赖:

用git将ffmpeg-android-javaclone到本地,然后把项目中FFmpegAndroid库的源码加入到自己的项目中。

2cf527f2129f?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

FFmpegAndroid

2.库的初始化

public class ZApplication extends Application {

@Override

public void onCreate() {

super.onCreate();

initFFmpegBinary(this);

}

private void initFFmpegBinary(Context context) {

try {

FFmpeg.getInstance(context).loadBinary(new LoadBinaryResponseHandler() {

@Override

public void onFailure() {

}

});

} catch (FFmpegNotSupportedException e) {

e.printStackTrace();

}

}

}

初始化的目的是根据Android手机的cpu架构,load对应架构的ffmpeg库。

3.执行ffmpeg的commend命令

上面的准备工作做完之后,剩下就是我们关心的问题了,如何执行ffmpeg命令行呢?在前面我已经说了,这个库是对ffmpeg的在Linux系统中命令行的一个封装,所以我们需要在该库中找到一个这样的API。

那我在FFmpegInterface.java类中找到了如下的PAI:

/**

* Executes a command

* @param environvenmentVars Environment variables

* @param cmd command to execute

* @param ffmpegExecuteResponseHandler {@link FFmpegExecuteResponseHandler}

* @throws FFmpegCommandAlreadyRunningException

*/

public void execute(Map environvenmentVars, String[] cmd, FFmpegExecuteResponseHandler ffmpegExecuteResponseHandler) throws FFmpegCommandAlreadyRunningException;

/**

* Executes a command

* @param cmd command to execute

* @param ffmpegExecuteResponseHandler {@link FFmpegExecuteResponseHandler}

* @throws FFmpegCommandAlreadyRunningException

*/

public void execute(String[] cmd, FFmpegExecuteResponseHandler ffmpegExecuteResponseHandler) throws FFmpegCommandAlreadyRunningException;

小伙伴们可以看到参数String[] cmd,就是我所说的控制台的命令行参数,只要将我们的命令行传入,设置好回调,剩下的事情就是静静等着ffmpeg触发我们的回调了,是不是感觉很爽!

下面是我的调用实现:

public static void trimVideo(Context context, String inputFile, String outputFile, long startMs, long endMs, final OnTrimVideoListener callback) {

final String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());

final String outputName = "trimmedVideo_" + timeStamp + ".mp4";

String start = convertSecondsToTime(startMs/1000);

String duration = convertSecondsToTime((endMs - startMs)/1000);

/**ffmpeg -ss START -t DURATION -i INPUT -vcodec copy -acodec copy OUTPUT

-ss 开始时间,如: 00:00:20,表示从20秒开始;

-t 时长,如: 00:00:10,表示截取10秒长的视频;

-i 输入,后面是空格,紧跟着就是输入视频文件;

-vcodec copy 和 -acodec copy 表示所要使用的视频和音频的编码格式,这里指定为copy表示原样拷贝;

INPUT,输入视频文件;

OUTPUT,输出视频文件*/

String cmd = "-ss " + start + " -t " + duration + " -i " + inputFile + " -vcodec copy -acodec copy " + outputFile + "/" + outputName;

String[] command = cmd.split(" ");

try {

FFmpeg.getInstance(context).execute(command, new ExecuteBinaryResponseHandler() {

@Override

public void onFailure(String s) {

}

@Override

public void onSuccess(String s) {

callback.onFinishTrim(null);

}

@Override

public void onStart() {

callback.onStartTrim();

}

@Override

public void onFinish() {

}

});

} catch (FFmpegCommandAlreadyRunningException e) {

// do nothing for now

}

}

上面主要是拼出ffmpeg视频裁剪的命令行参数。

FFmpeg命令大全

视频裁剪的命令如下:

ffmpeg -ss START -t DURATION -i INPUT -vcodec copy -acodec copy OUTPUT

需要主意的是:

DURATION 是表示视频的持续时间而不是结束时间

INPUT 表示输入的包含文件名的文件路径 e.g: sdcard/xxx/xx/input.mp4

OUTPUT 表示输出的包含文件名的文件路径 e.g: sdcard/xxx/xx/output.mov

其他命令也基本也差不多,需要实现什么功能之后可以去查询具体的命令行,对着实现就行。

Thanks for reading. To help others please click ❤ to recommend this article if you found it helpful.

You can also follow me at GitHub.

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐