目录
1. 先看一下分割结果
2. MAC安装ffmpeg
3. ffmpeg视频分割命令介绍
4.编写java程序
(1). 调用:
(2). 视频分割的java工具类
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