ffmpeg 将视频分割为小段

目录

1. 先看一下分割结果

2. MAC安装ffmpeg

3. ffmpeg视频分割命令介绍

4.编写java程序

(1). 调用:

(2). 视频分割的java工具类

5.参考:


1. 先看一下分割结果

视频命名规则:视频i_时间段xx_yy

  • i:第i个视频
  • xx:该段视频的开始时间
  • yy:该段视频的结束时间,如3即3分钟处结束,end表示视频末尾

2. MAC安装ffmpeg

我是在mac下开发的,即在终端输入:

brew install ffmpeg

等一会安装成功即可

3. ffmpeg视频分割命令介绍

/**
 * ffmpeg将视频分割
 * ffmpeg命令eg:
 * 1. ffmpeg -ss 00:00:00 -i test.mp4 -c copy -t  600  output.mp4
 * 此处是将视频test.mp4从00:00:00处分割600s,分割出的视频名字是output.mp4
 * 2. ffmpeg -ss 00:00:00 -t 00:01:30 -i test.mp4 -vcodec copy -acodec copy output.mp4
 * 此处是将视频test.mp4从00:00:00处分割到01:30处,分割出的视频名字是output.mp4
 *
 * 备注:
 * 有些视频裁剪后你会发现可能开始和结束都不是很准确,有可能是从00秒开始,33秒结束。
 * 因为这些视频里30秒处地方刚好不是关键帧,而ffmpeg会在你输入的时间点附近圆整到最接近的关键帧处,然后做接下来的事情。
 *
 * <p>
 * 注释:
 * -ss  指定从什么时间开始分割
 * -i   要分割的视频文件
 * -t   指定需要截取多长时间:
 * 格式如下
 * 1. -t  xx        // 单位 秒,指截取30s
 * 2. -t  00:01:30  // 时:分:秒,指截取到播放时间为01:30处
 * 注意 :-ss 要放在 -i 之前
 * <p>
 */

4.编写java程序

此处我直接把封装好的视频分割的java程序贴出

(1). 调用:

    public static final String VIDEO_PATH = "/Users/amarao/业余/剪辑/电影/我的影片.mp4";
    public static final String OUTPUT_PATH = "/Users/amarao/业余/剪辑/output/";

    public static void main(String[] args) throws IOException {

        // 将VIDEO_PATH分割为3分钟一段,VIDEO_PATH总共29分钟,如果结尾有不足3分钟的拼接的最后一段视频上
        FfmpegDevideVideo.splitVideoFile(VIDEO_PATH, OUTPUT_PATH, 29, 3, true);

    }

(2). 视频分割的java工具类

public class FfmpegDevideVideo {

    /**
     * 将视频分割为小段
     *
     * @param fileName    源文件名字(带路径)
     * @param outputPath  输出文件路径,会在该路径下根据系统时间创建目录,并在此目录下输出段视频
     * @param videoTime   总时间,单位 分钟
     * @param periodTime  小段视频时长 单位 分钟
     * @param merge       true合并,false单独分割 说明:是否将整个视频结尾部分不足一次分割时间的部分,合并到最后一次分割的视频中,即false会比true多生成一段视频
     *
     */
    public static void splitVideoFile(String fileName, String outputPath, float videoTime, int periodTime,  boolean merge) {
        final String TAG = "----------------------------";

        // 在outputPath路径下根据系统时间创建目录
        File file = createFileBySysTime(outputPath);
        if (file == null) {
            System.out.println("分割视频失败,创建目录失败");
            return;
        }
        outputPath = file.getPath() + File.separator; // 更新视频输出目录


        // 计算视频分割的个数
        int count;// 分割为几段
        float remain = 0; // 不足一次剪辑的剩余时间
        if (merge) {
            count = (int) (videoTime / periodTime);
            remain = videoTime % periodTime; // 不足一次剪辑的剩余时间
        } else {
            count = (int) (videoTime / periodTime) + 1;
        }
        System.out.println("将视频分割为" + count + "段,每段约" + periodTime + "分钟");

        String indexName; // 第 i 个视频,打印日志用
        final String FFMPEG = "ffmpeg";
        String startTime; // 每段视频的开始时间
        String periodVideoName; // 每段视频的名字,名字规则:视频i_时间段xx_yy
        float duration; // 每次分割的时长
        String command;// 执行的命令
        // 得到视频后缀 如.mp4
        String videoSuffix = fileName.substring(fileName.lastIndexOf("."));//得到点后面的后缀,包括点
        Runtime runtime = Runtime.getRuntime(); // 执行命令者

        // 将视频分割为count段
        for (int i = 0; i < count; i++) {
            indexName = "第" + i + "个视频";

            // 决定是否将整个视频结尾部分不足一次的时间,合并到最后一次分割的视频中
            if (merge) {
                if (i == count - 1) {
                    duration = periodTime * 60 + remain * 60;// 将整个视频不足一次剪辑的时间,拼接在最后一次剪裁中
                    startTime = periodTime * i + ":00";
                    periodVideoName = "视频" + i + "_时间段" + periodTime * i + "_end" + videoSuffix;
                } else {
                    duration = periodTime * 60;
                    startTime = periodTime * i + ":00";
                    periodVideoName = "视频" + i + "_时间段" + periodTime * i + "_" + periodTime * (i + 1) + videoSuffix;
                }
            } else {
                duration = periodTime * 60;
                startTime = periodTime * i + ":00";
                periodVideoName = "视频" + i + "_时间段" + periodTime * i + "_" + periodTime * (i + 1) + videoSuffix;
            }

            // 执行分割命令
            try {
                // 创建命令
                command = FFMPEG + " -ss " + startTime + " -i " + fileName + " -c copy -t " + duration + " " + outputPath + periodVideoName;

                System.out.println(TAG);
                System.out.println(indexName);
                System.out.println("执行命令:" + command);
                runtime.exec(command);
                System.out.println(indexName + "分割成功");
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println(indexName + "分割失败!!!!!!");
            }
        }

    }

    /**
     * 在指定目录下根据系统时间创建文件夹
     * 文件名字eg:2019-07-02-23-56-31
     *
     * @param path 路径:eg: "/Users/amarao/业余/剪辑/output/";
     *             结果:创建成功/Users/amarao/业余/剪辑/output/2019-07-03-10-28-05
     *             <p>
     *             步骤:
     *             1. 读取系统时间
     *             2. 格式化系统时间
     *             3. 创建文件夹
     *             <p>
     *             参考:http://www.bubuko.com/infodetail-1685972.html
     */
    public static File createFileBySysTime(String path) {

        // 1. 读取系统时间
        Calendar calendar = Calendar.getInstance();
        Date time = calendar.getTime();

        // 2. 格式化系统时间
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
        String fileName = format.format(time); //获取系统当前时间并将其转换为string类型,fileName即文件名

        // 3. 创建文件夹
        String newPath = path + fileName;
        File file = new File(newPath);
        //如果文件目录不存在则创建目录
        if (!file.exists()) {
            if (!file.mkdir()) {
                System.out.println("当前路径不存在,创建失败");
                return null;
            }
        }
        System.out.println("创建成功" + newPath);
        return file;
    }


}

5.参考:

http://yuncode.net/code/c_58c0fcb615db178

https://www.jianshu.com/p/cf1e61eb6fc8

https://blog.csdn.net/wanglf1986/article/details/54092203


 

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Amarao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值