当前位置: 首页 > article >正文

Android 关于使用videocompressor库压缩没有声音的问题

原库地址

https://gitcode.com/gh_mirrors/vi/VideoCompressor/overview
这个库用起来比较方便,使用Android原生的MediaCodec+mp4parser的方式进行压缩,不用接入so库也不用适配cpu

问题

接口库后你会发现过时了,所以你一阵捣鼓后你发现压缩正常但是输出文件没有声音,问题是什么?经过我一天的修改,问题是因为你升级了mp4parser库他接入的是com.googlecode.mp4parser:isoparser:1.0.6不论你升级到什么版本都会出现没有声音的问题,那是因为谷歌的问题,在1.0.6后在编码的时候更加严格,所以你不升级就ok了!

真的不升级?

随着时间的发展旧版本库无法满足需求,性能各方面都是差异,而且这是7年前的库了,所以你必须升级,那么怎么解决问题呢?

分析问题

问题代码

在1.0.6库之前和之后主要的出现问题代码就在createMovie中的创建FileChannel的问题,1.0.6支持你FileOutputStream.getChannel()这样创建但是1.0.6之后不可以这样,这样就会导致音视频无法同步,所以你需要更换创建方法:new RandomAccessFile(destinationPath, "rw").getChannel()其中destinationPath输出文件地址修改了这一行你会发现好了

其他解决思路

这个库的压缩思路:

  1. 获取视频的track,然后利用MediaCodec对原视频进行解码

  2. 获取原视频的宽高、帧率等,进行一定的比例缩放

  3. 在利用MediaCodec进行视频编码,输出一个只有视频没有声音的文件

  4. 在利用相同的方式获取音频的track,然后读取音频读写

  5. 最后对音视频进行合并,他是再同一个输出文件上读写的

  6. 完结
    所以根据上面思路你完全可以分开

  7. 先利用MediaCodec对视频进行压缩,输出到缓存目标文件A

  8. 在读取原文件的音频

  9. 合并两个文件,输出到真正的目录B,这里不可以和缓存目标文件A相同,必须不同的文件

把思路简化下代码大概是这样,是不是很简单,其实思路就这么点代码

    public static void appendMp4List(Context context, Uri sourcePath, String outPutPath) throws Exception {
        VideoInfo videoInfo = VideoUtils.getVideoInfo(context, sourcePath);
        if (videoInfo == null || videoInfo.width() == 0 || videoInfo.height() == 0) {
            return;
        }
        File tempFile = VideoUtils.copyFileToCacheDir(context, sourcePath);
        List<Track> audioTracks = new LinkedList<>();// 音频通道集合
        List<Track> videoTracks = new LinkedList<>();// 视频通道集合

        for (Track inMovieTrack : MovieCreator.build(tempFile.getAbsolutePath()).getTracks()) {
            if ("soun".equals(inMovieTrack.getHandler())) {// 从Movie对象中取出音频通道
                audioTracks.add(inMovieTrack);
            }
            if ("vide".equals(inMovieTrack.getHandler())) {// 从Movie对象中取出视频通道
                videoTracks.add(inMovieTrack);
            }
        }

        Movie resultMovie = new Movie();// 结果Movie对象[输出]
        if (!videoTracks.isEmpty()) {// 将所有视频通道追加合并
            writerVideo(tempFile,videoInfo,outPutPath);//压缩视频,但这样输出的只有视频没有音频
            List<Track> resultVideoTrack = MovieCreator.build(outPutPath).getTracks();
            for(Track videoTrack:resultVideoTrack){
                resultMovie.addTrack(videoTrack);
            }
        }
        if (!audioTracks.isEmpty()) {// 将所有音频通道追加合并
            resultMovie.addTrack(new AppendTrack(audioTracks.toArray(new Track[audioTracks.size()])));
        }
        Container outContainer = new DefaultMp4Builder().build(resultMovie);// 将结果Movie对象封装进容器
        FileChannel fileChannel = new RandomAccessFile(outPutPath, "rw").getChannel();
        outContainer.writeContainer(fileChannel);// 将容器内容写入磁盘
        fileChannel.close();
    }

最终的优化有的代码查看github

https://github.com/fzkf9225/mvvm-componnent-master/tree/master/commonmedia/src/main/java/pers/fz/media/videocompressor


http://www.kler.cn/a/394258.html

相关文章:

  • 基于OpenCV的自制Python访客识别程序
  • sol机器人pump机器人如何实现盈利的?什么是Pump 扫链机器人?
  • HBase使用create创建表时报错ERROR: KeeperErrorCode = NoNode for /hbase/master
  • linux设置主机名
  • 系统上线后发现bug,如何回退版本?已经产生的新业务数据怎么办?
  • 时序数据库TimescaleDB安装部署以及常见使用
  • GOF设计模式中各模式支持的可变方面(封装变化)
  • 远程链接mysql步骤
  • UE5.4 PCG 生成藤蔓墙体
  • Hbase小测
  • 基于Java Springboot快递物流管理系统
  • Leetcode 56-合并区间
  • [JAVAEE] 面试题(五) - HashMap, Hashtable, ConcurrentHashMap
  • 如何确定光伏建设中的最佳安装倾角
  • day08|计算机网络重难点之 DNS查询过程、CDN是什么,有什么作用?、Cookie和Session是什么?有什么区别?
  • 【CSS】opacity 影响 z-index 不生效
  • 【Java语言】String类
  • Spring源码(十二):Spring MVC之Spring Boot
  • PPT技巧:如何合并PPT文件?
  • SpringBoot+MyBatis+MySQL的Point实现范围查找
  • MATLAB用CNN-LSTM神经网络的语音情感分类深度学习研究
  • [DDNS][SSL][HTTPS]阿里云ACME Ubuntu22.04Server 安装教程
  • Mysql每日一题(行程与用户,困难※)
  • Vue3 项目权限控制最佳实践
  • 消息队列系列一:RabbitMQ入门讲解
  • git 提交报错 Error updating changes: bad signature 0x00000000index file corrupt