Java实现抓取通道(RTSP或MP4)图片
描述:需要去抓取监控流的一张图片作为监控区域分析图片。
使用技术:ffmpeg
代码实现#
方式一#
- 引入依赖
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5.9</version>
</dependency>
<dependency>
<groupId>org.openpnp</groupId>
<artifactId>opencv</artifactId>
<version>4.5.1-2</version>
</dependency>
- 代码实现
/**
* 抓取通道图片
*
* @param channelUrl 通道地址
* @param type 通道类型
*
* @return 结果
*/
private static String captureChannelPicture(String channelUrl, String type) {
try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(channelUrl);
Java2DFrameConverter converter = new Java2DFrameConverter();){
if("RTSP".equals(type)) {
grabber.setOption("rtsp_transport", "tcp"); // 使用TCP传输协议
}
grabber.setTimeout(5000); // 设置超时时间(毫秒)
grabber.start(); // 启动抓取器
// 抓取第一帧(可能需要多试几次才能获取有效帧)
for (int i = 0; i < 5; i++) {
Frame frame = grabber.grabImage();
if (frame != null) {
BufferedImage bufferedImage = converter.getBufferedImage(frame);
String uuid = UUID.randomUUID().toString().replace("-", "");
String filePath = "/data/app/images/base64/" + uuid + ".jpg";
javax.imageio.ImageIO.write(bufferedImage, "jpg", new File(filePath));
return filePath;
}
}
} catch (Exception e) {
log.error("抓取RTSP图片失败:{}", e.toString());
}
return null;
}
缺点:javacv-platform自带ffmpeg,导致所需jar包非常大,大概有1G多
方式二#
- 部署环境安装ffmpeg
- 代码实现
/**
* 抓取通道图片
* 使用框架执行导致jar包太大,lib大小有1G
*
* @param channelUrl 通道地址
* @param type 通道类型
*
* @return 结果
*/
private static String captureChannelPictureForCmd(String channelUrl, String type) {
String uuid = UUID.randomUUID().toString().replace("-", "");
String filePath = "/data/app/images/base64/" + uuid + ".jpg";
int maxRetries = 3; // 最大重试次数
int retryCount = 0;
while (retryCount < maxRetries) {
try {
// 构建FFmpeg命令
String[] command;
if ("RTSP".equals(type)) {
command = new String[]{
"ffmpeg",
"-i", channelUrl,
"-vframes", "1",
"-update", "1",
"-rtsp_transport", "tcp",
"-timeout", "5000", // 超时时间(毫秒)
filePath
};
} else {
command = new String[]{
"ffmpeg",
"-i", channelUrl,
"-vframes", "1",
"-update", "1",
"-timeout", "5000",
filePath
};
}
// 执行FFmpeg命令
ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();
int exitCode = process.waitFor();
if (exitCode == 0) {
return filePath;
} else {
log.warn("抓取RTSP图片失败,退出码: {}, 尝试重试 {}/{}", exitCode, retryCount + 1, maxRetries);
}
} catch (IOException | InterruptedException e) {
log.warn("抓取RTSP图片失败:{}, 尝试重试 {}/{}", e.toString(), retryCount + 1, maxRetries);
}
retryCount++;
}
log.error("抓取RTSP图片失败,重试次数已达上限");
return null;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了