javacv 切割视频
背景
- 要做一个预览视频的功能,把整个视频截取一段出来。没有直接使用FFmpeg,而是使用了javacpp的库。
代码
- 依赖的jar包
<properties>
<javacv>1.4.3</javacv>
<ffmpeg-platform>4.0.2-1.4.3</ffmpeg-platform>
<hutool.version>5.8.5</hutool.version>
</properties>
<dependencies>
<dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
</dependency>
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>ffmpeg-platform</artifactId>
</dependency>
</dependencies>
- 代码实现
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.StrSplitter;
import org.bytedeco.javacpp.Loader;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.bytedeco.javacpp.avcodec;
/**
* @author Zhou Zhongqing
* @ClassName PreviewVideoUtils
* @description: 预览视频
* @date 2023-03-03 14:58
*/
public class PreviewVideoUtils {
/**
* 生成预览视频
*
* @param sourcePath
* @param targetPath
*/
public static void generatePreviewVideo(String sourcePath, String targetPath) {
try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(sourcePath);
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(targetPath, grabber.getImageWidth(), grabber.getImageHeight(), 2)) {
grabber.start();
// 重新设置 宽高
recorder.setImageWidth(grabber.getImageWidth());
recorder.setImageHeight(grabber.getImageHeight());
// 解决生成的视频无法播放的问题
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.setFormat("mp4");
recorder.setFrameRate(grabber.getFrameRate());
recorder.setSampleRate(grabber.getSampleRate());
recorder.setAudioChannels(grabber.getAudioChannels());
recorder.setFrameRate(grabber.getFrameRate());
grabber.setTimestamp(20 * 1000000);
Map<String, Object> filter = MapUtil.filter(BeanUtil.beanToMap(grabber));
BeanUtil.copyProperties(filter, recorder);
recorder.start();
Frame inFrame;
int count = 0;
while ((inFrame = grabber.grab()) != null) {
// System.out.println(inFrame.timestamp);
// if (inFrame.timestamp >= 50 * 1000 * 1000) {
// break;
// }
if (count > 1000) {
break;
}
count++;
recorder.record(inFrame);
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
public static void main(String[] args) {
String inFile = "C:\\Users\\Windows3\\Videos\\test\\trailer.mp4"; //读取的视频
String outFile = "C:\\Users\\Windows3\\Videos\\test\\2.mp4"; //将要生成的剪切视频
generatePreviewVideo(inFile, outFile);
// test();
}
}
效果
- 原视频大约50几秒,转成了只有10几秒的预览视频
遇到的问题
- No video output stream (Is imageWidth > 0 && imageHeight > 0 and has start() been called?)
增加int imageWidth, int imageHeight,参数
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(“C:\Users\Windows3\Videos\2.mp4”, 1280, 720, 2)
参考
- https://segmentfault.com/a/1190000039782685?sort=newest
- https://www.cnblogs.com/wuxun1997/p/12936311.html
- https://my.oschina.net/110NotFound/blog/5336500
- https://juejin.cn/post/6988733165258932261
posted on 2023-03-05 14:41 愤怒的苹果ext 阅读(227) 评论(0) 编辑 收藏 举报 来源