记录javacv-platform截取rtsp图片和拍摄MP4

引入依赖

 <dependency>
       <groupId>org.bytedeco</groupId>
        <artifactId>javacv-platform</artifactId>
        <version>1.5.7</version>
  </dependency>
  或者单独引入
   <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>ffmpeg-platform</artifactId>
            <version>5.0-1.5.7</version>
            <exclusions>
                <exclusion>
                    <groupId>org.bytedeco</groupId>
                    <artifactId>javacpp</artifactId>
                </exclusion>
            </exclusions>
  </dependency>
 <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>1.5.7</version>
  </dependency>

代码块

截取某一帧成图

 	/**
     * 获取rtsp的某帧图片
     *
     * @param response
     * @return
     */
    public String getMonitorImage(String url) throws IOException {
        FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(url);
        grabber.setOption("rtsp_transport", "tcp");
        grabber.setImageWidth(960);
        grabber.setImageHeight(540);
        grabber.start();
        String currentDir = System.getProperty("user.dir");
        File outPut = new File(currentDir + "\\temp.jpg");
        while (true) {
            Frame frame = grabber.grabImage();
            if (frame != null) {
                ImageIO.write(FrameToBufferedImage(frame), "jpg", outPut);
                grabber.stop();
                grabber.release();
                break;
            }
        }
        String result = TransformPhotoToBase64Data(currentDir, "\\temp.jpg");
        outPut.delete();
        return result;
    }

	/**
     * 图片 转 base64
     *
     * @param LoadPath
     * @param DataName
     * @return
     */

    public String TransformPhotoToBase64Data(String LoadPath, String DataName) {
        //获取Base64编码器
        Base64.Encoder encoder = Base64.getEncoder();
        //数据集缓存器
        byte[] ImgContainer = null;
        //文件输入流
        FileInputStream fileInputStream = null;
        try {
            //到指定路径寻找文件
            fileInputStream = new FileInputStream(LoadPath + DataName);
            //设置图片字节数据缓冲区大小
            ImgContainer = new byte[fileInputStream.available()];
            //将数据流中的图片数据读进缓冲区
            fileInputStream.read(ImgContainer);
            //将图片编码转换成Base64格式的数据集
            String Base64ImgData = encoder.encodeToString(ImgContainer);
            //关闭数据流
            fileInputStream.close();
            //将缓冲区数据转换成字符数据返回
            return Base64ImgData;
        } catch (FileNotFoundException e) {
            return "找不到指定文件!";
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "null";
    }

录制MP4的方法,最好使用异步方法访问,可以返回uuid到前端,前端拿到uuid可以自己操作录制时长,同时也有最大时长的控制

  public static ConcurrentHashMap<String, Object> mp = new ConcurrentHashMap<>();
  		
     public void getMp4FromMonitor(String monitorUrl,String uuid) throws  FrameGrabber.Exception, InterruptedException {
        mp.put(uuid, ***);//唯一标识或是摄像头信息
        FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(monitorUrl);
        grabber.setOption("rtsp_transport", "tcp");
        grabber.setImageWidth(2560);
        grabber.setImageHeight(1440);
        String fileUrl = System.getProperty("user.dir") + "\\" + uuid + ".mp4";
        //流媒体输出地址,分辨率(长,高),是否录制音频(0:不录制/1:录制)
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(fileUrl, 2560, 1440, 1);
        recorder.setFrameRate(15);
        CountDownLatch count = new CountDownLatch(1);
        //最大录制时长控制
        new Thread(() -> {
            try {
                Thread.sleep(40000);
                mp.remove(uuid);
                count.countDown();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }, "setMp4Time").start();
       
        Thread t = new Thread(() -> {
            try {
                grabber.start();
                recorder.start();
                Frame frame = null;
                while (mp.containsKey(uuid) && (frame = grabber.grabFrame()) != null) {
                    recorder.record(frame);
                }
                recorder.stop();
                grabber.stop();
                count.countDown();
            } catch (FrameRecorder.Exception | FrameGrabber.Exception e) {
                System.out.println(uuid);
                throw new RuntimeException(e);
            }
        }, "getMp4");
        t.start();
        //主线程等待
        count.await();
        //防止最大时限后,主线程比录制线程更快执行保存逻辑
        while (!t.getState().equals(Thread.State.TERMINATED)) {
        }
        //调用接口保存mp4 
        ...
    }

    /**
     * 停止录制视频
     *
     * @param uuid
     */
    public void stopRecordMp4(String uuid) throws InterruptedException {
        mp.remove(uuid);
    }

你可能感兴趣的:(java)