美文网首页android
说说Android的视频裁剪(三)

说说Android的视频裁剪(三)

作者: WHOKNOWME | 来源:发表于2017-04-17 19:25 被阅读504次

    有一段时间没有更新博客了。
    最近有人在我的博客中跟我说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库的源码加入到自己的项目中。

    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<String, String> 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.

    相关文章

      网友评论

      • 难得糊涂_dffc:star了 我模拟器上能搜索到视频 但是真机上搜索不到 你加下我QQ 183883324 等你有时间了 教我下怎么压缩 谢谢
      • 62de48dd0dc0:试了好久好像还是不行啊。。。
        62de48dd0dc0:@WHOKNOWME 现在就是mp4的也不行,
        WHOKNOWME:@昵称_759a
        对了,按你的需求,查一下mp4转成mov的ffmpeg命名行参数是什么,对着参数来传参
        WHOKNOWME:@昵称_759a
        哪里不行?你跟踪看一下传的参数是否正确
      • 62de48dd0dc0:非常感谢大神的学习资源,我先试试:+1:

      本文标题:说说Android的视频裁剪(三)

      本文链接:https://www.haomeiwen.com/subject/tydtzttx.html