在 Java 中将视频分割成更小的定时片段
Split video into smaller timed segments in Java
我希望拍摄大型视频文件(3 小时以上)并传入我想要分割的视频片段。
例如,我可以传入一个 3 小时的视频 - 并希望将 00:10 到 00:11 分成一个单独的文件。
我目前有以下代码 - 获取我的视频并将其拆分为一个拆分号。的片段,但我将如何改为按时间分割视频?
代码:
try {
File file = new File("//Users//robeves//Desktop//Videos to split//TestVideo.mp4");//File read from Source folder to Split.
if (file.exists()) {
String videoFileName = file.getName().substring(0, file.getName().lastIndexOf(".")); // Name of the videoFile without extension
File splitFile = new File("//Users//robeves//Desktop//Videos to split//Converted//"+ videoFileName);//Destination folder to save.
if (!splitFile.exists()) {
splitFile.mkdirs();
System.out.println("Directory Created -> "+ splitFile.getAbsolutePath());
}
int i = 01;// Files count starts from 1
InputStream inputStream = new FileInputStream(file);
String videoFile = splitFile.getAbsolutePath() +"/"+ String.format("%02d", i) +"_"+ file.getName();// Location to save the files which are Split from the original file.
OutputStream outputStream = new FileOutputStream(videoFile);
System.out.println("File Created Location: "+ videoFile);
int totalPartsToSplit = 20;// Total files to split.
int splitSize = inputStream.available() / totalPartsToSplit;
int streamSize = 0;
int read = 0;
while ((read = inputStream.read()) != -1) {
if (splitSize == streamSize) {
if (i != totalPartsToSplit) {
i++;
String fileCount = String.format("%02d", i); // output will be 1 is 01, 2 is 02
videoFile = splitFile.getAbsolutePath() +"/"+ fileCount +"_"+ file.getName();
outputStream = new FileOutputStream(videoFile);
System.out.println("File Created Location: "+ videoFile);
streamSize = 0;
}
}
outputStream.write(read);
streamSize++;
}
inputStream.close();
outputStream.close();
System.out.println("Total files Split ->"+ totalPartsToSplit);
} else {
System.err.println(file.getAbsolutePath() +" File Not Found.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
如果您确实希望能够单独播放片段,那么如果只是在任意点分割文件,那么上面的代码可能无法工作,因为许多视频格式需要很好地完成 'boundary' 以启用正确播放。
正如 Binkan 所建议的那样,使用像 ffmpeg 这样的视频库,无论是在 cmd 行、包装 cmd 行中还是通过使用其关联的 C 库,都可以让您安全地以大多数常见格式分割视频。
例如,以下 ffmpeg cmd 行将从 mp4 视频创建片段:
ffmpeg -i inputVideo.mp4 -ss 00:00:00 -t 00:00:10 -c copy outputVideoSegment.mp4
以下代码在 'wrapper' 中使用此实用程序将视频文件分割成块:
int chunkSize = videoDurationSecs/(numberOfChunks + 1);
int startSecs = 0;
for (int i=0; i<numberOfChunks; i++) {
//Create video chunk
String startTime = convertSecsToTimeString(startSecs);
int endSecs = startSecs + ((i+1)*chunkSize);
if (endSecs > videoDurationSecs) {
//make sure rounding does not mean we go beyond end of video
endSecs = videoDurationSecs;
}
String endTime = convertSecsToTimeString(endSecs);
//Call ffmpeg to create this chunk of the video using a ffmpeg wrapper
String argv[] = {"ffmpeg", "-i", videoPath,
"-ss",startTime, "-t", endTime,
"-c","copy", segmentVideoPath[i]};
int ffmpegWrapperReturnCode = ffmpegWrapper(argv);
}
String convertSecsToTimeString(int timeSeconds) {
//Convert number of seconds into hours:mins:seconds string
int hours = timeSeconds / 3600;
int mins = (timeSeconds % 3600) / 60;
int secs = timeSeconds % 60;
String timeString = String.format("%02d:%02d:%02d", hours, mins, secs);
return timeString;
}
这里有包装器的例子,但是如果你不想使用包装器方法,你也可以直接使用 ffmpeg 库(它的缺点是 ffmpeg cmd 行并不是真的打算用这种方式包装):
我希望拍摄大型视频文件(3 小时以上)并传入我想要分割的视频片段。
例如,我可以传入一个 3 小时的视频 - 并希望将 00:10 到 00:11 分成一个单独的文件。
我目前有以下代码 - 获取我的视频并将其拆分为一个拆分号。的片段,但我将如何改为按时间分割视频?
代码:
try {
File file = new File("//Users//robeves//Desktop//Videos to split//TestVideo.mp4");//File read from Source folder to Split.
if (file.exists()) {
String videoFileName = file.getName().substring(0, file.getName().lastIndexOf(".")); // Name of the videoFile without extension
File splitFile = new File("//Users//robeves//Desktop//Videos to split//Converted//"+ videoFileName);//Destination folder to save.
if (!splitFile.exists()) {
splitFile.mkdirs();
System.out.println("Directory Created -> "+ splitFile.getAbsolutePath());
}
int i = 01;// Files count starts from 1
InputStream inputStream = new FileInputStream(file);
String videoFile = splitFile.getAbsolutePath() +"/"+ String.format("%02d", i) +"_"+ file.getName();// Location to save the files which are Split from the original file.
OutputStream outputStream = new FileOutputStream(videoFile);
System.out.println("File Created Location: "+ videoFile);
int totalPartsToSplit = 20;// Total files to split.
int splitSize = inputStream.available() / totalPartsToSplit;
int streamSize = 0;
int read = 0;
while ((read = inputStream.read()) != -1) {
if (splitSize == streamSize) {
if (i != totalPartsToSplit) {
i++;
String fileCount = String.format("%02d", i); // output will be 1 is 01, 2 is 02
videoFile = splitFile.getAbsolutePath() +"/"+ fileCount +"_"+ file.getName();
outputStream = new FileOutputStream(videoFile);
System.out.println("File Created Location: "+ videoFile);
streamSize = 0;
}
}
outputStream.write(read);
streamSize++;
}
inputStream.close();
outputStream.close();
System.out.println("Total files Split ->"+ totalPartsToSplit);
} else {
System.err.println(file.getAbsolutePath() +" File Not Found.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
如果您确实希望能够单独播放片段,那么如果只是在任意点分割文件,那么上面的代码可能无法工作,因为许多视频格式需要很好地完成 'boundary' 以启用正确播放。
正如 Binkan 所建议的那样,使用像 ffmpeg 这样的视频库,无论是在 cmd 行、包装 cmd 行中还是通过使用其关联的 C 库,都可以让您安全地以大多数常见格式分割视频。
例如,以下 ffmpeg cmd 行将从 mp4 视频创建片段:
ffmpeg -i inputVideo.mp4 -ss 00:00:00 -t 00:00:10 -c copy outputVideoSegment.mp4
以下代码在 'wrapper' 中使用此实用程序将视频文件分割成块:
int chunkSize = videoDurationSecs/(numberOfChunks + 1);
int startSecs = 0;
for (int i=0; i<numberOfChunks; i++) {
//Create video chunk
String startTime = convertSecsToTimeString(startSecs);
int endSecs = startSecs + ((i+1)*chunkSize);
if (endSecs > videoDurationSecs) {
//make sure rounding does not mean we go beyond end of video
endSecs = videoDurationSecs;
}
String endTime = convertSecsToTimeString(endSecs);
//Call ffmpeg to create this chunk of the video using a ffmpeg wrapper
String argv[] = {"ffmpeg", "-i", videoPath,
"-ss",startTime, "-t", endTime,
"-c","copy", segmentVideoPath[i]};
int ffmpegWrapperReturnCode = ffmpegWrapper(argv);
}
String convertSecsToTimeString(int timeSeconds) {
//Convert number of seconds into hours:mins:seconds string
int hours = timeSeconds / 3600;
int mins = (timeSeconds % 3600) / 60;
int secs = timeSeconds % 60;
String timeString = String.format("%02d:%02d:%02d", hours, mins, secs);
return timeString;
}
这里有包装器的例子,但是如果你不想使用包装器方法,你也可以直接使用 ffmpeg 库(它的缺点是 ffmpeg cmd 行并不是真的打算用这种方式包装):