使用FFmepg对视频进行切片

导入需要的依赖

     <dependency><groupId>org.bytedeco</groupId><artifactId>javacv</artifactId><version>1.4.3</version></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>javacpp</artifactId><version>1.4.3</version></dependency><dependency><groupId>org.bytedeco.javacpp-presets</groupId><artifactId>opencv-platform</artifactId><version>3.4.3-1.4.3</version></dependency><dependency><groupId>org.bytedeco.javacpp-presets</groupId><artifactId>ffmpeg-platform</artifactId><version>4.0.2-1.4.3</version></dependency>
import java.io.File;public class VideoSlicer {public void sliceVideo(String inputFile, String outputDirectory, int segmentDurationInSeconds) {// 创建 FFmpegFrameGrabber 对象FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputFile);try {grabber.start();double frameRate = grabber.getFrameRate();int totalFrameCount = grabber.getLengthInFrames();int segmentFrameCount = (int) Math.ceil(segmentDurationInSeconds * frameRate);int segmentIndex = 0;int frameIndex = 0;// 循环切片视频while (frameIndex < totalFrameCount) {// 创建切片输出目录String segmentOutputDirectory = outputDirectory + "/segment_" + segmentIndex;createDirectory(segmentOutputDirectory);// 设置切片的输出文件路径String segmentOutputFile = segmentOutputDirectory + "/segment_" + segmentIndex + ".ts";// 创建 FFmpegFrameRecorder 对象FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(segmentOutputFile, grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels());recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);recorder.setFormat("mpegts");  // 设置输出格式为 MPEG-TSrecorder.setFrameRate(frameRate);recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);recorder.setSampleRate(grabber.getSampleRate());recorder.setVideoBitrate(grabber.getVideoBitrate());recorder.setAspectRatio(grabber.getAspectRatio());recorder.setAudioBitrate(grabber.getAudioBitrate());recorder.setAudioOptions(grabber.getAudioOptions());recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);recorder.start();// 计算需要捕获的帧数int framesToCapture = Math.min(segmentFrameCount, totalFrameCount - frameIndex);// 捕获帧并写入切片文件for (int i = 0; i < framesToCapture; i++) {Frame frame = grabber.grabFrame();recorder.record(frame);frameIndex++;}// 停止和释放 recorderrecorder.stop();recorder.release();segmentIndex++;}// 创建 M3U8 文件createM3U8File(outputDirectory, segmentIndex);System.out.println("视频切片完成");} catch (FrameGrabber.Exception | FrameRecorder.Exception e) {e.printStackTrace();} finally {try {// 停止和释放 grabbergrabber.stop();grabber.release();} catch (FrameGrabber.Exception e) {e.printStackTrace();}}}// 创建目录private void createDirectory(String directoryPath) {File directory = new File(directoryPath);if (!directory.exists()) {directory.mkdirs();}}// 创建 M3U8 文件private void createM3U8File(String outputDirectory, int segmentCount) {String m3u8Content = "#EXTM3U\n" +"#EXT-X-VERSION:3\n" +"#EXT-X-TARGETDURATION:10\n" +  // 每个切片的目标时长(秒)"#EXT-X-MEDIA-SEQUENCE:0\n" +"#EXT-X-PLAYLIST-TYPE:VOD\n";  // 指定播放列表类型为点播for (int i = 0; i < segmentCount; i++) {String segmentFileName = "segment_" + i + ".ts";String segmentPath = "segment_" + i + "/" + segmentFileName;m3u8Content += "#EXTINF:10.0,\n";  // 每个切片的时长(秒)m3u8Content += segmentPath + "\n";}String m3u8FilePath = outputDirectory + "/playlist.m3u8";File m3u8File = new File(m3u8FilePath);// 写入 M3U8 文件writeTextFile(m3u8File, m3u8Content);}// 写入文本文件private void writeTextFile(File file, String content) {// 实现写入文本文件的逻辑,此处省略}
}

本文链接:https://my.lmcjl.com/post/1548.html

展开阅读全文

4 评论

留下您的评论.