| | |
| | | package com.ruoyi.system.util; |
| | | |
| | | import cn.hutool.core.io.FileUtil; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import org.bytedeco.ffmpeg.global.avcodec; |
| | | import org.bytedeco.ffmpeg.global.avutil; |
| | | import org.bytedeco.javacv.*; |
| | |
| | | |
| | | private static Map<Integer, FFmpegFrameGrabber> grabberMap = new ConcurrentHashMap<>(); |
| | | |
| | | private static Map<Integer, OpenCVFrameGrabber> grabberMap1 = new ConcurrentHashMap<>(); |
| | | |
| | | private static Map<Integer, FFmpegFrameRecorder> frameRecorderMap = new ConcurrentHashMap<>(); |
| | | |
| | | private static Map<Integer, Boolean> statusMap = new ConcurrentHashMap<>(); |
| | |
| | | * 视频拉流和推流 |
| | | */ |
| | | public static void push_flv(String inputUrl, String outputUrl, Integer deviceNumber){ |
| | | // OpenCVFrameGrabber grabber = null; |
| | | FFmpegFrameGrabber grabber = null; |
| | | OpenCVFrameGrabber grabber = null; |
| | | // FFmpegFrameGrabber grabber = null; |
| | | FFmpegFrameRecorder recorder = null; |
| | | try { |
| | | //关闭上一个没有正确关闭的流 |
| | | FFmpegFrameGrabber fFmpegFrameGrabber = grabberMap.get(deviceNumber); |
| | | if(null != fFmpegFrameGrabber){ |
| | | fFmpegFrameGrabber.close(); |
| | | } |
| | | OpenCVFrameGrabber openCVFrameGrabber = grabberMap1.get(deviceNumber); |
| | | if(null != openCVFrameGrabber){ |
| | | openCVFrameGrabber.close();; |
| | | } |
| | | FFmpegFrameRecorder fFmpegFrameRecorder = frameRecorderMap.get(deviceNumber); |
| | | if(null != fFmpegFrameRecorder){ |
| | |
| | | FFmpegLogCallback.set(); |
| | | |
| | | //视频抓帧 |
| | | grabber = new FFmpegFrameGrabber(inputUrl); |
| | | grabber.setOption("rtsp_transport", "tcp"); |
| | | // 正确设置超时时间 |
| | | grabber.setOption("timeout", "120000"); |
| | | grabber.start(); |
| | | grabberMap.put(deviceNumber, grabber); |
| | | |
| | | // grabber = new OpenCVFrameGrabber(0); |
| | | // grabber = new FFmpegFrameGrabber(inputUrl); |
| | | // grabber.setOption("rtsp_transport", "tcp"); |
| | | // // 正确设置超时时间 |
| | | // grabber.setOption("timeout", "120000"); |
| | | // grabber.start(); |
| | | // grabberMap.put(deviceNumber, grabber); |
| | | |
| | | grabber = new OpenCVFrameGrabber(0); |
| | | grabber.start(); |
| | | grabberMap1.put(deviceNumber, grabber); |
| | | |
| | | //录制视频,推送到流媒体服务器(nginx) |
| | | recorder = new FFmpegFrameRecorder(outputUrl, grabber.getImageWidth(), grabber.getImageHeight()); |
| | |
| | | recorder.setAudioOption("crf", "23"); |
| | | |
| | | //设置音频编码为AAC |
| | | // if (grabber.getAudioChannels() > 0) { |
| | | if (grabber.getAudioChannels() > 0) { |
| | | recorder.setAudioChannels(grabber.getAudioChannels()); |
| | | recorder.setAudioBitrate(grabber.getAudioBitrate()); |
| | | recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC); |
| | | // } |
| | | } |
| | | recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); |
| | | //将解码后的帧记录到输出文件中 |
| | | //recorder.start通常用于处理已经解码成图像的视频数据 |
| | | recorder.start(); |
| | | frameRecorderMap.put(deviceNumber, recorder); |
| | | //设置状态为开始 |
| | | statusMap.put(deviceNumber, true); |
| | | |
| | | Frame frame; |
| | | while ((frame = grabber.grab()) != null) { |
| | | recorder.record(frame); |
| | | //判断状态为停止,则结束此线程任务 |
| | | if(!statusMap.get(deviceNumber)){ |
| | | break; |
| | | } |
| | | } |
| | | } catch (FrameGrabber.Exception | FrameRecorder.Exception e) { |
| | | e.printStackTrace(); |
| | | }finally { |
| | | try { |
| | | statusMap.put(deviceNumber, false); |
| | | if(null != grabber){ |
| | | grabber.stop(); |
| | | } |
| | | if(null != recorder){ |
| | | recorder.stop(); |
| | | } |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | close(deviceNumber, null); |
| | | } |
| | | } |
| | | |
| | |
| | | /** |
| | | * 视频拉流和推流 |
| | | */ |
| | | public static void push_hls(String inputUrl, String outputUrl, Integer deviceNumber){ |
| | | public static void push_hls(String inputUrl, String outputUrl, Integer deviceNumber, String folderPath){ |
| | | OpenCVFrameGrabber grabber = null; |
| | | // FFmpegFrameGrabber grabber = null; |
| | | FFmpegFrameRecorder recorder = null; |
| | |
| | | FFmpegFrameGrabber fFmpegFrameGrabber = grabberMap.get(deviceNumber); |
| | | if(null != fFmpegFrameGrabber){ |
| | | fFmpegFrameGrabber.close(); |
| | | } |
| | | OpenCVFrameGrabber openCVFrameGrabber = grabberMap1.get(deviceNumber); |
| | | if(null != openCVFrameGrabber){ |
| | | openCVFrameGrabber.close();; |
| | | } |
| | | FFmpegFrameRecorder fFmpegFrameRecorder = frameRecorderMap.get(deviceNumber); |
| | | if(null != fFmpegFrameRecorder){ |
| | |
| | | |
| | | grabber = new OpenCVFrameGrabber(0); |
| | | grabber.start(); |
| | | grabberMap1.put(deviceNumber, grabber); |
| | | |
| | | //录制视频,推送到流媒体服务器(nginx) |
| | | recorder = new FFmpegFrameRecorder(outputUrl, grabber.getImageWidth(), grabber.getImageHeight()); |
| | |
| | | } catch (FrameGrabber.Exception | FrameRecorder.Exception e) { |
| | | e.printStackTrace(); |
| | | }finally { |
| | | try { |
| | | statusMap.put(deviceNumber, false); |
| | | if(null != grabber){ |
| | | grabber.stop(); |
| | | } |
| | | if(null != recorder){ |
| | | recorder.stop(); |
| | | } |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | close(deviceNumber, folderPath); |
| | | } |
| | | } |
| | | |
| | |
| | | * 关闭推流和拉流进程 |
| | | * @param deviceNumber |
| | | */ |
| | | public static void close(Integer deviceNumber){ |
| | | public static void close(Integer deviceNumber, String folderPath){ |
| | | //设置状态为停止 |
| | | Boolean status = statusMap.get(deviceNumber); |
| | | if(null == status || !status){ |
| | | return; |
| | | } |
| | | statusMap.put(deviceNumber, false); |
| | | FFmpegFrameGrabber fFmpegFrameGrabber = null; |
| | | OpenCVFrameGrabber openCVFrameGrabber = null; |
| | | FFmpegFrameRecorder fFmpegFrameRecorder = null; |
| | | try { |
| | | fFmpegFrameGrabber = grabberMap.get(deviceNumber); |
| | | if(null != fFmpegFrameGrabber){ |
| | | fFmpegFrameGrabber.flush(); |
| | | fFmpegFrameGrabber.close(); |
| | | } |
| | | openCVFrameGrabber = grabberMap1.get(deviceNumber); |
| | | if(null != openCVFrameGrabber){ |
| | | openCVFrameGrabber.flush(); |
| | | openCVFrameGrabber.close(); |
| | | } |
| | | fFmpegFrameRecorder = frameRecorderMap.get(deviceNumber); |
| | | if(null != fFmpegFrameRecorder){ |
| | | fFmpegFrameRecorder.flush(); |
| | | fFmpegFrameRecorder.close(); |
| | | } |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | }finally { |
| | | try { |
| | | fFmpegFrameGrabber = grabberMap.get(deviceNumber); |
| | | if(null != fFmpegFrameGrabber){ |
| | | fFmpegFrameGrabber.close(); |
| | | } |
| | | fFmpegFrameRecorder = frameRecorderMap.get(deviceNumber); |
| | | if(null != fFmpegFrameRecorder){ |
| | | fFmpegFrameRecorder.close(); |
| | | } |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | //开始清除视频文件 |
| | | if(StringUtils.isNotEmpty(folderPath)){ |
| | | FileUtil.del(folderPath); |
| | | } |
| | | } |
| | | } |