在 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 行并不是真的打算用这种方式包装):