Java程序处理视频裁剪(快速处理大文件)

这篇具有很好参考价值的文章主要介绍了Java程序处理视频裁剪(快速处理大文件)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        现在手机上的各种视频裁剪、剪切软件,裁剪视频特别方便。但是遇到大文件需要裁剪的时候,就麻烦了,动辄大几G、十几G的文件就不适合用手机裁剪app了,连上传都成功不了,而且还会被各种压缩,画质失真严重。这个时候,就只能用电脑裁剪了,电脑上还要找付费的视频剪切软件或费时费力找免费软件,就很麻烦了。这里用java程序实现一个视频剪切工具,处理大的视频软件不失真、速度快,轻松搞定大文件视频剪切的需求,非常方便,源码和思路往下看!

0.前期准备

下载并安装ffmpeg,如果电脑上已经有了,就可以忽略这个步骤。 ✈ 直达下载安装ffmpeg

找到解压之后的地址,进入bin目录下,可以看到ffmpeg.exe的文件
java 视频剪辑,音视频处理,Java,java,音视频
工具准备好了,下面开始整代码👇👇👇

1.新建一个java项目

建一个最基本的java项目就行,不需要引第三方的依赖包,jdk自带的方法就够用了,所以不需要建maven项目或springboot项目了。

2.代码生成ffmpeg指令

首先,要验证一下本地的ffmpeg的地址是否存在,只有确实有ffmpeg.exe才可以执行视频裁剪工作。

其次,构造生成ffmpeg的shell指令,用于执行视频裁剪任务。此外,还可以按照自己的规则设置输出文件的名称和地址。

方式一:ffmpeg.exe -ss %s -i %s -t %s -c copy %s -y
ffmpeg.exe -ss 00:00:05 -i test.mp4 -t 00:00:18 -c copy test_new.mp4 -y,说明:从第5秒开始剪辑,裁剪时长为18秒,最终裁剪的时间段应该为(5-23)

方式二:ffmpeg.exe -ss %s -i %s -to %s -c copy %s -y
ffmpeg.exe -ss 00:00:05 -i test.mp4 -to 00:00:18 -c copy test_new.mp4 -y,说明:从第5秒开始剪辑,第18秒为结束时间,最终裁剪的时间段应该为(5-18)

ffmpeg指令参数说明:
ss 起始时间;i 指定要转换的文件;t 裁剪时长;to 截止时间;c 操作方式copy;y 覆盖已存在的文件

踩坑指南:
按照官方的文档说明,正常t是裁剪的时长,to是裁剪的截止时间,但是t和to两种都用了之后,最终结果都是裁剪时长!暂时没找到原因,就先用裁剪时长吧,如果想要用截止时间,简单封装一下也可以

代码贴在这里:

/**
 * ffmpeg相关工具类
 */
public class FFMpegShellUtil {
    /**
     * ffmpeg是否存在
     * @return
     */
    public static boolean isFFMpegReadied() {
        //电脑本地的ffmpeg的地址
        String ffmpegPath = "D:\\ffmpeg\\ffmpeg-5.1.2-full_build-shared\\bin\\ffmpeg.exe";
        File file = new File(ffmpegPath);
        boolean exists = file.exists();
        System.out.println("ffmpeg工具准备状态:" + exists);
        return exists;
    }

    /**
     * 构造ffmpeg指令
     * @param startTime 开始时间 00:01:00
     * @param input     源文件 video.mp4
     * @param durTime   裁剪时长 00:02:00
     */
    public static String createCutShell(String input, String startTime, String durTime) {
        String shell;
        //输出文件名称
        String output = getOutputName(input, startTime, durTime);
        System.out.println("剪辑输出视频文件的地址:"+output);
        //系统名称
        String systemName = getSystemName();
        //ffmpeg指令参数说明(ss 起始时间 | i 指定要转换的文件 | t 裁剪时长 | c 操作方式,copy | y 覆盖已存在的文件)
        if (systemName.contains("windows")) { //windows系统
            shell = String.format("ffmpeg.exe -ss %s -i %s -t %s -c copy %s -y", startTime, input, durTime, output);
        } else { //其他系统
            shell = String.format("ffmpeg -ss %s -i %s -t %s -c copy %s -y", startTime, input, durTime, output);
        }
        return shell;
    }

    /**
     * 获取输出文件名称
     * @param input     源文件 video.mp4
     * @param startTime 开始时间 00:01:00
     * @param durTime   裁剪时长 00:02:00
     * @return
     */
    private static String getOutputName(String input, String startTime, String durTime){
        String[] arr = input.split("\\.");
        String name = arr[0];
        String suffix = arr[1];
        String start = startTime.replaceAll(":","");
        String dur = durTime.replaceAll(":","");
        return name+"_"+start+"_"+dur+"."+suffix;
    }

    /**
     * 获取系统平台名称:windows、linux...
     */
    private static String getSystemName() {
        return System.getProperty("os.name").toLowerCase();
    }
}

3.视频裁剪任务执行

使用Runtime.getRuntime().exec()的方法执行,主要是Java应用生成一个新的进程调用系统外部的的程序,本质上也就是用来执行ffmpeg的shell指令的。

但是这边有个很大的漏洞,使用waitFor()方法时,由于java给进程的输出流分配的缓冲区很小,特别容易发生缓冲区被填满、程序阻塞的问题,错误输出流缓冲区与标准输出流缓冲区会由于清空不及时发生阻塞,异步开两个线程分别去处理标准输出流和错误输出流,可以有效地解决缓冲区信息阻塞的问题,这里使用了两个线程方法threadExec执行!

/**
 * 视频裁剪任务
 */
public class VideoCutTask {

    /**
     * 任务执行
     * @param shell ffmpeg指令
     * @return
     */
    public static void exec(String shell) {
        System.out.println("shell:" + shell);
        BufferedReader bufferedReader = null;
        try {
            Process process = Runtime.getRuntime().exec(shell);

//            bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
//            String line;
//            StringBuilder sb = new StringBuilder();
//            while (null != (line = bufferedReader.readLine())) {
//                if (!line.isEmpty()) {
//                    sb.append(line);
//                }
//            }
//            process.waitFor();

            //使用waitFor()方法时,由于java给进程的输出流分配的缓冲区很小,特别容易发生缓冲区被填满、程序阻塞的问题
            //使用两个线程分别去处理标准输出流和错误输出流,可以有效地解决缓冲区信息阻塞的问题
            threadExec(process.getInputStream());
            threadExec(process.getErrorStream());
            process.waitFor();

            System.out.println("shell执行结束!");
        } catch (IOException e) {
            e.printStackTrace();
            System.err.println("shell执行IOException:" + e.getMessage());
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.err.println("shell执行InterruptedException:" + e.getMessage());
        } finally {
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 分线程执行
     * @param input 输入流
     */
    private static void threadExec(final InputStream input) {
        new Thread(()->{
            BufferedReader bf = new BufferedReader(new InputStreamReader(input));
            String line = null;
            try{
                while(null != (line = bf.readLine())) {
                    System.out.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

4.主程序执行效果展示

main方法处直接执行看生成的效果,需要传入的参数有:【视频源文件路径】、【剪辑开始时间】、【剪辑时长】三个参数,默认输出的文件与源文件放在同一目录下,命名方式不同做区分。

public class Main {

    public static void main(String[] args) {
        //视频源文件路径
        String inputPath = "D:\\videoTest\\trailer.mp4";
        //剪辑开始时间
        String start = "00:00:11";
        //剪辑时长
        String duration = "00:00:25";
        //验证ffmpeg是否就绪
        if (FFMpegShellUtil.isFFMpegReadied()) {
            //创建ffmpeg裁剪指令
            String shell = FFMpegShellUtil.createCutShell(inputPath, start, duration);
            //执行剪辑操作
            VideoCutTask.exec(shell);
        }
    }
}

最后执行的效果,可以看到当前路径下生成一个时长25秒的视频,就是裁剪后的视频,如下图
java 视频剪辑,音视频处理,Java,java,音视频

试着裁剪了个14G的大视频,裁取中间的一段视频,基本都是在秒级时间内完成的,速度非常的快。可以看一下裁剪的日志:

Connected to the target VM, address: '127.0.0.1:49712', transport: 'socket'
ffmpeg工具准备状态:true
剪辑输出视频文件的地址:E:\sjc_011210_000125.mp4
shell:ffmpeg.exe -ss 01:12:10 -i E:\sjc.mp4 -t 00:01:25 -c copy E:\sjc_011210_000125.mp4 -y
ffmpeg version 5.1.2-full_build-www.gyan.dev Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 12.1.0 (Rev2, Built by MSYS2 project)
  configuration: --enable-gpl --enable-version3 --enable-shared --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libaribb24 --enable-libdav1d --enable-libdavs2 --enable-libuavs3d --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libaom --enable-libjxl --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
  libavutil      57. 28.100 / 57. 28.100
  libavcodec     59. 37.100 / 59. 37.100
  libavformat    59. 27.100 / 59. 27.100
  libavdevice    59.  7.100 / 59.  7.100
  libavfilter     8. 44.100 /  8. 44.100
  libswscale      6.  7.100 /  6.  7.100
  libswresample   4.  7.100 /  4.  7.100
  libpostproc    56.  6.100 / 56.  6.100
[mov,mp4,m4a,3gp,3g2,mj2 @ 00000193bc227bc0] Unknown cover type: 0x1.
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'E:\sjc.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 2023-04-25T17:47:04.000000Z
    Hw              : 1
    bitrate         : 16000000
    maxrate         : 0
    te_is_reencode  : 1
    encoder         : Lavf58.76.100
  Duration: 02:34:43.70, start: 0.000000, bitrate: 12996 kb/s
  Stream #0:0[0x1](und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 12796 kb/s, 30 fps, 30 tbr, 30 tbn (default)
    Metadata:
      creation_time   : 2023-04-25T17:47:04.000000Z
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 194 kb/s (default)
    Metadata:
      creation_time   : 2023-04-25T17:47:04.000000Z
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
Output #0, mp4, to 'E:\sjc_011210_000125.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    te_is_reencode  : 1
    Hw              : 1
    bitrate         : 16000000
    maxrate         : 0
    encoder         : Lavf59.27.100
  Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 12796 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
    Metadata:
      creation_time   : 2023-04-25T17:47:04.000000Z
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 194 kb/s (default)
    Metadata:
      creation_time   : 2023-04-25T17:47:04.000000Z
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame=    0 fps=0.0 q=-1.0 size=       0kB time=00:00:00.00 bitrate=N/A speed=   0x    
frame= 1284 fps=0.0 q=-1.0 size=   65792kB time=00:00:43.76 bitrate=12314.9kbits/s speed=87.5x    
frame= 2551 fps=0.0 q=-1.0 Lsize=  130852kB time=00:01:25.00 bitrate=12610.4kbits/s speed=85.4x    
video:128759kB audio:2002kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.070083%
shell执行结束!
Disconnected from the target VM, address: '127.0.0.1:49712', transport: 'socket'

Process finished with exit code 0

这样就实现了用Java程序进行视频裁剪的操作,有兴趣的小伙伴可以试一试!文章来源地址https://www.toymoban.com/news/detail-703996.html

到了这里,关于Java程序处理视频裁剪(快速处理大文件)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • PR剪辑视频做自媒体添加字幕快速方式(简单好用的pr视频字幕模板)

    如何选择合适的字幕添加进短视频呢?首先要先确定增加的视频风格,简约、商务、科技感、炫酷;再确定用途,注释、标记、语音翻译、引用、介绍;最后在相应的模板中挑选几个尝试,悬着一个最切合主题的使用,这里有几个视频字幕合集,可供参考。 16个科技未来数码

    2024年02月04日
    浏览(57)
  • 视频批量高效剪辑,支持将视频文件转换为音频文件,轻松掌握视频格式

    在数字化时代,视频内容日益丰富,管理和编辑这些视频变得愈发重要。然而,传统的视频剪辑软件往往操作复杂,难以满足高效批量处理的需求。现在,一款全新的视频批量剪辑神器应运而生,它支持将视频文件一键转换为音频文件,同时轻松掌握各种视频格式,让你的视

    2024年04月14日
    浏览(67)
  • Java使用javacv处理视频文件过程记录

    最近接到一个需求是将.mp4/.m4v文件体积进行压缩,我使用javacv中的FFmpegFrameGrabber、FFmpegFrameFilter、FFmpegFrameRecorder简单的实现视频帧的抓取、过滤、录制与输出。 性能暂未验证。文章对这次的过程进行记录。 1.jdk的选择 mcr.microsoft.com/java/jdk:8u222-zulu-centos 2.maven依赖 3.实现过程

    2024年04月15日
    浏览(37)
  • AI大模型在短视频处理和剪辑中的应用,文末送书

    🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论⭐收藏 随着智能手机和社交媒体的普及,短视频成

    2024年02月06日
    浏览(54)
  • 简易版剪辑视频程序(python-VideoFileClip)

    很多剪辑软件要收费,自己写了一个。 参数设置: 具体实现: 上面的程序实现的是剪掉最后8s

    2024年02月10日
    浏览(37)
  • sql文件批处理程序-java桌面应用

        支持sql文件夹批处理,选中文件夹或者sql文件 支持测试连接,可以校验数据库配置 支持报错回显,弹出报错文件名以及问题语句 支持在程序中修改错误语句,用户可以选择保存修改内容继续执行或不保存修改只执行 支持动态显示执行进度 支持自动识别文件编码进行解

    2024年02月06日
    浏览(50)
  • 《Java面向对象程序设计》学习笔记——CSV文件的读写与处理

    ​笔记汇总: 《Java面向对象程序设计》学习笔记 笔记记录的不是非常详实,如果有补充的建议或纠错,请踊跃评论留言!!! CSV 是英文 comma-separated values 的缩写,翻译为 “逗号分隔值“。 CSV 文件可以理解为以带逗号分隔(也可以是其他简单字符分割)的纯文本形式存储

    2024年02月10日
    浏览(52)
  • ‘java‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件

    1.‘java’ 不是内部或外部命令,也不是可运行的程序 或批处理文件。 这种情况一般来说是没有配置环境变量或者是没有配置好 (1)找到安装java的位置 (2)进入控制面板==》系统与安全==》系统==》高级设置–》环境变量 2.开始配置 (1)系统变量中新建 变量名:JAVA_HOME 变

    2024年02月07日
    浏览(44)
  • 干货分享|视频制作技巧-视频拍摄/视频剪辑

    前几篇文章盘点了一些电脑、手机、网页视频剪辑软件和工具。尽管有了好上手的工具,可能一些刚入门短视频的朋友还是对怎样制作视频一头雾水。今天我们就抛开工具,从技巧的角度来看看如何入门短视频剪辑。 一、视频制作名词解释 视频制作是将图片、视频及背景音

    2023年04月08日
    浏览(55)
  • 视频素材网,视频剪辑必备。

     视频剪辑没素材,推荐6个网站帮你解决, 免费可商用 ,建议收藏! 1、菜鸟图库 视频素材下载_mp4视频大全 - 菜鸟图库 网站有超多视频素材,全部都是高清无水印,各种类型都有,像自然、城市、动物、科技、商业等等都能找到,分类也很清晰,重点是免费可商用,不用担

    2023年04月25日
    浏览(68)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包