From 2e1766b31e889d9ee54d433476d031220dfda294 Mon Sep 17 00:00:00 2001
From: Pu Zhibing <393733352@qq.com>
Date: 星期日, 27 四月 2025 17:46:24 +0800
Subject: [PATCH] 处理异常报错

---
 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/util/JavaCVStreamUtil.java |   92 ++++++++++++++++++++++++++--------------------
 1 files changed, 52 insertions(+), 40 deletions(-)

diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/util/JavaCVStreamUtil.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/util/JavaCVStreamUtil.java
index 58728c7..4356127 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/util/JavaCVStreamUtil.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/util/JavaCVStreamUtil.java
@@ -5,6 +5,7 @@
 import org.bytedeco.ffmpeg.global.avcodec;
 import org.bytedeco.ffmpeg.global.avutil;
 import org.bytedeco.javacv.*;
+import org.springframework.stereotype.Component;
 
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -12,9 +13,11 @@
 /**
  * 音视频推流拉流工具类
  * 参考资料:https://juejin.cn/post/7311230172237561866
+ *
  * @author zhibing.pu
  * @Date 2025/4/8 16:03
  */
+@Component
 public class JavaCVStreamUtil {
 	
 	private static Map<Integer, FFmpegFrameGrabber> grabberMap = new ConcurrentHashMap<>();
@@ -26,26 +29,33 @@
 	private static Map<Integer, Boolean> statusMap = new ConcurrentHashMap<>();
 	
 	
+	public static void main(String[] args) {
+		String url = "rtmp://127.0.0.1:1935/flv/test";
+		JavaCVStreamUtil.push_flv("C:\\Users\\39373\\Desktop\\图片\\trailer.mp4", url, 0);
+	}
+	
+	
+	
 	
 	/**
 	 * 视频拉流和推流
 	 */
-	public static void push_flv(String inputUrl, String outputUrl, Integer deviceNumber){
-		OpenCVFrameGrabber grabber = null;
-//		FFmpegFrameGrabber grabber = null;
+	public static void push_flv(String inputUrl, String outputUrl, Integer deviceNumber) {
+//		OpenCVFrameGrabber grabber = null;
+		FFmpegFrameGrabber grabber = null;
 		FFmpegFrameRecorder recorder = null;
 		try {
 			//关闭上一个没有正确关闭的流
 			FFmpegFrameGrabber fFmpegFrameGrabber = grabberMap.get(deviceNumber);
-			if(null != fFmpegFrameGrabber){
+			if (null != fFmpegFrameGrabber) {
 				fFmpegFrameGrabber.close();
 			}
 			OpenCVFrameGrabber openCVFrameGrabber = grabberMap1.get(deviceNumber);
-			if(null != openCVFrameGrabber){
-				openCVFrameGrabber.close();;
+			if (null != openCVFrameGrabber) {
+				openCVFrameGrabber.close();
 			}
 			FFmpegFrameRecorder fFmpegFrameRecorder = frameRecorderMap.get(deviceNumber);
-			if(null != fFmpegFrameRecorder){
+			if (null != fFmpegFrameRecorder) {
 				fFmpegFrameRecorder.close();
 			}
 			
@@ -54,36 +64,34 @@
 			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.setVideoCodec(avcodec.AV_CODEC_ID_H264);
 			grabber.start();
-			grabberMap1.put(deviceNumber, grabber);
+			grabberMap.put(deviceNumber, grabber);
+
+//			grabber = new OpenCVFrameGrabber(0);
+//			grabber.start();
+//			grabberMap1.put(deviceNumber, grabber);
 			
 			//录制视频,推送到流媒体服务器(nginx)
 			recorder = new FFmpegFrameRecorder(outputUrl, grabber.getImageWidth(), grabber.getImageHeight());
 			recorder.setFormat("flv");
 			// 设置视频比特率
 			recorder.setVideoBitrate(grabber.getVideoBitrate());
-//			// 设置帧率
-//			recorder.setFrameRate(grabber.getVideoFrameRate());
-//			// 设置关键帧间隔
-//			recorder.setGopSize((int) grabber.getVideoFrameRate());
+			// 设置帧率
+			recorder.setFrameRate(grabber.getVideoFrameRate());
+			// 设置关键帧间隔
+			recorder.setGopSize((int) grabber.getVideoFrameRate());
 			// CRF 是一种用于控制视频/音频质量的参数,它允许在保持目标质量的同时动态地调整比特率。较低的CRF值表示更高的质量,但也可能导致较大的文件大小
 			recorder.setAudioOption("crf", "23");
-			
+
 			//设置音频编码为AAC
 			if (grabber.getAudioChannels() > 0) {
 				recorder.setAudioChannels(grabber.getAudioChannels());
 				recorder.setAudioBitrate(grabber.getAudioBitrate());
-				recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
+				recorder.setAudioCodec(grabber.getAudioCodec());
 			}
-			recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
+			recorder.setVideoCodec(avcodec.AV_CODEC_ID_FLV1);
 			//将解码后的帧记录到输出文件中
 			//recorder.start通常用于处理已经解码成图像的视频数据
 			recorder.start();
@@ -95,13 +103,13 @@
 			while ((frame = grabber.grab()) != null) {
 				recorder.record(frame);
 				//判断状态为停止,则结束此线程任务
-				if(!statusMap.get(deviceNumber)){
+				if (!statusMap.get(deviceNumber)) {
 					break;
 				}
 			}
 		} catch (FrameGrabber.Exception | FrameRecorder.Exception e) {
 			e.printStackTrace();
-		}finally {
+		} finally {
 			close(deviceNumber, null);
 		}
 	}
@@ -110,7 +118,7 @@
 	/**
 	 * 视频拉流和推流
 	 */
-	public static void push_hls(String inputUrl, String outputUrl, Integer deviceNumber, String folderPath){
+	public static void push_hls(String inputUrl, String outputUrl, Integer deviceNumber, String folderPath) {
 		OpenCVFrameGrabber grabber = null;
 //		FFmpegFrameGrabber grabber = null;
 		FFmpegFrameRecorder recorder = null;
@@ -118,15 +126,16 @@
 		try {
 			//关闭上一个没有正确关闭的流
 			FFmpegFrameGrabber fFmpegFrameGrabber = grabberMap.get(deviceNumber);
-			if(null != fFmpegFrameGrabber){
+			if (null != fFmpegFrameGrabber) {
 				fFmpegFrameGrabber.close();
 			}
 			OpenCVFrameGrabber openCVFrameGrabber = grabberMap1.get(deviceNumber);
-			if(null != openCVFrameGrabber){
-				openCVFrameGrabber.close();;
+			if (null != openCVFrameGrabber) {
+				openCVFrameGrabber.close();
+				;
 			}
 			FFmpegFrameRecorder fFmpegFrameRecorder = frameRecorderMap.get(deviceNumber);
-			if(null != fFmpegFrameRecorder){
+			if (null != fFmpegFrameRecorder) {
 				fFmpegFrameRecorder.close();
 			}
 			
@@ -177,7 +186,7 @@
 				recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
 			}
 			
-			recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
+			recorder.setVideoCodec(avcodec.AV_CODEC_ID_FLV1);
 			//设置音频编码为AAC
 			if (grabber.getAudioChannels() > 0) {
 				recorder.setAudioChannels(grabber.getAudioChannels());
@@ -194,13 +203,13 @@
 			while ((frame = grabber.grab()) != null) {
 				recorder.record(frame);
 				//判断状态为停止,则结束此线程任务
-				if(!statusMap.get(deviceNumber)){
+				if (!statusMap.get(deviceNumber)) {
 					break;
 				}
 			}
 		} catch (FrameGrabber.Exception | FrameRecorder.Exception e) {
 			e.printStackTrace();
-		}finally {
+		} finally {
 			close(deviceNumber, folderPath);
 		}
 	}
@@ -208,12 +217,13 @@
 	
 	/**
 	 * 关闭推流和拉流进程
+	 *
 	 * @param deviceNumber
 	 */
-	public static void close(Integer deviceNumber, String folderPath){
+	public static void close(Integer deviceNumber, String folderPath) {
 		//设置状态为停止
 		Boolean status = statusMap.get(deviceNumber);
-		if(null == status || !status){
+		if (null == status || !status) {
 			return;
 		}
 		statusMap.put(deviceNumber, false);
@@ -222,26 +232,28 @@
 		FFmpegFrameRecorder fFmpegFrameRecorder = null;
 		try {
 			fFmpegFrameGrabber = grabberMap.get(deviceNumber);
-			if(null != fFmpegFrameGrabber){
+			if (null != fFmpegFrameGrabber) {
 				fFmpegFrameGrabber.flush();
 				fFmpegFrameGrabber.close();
 			}
 			openCVFrameGrabber = grabberMap1.get(deviceNumber);
-			if(null != openCVFrameGrabber){
+			if (null != openCVFrameGrabber) {
 				openCVFrameGrabber.flush();
 				openCVFrameGrabber.close();
 			}
 			fFmpegFrameRecorder = frameRecorderMap.get(deviceNumber);
-			if(null != fFmpegFrameRecorder){
+			if (null != fFmpegFrameRecorder) {
 				fFmpegFrameRecorder.flush();
 				fFmpegFrameRecorder.close();
 			}
-		}catch (Exception e){
+		} catch (Exception e) {
 			e.printStackTrace();
 		}
 		//开始清除视频文件
-		if(StringUtils.isNotEmpty(folderPath)){
+		if (StringUtils.isNotEmpty(folderPath)) {
 			FileUtil.del(folderPath);
 		}
 	}
+	
+	
 }

--
Gitblit v1.7.1