diff --git a/ruoyi-video/pom.xml b/ruoyi-video/pom.xml
index eee5339..889f26a 100644
--- a/ruoyi-video/pom.xml
+++ b/ruoyi-video/pom.xml
@@ -67,14 +67,47 @@
2.6
-
+
+
+
+
+
+
+
+
+
+
- sunjce_provider
- sunjce_provider
- 0.0.1
- system
- ${project.basedir}/src/main/resources/libs/arcsoft-sdk-face-3.0.0.0.jar
-
+ org.bytedeco
+ javacv-platform
+ 1.5.10
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.17.1
+
+
+
+ org.bytedeco
+ javacv-platform
+ 1.5.10
+
+
+
+
+ org.bytedeco
+ opencv-platform
+ 4.9.0-1.5.10
+
+
+
+
+ org.bytedeco
+ ffmpeg-platform
+ 6.1.1-1.5.10
diff --git a/ruoyi-video/src/main/java/com/ruoyi/video/common/ModelManager.java b/ruoyi-video/src/main/java/com/ruoyi/video/common/ModelManager.java
new file mode 100644
index 0000000..253662a
--- /dev/null
+++ b/ruoyi-video/src/main/java/com/ruoyi/video/common/ModelManager.java
@@ -0,0 +1,47 @@
+package com.ruoyi.video.common;
+
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.ruoyi.video.thread.detector.*;
+import java.net.URL;
+import java.nio.file.*;
+import java.util.*;
+
+public final class ModelManager implements AutoCloseable {
+ private final Map map = new LinkedHashMap<>();
+
+ public void load(URL modelsJson) throws Exception {
+ ObjectMapper om = new ObjectMapper();
+ ArrayNode arr = (ArrayNode) om.readTree(modelsJson);
+
+ // 简易调色板(不同模型不同颜色)
+ int[] palette = {0x00FF00, 0xFF8000, 0x00A0FF, 0xFF00FF, 0x00FFFF, 0xFF0000, 0x80FF00};
+
+ int i=0;
+ for (var node : arr) {
+ String name = node.get("name").asText();
+ String path = node.get("path").asText();
+ int w = node.get("size").get(0).asInt();
+ int h = node.get("size").get(1).asInt();
+ String backend = node.get("backend").asText();
+
+ URL dirUrl = Objects.requireNonNull(getClass().getClassLoader().getResource(path),
+ "Resource not found: " + path);
+ Path dir = Paths.get(dirUrl.toURI());
+
+ int rgb = palette[i % palette.length]; i++;
+ int bgr = ((rgb & 0xFF) << 16) | (rgb & 0xFF00) | ((rgb >> 16) & 0xFF);
+
+ YoloDetector det = new OpenVinoYoloDetector(name, dir, w, h, backend, bgr);
+ map.put(name, det);
+ }
+ }
+
+ public YoloDetector get(String name){ return map.get(name); }
+ public List all(){ return new ArrayList<>(map.values()); }
+
+ @Override public void close() {
+ map.values().forEach(d -> { try { d.close(); } catch(Exception ignored){} });
+ map.clear();
+ }
+}
diff --git a/ruoyi-video/src/main/java/com/ruoyi/video/domain/Detection.java b/ruoyi-video/src/main/java/com/ruoyi/video/domain/Detection.java
new file mode 100644
index 0000000..a7cf467
--- /dev/null
+++ b/ruoyi-video/src/main/java/com/ruoyi/video/domain/Detection.java
@@ -0,0 +1,6 @@
+package com.ruoyi.video.domain;
+
+import org.bytedeco.opencv.opencv_core.Rect;
+
+public record Detection(String cls, float conf, Rect box, int colorBGR) {
+}
diff --git a/ruoyi-video/src/main/java/com/ruoyi/video/server/FlvHandler.java b/ruoyi-video/src/main/java/com/ruoyi/video/server/FlvHandler.java
index ab5c306..44b0d30 100644
--- a/ruoyi-video/src/main/java/com/ruoyi/video/server/FlvHandler.java
+++ b/ruoyi-video/src/main/java/com/ruoyi/video/server/FlvHandler.java
@@ -99,8 +99,6 @@ public class FlvHandler extends SimpleChannelInboundHandler