几种框架的比较:
https://www.zhihu.com/question/278431860

方法一(Fail)

利用MediaMux实现音视频的合成。

效果:可以实现音视频的合并,利用Android原生的VideoView和SurfaceView播放正常,大部分的播放器也播放正常,但是,但是,在上传Youtube就会出现问题:音频不连续,分析主要是上传Youtube时会被再次的压缩,可能在压缩的过程中出现音频的帧率出现问题。

方法二

利用mp4parser实现

mp4parser是一个视频处理的开源工具箱,由于mp4parser里的方法都依靠工具箱里的一些内容,所以需要将这些内容打包成jar包,放到自己的工程里,才能对mp4parser的方法进行调用。

方法三

利用FFmpeg大法

FFmpeg 由于其丰富的 codec 插件,详细的文档说明,并且与其调试复杂量大的编解码代码(是的,用 MediaCodec 实现起来十分啰嗦和繁琐)还是不如调试一行 ffmpeg 命令来的简单。

实现步骤:
1.添加依赖
implementation 'com.googlecode.mp4parser:isoparser:1.1.21'

2.视频裁剪

/**
 * 裁剪视频
 * @param srcPath 需要裁剪的原视频路径
 * @param outPath 裁剪后的视频输出路径
 * @param startTimeMs 裁剪的起始时间
 * @param endTimeMs 裁剪的结束时间
 */
public static void clip(String srcPath, String outPath, double startTimeMs, double endTimeMs) throws IOException, IllegalArgumentException {if (TextUtils.isEmpty(srcPath) || TextUtils.isEmpty(outPath)) {throw new IllegalArgumentException("file path can't be null!!!!");
    }if (!(new File(srcPath).exists())) {throw new IllegalArgumentException("the source file is not exist!!!!");
    }if (startTimeMs >= endTimeMs) {throw new IllegalArgumentException("the startTimeMs is larger than endTimeMs!!!!");
    }Movie movie = MovieCreator.build(srcPath);
    List<Track> tracks = movie.getTracks();
    //移除旧的track
    movie.setTracks(new LinkedList<Track>());
    //处理的时间以秒为单位
    double startTime = startTimeMs/1000;
    double endTime = endTimeMs/1000;
    YDLog.logDebeg(TAG, "--->>>>startTimeMs = " + startTimeMs + "\n endTimeMs = " + endTimeMs + "\n tracks.size = " + tracks.size());
    //计算剪切时间,视频的采样间隔大,以视频为准
    for (Track track : tracks) {if (track.getSyncSamples() != null && track.getSyncSamples().length > 0) {startTime = correctTimeToSyncSample(track, startTime, false);
            endTime = correctTimeToSyncSample(track, endTime, true);
            if (track.getHandler().equals("vide")) {break;
            }}}YDLog.logDebeg(TAG, "--->>>>startTime = " + startTime + "\n endTime = " + endTime);

    long currentSample;
    double currentTime;
    double lastTime;
    long startSample1;
    long endSample1;
    long delta;

    for (Track track : tracks) {currentSample = 0;
        currentTime = 0;
        lastTime = -1;
        startSample1 = -1;
        endSample1 = -1;
//根据起始时间和截止时间获取起始sample和截止sample的位置
        for (int i = 0; i < track.getSampleDurations().length; i++) {delta = track.getSampleDurations()[i];
            if (currentTime > lastTime && currentTime <= startTime) {startSample1 = currentSample;
            }if (currentTime > lastTime && currentTime <= endTime) {endSample1 = currentSample;
            }lastTime = currentTime;
            currentTime += (double)delta / (double)track.getTrackMetaData().getTimescale();
            currentSample++;
        }Log.d(TAG, "track.getHandler() = " + track.getHandler() + "\n startSample1 = " + startSample1 + "\n endSample1 = " + endSample1);
        if (startSample1 <= 0 && endSample1 <= 0) {throw new RuntimeException("clip failed !!");
        }movie.addTrack(new CroppedTrack(track, startSample1, endSample1));// 添加截取的track
    }//合成视频mp4
    Container out = new DefaultMp4Builder().build(movie);
    FileOutputStream fos = new FileOutputStream(outPath);
    FileChannel fco = fos.getChannel();
    out.writeContainer(fco);
    fco.close();
    fos.close();
}

3.视频合成

/**
 * 将 AAC 和 MP4 进行混合[替换了视频的音轨]
 *
 * @param aacPath .aac
 * @param mp4Path .mp4
 * @param outPath .mp4
 */
public static boolean muxAacMp4(String aacPath, String mp4Path, String outPath) {try {AACTrackImpl aacTrack = new AACTrackImpl(new FileDataSourceImpl(aacPath));
        Movie videoMovie = MovieCreator.build(mp4Path);
        Track videoTracks = null;// 获取视频的单纯视频部分
        for (Track videoMovieTrack : videoMovie.getTracks()) {if ("vide".equals(videoMovieTrack.getHandler())) {videoTracks = videoMovieTrack;
            }}Movie resultMovie = new Movie();
        resultMovie.addTrack(videoTracks);// 视频部分
        resultMovie.addTrack(aacTrack);// 音频部分
Container out = new DefaultMp4Builder().build(resultMovie);
        FileOutputStream fos = new FileOutputStream(new File(outPath));
        out.writeContainer(fos.getChannel());
        fos.close();
    } catch (Exception e) {e.printStackTrace();
    }return true;
}

4.合成音视频长度不一样的问题

/***
 * 把视频裁剪15s。然后和音频合并。然后再裁剪15s
 * @param sdCardPath
 */
public static void getMergeVideo(String sdCardPath) {String srcMergePath = sdCardPath + "/4.mp4";//录屏文件
    String aacPath = sdCardPath + "/5.aac";
    Log.d("peng", "onClick:  aacPath" + aacPath);
    String outMergePath = sdCardPath + "/6.mp4";//得到临时的合成的视频文件
    Log.d("peng", "onClick:  outMergePath" + outMergePath);

    long startTime = 0;
    long endTime = 15 * 1000;

    boolean isMux =  VideoClipUtils.muxAacMp4(aacPath, srcMergePath, outMergePath);

    if (isMux) {String outMergeClipPath = sdCardPath + "/7.mp4";
        Log.d("peng", "onClick:  outMergeClipPath" + outMergeClipPath);

        try {VideoClipUtils.clip(outMergePath, outMergeClipPath, startTime, endTime);
            Log.d("peng", "OKKKKKKKK");
        } catch (IOException e) {e.printStackTrace();
        }}
}

遇到的问题:

1.音频和视频合成,他们的长度
     要以视频为准的
2.合成音视频的格式,是否支持,2种方案
方案一:
先全部合并,然后再裁剪15s
方案二:(没有声音)
把视频裁剪15s。然后和音频合并。然后再裁剪15s
方案三:(导致有视频不一定有声音,或者有声音不一定有视频)
视频剪切,音频剪切,音频和视频合并
方法一:
MediaMuxer文件生成:
官方文档:
https://developer.android.google.cn/reference/android/media/MediaMuxer?hl=zh-cn
=========================================================
mp4方案:
https://blog.csdn.net/lxy_tap/article/details/74567282
http://blog.chinaunix.net/uid-20771867-id-4114253.html
使用map4parser作为视频处理包,android studio引入 compile 'com.googlecode.mp4parser:isoparser:1.1.21'//视频处理

2017年4月10日更新:

我发现该框架还有诸多问题和BUG,比如无法合并不同格式(帧率,分辨率)的视频,最近已改用MediaCodec,如果需要做一些比较复杂的处理,还是推荐使用MediaCodec和FFmpeg,后面有时间我会写一写相关的内容。

Android 使用 mp4parser 做视频裁剪

https://blog.csdn.net/u011520181/article/details/84309734

mp4parser (所有的用法-----可以)

https://www.jianshu.com/p/c87ada9b0f65
不错的库:
https://blog.csdn.net/sdvch/article/details/38348411?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param
https://github.com/sannies/mp4parser
Android(java方法)上实现mp4的分割和拼接 (二)
https://www.cnblogs.com/android-blogs/p/5711171.html

Android 3分钟一个库搞定视频替换音频 视频合成 视频裁剪(高仿剪映)相关推荐

  1. Android线程创建aop,【android安卓】一个注解搞定线程切换,基于AOP的线程转换框架...

    最简单的使用方法: 模拟进度展示: @RunOnIOThread public void progress() { for (int i = 0; i <= 100; i++) { showPr ...

  2. 照片宽高比怎么设置_用好PPT插件,三分钟就能搞定一个心形照片墙

    作者丨Jesse 快放寒假了,每年的这个时候,我们学院都会举办毕业班的毕业晚会--因为最后一学期学生们都在外实习,因此毕业晚会都是提前到大四上学期举办. 离别总是伴随着不舍,在晚会开场之前,LED屏上 ...

  3. android sim卡槽,包教包会,十分钟让你搞定与或卡槽

    包教包会,十分钟让你搞定与或卡槽 2016-04-29 11:48:20 27点赞 83收藏 35评论 前言:很多手机厂商为了节省成本都会选择与或卡槽,美其名曰节省内部空间,让你的手机更薄,也有华为m ...

  4. qlv格式的视频转换MP4格式文件,不需要任何软件,一个插件搞定

    qlv格式的视频转换MP4格式文件,不需要任何软件,一个插件搞定 插件法,此法对于网页视频有奇效 亲测:QQ浏览器,应用中心,搜索 猫抓,安装此应用插件,就可以直接下载腾讯视频,而且下载是MP4格式

  5. python利器app怎么查文献-科研人必备:一个工具搞定文献查阅、数据分析、模型搭建...

    原标题:科研人必备:一个工具搞定文献查阅.数据分析.模型搭建 写论文有多难?这首诗形容得好: 进入学校先选题,踌躇满志万人敌:发现前辈都做过,满脸懵逼加惊奇. 终于找到大空白,我真是个小天才:左试右试 ...

  6. 封装一个类搞定90%安卓客户端与服务器端交互

    本实例封装了一个处理安卓客户端与服务器端交互的几个方法,对于中文乱码问题本实例也找到了解决方案.本例可以处理的场景如下: 1.与服务器端交互json数据. 2.Get方式与服务器端交互数据. 3.Po ...

  7. ppt倒计时3分钟_老板发来200页PPT文件,让我翻译成英文,3分钟教你搞定

    过年放假期间,终于可以好好休息几天了,把工作烦恼全部抛在脑后. 如果老板突然发来200页PPT文件,让你翻译成英文,你还在抱怨吗? 下面就来教你两种方法,如何将PPT翻译成英文,3分钟就能搞定. 一. ...

  8. 通用人工智能最新突破!一个Transformer搞定一切

    Datawhale干货 编辑:梦晨 鱼羊,来源:量子位 通用人工智能,还得看DeepMind. 这回,只一个模型,使用相同的权重,不仅把看家本领雅达利游戏玩得飞起. 和人类聊聊天.看图写话也不在话下. ...

  9. 软件测试教程编发中长发,真人教程︱短发、中发、长发的六款速成编发,手残党五分钟就能搞定!...

    原标题:真人教程︱短发.中发.长发的六款速成编发,手残党五分钟就能搞定! 大家好,我是安哥拉·兔. 我之前说过吧,我跟狗哥在家互相剪头发,结果一发不可收拾,我的头发就越来越短了,但我还蛮喜欢现在这样子 ...

最新文章

  1. 多线程 并发编程 看了这篇 终于了解了
  2. 电脑开机进入桌面很慢的解决办法
  3. boost::sort::block_indirect_sort相关的测试程序
  4. linux 命令行使用技巧linux 下的文件管理
  5. GLSL中 Billboard和Point的顶点空间变换
  6. 作者:杨晋吉(1968-),男,华南师范大学计算机学院教授。赵淦森(1977-),男,博士,华南师范大学计算机学院教授、副院长。...
  7. python 访问网站 json_python爬虫用selenium访问一个网址返回的是个json字符串,怎么获取这个json字符串?...
  8. javaweb项目大概轮廓
  9. 学科实践活动感悟50字_学科实践活动写实记录50字3篇
  10. 【图论】 腾讯大战360
  11. 智能问答(Question Answering)的主要研究方向
  12. 让Google搜索结果居中显示
  13. mmdetection(6):Gradient Harmonized Single-stage Detector
  14. Python+Vue计算机毕业设计停车场管理系统8f46a(源码+程序+LW+部署)
  15. 交互式多模型算法IMM——机动目标跟踪中的应用
  16. 业余无线电通信_享年109岁,美国最年长业余无线电爱好者因感染新冠肺炎逝世...
  17. 图灵奖今日出炉,“龙书” 作者、编程语言大佬 Alfred Aho 和 Jeffrey Ullman 获奖
  18. 我的健身日记--序篇
  19. C++浅谈构造函数和析构函数
  20. 微信小程序入门教程之三:脚本编程

热门文章

  1. 流媒体转发服务器的数据传输原理,23.1.1 流媒体传输的基本原理
  2. 火车最少钢轨数问题(概率算法实现,带详细注释C++代码)
  3. 【软件质量】软件一致性
  4. 数据库间表结构对比和数据对比
  5. PTA 黑洞数 C语言
  6. 零时科技 || BEGO Token 攻击事件分析
  7. 对齐标识符C语言,以下正确的C语言标识符是__________。
  8. 商店销售某一商品,商店每天公布统一的折扣(discount)。同时允许销售人员在销售时灵活掌握售价(price),
  9. Linux安装NS3
  10. php数组练习十六道题