package com.zhgd.xmgl.util; import lombok.extern.slf4j.Slf4j; import org.bytedeco.javacv.FFmpegFrameGrabber; import org.bytedeco.javacv.Frame; import org.bytedeco.javacv.FrameGrabber; import org.bytedeco.javacv.Java2DFrameConverter; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; @Slf4j public class RtspUtils { private static String RTSP_TRANSPORT_TYPE = "tcp"; /** * 视频帧率 */ private static int FRAME_RATE = 1; /** * 视频宽度 */ // private static int FRAME_WIDTH = 1920; private static int FRAME_WIDTH = 426; /** * 视频高度 */ // private static int FRAME_HEIGHT = 1080; private static int FRAME_HEIGHT = 240; /** * 遍历500次确保实时图片显示正常图片 */ private static int COUNT = 100; /** * 解析视频地址并截图 * * @param path rstp 流地址 * @param picPath 图片存放地址 * @throws Exception */ public static void getVideoImagePathByRSTP(String path, String picPath) throws Exception { //创建rstp流对象 FFmpegFrameGrabber grabber = createGrabber(path); try { //开启流获取 grabber.start(); //由于视频第一帧的流可能为黑屏 为了确保实时能截取到准确图像 // 故此做了个for循环用于覆盖生成图片 for (int i = 0; i < COUNT; i++) { //获取流视频框内的图像 Frame frame = grabber.grabFrame(); //转换图像 Java2DFrameConverter converter = new Java2DFrameConverter(); BufferedImage srcImage = converter.getBufferedImage(frame); if (srcImage != null) { //自定义画图 int w = srcImage.getWidth(); int h = srcImage.getHeight(); int weight = 426; int height = new BigDecimal(weight).divide(new BigDecimal(w), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(h)).setScale(0, RoundingMode.HALF_UP).intValue(); BufferedImage bufferedImage = new BufferedImage(weight, height, BufferedImage.TYPE_3BYTE_BGR); bufferedImage.getGraphics().drawImage(srcImage.getScaledInstance(weight, height, Image.SCALE_SMOOTH), 0, 0, null); //创建文件 File file = new File(picPath); //输出文件 ImageIO.write(bufferedImage, "jpg", file); break; } } } finally { grabber.stop(); grabber.close(); } } /** * 构造视频抓取器 * * @param rtsp 拉流地址 * @return */ private static FFmpegFrameGrabber createGrabber(String rtsp) { // 获取视频源 try { FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(rtsp); //设置传输方式 TCP | UDP grabber.setOption("rtsp_transport", RTSP_TRANSPORT_TYPE); //设置帧率 grabber.setFrameRate(FRAME_RATE); //设置获取的视频宽度 grabber.setImageWidth(FRAME_WIDTH); //设置获取的视频高度 grabber.setImageHeight(FRAME_HEIGHT); // 设置采集器构造超时时间(单位微秒,1秒=1000000微秒) grabber.setOption("stimeout", "2000000000"); //设置视频bit率 // grabber.setVideoBitrate(2000000); // 过滤坏掉的帧 grabber.setVideoOption("skip_frame", "nokey"); // grabber.setOption("Connection", "keep-alive"); // 设置缓冲区大小为1MB grabber.setOption("buffer_size", "10240000"); return grabber; } catch (FrameGrabber.Exception e) { log.error("创建解析rtsp FFmpegFrameGrabber 失败"); log.error("create rtsp FFmpegFrameGrabber exception: ", e); return null; } } public static void main(String[] args) { try { //参数1 rtsp 地址自行获取 参数2 截取图片存放地址 RtspUtils.getVideoImagePathByRSTP("rtsp://222.80.185.228:554/openUrl/uAYM6I0", "C:\\Users\\Administrator\\Desktop\\t\\new\\1000.jpg"); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } }