作者 钟来

完成摄像头本地解码器开发

正在显示 92 个修改的文件 包含 1445 行增加2872 行删除
@@ -5,6 +5,39 @@ import com.zhonglai.luhui.device.analysis.dto.Message; @@ -5,6 +5,39 @@ import com.zhonglai.luhui.device.analysis.dto.Message;
5 /** 5 /**
6 * 回复给前端的消息 6 * 回复给前端的消息
7 */ 7 */
8 -public interface ApiClientRePlyDto {  
9 - void setReplyMessage(Message message); 8 +public class ApiClientRePlyDto {
  9 + private int code;
  10 + private String message;
  11 + private Object data;
  12 +
  13 + public int getCode() {
  14 + return code;
  15 + }
  16 +
  17 + public void setCode(int code) {
  18 + this.code = code;
  19 + }
  20 +
  21 + public String getMessage() {
  22 + return message;
  23 + }
  24 +
  25 + public void setMessage(String message) {
  26 + this.message = message;
  27 + }
  28 +
  29 + public Object getData() {
  30 + return data;
  31 + }
  32 +
  33 + public void setData(Object data) {
  34 + this.data = data;
  35 + }
  36 +
  37 + public void setReplyMessage(Message message)
  38 + {
  39 + message.setData(this.code);
  40 + message.setMessage(this.message);
  41 + message.setData(this.data);
  42 + }
10 } 43 }
1 package com.zhonglai.luhui.api.controller.test; 1 package com.zhonglai.luhui.api.controller.test;
2 2
3 -import cn.hutool.http.HttpRequest;  
4 -import cn.hutool.http.HttpUtil;  
5 -import com.google.gson.JsonArray; 3 +import com.alibaba.fastjson.JSONObject;
6 import com.google.gson.JsonObject; 4 import com.google.gson.JsonObject;
7 import com.ruoyi.common.core.domain.AjaxResult; 5 import com.ruoyi.common.core.domain.AjaxResult;
8 -import com.ruoyi.common.utils.DateUtils; 6 +import com.ruoyi.common.utils.FeishuUtil;
9 import com.ruoyi.common.utils.GsonConstructor; 7 import com.ruoyi.common.utils.GsonConstructor;
10 import com.zhonglai.luhui.api.controller.test.dto.ClueData; 8 import com.zhonglai.luhui.api.controller.test.dto.ClueData;
11 -import com.zhonglai.luhui.api.controller.test.dto.TenantAccessToken;  
12 -import com.zhonglai.luhui.config.requestbodymiss.RequestReaderHttpServletRequestWrapper;  
13 import io.swagger.annotations.Api; 9 import io.swagger.annotations.Api;
14 import io.swagger.annotations.ApiOperation; 10 import io.swagger.annotations.ApiOperation;
15 import org.springframework.util.StreamUtils; 11 import org.springframework.util.StreamUtils;
@@ -20,9 +16,7 @@ import org.springframework.web.bind.annotation.RestController; @@ -20,9 +16,7 @@ import org.springframework.web.bind.annotation.RestController;
20 16
21 import javax.servlet.http.HttpServletRequest; 17 import javax.servlet.http.HttpServletRequest;
22 import java.io.IOException; 18 import java.io.IOException;
23 -import java.util.Date;  
24 import java.util.Enumeration; 19 import java.util.Enumeration;
25 -import java.util.HashMap;  
26 import java.util.Map; 20 import java.util.Map;
27 21
28 @Api(tags = "测试") 22 @Api(tags = "测试")
@@ -83,62 +77,6 @@ public class TestController { @@ -83,62 +77,6 @@ public class TestController {
83 "}"; 77 "}";
84 } 78 }
85 79
86 -  
87 - private static Map<String, TenantAccessToken> tenant_access_token_map = new HashMap<>();  
88 -  
89 - private static String gettenant_access_token(String yy_app_id,String yy_app_secret) {  
90 - if(tenant_access_token_map.containsKey(yy_app_id))  
91 - {  
92 - TenantAccessToken tenant_access_token = tenant_access_token_map.get(yy_app_id);  
93 - // 判断token是否未超时  
94 - if (tenant_access_token.getTenant_access_token() != null && System.currentTimeMillis() < tenant_access_token.getTokenExpireTime()) {  
95 - return tenant_access_token.getTenant_access_token();  
96 - }  
97 - }  
98 -  
99 - String url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal";  
100 - JsonObject params = new JsonObject();  
101 - params.addProperty("app_id", yy_app_id); // 替换为实际的 app_id  
102 - params.addProperty("app_secret", yy_app_secret); // 替换为实际的 app_secret  
103 -  
104 - String str = HttpRequest.post(url).header("Content-Type", "application/json; charset=utf-8").body(params.toString()).execute().body();  
105 -  
106 - JsonObject responseMap = GsonConstructor.get().fromJson(str, JsonObject.class);  
107 -  
108 - if (responseMap != null && responseMap.get("code").getAsInt()==0) {  
109 - TenantAccessToken tenant_access_token = new TenantAccessToken();  
110 - tenant_access_token.setTenant_access_token(responseMap.get("tenant_access_token").getAsString());  
111 - // 设置token过期时间,假设token有效期为7200秒  
112 - tenant_access_token.setTokenExpireTime(System.currentTimeMillis() + responseMap.get("expire").getAsInt() * 1000);  
113 - tenant_access_token_map.put(yy_app_id, tenant_access_token);  
114 - return tenant_access_token.getTenant_access_token();  
115 - } else {  
116 - throw new RuntimeException("Failed to get tenant_access_token: " + str);  
117 - }  
118 - }  
119 -  
120 - /**  
121 - * HTTP URL  
122 - * https://open.feishu.cn/open-apis/bitable/v1/apps/:app_token/tables/:table_id/records  
123 - * HTTP Method  
124 - * POST  
125 - * 接口频率限制  
126 - * 50 次/秒  
127 - *  
128 - * 请求头 :Authorization、Content-Type  
129 - */  
130 - private static void subFeishuTables(String tenant_access_token,String app_token,String table_id, JsonObject field )  
131 - {  
132 - String url = "https://open.feishu.cn/open-apis/bitable/v1/apps/"+app_token+"/tables/"+table_id+"/records";  
133 -  
134 - JsonObject params = new JsonObject();  
135 - params.add("fields",field);  
136 -  
137 - System.out.println(params.toString());  
138 - String str = HttpRequest.post(url).header("Authorization", "Bearer "+tenant_access_token ).header("Content-Type", "application/json").body(params.toString()).execute().body();  
139 - System.out.println(str);  
140 - }  
141 -  
142 public static void main(String[] args) { 80 public static void main(String[] args) {
143 String jsr= "{\"store_id\":0,\"create_time\":\"1746668144\",\"gender\":\"未知\",\"action_type\":3,\"telephone\":\"18061271693\",\"promotion_id\":0,\"clue_source\":5,\"store_pack_id\":0,\"refer_dy_id\":\"2046931013\",\"app_name\":\"暂未获取到\",\"ad_id\":\"0\",\"module_id\":\"1805421364269097\",\"flow_type\":1,\"name\":\"未命名\",\"site_id\":\"0\",\"remark_dict\":{},\"adv_id\":\"0\",\"clue_type\":2,\"location\":\"山东+泰安\",\"id\":\"7501883876034215974\",\"module_name\":\"官方电话\",\"clue_convert_status\":\"外部流量\",\"refer_dy_name\":\"鱼儿乐>智慧渔业系统\"}"; 81 String jsr= "{\"store_id\":0,\"create_time\":\"1746668144\",\"gender\":\"未知\",\"action_type\":3,\"telephone\":\"18061271693\",\"promotion_id\":0,\"clue_source\":5,\"store_pack_id\":0,\"refer_dy_id\":\"2046931013\",\"app_name\":\"暂未获取到\",\"ad_id\":\"0\",\"module_id\":\"1805421364269097\",\"flow_type\":1,\"name\":\"未命名\",\"site_id\":\"0\",\"remark_dict\":{},\"adv_id\":\"0\",\"clue_type\":2,\"location\":\"山东+泰安\",\"id\":\"7501883876034215974\",\"module_name\":\"官方电话\",\"clue_convert_status\":\"外部流量\",\"refer_dy_name\":\"鱼儿乐>智慧渔业系统\"}";
144 ClueData clueData = GsonConstructor.get().fromJson(jsr, ClueData.class); 82 ClueData clueData = GsonConstructor.get().fromJson(jsr, ClueData.class);
@@ -154,23 +92,24 @@ public class TestController { @@ -154,23 +92,24 @@ public class TestController {
154 92
155 private static void subFeishuLiushuiyu(ClueData clueData) 93 private static void subFeishuLiushuiyu(ClueData clueData)
156 { 94 {
157 - JsonObject field = new JsonObject();  
158 - field.addProperty("线索时间",Integer.parseInt(clueData.getCreate_time())*1000l);  
159 - field.addProperty("账号",clueData.getRefer_dy_name());  
160 - field.addProperty("联系方式",clueData.getTelephone());  
161 - field.addProperty("渠道","抖音平台"); 95 + JSONObject field = new JSONObject();
  96 + field.put("线索时间",Integer.parseInt(clueData.getCreate_time())*1000l);
  97 + field.put("账号",clueData.getRefer_dy_name());
  98 + field.put("联系方式",clueData.getTelephone());
  99 + field.put("渠道","测试数据看到请删除");
162 // field.addProperty("地区",clueData.getLocation()); 100 // field.addProperty("地区",clueData.getLocation());
163 - subFeishuTables(gettenant_access_token("cli_a88a14d3b279d01c","Z3hpYKHeR1yR2aiv6Rp0mcnwKvehkzmT"),"VLGDbZTtPaJIrgsAzzJcyb8Vnve","tblgzxv9TNwKjUFv",field); 101 + FeishuUtil.subFeishuTables(FeishuUtil.gettenant_access_token("cli_a88a14d3b279d01c","Z3hpYKHeR1yR2aiv6Rp0mcnwKvehkzmT"),"VLGDbZTtPaJIrgsAzzJcyb8Vnve","tblgzxv9TNwKjUFv",field);
164 } 102 }
165 private static void subFeishuLuhui(ClueData clueData) 103 private static void subFeishuLuhui(ClueData clueData)
166 { 104 {
167 - JsonObject field = new JsonObject();  
168 - field.addProperty("日期",Integer.parseInt(clueData.getCreate_time())*1000l);  
169 - field.addProperty("发送人","");  
170 - field.addProperty("接收人",clueData.getRefer_dy_name());  
171 - field.addProperty("内容",clueData.getTelephone());  
172 - field.addProperty("线索来源","抖音");  
173 - field.addProperty("地址",clueData.getLocation());  
174 - subFeishuTables(gettenant_access_token("cli_a77e560b9475100c","7E80HFwgkmHjngFWDNsz6Pe1aqtKLC3m"),"YY58bkeMjahX5Uskh4WcnYOCnZc","tbldo1VjlU9jY51Y",field); 105 + JSONObject field = new JSONObject();
  106 + field.put("日期",Integer.parseInt(clueData.getCreate_time())*1000l);
  107 + field.put("发送人","");
  108 + field.put("接收人",clueData.getRefer_dy_name());
  109 + field.put("内容",clueData.getTelephone());
  110 + field.put("线索来源","抖音");
  111 + field.put("地址",clueData.getLocation());
  112 + FeishuUtil.subFeishuTables(FeishuUtil.gettenant_access_token("cli_a77e560b9475100c","7E80HFwgkmHjngFWDNsz6Pe1aqtKLC3m"),"YY58bkeMjahX5Uskh4WcnYOCnZc","tbldo1VjlU9jY51Y",field);
175 } 113 }
  114 +
176 } 115 }
@@ -35,36 +35,13 @@ @@ -35,36 +35,13 @@
35 <groupId>cn.hutool</groupId> 35 <groupId>cn.hutool</groupId>
36 <artifactId>hutool-all</artifactId> 36 <artifactId>hutool-all</artifactId>
37 </dependency> 37 </dependency>
38 - <dependency>  
39 - <groupId>net.java.dev.jna</groupId>  
40 - <artifactId>jna</artifactId>  
41 - <version>3.0.9</version>  
42 - <scope>system</scope>  
43 - <systemPath>${project.basedir}/src/main/resources/lib/jna.jar</systemPath>  
44 - <optional>true</optional>  
45 - </dependency>  
46 - <dependency>  
47 - <groupId>com.sun.jna.examples</groupId>  
48 - <artifactId>examples</artifactId>  
49 - <version>1.0</version>  
50 - <scope>system</scope>  
51 - <systemPath>${project.basedir}/src/main/resources/lib/examples.jar</systemPath>  
52 - <optional>true</optional>  
53 - </dependency>  
54 - <dependency>  
55 - <groupId>org.jb2011</groupId>  
56 - <artifactId>beautyeye_lnf</artifactId>  
57 - <version>1.0</version>  
58 - <scope>system</scope>  
59 - <systemPath>${project.basedir}/src/main/resources/lib/beautyeye_lnf.jar</systemPath>  
60 - <optional>true</optional>  
61 - </dependency>  
62 38
  39 + <!-- mqtt -->
63 <dependency> 40 <dependency>
64 - <groupId>org.bytedeco</groupId>  
65 - <artifactId>javacv-platform</artifactId>  
66 - <version>1.5.5</version> 41 + <groupId>org.eclipse.paho</groupId>
  42 + <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
67 </dependency> 43 </dependency>
  44 +
68 </dependencies> 45 </dependencies>
69 46
70 <build> 47 <build>
@@ -90,7 +67,7 @@ @@ -90,7 +67,7 @@
90 生成的manifest中classpath的前缀,因为要把第三方jar放到lib目录下,所以classpath的前缀是lib/ 67 生成的manifest中classpath的前缀,因为要把第三方jar放到lib目录下,所以classpath的前缀是lib/
91 --> 68 -->
92 <classpathPrefix>lib/</classpathPrefix> 69 <classpathPrefix>lib/</classpathPrefix>
93 - <mainClass>com.zhonglai.luhui.camera.hk.sdk.App</mainClass> 70 + <mainClass>com.zhonglai.luhui.camera.App</mainClass>
94 </manifest> 71 </manifest>
95 <!-- 打包时添加本地包引入 --> 72 <!-- 打包时添加本地包引入 -->
96 <manifestEntries> 73 <manifestEntries>
  1 +package com.zhonglai.luhui.camera;
  2 +
  3 +import com.zhonglai.luhui.camera.config.SysConfig;
  4 +import com.zhonglai.luhui.camera.httpservice.SimpleHttpServer;
  5 +import com.zhonglai.luhui.camera.mqtt.MqttService;
  6 +import com.zhonglai.luhui.camera.mqtt.Task;
  7 +import org.eclipse.paho.client.mqttv3.MqttException;
  8 +import org.slf4j.Logger;
  9 +import org.slf4j.LoggerFactory;
  10 +
  11 +import java.io.IOException;
  12 +
  13 +public class App
  14 +{
  15 + private static Logger logger = LoggerFactory.getLogger(App.class);
  16 + public static void main( String[] args ) throws IOException, MqttException {
  17 + SysConfig.init();
  18 + MqttService mqttService = MqttService.getInstance();
  19 +
  20 + Task task = new Task();
  21 + task.updata();
  22 + // 添加关闭钩子
  23 + // 使用Lambda表达式添加关闭钩子
  24 + Runtime.getRuntime().addShutdownHook(new Thread(() -> {
  25 + logger.info("正在关闭应用程序...");
  26 + try {
  27 + mqttService.stop();
  28 + } catch (MqttException e) {
  29 + logger.error("MQTT服务停止异常", e);
  30 + }
  31 + task.stopScheduler();
  32 + logger.info("应用程序关闭成功");
  33 + }));
  34 + }
  35 +}
  1 +package com.zhonglai.luhui.camera.config;
  2 +
  3 +import com.zhonglai.luhui.camera.dto.MqttConfig;
  4 +import com.zhonglai.luhui.camera.rtspwebrtc.DockerSecretFetcher;
  5 +
  6 +import java.io.FileReader;
  7 +import java.util.HashSet;
  8 +import java.util.Properties;
  9 +
  10 +public class SysConfig {
  11 + public static MqttConfig mqttConfig;
  12 +
  13 + public static String yuerleApiUrl;
  14 +
  15 + public static String webrtc_host;
  16 + public static String webrtc_app;
  17 +
  18 + private static String webrtc_secret;
  19 +
  20 + public static String cameraSerial;
  21 + public static Integer sysTaskInterval;
  22 +
  23 + public static void init()
  24 + {
  25 + //加载properties配置文件
  26 + Properties properties = loadProperties();
  27 +
  28 + mqttConfig = new MqttConfig();
  29 + mqttConfig.mqttBroker = properties.getProperty("mqtt.broker");
  30 + mqttConfig.mqttUserName = properties.getProperty("mqtt.username");
  31 + mqttConfig.mqttPassword = properties.getProperty("mqtt.password");
  32 + mqttConfig.mqttClientId = properties.getProperty("mqtt.clientId");
  33 + mqttConfig.subTopic = new HashSet<>();
  34 +
  35 + String topicsStr = properties.getProperty("mqtt.subTopic");
  36 + if(null != topicsStr && !"".equals(topicsStr))
  37 + {
  38 + if (topicsStr != null && !topicsStr.trim().isEmpty()) {
  39 + String[] topics = topicsStr.split(",");
  40 + for (String topic : topics) {
  41 + mqttConfig.subTopic.add(topic.trim());
  42 + }
  43 + }
  44 + }
  45 +
  46 + yuerleApiUrl = properties.getProperty("yuerle.api.url");
  47 +
  48 + webrtc_host = properties.getProperty("webrtc.host");
  49 + webrtc_app = properties.getProperty("webrtc.app");
  50 +
  51 + cameraSerial = properties.getProperty("camera.serial");
  52 +
  53 + sysTaskInterval = Integer.parseInt(properties.getProperty("sys.task.interval"));
  54 + }
  55 +
  56 + /**
  57 + * 获取webrtc的密钥
  58 + * @return
  59 + */
  60 + public static String getWebrtcSecret() {
  61 + if(null == webrtc_secret)
  62 + {
  63 + refreshWebrtcSecret();
  64 + }
  65 + return webrtc_secret;
  66 + }
  67 +
  68 + /**
  69 + * 刷新webrtc的密钥
  70 + */
  71 + public static void refreshWebrtcSecret()
  72 + {
  73 + webrtc_secret = DockerSecretFetcher.getZLMSecret();
  74 + }
  75 +
  76 + public static Properties loadProperties()
  77 + {
  78 + Properties properties = new Properties();
  79 + try {
  80 + if(null != System.getProperty("configPath") && !"".equals(System.getProperty("configPath")))
  81 + {
  82 + properties.load(new FileReader(System.getProperty("configPath")));
  83 + }else{
  84 + properties.load(SysConfig.class.getClassLoader().getResourceAsStream("sys.properties"));
  85 + }
  86 +
  87 + } catch (Exception e) {
  88 + e.printStackTrace();
  89 + }
  90 + return properties;
  91 + }
  92 +}
1 -package com.zhonglai.luhui.camera.hk.sdk.dto; 1 +package com.zhonglai.luhui.camera.dto;
2 2
3 public class Camera { 3 public class Camera {
4 public String name; 4 public String name;
1 -package com.zhonglai.luhui.camera.hk.sdk.dto; 1 +package com.zhonglai.luhui.camera.dto;
2 2
3 import java.util.ArrayList; 3 import java.util.ArrayList;
4 import java.util.HashMap; 4 import java.util.HashMap;
  1 +package com.zhonglai.luhui.camera.dto;
  2 +
  3 +import java.util.Set;
  4 +
  5 +public class MqttConfig {
  6 + public static String mqttBroker;
  7 + public static String mqttUserName;
  8 + public static String mqttPassword;
  9 + public static String mqttClientId;
  10 +
  11 + public static Set<String> subTopic;
  12 +}
  1 +package com.zhonglai.luhui.camera.dto;
  2 +
  3 +public class Topic {
  4 + public static final String TOPIC_PUT = "PUT";
  5 + public static final String TOPIC_READ = "READ";
  6 + private String topicType;
  7 + private String time;
  8 + public Topic()
  9 + {
  10 +
  11 + }
  12 + public Topic(String stopicStr)
  13 + {
  14 + String[] strs = stopicStr.split("/");
  15 + topicType = strs[0];
  16 + time = strs[1];
  17 + }
  18 +
  19 + public String getTopicType() {
  20 + return topicType;
  21 + }
  22 +
  23 + public void setTopicType(String topicType) {
  24 + this.topicType = topicType;
  25 + }
  26 +
  27 + public String getTime() {
  28 + return time;
  29 + }
  30 +
  31 + public void setTime(String time) {
  32 + this.time = time;
  33 + }
  34 +}
1 -package com.zhonglai.luhui.camera.hk.sdk;  
2 -  
3 -import com.zhonglai.luhui.camera.hk.sdk.func.HCSadpSdkFunc;  
4 -import com.zhonglai.luhui.camera.hk.sdk.func.callBack.DeviceFindCallBack;  
5 -import com.zhonglai.luhui.camera.hk.sdk.sdk.SdkPath;  
6 -import com.zhonglai.luhui.camera.hk.sdk.service.SimpleHttpServer;  
7 -import org.slf4j.Logger;  
8 -import org.slf4j.LoggerFactory;  
9 -  
10 -import java.io.File;  
11 -import java.io.IOException;  
12 -  
13 -public class App  
14 -{  
15 - private static Logger logger = LoggerFactory.getLogger(App.class);  
16 - public static void main( String[] args ) throws IOException {  
17 -  
18 -// HCNetSdkFunc netSdk = new HCNetSdkFunc("192.168.0.101","admin","Luhui586", 8000);  
19 -  
20 - HCSadpSdkFunc.getInstance().startSearchDevices(new DeviceFindCallBack());  
21 -  
22 - SimpleHttpServer.startHttpServer(18008);  
23 - }  
24 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.func;  
2 -  
3 -  
4 -import com.zhonglai.luhui.camera.hk.sdk.sdk.HCSadpSdk;  
5 -import com.zhonglai.luhui.camera.hk.sdk.sdk.SdkPath;  
6 -import com.zhonglai.luhui.camera.hk.sdk.sdk.HCSadpSdk.SADP_DEV_NET_PARAM;  
7 -import com.zhonglai.luhui.camera.hk.sdk.util.ByteUtil;  
8 -import com.zhonglai.luhui.camera.hk.sdk.util.SdkErrorUtil;  
9 -  
10 -import cn.hutool.core.lang.Assert;  
11 -import org.slf4j.Logger;  
12 -import org.slf4j.LoggerFactory;  
13 -  
14 -/**  
15 - *  
16 - * @ClassName: HkSadpSdkFunc  
17 - * @Description: 设备网络搜索SDK函数封装  
18 - * @author: ShenYue  
19 - * @date: 2019年4月23日 下午4:38:27  
20 - */  
21 -public class HCSadpSdkFunc implements SdkFunc{  
22 -  
23 - private static Logger logger = LoggerFactory.getLogger(HCSadpSdkFunc.class);  
24 - public static HCSadpSdk sadpSdk = HCSadpSdk.INSTANCE;  
25 - private static boolean isInit = false;  
26 - private boolean isSearching = false;  
27 -  
28 - private static class HCSadpSdkFuncInstance {  
29 - private static final HCSadpSdkFunc INSTANCE = new HCSadpSdkFunc();  
30 - }  
31 -  
32 - public static HCSadpSdkFunc getInstance() {  
33 - return HCSadpSdkFuncInstance.INSTANCE;  
34 - }  
35 -  
36 - private HCSadpSdkFunc() {  
37 - super();  
38 - init();  
39 - }  
40 -  
41 - @Override  
42 - public void init() {  
43 - if(!isInit){  
44 - // 获取SDK版本  
45 - int version = sadpSdk.SADP_GetSadpVersion();  
46 - System.out.printf("SADP SDK 版本: %d.%d.%d.%d%n",  
47 - (version >> 24) & 0xFF,  
48 - (version >> 16) & 0xFF,  
49 - (version >> 8) & 0xFF,  
50 - version & 0xFF);  
51 -  
52 - sadpSdk.SADP_SetLogToFile(3,SdkPath.ROOT_PATH+"/log",1);  
53 - isInit=true;  
54 - logger.info("HCSadpSdk init success.");  
55 - }  
56 - }  
57 -  
58 - /**  
59 - * 开始搜索网络设备  
60 - */  
61 - public boolean startSearchDevices(HCSadpSdk.PDEVICE_FIND_CALLBACK callBack){  
62 - Assert.isFalse(isSearching,"device must stop searching first.");  
63 - logger.info("HkSadpSdk search devices.");  
64 - boolean isSuccess=sadpSdk.SADP_Start_V30(callBack,1,null);  
65 - if(isSuccess){  
66 - logger.info("searching devices start.");  
67 - isSearching=true;  
68 - return true;  
69 - }else{  
70 - logger.error(SdkErrorUtil.getHCSadpErrorMsg());  
71 - return false;  
72 - }  
73 - }  
74 -  
75 - /**  
76 - * 手动刷新网络设备  
77 - */  
78 - public boolean refreshDevices(){  
79 - Assert.isTrue(isSearching,"must start devices searching first.");  
80 - logger.info("refresh devices.");  
81 - boolean isSuccess=sadpSdk.SADP_SendInquiry();  
82 - if(isSuccess){  
83 - logger.info("refresh devices success.");  
84 - return true;  
85 - }else{  
86 - logger.error(SdkErrorUtil.getHCSadpErrorMsg());  
87 - return false;  
88 - }  
89 - }  
90 -  
91 - /**  
92 - * 停止搜索网络设备  
93 - * @return  
94 - */  
95 - public boolean stopSearchDevices(){  
96 - Assert.isTrue(isSearching,"devices searching not start.");  
97 - logger.info("stop search devices.");  
98 - boolean isSuccess=sadpSdk.SADP_Stop();  
99 - if(isSuccess){  
100 - logger.info("stop search devices success.");  
101 - isSearching=false;  
102 - return true;  
103 - }else{  
104 - logger.error(SdkErrorUtil.getHCSadpErrorMsg());  
105 - return false;  
106 - }  
107 - }  
108 -  
109 - /**  
110 - * 激活设备  
111 - * @param serialNO 设备序列号  
112 - * @param password 初始密码  
113 - * @return  
114 - */  
115 - public boolean activeDevice(String serialNO,String password){  
116 - logger.info("try to active devices,serialNO = "+serialNO+", password = "+password);  
117 - boolean isSuccess=sadpSdk.SADP_ActivateDevice(serialNO,password);  
118 - if(isSuccess){  
119 - logger.info("active devices success.");  
120 - return true;  
121 - }else{  
122 - logger.error(SdkErrorUtil.getHCSadpErrorMsg());  
123 - return false;  
124 - }  
125 - }  
126 -  
127 - /**  
128 - * 修改设备网络参数  
129 - * @param sMAC MAC地址  
130 - * @param password 设备密码  
131 - * @param ip IP地址  
132 - * @param gateWay 网关  
133 - * @param netMask 子网掩码  
134 - * @return  
135 - */  
136 - public static boolean setDeviceNetParam(String sMAC,String password,String ip,String gateWay,String netMask){  
137 - logger.info("Modify device netParam -> sMAC = "+sMAC+",password= "+password+",ip= "+ip+",gateWay= "+gateWay+",netMask= "+netMask);  
138 - SADP_DEV_NET_PARAM.ByValue netParam =new SADP_DEV_NET_PARAM.ByValue();  
139 - netParam.szIPv4Address=ByteUtil.setStrToByteArr(ip, 16);  
140 - netParam.szIPv4Gateway=ByteUtil.setStrToByteArr(gateWay, 16);  
141 - netParam.szIPv4SubnetMask=ByteUtil.setStrToByteArr(netMask, 16);  
142 - netParam.szIPv6Gateway=ByteUtil.setStrToByteArr("::", 128);  
143 - netParam.szIPv6Address=ByteUtil.setStrToByteArr("::", 128);  
144 - netParam.byDhcpEnable=0;  
145 - netParam.wPort=8000;  
146 - netParam.wHttpPort=80;  
147 - netParam.byIPv6MaskLen=0;  
148 - netParam.write();  
149 - boolean isSuccess=sadpSdk.SADP_ModifyDeviceNetParam(sMAC,password, netParam.getPointer());  
150 - if(isSuccess){  
151 - logger.info("Modify devices params success.");  
152 - return true;  
153 - }else{  
154 - logger.error(SdkErrorUtil.getHCSadpErrorMsg());  
155 - return false;  
156 - }  
157 - }  
158 -  
159 -  
160 -  
161 - @Override  
162 - public boolean isSuccess() {  
163 - return false;  
164 - }  
165 -  
166 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.func;  
2 -  
3 -public interface SdkFunc {  
4 -  
5 - void init();  
6 -  
7 - boolean isSuccess();  
8 -  
9 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.func.callBack;  
2 -  
3 -import com.sun.jna.Pointer;  
4 -import com.zhonglai.luhui.camera.hk.sdk.dto.Camera;  
5 -import com.zhonglai.luhui.camera.hk.sdk.dto.CameraMap;  
6 -import com.zhonglai.luhui.camera.hk.sdk.sdk.HCSadpSdk;  
7 -import com.zhonglai.luhui.camera.hk.sdk.util.ConvertUtil;  
8 -import org.slf4j.Logger;  
9 -import org.slf4j.LoggerFactory;  
10 -  
11 -import java.util.Map;  
12 -  
13 -  
14 -public class DeviceFindCallBack implements HCSadpSdk.PDEVICE_FIND_CALLBACK {  
15 - private static Logger logger = LoggerFactory.getLogger(DeviceFindCallBack.class);  
16 - @Override  
17 - public void invoke(HCSadpSdk.SADP_DEVICE_INFO lpDeviceInfo, Pointer pUserData) {  
18 - Map<String,Object> map = ConvertUtil.struct2Map(lpDeviceInfo);  
19 - logger.info("搜索到设备{}",map);  
20 -  
21 - Camera camera = new Camera();  
22 - String name= (String) map.get("szSerialNO");  
23 - camera.setName(name);  
24 - camera.setRtsp("rtsp://admin:Luhui586@"+map.get("szIPv4Address")+":554/h264/ch1/main/av_stream");  
25 - String serialNO = name.substring(9<name.length()?name.length()-9:name.length());  
26 - CameraMap.add(serialNO,camera);  
27 - }  
28 -  
29 -  
30 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.sdk;  
2 -  
3 -import com.sun.jna.Library;  
4 -import com.sun.jna.Native;  
5 -import com.sun.jna.Pointer;  
6 -import com.sun.jna.Structure;  
7 -import com.sun.jna.win32.StdCallLibrary;  
8 -import com.zhonglai.luhui.camera.hk.sdk.App;  
9 -import org.slf4j.Logger;  
10 -import org.slf4j.LoggerFactory;  
11 -  
12 -import java.io.File;  
13 -  
14 -public interface HCSadpSdk extends Library {  
15 - HCSadpSdk INSTANCE = (HCSadpSdk) Native.loadLibrary(SdkPath.DLL_PATH, HCSadpSdk.class);  
16 - public static class SADP_DEVICE_INFO extends Structure {  
17 - public byte[] szSeries = new byte[12];  
18 - public byte[] szSerialNO = new byte[48];  
19 - public byte[] szMAC = new byte[20];  
20 - public byte[] szIPv4Address = new byte[16];  
21 - public byte[] szIPv4SubnetMask = new byte[16];  
22 - public int dwDeviceType;  
23 - public int dwPort;  
24 - public int dwNumberOfEncoders;  
25 - public int dwNumberOfHardDisk;  
26 - public byte[] szDeviceSoftwareVersion = new byte[48];  
27 - public byte[] szDSPVersion = new byte[48];  
28 - public byte[] szBootTime = new byte[48];  
29 - public int iResult;  
30 - public byte[] szDevDesc = new byte[24];  
31 - public byte[] szOEMinfo = new byte[24];  
32 - public byte[] szIPv4Gateway = new byte[16];  
33 - public byte[] szIPv6Address = new byte[46];  
34 - public byte[] szIPv6Gateway = new byte[46];  
35 - public byte byIPv6MaskLen;  
36 - public byte bySupport;  
37 - public byte byDhcpEnabled;  
38 - public byte byDeviceAbility;  
39 - public byte wHttpPort;  
40 - public short wDigitalChannelNum;  
41 - public byte[] szCmsIPv4 = new byte[16];  
42 - public short wCmsPort;  
43 - public byte byOEMCode;  
44 - public byte byActivated;  
45 - public byte[] szBaseDesc = new byte[24];  
46 - public byte[] byRes = new byte[16];  
47 - }  
48 -  
49 - public static class SADP_DEV_NET_PARAM extends Structure {  
50 -  
51 - public byte[] szIPv4Address = new byte[16];  
52 - public byte[] szIPv4SubnetMask = new byte[16];  
53 - public byte[] szIPv4Gateway = new byte[16];  
54 - public byte[] szIPv6Address = new byte[128];  
55 - public byte[] szIPv6Gateway = new byte[128];  
56 - public short wPort;  
57 - public byte byIPv6MaskLen;  
58 - public byte byDhcpEnable;  
59 - public short wHttpPort;  
60 - public byte[] byRes = new byte[126];  
61 -  
62 - public static class ByReference extends SADP_DEV_NET_PARAM implements Structure.ByReference{  
63 - }  
64 -  
65 - public static class ByValue extends SADP_DEV_NET_PARAM implements Structure.ByValue{  
66 - }  
67 - }  
68 -  
69 - boolean SADP_SetLogToFile(int nLogLevel, String strLogDir, int bAutoDel);  
70 - boolean SADP_Start_V30(PDEVICE_FIND_CALLBACK pDeviceFindCallBack, int bInstallNPF ,Pointer pUserData);  
71 - boolean SADP_SendInquiry();  
72 - boolean SADP_Stop();  
73 - boolean SADP_ActivateDevice(String sDevSerialNO,String sCommand);  
74 - boolean SADP_ModifyDeviceNetParam(String sMAC,String sPassword,Pointer lpNetParam);  
75 -  
76 - public static interface PDEVICE_FIND_CALLBACK extends StdCallLibrary.StdCallCallback {  
77 - public void invoke(SADP_DEVICE_INFO lpDeviceInfo,Pointer pUserData);  
78 - }  
79 - int SADP_GetSadpVersion();  
80 - int SADP_GetLastError();  
81 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.sdk;  
2 -  
3 -import com.zhonglai.luhui.camera.hk.sdk.App;  
4 -import org.slf4j.Logger;  
5 -import org.slf4j.LoggerFactory;  
6 -  
7 -import java.io.File;  
8 -import java.io.UnsupportedEncodingException;  
9 -  
10 -public class SdkPath {  
11 - private static Logger logger = LoggerFactory.getLogger(SdkPath.class);  
12 - public static String ROOT_PATH;  
13 - public static String DLL_PATH;  
14 -  
15 - static{  
16 - ROOT_PATH = System.getProperty("dllPath");  
17 - if(null == ROOT_PATH)  
18 - {  
19 - ROOT_PATH = new File(ClassLoader.getSystemResource("").getPath()).getParentFile().getParent();  
20 - }  
21 - DLL_PATH = SdkPath.ROOT_PATH+ "/dll/SadpSdk/" +(System.getProperty("os.name").contains("Windows") ? "Sadp.dll" : "libsadp.so");  
22 - logger.info("动态库的地址:"+new File(DLL_PATH).getAbsolutePath());  
23 - }  
24 -  
25 -}  
26 -  
1 -package com.zhonglai.luhui.camera.hk.sdk.service;  
2 -  
3 -import com.alibaba.fastjson.JSONObject;  
4 -import com.sun.net.httpserver.*;  
5 -import com.zhonglai.luhui.camera.hk.sdk.dto.Camera;  
6 -import com.zhonglai.luhui.camera.hk.sdk.dto.CameraMap;  
7 -import com.zhonglai.luhui.camera.rtspwebrtc.WebRtcService;  
8 -  
9 -import java.io.*;  
10 -import java.util.*;  
11 -  
12 -/**  
13 - * 摄像头数据处理器  
14 - */  
15 -public class CamerasHandler implements HttpHandler{  
16 - @Override  
17 - public void handle(HttpExchange exchange) throws IOException {  
18 - // 读取摄像头配置文件  
19 - List<Camera> camerasData = CameraMap.toArrayList();  
20 -  
21 - Map<String, String> params = getQueryMap(exchange);  
22 - if(params.containsKey("command"))  
23 - {  
24 - switch (params.get("command"))  
25 - {  
26 - case "startStream":  
27 - startStream(exchange,params);  
28 - return;  
29 - case "stopStream":  
30 - stopStream(exchange,params);  
31 - return;  
32 - }  
33 - }  
34 - // 返回摄像头数据  
35 - String jsonResponse = JSONObject.toJSONString(camerasData);  
36 - returnString(200,exchange,jsonResponse);  
37 - }  
38 -  
39 - private void returnString(Integer state,HttpExchange exchange,String jsonResponse) throws IOException  
40 - {  
41 - exchange.getResponseHeaders().add("Content-Type", "application/json");  
42 - exchange.sendResponseHeaders(state, jsonResponse.getBytes().length);  
43 - try (OutputStream os = exchange.getResponseBody()) {  
44 - os.write(jsonResponse.getBytes());  
45 - }  
46 - }  
47 -  
48 - private void startStream(HttpExchange exchange,Map<String, String> params) throws IOException {  
49 - if(params.containsKey("serialNO") && CameraMap.has(params.get("serialNO")))  
50 - {  
51 - String rtsp = CameraMap.get(params.get("serialNO")).getRtsp();  
52 - String jsonstr = WebRtcService.startStream(params.get("serialNO"),rtsp,"yuerle");  
53 - JSONObject jsonObject = JSONObject.parseObject(jsonstr);  
54 - if(jsonObject.containsKey("code") && jsonObject.getInteger("code")==0)  
55 - {  
56 - JSONObject data = jsonObject.getJSONObject("data");  
57 - data.put("app","yuerle");  
58 - data.put("stream",params.get("serialNO"));  
59 - returnString(200,exchange,jsonObject.toJSONString());  
60 - return;  
61 - }else{  
62 - returnString(500,exchange,jsonstr);  
63 - return;  
64 - }  
65 - }  
66 - JSONObject json = new JSONObject();  
67 - json.put("msg","请输入正确的设备序列号");  
68 - returnString(500,exchange,json.toJSONString());  
69 - }  
70 -  
71 - private void stopStream(HttpExchange exchange,Map<String, String> params) throws IOException {  
72 - if(params.containsKey("serialNO") && CameraMap.has(params.get("serialNO")))  
73 - {  
74 - String jsonstr = WebRtcService.stopStream(params.get("serialNO"),"yuerle");  
75 - if(jsonstr.contains("success"))  
76 - {  
77 - returnString(200,exchange,jsonstr);  
78 - return;  
79 - }else{  
80 - returnString(500,exchange,jsonstr);  
81 - return;  
82 - }  
83 - }  
84 - JSONObject json = new JSONObject();  
85 - json.put("msg","请输入正确的设备序列号");  
86 - returnString(500,exchange,json.toJSONString());  
87 - }  
88 -  
89 - private Map<String,String> getQueryMap(HttpExchange exchange){  
90 - String query = exchange.getRequestURI().getQuery();  
91 - Map<String, String> params = new HashMap<>();  
92 - if (query != null) {  
93 - for (String param : query.split("&")) {  
94 - String[] pair = param.split("=");  
95 - if (pair.length > 1) {  
96 - params.put(pair[0], pair[1]);  
97 - } else {  
98 - params.put(pair[0], null);  
99 - }  
100 - }  
101 - }  
102 - return params;  
103 - }  
104 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.ui;  
2 -  
3 -import java.awt.Color;  
4 -import java.util.Date;  
5 -  
6 -import javax.swing.JOptionPane;  
7 -import javax.swing.JTextPane;  
8 -import javax.swing.text.BadLocationException;  
9 -import javax.swing.text.Style;  
10 -import javax.swing.text.StyleConstants;  
11 -  
12 -import com.zhonglai.luhui.camera.hk.sdk.util.SdkErrorUtil;  
13 -  
14 -import cn.hutool.core.date.DatePattern;  
15 -import cn.hutool.core.date.DateUtil;  
16 -import cn.hutool.core.text.StrFormatter;  
17 -  
18 -public class MessageBox {  
19 -  
20 -  
21 - public static boolean checkHCSadpError(){  
22 - String msg=SdkErrorUtil.getHCSadpErrorMsg();  
23 - if(msg !=null){  
24 - MessageBox.error(msg);  
25 - return false;  
26 - }  
27 - return true;  
28 - }  
29 -  
30 - public static void error(String msg,Object...params){  
31 - ;  
32 - JOptionPane.showMessageDialog(null,StrFormatter.format(msg, params),"消息提示",JOptionPane.ERROR_MESSAGE);  
33 - throw new RuntimeException(msg);  
34 - }  
35 -  
36 - public static void tip(String msg){  
37 - JOptionPane.showMessageDialog(null,msg,"消息提示",JOptionPane.INFORMATION_MESSAGE);  
38 - }  
39 -  
40 - public static void log(JTextPane console,String msg){  
41 - try {  
42 - console.getDocument()  
43 - .insertString(console.getDocument().getLength(),  
44 - getConsoleHeader()+msg+"\r\n",  
45 - console.getStyle("def"));  
46 - } catch (BadLocationException e) {  
47 - e.printStackTrace();  
48 - }  
49 - }  
50 -  
51 - public static void logWarn(JTextPane console,String msg){  
52 - try {  
53 - console.getDocument()  
54 - .insertString(console.getDocument().getLength(),  
55 - getConsoleHeader()+msg+"\r\n",  
56 - console.getStyle("warn"));  
57 - } catch (BadLocationException e) {  
58 - e.printStackTrace();  
59 - }  
60 - }  
61 -  
62 - public static void logError(JTextPane console,String msg){  
63 - try {  
64 - console.getDocument()  
65 - .insertString(console.getDocument().getLength(),  
66 - getConsoleHeader()+msg+"\r\n",  
67 - console.getStyle("error"));  
68 - } catch (BadLocationException e) {  
69 - e.printStackTrace();  
70 - }  
71 - }  
72 -  
73 - public static void check(boolean condition,String msg,Object...params){  
74 - if(!condition){  
75 - error(msg,params);  
76 - }  
77 - }  
78 -  
79 - private static String getConsoleHeader(){  
80 - return "Console("+DateUtil.format(new Date(),DatePattern.NORM_TIME_PATTERN)+"):";  
81 - }  
82 -  
83 - public static void initJTextPaneStyle(JTextPane pane){  
84 - //def  
85 - Style noStyle = pane.getStyledDocument().addStyle(null, null);  
86 - StyleConstants.setFontFamily(noStyle, "verdana");  
87 - StyleConstants.setFontSize(noStyle, 12);  
88 - Style def=pane.addStyle("def", noStyle);  
89 -  
90 - //warn  
91 - Style warn = pane.addStyle("warn",def);  
92 - StyleConstants.setForeground(warn, Color.blue);  
93 -  
94 - //error  
95 - Style error = pane.addStyle("error",def);  
96 - StyleConstants.setForeground(error, Color.red);  
97 - }  
98 -}  
1 -  
2 -package com.zhonglai.luhui.camera.hk.sdk.ui;  
3 -  
4 -import java.io.File;  
5 -import java.util.List;  
6 -import javax.swing.JFileChooser;  
7 -import javax.swing.JFrame;  
8 -import javax.swing.filechooser.FileNameExtensionFilter;  
9 -import javax.swing.filechooser.FileSystemView;  
10 -  
11 -import com.zhonglai.luhui.camera.hk.sdk.ui.handler.AbstractHandler;  
12 -import com.zhonglai.luhui.camera.hk.sdk.ui.handler.ActiveDeviceHandler;  
13 -import com.zhonglai.luhui.camera.hk.sdk.ui.handler.DeviceNetParamHandler;  
14 -import com.zhonglai.luhui.camera.hk.sdk.ui.vo.DeviceVo;  
15 -import com.zhonglai.luhui.camera.hk.sdk.ui.vo.NetParamVo;  
16 -import com.zhonglai.luhui.camera.hk.sdk.util.ConvertUtil;  
17 -  
18 -import cn.hutool.poi.excel.ExcelUtil;  
19 -  
20 -/**  
21 - *  
22 - * @ClassName: WinHCSadpActiveDevice  
23 - * @Description:TODO(这里用一句话描述这个类的作用)  
24 - * @author: ShenYue  
25 - * @date: 2019年4月30日 上午11:12:01  
26 - */  
27 -public class WinHCSadpActiveDevice extends javax.swing.JFrame {  
28 -  
29 - private static final long serialVersionUID = 2658391598049771347L;  
30 - private List<DeviceVo> unactiveDevices;  
31 - private List<NetParamVo> netParams;  
32 -  
33 - private static final String [] TABLE_HEADER_NAME= new String [] {"设备序列号", "IP", "网关", "子网掩码","MAC", "版本", "激活状态"};  
34 -  
35 - public WinHCSadpActiveDevice() {  
36 - initComponents();  
37 - }  
38 -  
39 - private void initComponents() {  
40 -  
41 - this.setResizable(false);  
42 - this.setLocation(400, 200);  
43 -  
44 - panel = new javax.swing.JPanel();  
45 - avctiveButton = new javax.swing.JButton();  
46 - importConfigButton = new javax.swing.JButton();  
47 - scrollPane = new javax.swing.JScrollPane();  
48 - deviceTable = new javax.swing.JTable();  
49 - jLabel1 = new javax.swing.JLabel();  
50 - jScrollPane2 = new javax.swing.JScrollPane();  
51 - console = new javax.swing.JTextPane();  
52 - jLabel2 = new javax.swing.JLabel();  
53 -  
54 - setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);  
55 -  
56 - avctiveButton.setEnabled(false);  
57 - avctiveButton.setText("开始激活");  
58 - avctiveButton.addActionListener(new java.awt.event.ActionListener() {  
59 - public void actionPerformed(java.awt.event.ActionEvent evt) {  
60 - avctiveButtonEvt(evt);  
61 - }  
62 - });  
63 -  
64 - importConfigButton.setText("导入配置");  
65 - importConfigButton.addActionListener(new java.awt.event.ActionListener() {  
66 - public void actionPerformed(java.awt.event.ActionEvent evt) {  
67 - importConfigButtonEvt(evt);  
68 - }  
69 - });  
70 -  
71 - deviceTable.setModel(new javax.swing.table.DefaultTableModel(  
72 - ConvertUtil.toObjArray(unactiveDevices),  
73 - TABLE_HEADER_NAME  
74 - ));  
75 - scrollPane.setViewportView(deviceTable);  
76 -  
77 - jLabel1.setText("设备列表");  
78 -  
79 - jScrollPane2.setViewportView(console);  
80 -  
81 - jLabel2.setText("实时日志");  
82 -  
83 - AbstractHandler.init(console);  
84 -  
85 - javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(panel);  
86 - panel.setLayout(jPanel1Layout);  
87 - jPanel1Layout.setHorizontalGroup(  
88 - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)  
89 - .addGroup(jPanel1Layout.createSequentialGroup()  
90 - .addGap(30, 30, 30)  
91 - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)  
92 - .addComponent(jLabel2)  
93 - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)  
94 - .addComponent(jScrollPane2)  
95 - .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 840, Short.MAX_VALUE)  
96 - .addGroup(jPanel1Layout.createSequentialGroup()  
97 - .addComponent(avctiveButton)  
98 - .addGap(36, 36, 36)  
99 - .addComponent(importConfigButton)  
100 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)  
101 - .addComponent(jLabel1))))  
102 - .addContainerGap(19, Short.MAX_VALUE))  
103 - );  
104 - jPanel1Layout.setVerticalGroup(  
105 - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)  
106 - .addGroup(jPanel1Layout.createSequentialGroup()  
107 - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)  
108 - .addGroup(jPanel1Layout.createSequentialGroup()  
109 - .addGap(24, 24, 24)  
110 - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)  
111 - .addComponent(avctiveButton)  
112 - .addComponent(importConfigButton))  
113 - .addGap(18, 18, 18))  
114 - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()  
115 - .addContainerGap()  
116 - .addComponent(jLabel1)  
117 - .addGap(6, 6, 6)))  
118 - .addComponent(scrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 305, javax.swing.GroupLayout.PREFERRED_SIZE)  
119 - .addGap(13, 13, 13)  
120 - .addComponent(jLabel2)  
121 - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)  
122 - .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 238, Short.MAX_VALUE)  
123 - .addContainerGap())  
124 - );  
125 -  
126 - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());  
127 - getContentPane().setLayout(layout);  
128 - layout.setHorizontalGroup(  
129 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)  
130 - .addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)  
131 - );  
132 - layout.setVerticalGroup(  
133 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)  
134 - .addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)  
135 - );  
136 -  
137 - pack();  
138 - }// </editor-fold>  
139 -  
140 - private void avctiveButtonEvt(java.awt.event.ActionEvent evt) {  
141 - new Thread(new Runnable() {  
142 - @Override  
143 - public void run() {  
144 - for(int device_index=0;device_index<unactiveDevices.size();device_index++){  
145 - ActiveDeviceHandler activeHandler = new ActiveDeviceHandler(unactiveDevices.get(device_index),netParams.get(device_index));  
146 - DeviceNetParamHandler netParamHandler = new DeviceNetParamHandler(unactiveDevices.get(device_index),netParams.get(device_index));  
147 - activeHandler.setNext(netParamHandler);  
148 - activeHandler.handleRequest(true);  
149 - }  
150 - }  
151 - }).start();  
152 - }  
153 -  
154 - private void importConfigButtonEvt(java.awt.event.ActionEvent evt) {  
155 - // 导入Excel配置  
156 - fileChooser = new JFileChooser();  
157 - //初始化当前路径  
158 - FileSystemView fsv = FileSystemView.getFileSystemView();  
159 - File homeFile =fsv.getHomeDirectory();  
160 - fileChooser.setCurrentDirectory(homeFile);  
161 -  
162 - //初始化文件过滤器  
163 - FileNameExtensionFilter filter = new FileNameExtensionFilter("EXCEL文件","xls","xlsx");  
164 - fileChooser.setFileFilter(filter);  
165 -  
166 - //初始化选择模式  
167 - fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);  
168 - //是否允许多选  
169 - fileChooser.setMultiSelectionEnabled(false);  
170 - //打开文件选择器  
171 - int i = fileChooser.showDialog(this, "选择");  
172 - if(i == JFileChooser.APPROVE_OPTION){  
173 - netParams.clear();  
174 - File file = fileChooser.getSelectedFile();  
175 - List<NetParamVo> importNetParams=ExcelUtil.getReader(file,0).readAll(NetParamVo.class);  
176 - if(!importNetParams.isEmpty()){  
177 - avctiveButton.setEnabled(true);  
178 - MessageBox.check(importNetParams.size()==unactiveDevices.size(),"配置数量不一致,导入配置{}项,未激活设备{}项",importNetParams.size(),unactiveDevices.size());  
179 - MessageBox.tip("导入"+netParams.size()+" 个配置项");  
180 - }  
181 - }  
182 - }  
183 -  
184 - // Variables declaration - do not modify  
185 - private javax.swing.JButton avctiveButton;  
186 - private javax.swing.JButton importConfigButton;  
187 - private javax.swing.JLabel jLabel1;  
188 - private javax.swing.JLabel jLabel2;  
189 - private javax.swing.JPanel panel;  
190 - private javax.swing.JScrollPane scrollPane;  
191 - private javax.swing.JScrollPane jScrollPane2;  
192 - private javax.swing.JTable deviceTable;  
193 - private javax.swing.JTextPane console;  
194 - private javax.swing.JFileChooser fileChooser;  
195 - // End of variables declaration  
196 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.ui;  
2 -  
3 -import java.util.ArrayList;  
4 -import java.util.List;  
5 -import java.util.Map;  
6 -import java.util.stream.Collectors;  
7 -  
8 -import org.jb2011.lnf.beautyeye.ch3_button.BEButtonUI;  
9 -  
10 -import com.sun.jna.Pointer;  
11 -import com.zhonglai.luhui.camera.hk.sdk.func.HCSadpSdkFunc;  
12 -import com.zhonglai.luhui.camera.hk.sdk.sdk.HCSadpSdk.PDEVICE_FIND_CALLBACK;  
13 -import com.zhonglai.luhui.camera.hk.sdk.sdk.HCSadpSdk.SADP_DEVICE_INFO;  
14 -import com.zhonglai.luhui.camera.hk.sdk.ui.render.WindowRender;  
15 -import com.zhonglai.luhui.camera.hk.sdk.ui.vo.DeviceVo;  
16 -import com.zhonglai.luhui.camera.hk.sdk.util.ConvertUtil;  
17 -  
18 -import cn.hutool.core.lang.Assert;  
19 -  
20 -/**  
21 - *  
22 - * @ClassName: WinHCSadpLauncher  
23 - * @Description: 海康SADP sdk 启动类  
24 - * @author: ShenYue  
25 - * @date: 2018年6月29日 下午7:52:04  
26 - */  
27 -public class WinHCSadpLauncher extends javax.swing.JFrame {  
28 -  
29 - private static final long serialVersionUID = -600334410958525284L;  
30 - private boolean isSearching=false;  
31 - private List<DeviceVo> devices=new ArrayList<>();  
32 -  
33 - private static final String [] TABLE_HEADER_NAME= new String [] {"设备序列号", "IP", "网关", "子网掩码","MAC", "版本", "激活状态"};  
34 -  
35 - public WinHCSadpLauncher() {  
36 - initComponents();  
37 - }  
38 -  
39 - private void initComponents() {  
40 -  
41 - this.setResizable(false);  
42 - this.setLocation(400, 200);  
43 -  
44 - panel = new javax.swing.JPanel();  
45 - scrollPane = new javax.swing.JScrollPane();  
46 - deviceTable = new javax.swing.JTable();  
47 - startSearchButton = new javax.swing.JButton();  
48 - refreshButton = new javax.swing.JButton();  
49 - stopSearchButton = new javax.swing.JButton();  
50 - batchConfigButton = new javax.swing.JButton();  
51 -  
52 - setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);  
53 -  
54 - deviceTable.setModel(new javax.swing.table.DefaultTableModel(  
55 - ConvertUtil.toObjArray(devices),  
56 - TABLE_HEADER_NAME  
57 - ));  
58 - scrollPane.setViewportView(deviceTable);  
59 -  
60 - startSearchButton.setText("搜索设备");  
61 - startSearchButton.addActionListener(new java.awt.event.ActionListener() {  
62 - public void actionPerformed(java.awt.event.ActionEvent evt) {  
63 - startSearchButtonEvt(evt);  
64 - }  
65 - });  
66 -  
67 - refreshButton.setEnabled(false);  
68 - refreshButton.setText("刷新");  
69 - refreshButton.addActionListener(new java.awt.event.ActionListener() {  
70 - public void actionPerformed(java.awt.event.ActionEvent evt) {  
71 - refreshButtonEvt(evt);  
72 - }  
73 - });  
74 -  
75 - stopSearchButton.setEnabled(false);  
76 - stopSearchButton.setText("停止搜索");  
77 - stopSearchButton.addActionListener(new java.awt.event.ActionListener() {  
78 - public void actionPerformed(java.awt.event.ActionEvent evt) {  
79 - stopSearchButtonEvt(evt);  
80 - }  
81 - });  
82 -  
83 - batchConfigButton.setText("批量激活");  
84 - WindowRender.changeButtonStyle(batchConfigButton,BEButtonUI.NormalColor.lightBlue);  
85 - batchConfigButton.addActionListener(new java.awt.event.ActionListener() {  
86 - public void actionPerformed(java.awt.event.ActionEvent evt) {  
87 - batchConfigButtonEvt(evt);  
88 - }  
89 - });  
90 -  
91 - javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(panel);  
92 - panel.setLayout(jPanel2Layout);  
93 - jPanel2Layout.setHorizontalGroup(  
94 - jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)  
95 - .addGroup(jPanel2Layout.createSequentialGroup()  
96 - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)  
97 - .addComponent(batchConfigButton)  
98 - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)  
99 - .addGroup(jPanel2Layout.createSequentialGroup()  
100 - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)  
101 - .addComponent(startSearchButton)  
102 - .addGap(30, 30, 30)  
103 - .addComponent(refreshButton)  
104 - .addGap(28, 28, 28)  
105 - .addComponent(stopSearchButton))  
106 - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel2Layout.createSequentialGroup()  
107 - .addGap(32, 32, 32)  
108 - .addComponent(scrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 893, javax.swing.GroupLayout.PREFERRED_SIZE))))  
109 - .addContainerGap(30, Short.MAX_VALUE))  
110 - );  
111 - jPanel2Layout.setVerticalGroup(  
112 - jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)  
113 - .addGroup(jPanel2Layout.createSequentialGroup()  
114 - .addContainerGap()  
115 - .addComponent(batchConfigButton)  
116 - .addGap(18, 18, 18)  
117 - .addComponent(scrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 506, javax.swing.GroupLayout.PREFERRED_SIZE)  
118 - .addGap(18, 18, 18)  
119 - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)  
120 - .addComponent(refreshButton)  
121 - .addComponent(stopSearchButton)  
122 - .addComponent(startSearchButton))  
123 - .addContainerGap(17, Short.MAX_VALUE))  
124 - );  
125 -  
126 - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());  
127 - getContentPane().setLayout(layout);  
128 - layout.setHorizontalGroup(  
129 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)  
130 - .addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)  
131 - );  
132 - layout.setVerticalGroup(  
133 - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)  
134 - .addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)  
135 - );  
136 -  
137 - pack();  
138 - }// </editor-fold>  
139 -  
140 - private void batchConfigButtonEvt(java.awt.event.ActionEvent evt) {  
141 - List<DeviceVo> unactiveDevices=devices.stream().filter(d -> !"已激活".equals(d.getActiveStatus())).collect(Collectors.toList());  
142 - if(!unactiveDevices.isEmpty()){  
143 - MessageBox.tip("没有需要激活的设备!");  
144 - }else{  
145 - java.awt.EventQueue.invokeLater(new Runnable() {  
146 - public void run() {  
147 - new WinHCSadpActiveDevice().setVisible(true);  
148 - }  
149 - });  
150 - }  
151 - }  
152 -  
153 - private void startSearchButtonEvt(java.awt.event.ActionEvent evt) {  
154 - // 设备搜索  
155 - boolean success=HCSadpSdkFunc.getInstance().startSearchDevices(new PDEVICE_FIND_CALLBACK() {  
156 - @Override  
157 - public void invoke(SADP_DEVICE_INFO lpDeviceInfo, Pointer pUserData) {  
158 - Map<String, Object> deviceInfo=ConvertUtil.struct2Map(lpDeviceInfo);  
159 - DeviceVo device=new DeviceVo(  
160 - (String)deviceInfo.get("szSerialNO"),  
161 - (String)deviceInfo.get("szIPv4Address"),  
162 - (String)deviceInfo.get("szIPv4Gateway"),  
163 - (String)deviceInfo.get("szIPv4SubnetMask"),  
164 - (String)deviceInfo.get("szMAC"),  
165 - (String)deviceInfo.get("szDeviceSoftwareVersion"),  
166 - (byte)deviceInfo.get("byActivated"));  
167 - if(!devices.contains(device)){  
168 - devices.add(device);  
169 - refreshTable();  
170 - }  
171 - }  
172 - });  
173 - if(!success){  
174 - MessageBox.checkHCSadpError();  
175 - }else{  
176 - startSearch();  
177 - }  
178 - }  
179 -  
180 - private void refreshButtonEvt(java.awt.event.ActionEvent evt) {  
181 - boolean success=HCSadpSdkFunc.getInstance().refreshDevices();  
182 - if(!success){  
183 - MessageBox.checkHCSadpError();  
184 - }  
185 - }  
186 -  
187 - private void stopSearchButtonEvt(java.awt.event.ActionEvent evt) {  
188 - boolean success=HCSadpSdkFunc.getInstance().stopSearchDevices();  
189 - if(!success){  
190 - MessageBox.checkHCSadpError();  
191 - }else{  
192 - devices.clear();  
193 - refreshTable();  
194 - stopSearch();  
195 - }  
196 - }  
197 -  
198 - public static void main(String args[]) {  
199 - java.awt.EventQueue.invokeLater(new Runnable() {  
200 - public void run() {  
201 - WindowRender.render();  
202 - new WinHCSadpLauncher().setVisible(true);  
203 - }  
204 - });  
205 - }  
206 -  
207 - private void refreshTable(){  
208 - synchronized (this) {  
209 - deviceTable.removeAll();  
210 - deviceTable.setModel(new javax.swing.table.DefaultTableModel(  
211 - ConvertUtil.toObjArray(devices),  
212 - TABLE_HEADER_NAME  
213 - ));  
214 - }  
215 - }  
216 -  
217 - private void startSearch(){  
218 - Assert.isFalse(isSearching,"设备搜索中.");  
219 - isSearching=true;  
220 - refreshButton.setEnabled(true);  
221 - stopSearchButton.setEnabled(true);  
222 - }  
223 -  
224 - private void stopSearch(){  
225 - Assert.isTrue(isSearching,"设备搜索未开启.");  
226 - isSearching=false;  
227 - refreshButton.setEnabled(false);  
228 - stopSearchButton.setEnabled(false);  
229 - }  
230 -  
231 - // Variables declaration - do not modify  
232 - private javax.swing.JButton startSearchButton;  
233 - private javax.swing.JButton refreshButton;  
234 - private javax.swing.JButton stopSearchButton;  
235 - private javax.swing.JButton batchConfigButton;  
236 - private javax.swing.JPanel panel;  
237 - private javax.swing.JScrollPane scrollPane;  
238 - private javax.swing.JTable deviceTable;  
239 - // End of variables declaration  
240 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.ui.handler;  
2 -  
3 -import javax.swing.JTextPane;  
4 -  
5 -import com.zhonglai.luhui.camera.hk.sdk.ui.MessageBox;  
6 -import com.zhonglai.luhui.camera.hk.sdk.util.SdkErrorUtil;  
7 -  
8 -public abstract class AbstractHandler {  
9 -  
10 - protected AbstractHandler next;  
11 - protected static JTextPane console;  
12 -  
13 - public static void init(JTextPane console){  
14 - AbstractHandler.console=console;  
15 - }  
16 -  
17 - public void setNext(AbstractHandler next) {  
18 - this.next = next;  
19 - }  
20 -  
21 - public JTextPane getConsole() {  
22 - return console;  
23 - }  
24 -  
25 -  
26 - public void handleRequest(boolean success){  
27 - if(success){  
28 - success=doRequest();  
29 - if(success){  
30 - MessageBox.log(console,"设备操作成功.");  
31 - }  
32 - if(next != null){  
33 - next.handleRequest(success);  
34 - }  
35 - }else{  
36 - MessageBox.logError(console,SdkErrorUtil.getHCSadpErrorMsg());  
37 - }  
38 - }  
39 -  
40 - abstract protected boolean doRequest();  
41 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.ui.handler;  
2 -  
3 -import com.zhonglai.luhui.camera.hk.sdk.func.HCSadpSdkFunc;  
4 -import com.zhonglai.luhui.camera.hk.sdk.ui.MessageBox;  
5 -import com.zhonglai.luhui.camera.hk.sdk.ui.vo.DeviceVo;  
6 -import com.zhonglai.luhui.camera.hk.sdk.ui.vo.NetParamVo;  
7 -  
8 -public class ActiveDeviceHandler extends AbstractHandler{  
9 -  
10 - private DeviceVo device;  
11 - private NetParamVo netParam;  
12 -  
13 - public ActiveDeviceHandler(DeviceVo device, NetParamVo netParam) {  
14 - super();  
15 - this.device = device;  
16 - this.netParam = netParam;  
17 - }  
18 -  
19 - @Override  
20 - protected boolean doRequest() {  
21 - MessageBox.log(console,"开始激活设备 "+device.getSerialNumber());  
22 - return HCSadpSdkFunc.getInstance().activeDevice(device.getSerialNumber(),netParam.getPassword());  
23 - }  
24 -  
25 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.ui.handler;  
2 -  
3 -import com.zhonglai.luhui.camera.hk.sdk.func.HCSadpSdkFunc;  
4 -import com.zhonglai.luhui.camera.hk.sdk.ui.MessageBox;  
5 -import com.zhonglai.luhui.camera.hk.sdk.ui.vo.DeviceVo;  
6 -import com.zhonglai.luhui.camera.hk.sdk.ui.vo.NetParamVo;  
7 -  
8 -/**  
9 - *  
10 - * @ClassName: DeviceNetParamHandler  
11 - * @Description:TODO(这里用一句话描述这个类的作用)  
12 - * @author: ShenYue  
13 - * @date: 2019年5月5日 上午11:11:00  
14 - */  
15 -public class DeviceNetParamHandler extends AbstractHandler{  
16 -  
17 - private DeviceVo device;  
18 - private NetParamVo netParam;  
19 -  
20 - public DeviceNetParamHandler(DeviceVo device, NetParamVo netParam) {  
21 - super();  
22 - this.device = device;  
23 - this.netParam = netParam;  
24 - }  
25 -  
26 - @Override  
27 - protected boolean doRequest() {  
28 - MessageBox.log(console,"设备 "+device.getSerialNumber()+"开始设置配置IP地址、子网掩码、网关。");  
29 - return HCSadpSdkFunc.setDeviceNetParam(  
30 - device.getMacAddr(),  
31 - netParam.getPassword(),  
32 - netParam.getIp(),  
33 - netParam.getGateWay(),  
34 - netParam.getNetMask());  
35 - }  
36 -  
37 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.ui.render;  
2 -  
3 -import javax.swing.JButton;  
4 -import javax.swing.UIManager;  
5 -  
6 -import org.jb2011.lnf.beautyeye.BeautyEyeLNFHelper;  
7 -import org.jb2011.lnf.beautyeye.ch3_button.BEButtonUI;  
8 -  
9 -public class WindowRender {  
10 -  
11 - public static void render(){  
12 - //边框样式  
13 - BeautyEyeLNFHelper.frameBorderStyle = BeautyEyeLNFHelper.FrameBorderStyle.translucencyAppleLike;  
14 - //移除默认设置按钮  
15 - UIManager.put("RootPane.setupButtonVisible", false);  
16 - //关闭透明效果  
17 - BeautyEyeLNFHelper.translucencyAtFrameInactive = false;  
18 - try {  
19 - BeautyEyeLNFHelper.launchBeautyEyeLNF();  
20 - } catch (Exception e) {  
21 - // TODO Auto-generated catch block  
22 - e.printStackTrace();  
23 - }  
24 - }  
25 -  
26 - public static void changeButtonStyle(JButton button,BEButtonUI.NormalColor color){  
27 - button.setUI(new BEButtonUI().setNormalColor(color));  
28 - }  
29 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.ui.vo;  
2 -  
3 -public class CameraVo {  
4 -  
5 - //设备参数  
6 - private String ip;  
7 - private String username;  
8 - private String password;  
9 - private int port;  
10 -  
11 - //通道参数  
12 - private String chanName;  
13 -  
14 - //平台参数  
15 - private String szSipAuthenticateID;  
16 - private String wServerSipPort;  
17 - private String wLocalSipPort;  
18 - private String byStreamType;  
19 - private String byEnable;  
20 - private String dwRegisterInterval;  
21 - private String szDeviceDomain;  
22 - private String dwRegisterValid;  
23 - private String byTransProtocol;  
24 - private String byProtocolVersion;  
25 - private String szServerID;  
26 - private String szSipAuthenticatePasswd;  
27 - private String dwAutoAllocChannelID;  
28 - private String szServerDomain;  
29 - private String byHeartbeatInterval;  
30 - private String byDeviceStatus;  
31 - private String szSipServerAddress;  
32 - private String szSipUserName;  
33 - private String byMaxHeartbeatTimeOut;  
34 -  
35 - private String status;  
36 - private String msg;  
37 -  
38 - public CameraVo() {  
39 - super();  
40 - this.status="未处理";  
41 - }  
42 -  
43 - public String getIp() {  
44 - return ip;  
45 - }  
46 -  
47 - public void setIp(String ip) {  
48 - this.ip = ip;  
49 - }  
50 -  
51 - public String getUsername() {  
52 - return username;  
53 - }  
54 -  
55 - public void setUsername(String username) {  
56 - this.username = username;  
57 - }  
58 -  
59 - public String getPassword() {  
60 - return password;  
61 - }  
62 -  
63 - public void setPassword(String password) {  
64 - this.password = password;  
65 - }  
66 -  
67 - public int getPort() {  
68 - return port;  
69 - }  
70 -  
71 - public void setPort(int port) {  
72 - this.port = port;  
73 - }  
74 -  
75 - public String getChanName() {  
76 - return chanName;  
77 - }  
78 -  
79 - public void setChanName(String chanName) {  
80 - this.chanName = chanName;  
81 - }  
82 -  
83 - public String getSzSipAuthenticateID() {  
84 - return szSipAuthenticateID;  
85 - }  
86 -  
87 - public void setSzSipAuthenticateID(String szSipAuthenticateID) {  
88 - this.szSipAuthenticateID = szSipAuthenticateID;  
89 - }  
90 -  
91 - public String getwServerSipPort() {  
92 - return wServerSipPort;  
93 - }  
94 -  
95 - public void setwServerSipPort(String wServerSipPort) {  
96 - this.wServerSipPort = wServerSipPort;  
97 - }  
98 -  
99 - public String getwLocalSipPort() {  
100 - return wLocalSipPort;  
101 - }  
102 -  
103 - public void setwLocalSipPort(String wLocalSipPort) {  
104 - this.wLocalSipPort = wLocalSipPort;  
105 - }  
106 -  
107 - public String getByStreamType() {  
108 - return byStreamType;  
109 - }  
110 -  
111 - public void setByStreamType(String byStreamType) {  
112 - this.byStreamType = byStreamType;  
113 - }  
114 -  
115 - public String getByEnable() {  
116 - return byEnable;  
117 - }  
118 -  
119 - public void setByEnable(String byEnable) {  
120 - this.byEnable = byEnable;  
121 - }  
122 -  
123 - public String getDwRegisterInterval() {  
124 - return dwRegisterInterval;  
125 - }  
126 -  
127 - public void setDwRegisterInterval(String dwRegisterInterval) {  
128 - this.dwRegisterInterval = dwRegisterInterval;  
129 - }  
130 -  
131 - public String getSzDeviceDomain() {  
132 - return szDeviceDomain;  
133 - }  
134 -  
135 - public void setSzDeviceDomain(String szDeviceDomain) {  
136 - this.szDeviceDomain = szDeviceDomain;  
137 - }  
138 -  
139 - public String getDwRegisterValid() {  
140 - return dwRegisterValid;  
141 - }  
142 -  
143 - public void setDwRegisterValid(String dwRegisterValid) {  
144 - this.dwRegisterValid = dwRegisterValid;  
145 - }  
146 -  
147 - public String getByTransProtocol() {  
148 - return byTransProtocol;  
149 - }  
150 -  
151 - public void setByTransProtocol(String byTransProtocol) {  
152 - this.byTransProtocol = byTransProtocol;  
153 - }  
154 -  
155 - public String getByProtocolVersion() {  
156 - return byProtocolVersion;  
157 - }  
158 -  
159 - public void setByProtocolVersion(String byProtocolVersion) {  
160 - this.byProtocolVersion = byProtocolVersion;  
161 - }  
162 -  
163 - public String getSzServerID() {  
164 - return szServerID;  
165 - }  
166 -  
167 - public void setSzServerID(String szServerID) {  
168 - this.szServerID = szServerID;  
169 - }  
170 -  
171 - public String getSzSipAuthenticatePasswd() {  
172 - return szSipAuthenticatePasswd;  
173 - }  
174 -  
175 - public void setSzSipAuthenticatePasswd(String szSipAuthenticatePasswd) {  
176 - this.szSipAuthenticatePasswd = szSipAuthenticatePasswd;  
177 - }  
178 -  
179 - public String getDwAutoAllocChannelID() {  
180 - return dwAutoAllocChannelID;  
181 - }  
182 -  
183 - public void setDwAutoAllocChannelID(String dwAutoAllocChannelID) {  
184 - this.dwAutoAllocChannelID = dwAutoAllocChannelID;  
185 - }  
186 -  
187 - public String getSzServerDomain() {  
188 - return szServerDomain;  
189 - }  
190 -  
191 - public void setSzServerDomain(String szServerDomain) {  
192 - this.szServerDomain = szServerDomain;  
193 - }  
194 -  
195 - public String getByHeartbeatInterval() {  
196 - return byHeartbeatInterval;  
197 - }  
198 -  
199 - public void setByHeartbeatInterval(String byHeartbeatInterval) {  
200 - this.byHeartbeatInterval = byHeartbeatInterval;  
201 - }  
202 -  
203 - public String getByDeviceStatus() {  
204 - return byDeviceStatus;  
205 - }  
206 -  
207 - public void setByDeviceStatus(String byDeviceStatus) {  
208 - this.byDeviceStatus = byDeviceStatus;  
209 - }  
210 -  
211 - public String getSzSipServerAddress() {  
212 - return szSipServerAddress;  
213 - }  
214 -  
215 - public void setSzSipServerAddress(String szSipServerAddress) {  
216 - this.szSipServerAddress = szSipServerAddress;  
217 - }  
218 -  
219 - public String getSzSipUserName() {  
220 - return szSipUserName;  
221 - }  
222 -  
223 - public void setSzSipUserName(String szSipUserName) {  
224 - this.szSipUserName = szSipUserName;  
225 - }  
226 -  
227 - public String getByMaxHeartbeatTimeOut() {  
228 - return byMaxHeartbeatTimeOut;  
229 - }  
230 -  
231 - public void setByMaxHeartbeatTimeOut(String byMaxHeartbeatTimeOut) {  
232 - this.byMaxHeartbeatTimeOut = byMaxHeartbeatTimeOut;  
233 - }  
234 -  
235 - public String getStatus() {  
236 - return status;  
237 - }  
238 -  
239 - public void setStatus(String status) {  
240 - this.status = status;  
241 - }  
242 -  
243 - public String getMsg() {  
244 - return msg;  
245 - }  
246 -  
247 - public void setMsg(String msg) {  
248 - this.msg = msg;  
249 - }  
250 -  
251 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.ui.vo;  
2 -  
3 -public class DeviceVo {  
4 -  
5 - /*序列号*/  
6 - private String serialNumber;  
7 - /*IP*/  
8 - private String ip;  
9 - /*网关*/  
10 - private String gateWay;  
11 - /*子网掩码*/  
12 - private String netMask;  
13 - /*Mac地址*/  
14 - private String macAddr;  
15 - /*软件版本*/  
16 - private String dversion;  
17 - /*激活状态*/  
18 - private String activeStatus;  
19 -  
20 - public DeviceVo(String serialNumber, String ip, String gateWay,String netMask, String macAddr, String dversion, byte activeStatus) {  
21 - super();  
22 - this.serialNumber = serialNumber;  
23 - this.ip = ip;  
24 - this.gateWay = gateWay;  
25 - this.netMask= netMask;  
26 - this.macAddr = macAddr;  
27 - this.dversion = dversion;  
28 - this.activeStatus = activeStatus==0 ? "已激活":"未激活" ;  
29 - }  
30 -  
31 - public String getSerialNumber() {  
32 - return serialNumber;  
33 - }  
34 -  
35 -  
36 -  
37 - public void setSerialNumber(String serialNumber) {  
38 - this.serialNumber = serialNumber;  
39 - }  
40 -  
41 -  
42 -  
43 - public String getIp() {  
44 - return ip;  
45 - }  
46 -  
47 -  
48 -  
49 - public void setIp(String ip) {  
50 - this.ip = ip;  
51 - }  
52 -  
53 -  
54 -  
55 - public String getGateWay() {  
56 - return gateWay;  
57 - }  
58 -  
59 -  
60 -  
61 - public void setGateWay(String gateWay) {  
62 - this.gateWay = gateWay;  
63 - }  
64 -  
65 -  
66 -  
67 - public String getNetMask() {  
68 - return netMask;  
69 - }  
70 -  
71 -  
72 -  
73 - public void setNetMask(String netMask) {  
74 - this.netMask = netMask;  
75 - }  
76 -  
77 -  
78 -  
79 - public String getMacAddr() {  
80 - return macAddr;  
81 - }  
82 -  
83 -  
84 -  
85 - public void setMacAddr(String macAddr) {  
86 - this.macAddr = macAddr;  
87 - }  
88 -  
89 -  
90 -  
91 - public String getDversion() {  
92 - return dversion;  
93 - }  
94 -  
95 -  
96 -  
97 - public void setDversion(String dversion) {  
98 - this.dversion = dversion;  
99 - }  
100 -  
101 -  
102 -  
103 - public String getActiveStatus() {  
104 - return activeStatus;  
105 - }  
106 -  
107 -  
108 -  
109 - public void setActiveStatus(String activeStatus) {  
110 - this.activeStatus = activeStatus;  
111 - }  
112 -  
113 -  
114 -  
115 - @Override  
116 - public int hashCode() {  
117 - final int prime = 31;  
118 - int result = 1;  
119 - result = prime * result + ((serialNumber == null) ? 0 : serialNumber.hashCode());  
120 - return result;  
121 - }  
122 -  
123 - @Override  
124 - public boolean equals(Object obj) {  
125 - if (this == obj)  
126 - return true;  
127 - if (obj == null)  
128 - return false;  
129 - if (getClass() != obj.getClass())  
130 - return false;  
131 - DeviceVo other = (DeviceVo) obj;  
132 - if (!serialNumber.equals(other.serialNumber))  
133 - return false;  
134 - return true;  
135 - }  
136 -  
137 -  
138 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.ui.vo;  
2 -  
3 -public class GBT28181Vo {  
4 -  
5 - private String byRes3;  
6 - private String szSipAuthenticateID;  
7 - private String byRes4;  
8 - private String wServerSipPort;  
9 - private String wLocalSipPort;  
10 - private String byStreamType;  
11 - private String byEnable;  
12 - private String dwRegisterInterval;  
13 - private String szDeviceDomain;  
14 - private String dwRegisterValid;  
15 - private String dwSize;  
16 - private String byTransProtocol;  
17 - private String byProtocolVersion;  
18 - private String szServerID;  
19 - private String szSipAuthenticatePasswd;  
20 - private String dwAutoAllocChannelID;  
21 - private String szServerDomain;  
22 - private String byHeartbeatInterval;  
23 - private String byDeviceStatus;  
24 - private String szSipServerAddress;  
25 - private String szSipUserName;  
26 - private String byMaxHeartbeatTimeOut;  
27 -  
28 -  
29 - public String getByRes3() {  
30 - return byRes3;  
31 - }  
32 - public void setByRes3(String byRes3) {  
33 - this.byRes3 = byRes3;  
34 - }  
35 - public String getSzSipAuthenticateID() {  
36 - return szSipAuthenticateID;  
37 - }  
38 - public void setSzSipAuthenticateID(String szSipAuthenticateID) {  
39 - this.szSipAuthenticateID = szSipAuthenticateID;  
40 - }  
41 - public String getByRes4() {  
42 - return byRes4;  
43 - }  
44 - public void setByRes4(String byRes4) {  
45 - this.byRes4 = byRes4;  
46 - }  
47 - public String getwServerSipPort() {  
48 - return wServerSipPort;  
49 - }  
50 - public void setwServerSipPort(String wServerSipPort) {  
51 - this.wServerSipPort = wServerSipPort;  
52 - }  
53 - public String getwLocalSipPort() {  
54 - return wLocalSipPort;  
55 - }  
56 - public void setwLocalSipPort(String wLocalSipPort) {  
57 - this.wLocalSipPort = wLocalSipPort;  
58 - }  
59 - public String getByStreamType() {  
60 - return byStreamType;  
61 - }  
62 - public void setByStreamType(String byStreamType) {  
63 - this.byStreamType = byStreamType;  
64 - }  
65 - public String getByEnable() {  
66 - return byEnable;  
67 - }  
68 - public void setByEnable(String byEnable) {  
69 - this.byEnable = byEnable;  
70 - }  
71 - public String getDwRegisterInterval() {  
72 - return dwRegisterInterval;  
73 - }  
74 - public void setDwRegisterInterval(String dwRegisterInterval) {  
75 - this.dwRegisterInterval = dwRegisterInterval;  
76 - }  
77 - public String getSzDeviceDomain() {  
78 - return szDeviceDomain;  
79 - }  
80 - public void setSzDeviceDomain(String szDeviceDomain) {  
81 - this.szDeviceDomain = szDeviceDomain;  
82 - }  
83 - public String getDwRegisterValid() {  
84 - return dwRegisterValid;  
85 - }  
86 - public void setDwRegisterValid(String dwRegisterValid) {  
87 - this.dwRegisterValid = dwRegisterValid;  
88 - }  
89 - public String getDwSize() {  
90 - return dwSize;  
91 - }  
92 - public void setDwSize(String dwSize) {  
93 - this.dwSize = dwSize;  
94 - }  
95 - public String getByTransProtocol() {  
96 - return byTransProtocol;  
97 - }  
98 - public void setByTransProtocol(String byTransProtocol) {  
99 - this.byTransProtocol = byTransProtocol;  
100 - }  
101 - public String getByProtocolVersion() {  
102 - return byProtocolVersion;  
103 - }  
104 - public void setByProtocolVersion(String byProtocolVersion) {  
105 - this.byProtocolVersion = byProtocolVersion;  
106 - }  
107 - public String getSzServerID() {  
108 - return szServerID;  
109 - }  
110 - public void setSzServerID(String szServerID) {  
111 - this.szServerID = szServerID;  
112 - }  
113 - public String getSzSipAuthenticatePasswd() {  
114 - return szSipAuthenticatePasswd;  
115 - }  
116 - public void setSzSipAuthenticatePasswd(String szSipAuthenticatePasswd) {  
117 - this.szSipAuthenticatePasswd = szSipAuthenticatePasswd;  
118 - }  
119 - public String getDwAutoAllocChannelID() {  
120 - return dwAutoAllocChannelID;  
121 - }  
122 - public void setDwAutoAllocChannelID(String dwAutoAllocChannelID) {  
123 - this.dwAutoAllocChannelID = dwAutoAllocChannelID;  
124 - }  
125 - public String getSzServerDomain() {  
126 - return szServerDomain;  
127 - }  
128 - public void setSzServerDomain(String szServerDomain) {  
129 - this.szServerDomain = szServerDomain;  
130 - }  
131 - public String getByHeartbeatInterval() {  
132 - return byHeartbeatInterval;  
133 - }  
134 - public void setByHeartbeatInterval(String byHeartbeatInterval) {  
135 - this.byHeartbeatInterval = byHeartbeatInterval;  
136 - }  
137 - public String getByDeviceStatus() {  
138 - return byDeviceStatus;  
139 - }  
140 - public void setByDeviceStatus(String byDeviceStatus) {  
141 - this.byDeviceStatus = byDeviceStatus;  
142 - }  
143 - public String getSzSipServerAddress() {  
144 - return szSipServerAddress;  
145 - }  
146 - public void setSzSipServerAddress(String szSipServerAddress) {  
147 - this.szSipServerAddress = szSipServerAddress;  
148 - }  
149 - public String getSzSipUserName() {  
150 - return szSipUserName;  
151 - }  
152 - public void setSzSipUserName(String szSipUserName) {  
153 - this.szSipUserName = szSipUserName;  
154 - }  
155 - public String getByMaxHeartbeatTimeOut() {  
156 - return byMaxHeartbeatTimeOut;  
157 - }  
158 - public void setByMaxHeartbeatTimeOut(String byMaxHeartbeatTimeOut) {  
159 - this.byMaxHeartbeatTimeOut = byMaxHeartbeatTimeOut;  
160 - }  
161 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.ui.vo;  
2 -  
3 -public class NetParamVo {  
4 -  
5 - /*IP*/  
6 - private String ip;  
7 - /*网关*/  
8 - private String gateWay;  
9 - /*子网掩码*/  
10 - private String netMask;  
11 - /*初始密码*/  
12 - private String password;  
13 -  
14 - public String getIp() {  
15 - return ip;  
16 - }  
17 - public void setIp(String ip) {  
18 - this.ip = ip;  
19 - }  
20 - public String getGateWay() {  
21 - return gateWay;  
22 - }  
23 - public void setGateWay(String gateWay) {  
24 - this.gateWay = gateWay;  
25 - }  
26 - public String getNetMask() {  
27 - return netMask;  
28 - }  
29 - public void setNetMask(String netMask) {  
30 - this.netMask = netMask;  
31 - }  
32 - public String getPassword() {  
33 - return password;  
34 - }  
35 - public void setPassword(String password) {  
36 - this.password = password;  
37 - }  
38 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.ui.vo;  
2 -  
3 -public class VedioCompreDtVo {  
4 -  
5 - private byte byPicQuality;  
6 - private byte byStreamType;  
7 - private byte byResolution;  
8 - private byte byBitrateType;  
9 - private int dwVideoFrameRate;  
10 - private int dwVideoBitrate;  
11 - private int wIntervalFrameI;  
12 - private byte byIntervalBPFrame;  
13 -  
14 -  
15 - public byte getByPicQuality() {  
16 - return byPicQuality;  
17 - }  
18 - public void setByPicQuality(byte byPicQuality) {  
19 - this.byPicQuality = byPicQuality;  
20 - }  
21 - public byte getByStreamType() {  
22 - return byStreamType;  
23 - }  
24 - public void setByStreamType(byte byStreamType) {  
25 - this.byStreamType = byStreamType;  
26 - }  
27 - public byte getByResolution() {  
28 - return byResolution;  
29 - }  
30 - public void setByResolution(byte byResolution) {  
31 - this.byResolution = byResolution;  
32 - }  
33 - public byte getByBitrateType() {  
34 - return byBitrateType;  
35 - }  
36 - public void setByBitrateType(byte byBitrateType) {  
37 - this.byBitrateType = byBitrateType;  
38 - }  
39 - public int getDwVideoFrameRate() {  
40 - return dwVideoFrameRate;  
41 - }  
42 - public void setDwVideoFrameRate(int dwVideoFrameRate) {  
43 - this.dwVideoFrameRate = dwVideoFrameRate;  
44 - }  
45 - public int getDwVideoBitrate() {  
46 - return dwVideoBitrate;  
47 - }  
48 - public void setDwVideoBitrate(int dwVideoBitrate) {  
49 - this.dwVideoBitrate = dwVideoBitrate;  
50 - }  
51 - public int getwIntervalFrameI() {  
52 - return wIntervalFrameI;  
53 - }  
54 - public void setwIntervalFrameI(int wIntervalFrameI) {  
55 - this.wIntervalFrameI = wIntervalFrameI;  
56 - }  
57 - public byte getByIntervalBPFrame() {  
58 - return byIntervalBPFrame;  
59 - }  
60 - public void setByIntervalBPFrame(byte byIntervalBPFrame) {  
61 - this.byIntervalBPFrame = byIntervalBPFrame;  
62 - }  
63 -  
64 -  
65 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.ui.vo;  
2 -  
3 -public class VedioCompreVo {  
4 -  
5 - private VedioCompreDtVo struNormHighRecordPara;  
6 - private VedioCompreDtVo struEventRecordPara;  
7 - private VedioCompreDtVo struNetPara;  
8 -  
9 - public VedioCompreDtVo getStruNormHighRecordPara() {  
10 - return struNormHighRecordPara;  
11 - }  
12 - public void setStruNormHighRecordPara(VedioCompreDtVo struNormHighRecordPara) {  
13 - this.struNormHighRecordPara = struNormHighRecordPara;  
14 - }  
15 - public VedioCompreDtVo getStruEventRecordPara() {  
16 - return struEventRecordPara;  
17 - }  
18 - public void setStruEventRecordPara(VedioCompreDtVo struEventRecordPara) {  
19 - this.struEventRecordPara = struEventRecordPara;  
20 - }  
21 - public VedioCompreDtVo getStruNetPara() {  
22 - return struNetPara;  
23 - }  
24 - public void setStruNetPara(VedioCompreDtVo struNetPara) {  
25 - this.struNetPara = struNetPara;  
26 - }  
27 -  
28 -  
29 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.util;  
2 -  
3 -import cn.hutool.core.lang.Assert;  
4 -  
5 -public class ByteUtil {  
6 -  
7 - public static byte[] setStrToByteArr(String str,int arrLen){  
8 - byte [] arr = new byte[arrLen];  
9 - byte [] strBytes=str.getBytes();  
10 - Assert.isTrue(arrLen>strBytes.length,"arrLen is too small.");  
11 - for(int i=0;i<strBytes.length;i++){  
12 - arr[i]=strBytes[i];  
13 - }  
14 - return arr;  
15 - }  
16 -  
17 - public static int getValidLength(byte[] bytes){  
18 - int i = 0;  
19 - if (null == bytes || 0 == bytes.length)  
20 - return i ;  
21 - for (; i < bytes.length; i++) {  
22 - if (bytes[i] == '\0')  
23 - break;  
24 - }  
25 - return i;  
26 - }  
27 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.util;  
2 -  
3 -import java.util.*;  
4 -  
5 -/**  
6 - * @author gongjunlang  
7 - */  
8 -public class ComnUtil {  
9 -  
10 - /**  
11 - * 判断一个对象是否为空  
12 - * <p>  
13 - * 以下情况为true  
14 - * <p>  
15 - * 对象为null  
16 - * <p>  
17 - * 字符串对象为""或者length为0  
18 - * <p>  
19 - * 集合对象size为0  
20 - * <p>  
21 - * 数组对象length为0  
22 - *  
23 - * @param obj  
24 - * @return  
25 - */  
26 - public static boolean isEmpty(Object obj) {  
27 - if (obj == null) {  
28 - return true;  
29 - } else if (obj instanceof String) {  
30 - return ((String) obj).trim().equals("");  
31 - } else if (obj instanceof StringBuilder) {  
32 - return ((StringBuilder) obj).length() == 0;  
33 - } else if (Collection.class.isAssignableFrom(obj.getClass())) {  
34 - return ((Collection<?>) obj).size() == 0;  
35 - } else if (obj instanceof Map) {  
36 - return ((Map<?, ?>) obj).size() == 0;  
37 - } else if (obj.getClass().isArray()) {  
38 - if (obj instanceof byte[]) {  
39 - return ((byte[]) obj).length == 0;  
40 - }  
41 - if (obj instanceof short[]) {  
42 - return ((short[]) obj).length == 0;  
43 - }  
44 - if (obj instanceof int[]) {  
45 - return ((int[]) obj).length == 0;  
46 - }  
47 - if (obj instanceof long[]) {  
48 - return ((long[]) obj).length == 0;  
49 - }  
50 - if (obj instanceof char[]) {  
51 - return ((char[]) obj).length == 0;  
52 - }  
53 - if (obj instanceof float[]) {  
54 - return ((float[]) obj).length == 0;  
55 - }  
56 - if (obj instanceof double[]) {  
57 - return ((double[]) obj).length == 0;  
58 - }  
59 - if (obj instanceof boolean[]) {  
60 - return ((boolean[]) obj).length == 0;  
61 - }  
62 - return ((Object[]) obj).length == 0;  
63 - } else if (obj instanceof StringBuffer) {  
64 - return ((StringBuffer) obj).length() == 0;  
65 - }  
66 - return false;  
67 - }  
68 -  
69 - /**  
70 - * 判断一个对象是否为空  
71 - * <p>  
72 - * 以下情况为true  
73 - * <p>  
74 - * 对象为null  
75 - * <p>  
76 - * 字符串对象为""或者length为0  
77 - * <p>  
78 - * 集合对象size为0  
79 - * <p>  
80 - * 数组对象length为0  
81 - * <p>  
82 - * 数字对象值为0  
83 - *  
84 - * @param obj  
85 - * @return  
86 - */  
87 - public static boolean isEmptyOrZero(Object obj) {  
88 - if (Number.class.isAssignableFrom(obj.getClass())) {  
89 - if (((Number) obj).intValue() == 0 || ((Number) obj).doubleValue() == 0 || ((Number) obj).longValue() == 0  
90 - || ((Number) obj).floatValue() == 0 || ((Number) obj).shortValue() == 0  
91 - || ((Number) obj).byteValue() == 0) {  
92 - return true;  
93 - }  
94 - }  
95 - return isEmpty(obj);  
96 - }  
97 -  
98 - /**  
99 - * 适用于非复合主键数据  
100 - *  
101 - * @param key  
102 - * @return  
103 - */  
104 - public static String getStringWithSingleQuotes(String key, String split) {  
105 - String[] ids = key.split(split);  
106 - String result = "";  
107 - for (String id : ids) {  
108 - result += ",'" + id + "'";  
109 - }  
110 - if (result.length() > 0) {  
111 - return result.substring(1);  
112 - }  
113 - return null;  
114 - }  
115 -  
116 - public static List<String> string2List(String key, String split) {  
117 - if (isEmpty(key)) {  
118 - return new ArrayList<String>();  
119 - }  
120 - return Arrays.asList(key.split(split));  
121 - }  
122 -  
123 - /**  
124 - * @param src  
125 - * @param concat  
126 - * @return  
127 - */  
128 - public static <T> T[] concatArray(T[] src, T[] concat) {  
129 - List<T> srcList = new ArrayList<T>(Arrays.asList(src));  
130 - List<T> concatList = new ArrayList<T>(Arrays.asList(concat));  
131 - srcList.addAll(concatList);  
132 - return srcList.toArray(src);  
133 - }  
134 -  
135 - // public static Object[] concatArray(Object[] src, Object[] concat) {  
136 - // List<Object> srcList = new ArrayList<Object>(Arrays.asList(src));  
137 - // List<Object> concatList = new ArrayList<Object>(Arrays.asList(concat));  
138 - // srcList.addAll(concatList);  
139 - // return srcList.toArray(src);  
140 - // }  
141 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.util;  
2 -  
3 -import java.lang.reflect.Field;  
4 -import java.util.Arrays;  
5 -import java.util.HashMap;  
6 -import java.util.List;  
7 -import java.util.Map;  
8 -  
9 -import com.alibaba.fastjson.JSONObject;  
10 -import com.sun.jna.Structure;  
11 -  
12 -import cn.hutool.json.JSONUtil;  
13 -import org.slf4j.Logger;  
14 -import org.slf4j.LoggerFactory;  
15 -  
16 -/**  
17 - *  
18 - * @ClassName: ConvertUtil  
19 - * @Description: 数据转换工具类  
20 - * @author: ShenYue  
21 - * @date: 2019年4月22日 下午3:22:59  
22 - */  
23 -public class ConvertUtil {  
24 -  
25 - private static Logger logger = LoggerFactory.getLogger(ConvertUtil.class);  
26 -  
27 - /**  
28 - * 结构体转map  
29 - * @param t 待转换的结构体  
30 - * @param ignoreFields 忽略的字段列表  
31 - * @return 转换后的map,传入的结构体为NULL时,返回值也为NULL  
32 - */  
33 - public static <T> Map<String,Object> struct2Map(T t,String...ignoreFields){  
34 - if(t == null){  
35 - return null;  
36 - }  
37 - Class<?> clazz = t.getClass();  
38 - List<String> ignoreList=Arrays.asList(ignoreFields);  
39 - Map<String,Object> map = new HashMap<>(32);  
40 - Field[] fields = clazz.getDeclaredFields();  
41 - for(Field field : fields){  
42 - Class<?> type=field.getType();  
43 - String fieldName=field.getName();  
44 - field.setAccessible(true);  
45 - try{  
46 - if(!ignoreList.contains(fieldName)){  
47 - if(isBaseType(type)){  
48 - map.put(fieldName,field.get(t));  
49 - }else if(type == byte[].class){  
50 - byte[] bytes=(byte[]) field.get(t);  
51 - int validByteLen=ByteUtil.getValidLength(bytes);  
52 - map.put(fieldName,new String(bytes,0,validByteLen));  
53 - }else if(type.newInstance() instanceof Structure){  
54 - map.put(fieldName,struct2Map(field.get(t)));  
55 - }else{  
56 - logger.warn("unsupport type "+type);  
57 - }  
58 - }  
59 - } catch ( InstantiationException e) {  
60 - logger.error("can not instance obj.");  
61 - e.printStackTrace();  
62 - } catch (IllegalAccessException e) {  
63 - logger.error("no access to convert field.");  
64 - e.printStackTrace();  
65 - }  
66 - }  
67 - return map;  
68 - }  
69 -  
70 - /**  
71 - * 结构体转换为json  
72 - * @param t 待转换的结构体  
73 - * @param ignoreFields 忽略的字段列表  
74 - * @return  
75 - */  
76 - public static <T> String struct2Json(T t,String...ignoreFields){  
77 - return JSONUtil.toJsonPrettyStr(struct2Map(t,ignoreFields));  
78 - }  
79 -  
80 - /**  
81 - * 将map中的参数值赋值到结构体中  
82 - * @param t 待赋值的结构体  
83 - * @param params 封装相关参数的map  
84 - * @return 赋值完成的结构体,传入的结构体为NULL时,返回值也为NULL  
85 - */  
86 - public static <T> T map2Struct(T t,Map<String,Object> params){  
87 - if(t == null){  
88 - return null;  
89 - }  
90 - Class<?> clazz = t.getClass();  
91 - Field[] fields = clazz.getDeclaredFields();  
92 - for(Field field : fields){  
93 - Class<?> type=field.getType();  
94 - String fieldName=field.getName();  
95 - field.setAccessible(true);  
96 - try{  
97 - if(params.containsKey(fieldName) && !ComnUtil.isEmpty(params.get(fieldName))){  
98 - if(type == byte[].class){  
99 - int byteLen = ((byte[])field.get(t)).length;  
100 - field.set(t,ComnUtil.isEmpty(params.get(fieldName).toString())? field.get(t) : ByteUtil.setStrToByteArr(params.get(fieldName).toString(),byteLen));  
101 - }else if(type == byte.class){  
102 - field.set(t,Byte.valueOf(String.valueOf(params.get(fieldName))).intValue());  
103 - }else if(type == int.class){  
104 - field.set(t,Integer.valueOf(String.valueOf(params.get(fieldName))).intValue());  
105 - }else if(type == short.class){  
106 - field.set(t,Short.valueOf(String.valueOf(params.get(fieldName))).intValue());  
107 - }else if(type == double.class){  
108 - field.set(t,Double.valueOf(String.valueOf(params.get(fieldName))).intValue());  
109 - }else if(type == float.class){  
110 - field.set(t,Float.valueOf(String.valueOf(params.get(fieldName))).intValue());  
111 - }else if(type == char.class){  
112 - String source=String.valueOf(params.get(fieldName));  
113 - if(source.length()!=1){  
114 - logger.error("can not convert "+type+" to char.");  
115 - throw new RuntimeException("can not convert "+type+" to char.");  
116 - }  
117 - field.set(t,String.valueOf(params.get(fieldName)).charAt(0));  
118 - }else {  
119 - logger.warn("unsupport type "+type+","+fieldName+" is skiped.");  
120 - }  
121 - }  
122 - }catch (IllegalAccessException e) {  
123 - logger.error("no access to convert field.");  
124 - e.printStackTrace();  
125 - }  
126 - }  
127 - return t;  
128 - }  
129 -  
130 - /**  
131 - * list转obj二维数组  
132 - * @param list 待转换的list  
133 - * @return  
134 - */  
135 - public static <T> Object[][] toObjArray(List<T> list){  
136 - try{  
137 - if(list== null || list.size()==0){  
138 - return null;  
139 - }  
140 - Field[] fields = list.get(0).getClass().getDeclaredFields();  
141 - Object[][] objs=new Object[list.size()][fields.length];  
142 - for(int row=0;row<list.size();row++){  
143 - T t=list.get(row);  
144 - fields =t.getClass().getDeclaredFields();  
145 - for(int col=0;col<fields.length;col++){  
146 - fields[col].setAccessible(true);  
147 - objs[row][col]=fields[col].get(t);  
148 - }  
149 - }  
150 - return objs;  
151 - }catch(Exception e){  
152 - logger.error("no access to convert field.");  
153 - e.printStackTrace();  
154 - }  
155 - return null;  
156 - }  
157 -  
158 - /**  
159 - * map转对象  
160 - * @param paramMap 待转换map  
161 - * @param cls 转换对象的class  
162 - * @return  
163 - */  
164 - public static <T> T map2Object(Map<?, ?> paramMap, Class<T> cls) {  
165 - return JSONObject.parseObject(JSONObject.toJSONString(paramMap), cls);  
166 - }  
167 -  
168 - /**  
169 - * json转map  
170 - * @param jsonObj json字符串  
171 - * @return  
172 - */  
173 - public static Map<String, Object> jsonToMap(String jsonObj) {  
174 - return (Map<String, Object>) JSONObject.parseObject(jsonObj);  
175 - }  
176 -  
177 - /**  
178 - * 判断是否为基本类型  
179 - * @param type 传入类型  
180 - * @return  
181 - */  
182 - public static boolean isBaseType(Class<?> type) {  
183 - if (type.equals(int.class) ||  
184 - type.equals(byte.class) ||  
185 - type.equals(long.class) ||  
186 - type.equals(double.class) ||  
187 - type.equals(float.class) ||  
188 - type.equals(char.class) ||  
189 - type.equals(short.class) ||  
190 - type.equals(boolean.class)) {  
191 - return true;  
192 - }  
193 - return false;  
194 - }  
195 -  
196 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.util;  
2 -  
3 -import java.util.HashMap;  
4 -import java.util.Map;  
5 -import cn.hutool.setting.dialect.Props;  
6 -  
7 -public class DicUtil {  
8 -  
9 - private static Props dicEn2CnProps;  
10 - private static Props dicCn2EnProps;  
11 -  
12 - private static Props getDicCn2EnProps(){  
13 - if(dicCn2EnProps==null){  
14 - dicCn2EnProps=new Props("dic/dic_cn_en.properties");  
15 - }  
16 - return dicCn2EnProps;  
17 - }  
18 -  
19 - private static Props getDicEn2CnProps(){  
20 - if(dicEn2CnProps==null){  
21 - dicEn2CnProps=new Props("dic/dic_en_cn.properties");  
22 - }  
23 - return dicEn2CnProps;  
24 - }  
25 -  
26 - public static Map<String,Object> translateMap2CnKey(Map<String,Object> map,boolean skipNoneNote){  
27 - return translateMapKey(map,getDicEn2CnProps(),skipNoneNote);  
28 - }  
29 -  
30 - public static Map<String,Object> translateMap2EnKey(Map<String,Object> map,boolean skipNoneNote){  
31 - return translateMapKey(map,getDicCn2EnProps(),skipNoneNote);  
32 - }  
33 -  
34 - private static Map<String,Object> translateMapKey(Map<String,Object> map,Props dicProps,boolean skipNoneNote){  
35 - Map<String,Object> currMap = new HashMap<>();  
36 - for (Map.Entry<String,Object> entry : map.entrySet()) {  
37 - if(dicProps.containsKey(entry.getKey())){  
38 - currMap.put(dicProps.getProperty(entry.getKey()),entry.getValue());  
39 - }else{  
40 - if(!skipNoneNote){  
41 - currMap.put(entry.getKey(),entry.getValue());  
42 - }  
43 - }  
44 - }  
45 - return currMap;  
46 - }  
47 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.util;  
2 -  
3 -  
4 -import com.zhonglai.luhui.camera.hk.sdk.func.HCSadpSdkFunc;  
5 -  
6 -import cn.hutool.setting.dialect.Props;  
7 -import org.slf4j.Logger;  
8 -import org.slf4j.LoggerFactory;  
9 -  
10 -public class SdkErrorUtil {  
11 - private static Logger logger = LoggerFactory.getLogger(SdkErrorUtil.class);  
12 - private static Props HkNetErrorProps;  
13 - private static Props HkSadpErrorProps;  
14 - private final static String HK_NET_ERROR_PREFIX="HK_NET_ERROR_";  
15 - private final static String HK_SADP_ERROR_PREFIX="HK_SADP_ERROR_";  
16 -  
17 - private static Props getHkNetErrorProps(){  
18 - if(HkNetErrorProps==null){  
19 - HkNetErrorProps=new Props("hk_net_error.properties");  
20 - }  
21 - return HkNetErrorProps;  
22 - }  
23 -  
24 - private static Props getHkSadpErrorProps(){  
25 - if(HkSadpErrorProps==null){  
26 - HkSadpErrorProps=new Props("hk_sadp_error.properties");  
27 - }  
28 - return HkSadpErrorProps;  
29 - }  
30 -  
31 - public static String getHCSadpErrorMsg(){  
32 - int code=HCSadpSdkFunc.sadpSdk.SADP_GetLastError();  
33 - if(code!=0){  
34 - String error=getHkSadpErrorProps().getStr(HK_SADP_ERROR_PREFIX+code);  
35 - logger.error(code+"--"+error);  
36 - return error;  
37 - }  
38 - return null;  
39 - }  
40 -  
41 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.util;  
2 -  
3 -import java.io.IOException;  
4 -import java.net.DatagramPacket;  
5 -import java.net.DatagramSocket;  
6 -import java.net.InetAddress;  
7 -  
8 -public class Test {  
9 - private static final String BROADCAST_IP = "255.255.255.255";  
10 - private static final int BROADCAST_PORT = 37020; // 假设海康搜索使用该端口(根据实际配置)  
11 -  
12 - public static void main(String[] args) throws IOException {  
13 - DatagramSocket socket = new DatagramSocket();  
14 - socket.setBroadcast(true);  
15 -  
16 - String discoveryMessage = "HIKDISCOVERY"; // 模拟发送搜索请求  
17 - byte[] buffer = discoveryMessage.getBytes();  
18 -  
19 - DatagramPacket packet = new DatagramPacket(  
20 - buffer, buffer.length,  
21 - InetAddress.getByName(BROADCAST_IP),  
22 - BROADCAST_PORT  
23 - );  
24 -  
25 - socket.send(packet);  
26 -  
27 - System.out.println("等待设备响应...");  
28 - byte[] recvBuf = new byte[15000];  
29 - DatagramPacket receivePacket = new DatagramPacket(recvBuf, recvBuf.length);  
30 - socket.receive(receivePacket);  
31 -  
32 - String response = new String(receivePacket.getData(), 0, receivePacket.getLength());  
33 - System.out.println("发现设备: " + response);  
34 -  
35 - socket.close();  
36 - }  
37 -}  
1 -package com.zhonglai.luhui.camera.hk.sdk.service; 1 +package com.zhonglai.luhui.camera.httpservice;
2 2
3 import com.sun.net.httpserver.*; 3 import com.sun.net.httpserver.*;
4 4
@@ -14,7 +14,7 @@ public class SimpleHttpServer { @@ -14,7 +14,7 @@ public class SimpleHttpServer {
14 server.createContext("/static/", new StaticFileHandler("static")); 14 server.createContext("/static/", new StaticFileHandler("static"));
15 15
16 // 映射 /cameras 到动态摄像头数据 16 // 映射 /cameras 到动态摄像头数据
17 - server.createContext("/cameras", new CamerasHandler()); 17 +// server.createContext("/cameras", new CamerasHandler());
18 18
19 server.setExecutor(null); // 默认线程池 19 server.setExecutor(null); // 默认线程池
20 server.start(); 20 server.start();
1 -package com.zhonglai.luhui.camera.hk.sdk.service; 1 +package com.zhonglai.luhui.camera.httpservice;
2 2
3 import com.sun.net.httpserver.*; 3 import com.sun.net.httpserver.*;
4 4
  1 +package com.zhonglai.luhui.camera.mqtt;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import com.zhonglai.luhui.camera.dto.Topic;
  5 +import com.zhonglai.luhui.camera.mqtt.cmmd.AnalysisCommd;
  6 +import com.zhonglai.luhui.camera.mqtt.cmmd.AnalysisPut;
  7 +import com.zhonglai.luhui.camera.mqtt.cmmd.AnalysisRead;
  8 +
  9 +public class CommdOperateService {
  10 + private Topic topic;
  11 + private JSONObject data;
  12 + private CommdOperateService(Topic topic,JSONObject data)
  13 + {
  14 + this.topic = topic;
  15 + this.data = data;
  16 + }
  17 + public static CommdOperateService getInstance(String topic,JSONObject data)
  18 + {
  19 + return new CommdOperateService(new Topic(topic),data);
  20 + }
  21 +
  22 + public AnalysisCommd operate()
  23 + {
  24 + switch (topic.getTopicType())
  25 + {
  26 + case Topic.TOPIC_PUT:
  27 + return new AnalysisPut(topic.getTime(),data);
  28 + case Topic.TOPIC_READ:
  29 + return new AnalysisRead(topic.getTime(),data);
  30 + default:
  31 + return null;
  32 + }
  33 + }
  34 +
  35 +}
  1 +package com.zhonglai.luhui.camera.mqtt;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
  5 +import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
  6 +import org.eclipse.paho.client.mqttv3.MqttException;
  7 +import org.eclipse.paho.client.mqttv3.MqttMessage;
  8 +import org.slf4j.Logger;
  9 +import org.slf4j.LoggerFactory;
  10 +
  11 +import java.util.Set;
  12 +
  13 +/**
  14 + * mqtt回调
  15 + */
  16 +public class MqttCallback implements MqttCallbackExtended {
  17 + private final Logger log = LoggerFactory.getLogger(this.getClass());
  18 +
  19 + private MqttService mqttclient;
  20 + public MqttCallback(MqttService mqttclient)
  21 + {
  22 + this.mqttclient = mqttclient;
  23 + }
  24 + @Override
  25 + public void connectComplete(boolean b, String s) {
  26 + log.info("连接成功");
  27 + Set<String> topics = mqttclient.subscribe();
  28 + log.info("-----------订阅成功:{}--------------------",topics);
  29 + }
  30 +
  31 + @Override
  32 + public void connectionLost(Throwable cause) {
  33 + log.error("连接丢失重新链接",cause);
  34 + while (!mqttclient.connect())
  35 + {
  36 + try {
  37 + Thread.sleep(60000);
  38 + } catch (InterruptedException e) {
  39 + e.printStackTrace();
  40 + }
  41 + }
  42 + }
  43 +
  44 + @Override
  45 + public void messageArrived(String topic, MqttMessage message) throws Exception {
  46 + log.info("mqtt发来消息>>>>>>>:{} 《===============》 字符串:【{}】",topic,message.toString());
  47 + String str = new String(message.getPayload());
  48 + JSONObject jsonObject = JSONObject.parseObject(str);
  49 + if (jsonObject.containsKey("1_1") && !jsonObject.getJSONObject("1_1").isEmpty())
  50 + {
  51 + JSONObject payloaddata = jsonObject.getJSONObject("1_1");
  52 + CommdOperateService.getInstance(topic,payloaddata).operate().returnData(mqttclient);
  53 + }
  54 + }
  55 +
  56 + @Override
  57 + public void deliveryComplete(IMqttDeliveryToken token) {
  58 + log.info("消息发送完成");
  59 + }
  60 +}
  1 +package com.zhonglai.luhui.camera.mqtt;
  2 +
  3 +import com.zhonglai.luhui.camera.config.SysConfig;
  4 +import org.eclipse.paho.client.mqttv3.MqttClient;
  5 +import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
  6 +import org.eclipse.paho.client.mqttv3.MqttException;
  7 +import org.eclipse.paho.client.mqttv3.MqttMessage;
  8 +import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
  9 +import org.slf4j.Logger;
  10 +import org.slf4j.LoggerFactory;
  11 +
  12 +import javax.annotation.PreDestroy;
  13 +import java.io.IOException;
  14 +import java.util.Set;
  15 +
  16 +public class MqttService {
  17 + private final Logger log = LoggerFactory.getLogger(this.getClass());
  18 +
  19 + private MqttClient mqttclient;
  20 + private MqttConnectOptions options;
  21 +
  22 + // 使用 volatile 确保多线程内存可见性和禁止指令重排
  23 + private static volatile MqttService instance;
  24 +
  25 + private MqttService() {
  26 + // 初始化代码
  27 + try {
  28 + sart();
  29 + } catch (MqttException e) {
  30 + throw new RuntimeException(e);
  31 + }
  32 + }
  33 +
  34 + public static MqttService getInstance() {
  35 + if (instance == null) {
  36 + synchronized (MqttService.class) {
  37 + if (instance == null) {
  38 + instance = new MqttService();
  39 + }
  40 + }
  41 + }
  42 + return instance;
  43 + }
  44 +
  45 + private void init() throws MqttException {
  46 + if(null == mqttclient)
  47 + {
  48 + mqttclient = new MqttClient(SysConfig.mqttConfig.mqttBroker, SysConfig.mqttConfig.mqttClientId, new MemoryPersistence());
  49 + }
  50 + options = new MqttConnectOptions();
  51 + options.setCleanSession(true);
  52 + options.setConnectionTimeout(15);
  53 + options.setKeepAliveInterval(60); // 添加心跳设置,单位为秒
  54 + //设置断开后重新连接
  55 + options.setAutomaticReconnect(true);
  56 + mqttclient.setCallback(new MqttCallback(this));
  57 + }
  58 +
  59 + public boolean connect() {
  60 + try {
  61 + options.setUserName(SysConfig.mqttConfig.mqttUserName);
  62 + options.setPassword(SysConfig.mqttConfig.mqttPassword.toCharArray());
  63 + mqttclient.connect(options);
  64 + return true;
  65 + } catch (MqttException e) {
  66 + log.error("-----------mqtt连接服务器失败--------------------",e);
  67 + }
  68 + return false;
  69 + }
  70 +
  71 + public void sart() throws MqttException{
  72 + log.info("-----------开始启动mqtt监听服务--------------------");
  73 + init();
  74 + connect();
  75 + log.info("-----------mqtt连接服务器成功--------------------");
  76 +
  77 + }
  78 +
  79 + @PreDestroy
  80 + public void stop() throws MqttException {
  81 + if(null != mqttclient)
  82 + {
  83 + log.info("退出mqtt服务");
  84 + mqttclient.unsubscribe(SysConfig.mqttConfig.subTopic.toArray(new String[SysConfig.mqttConfig.subTopic.size()]));
  85 + mqttclient.disconnect();
  86 + mqttclient.close();
  87 + }
  88 + instance = null;
  89 + }
  90 + public void publish(String topic, String messageStr) throws MqttException {
  91 + MqttMessage message = new MqttMessage();
  92 + message.setPayload(messageStr.getBytes());
  93 + mqttclient.publish(topic,message);
  94 + }
  95 +
  96 + public Set<String> subscribe()
  97 + {
  98 + try {
  99 + mqttclient.subscribe(SysConfig.mqttConfig.subTopic.toArray(new String[SysConfig.mqttConfig.subTopic.size()]));
  100 + } catch (MqttException e) {
  101 + e.printStackTrace();
  102 + }
  103 + return SysConfig.mqttConfig.subTopic;
  104 + }
  105 +}
  1 +package com.zhonglai.luhui.camera.mqtt;
  2 +
  3 +
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.zhonglai.luhui.camera.config.SysConfig;
  6 +import com.zhonglai.luhui.camera.rtspwebrtc.DockerSecretFetcher;
  7 +import com.zhonglai.luhui.camera.rtspwebrtc.WebRtcService;
  8 +import org.eclipse.paho.client.mqttv3.MqttException;
  9 +import org.slf4j.Logger;
  10 +import org.slf4j.LoggerFactory;
  11 +
  12 +import java.util.concurrent.Executors;
  13 +import java.util.concurrent.ScheduledExecutorService;
  14 +import java.util.concurrent.TimeUnit;
  15 +public class Task {
  16 + private final Logger logger = LoggerFactory.getLogger(this.getClass());
  17 + private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
  18 +
  19 + public void updata() {
  20 + // 每隔 30 秒执行一次
  21 + scheduler.scheduleAtFixedRate(() -> {
  22 + System.out.println("定时任务正在执行...");
  23 + try {
  24 + String localip = WebRtcService.getLocalIpAddress();
  25 + String playurl = WebRtcService.getPlayUrl(localip, SysConfig.webrtc_app, SysConfig.cameraSerial);
  26 + boolean oline = WebRtcService.isMediaOnline(SysConfig.cameraSerial, SysConfig.webrtc_app, SysConfig.getWebrtcSecret());
  27 + JSONObject jsonObject = new JSONObject();
  28 + JSONObject data = new JSONObject();
  29 + data.put("playurl", playurl);
  30 + data.put("online", oline);
  31 + jsonObject.put("1_1",data);
  32 + MqttService.getInstance().publish("ADD_POST", jsonObject.toJSONString());
  33 + } catch (Exception e) {
  34 + logger.error("定时任务执行异常", e);
  35 + }
  36 + }, 0, SysConfig.sysTaskInterval, TimeUnit.SECONDS);
  37 + }
  38 +
  39 + public void stopScheduler() {
  40 + if (null != scheduler)
  41 + {
  42 + logger.info("停止定时任务");
  43 + scheduler.shutdown();
  44 + }
  45 + }
  46 +}
  1 +package com.zhonglai.luhui.camera.mqtt.cmmd;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import com.zhonglai.luhui.camera.mqtt.MqttService;
  5 +
  6 +public interface AnalysisCommd {
  7 + void returnData(MqttService mqttService);
  8 +}
  1 +package com.zhonglai.luhui.camera.mqtt.cmmd;
  2 +
  3 +import com.zhonglai.luhui.camera.mqtt.MqttService;
  4 +
  5 +public class AnalysisDefault implements AnalysisCommd{
  6 + @Override
  7 + public void returnData(MqttService mqttService) {
  8 + System.out.println("未知的topic");
  9 + }
  10 +}
  1 +package com.zhonglai.luhui.camera.mqtt.cmmd;
  2 +
  3 +import com.alibaba.fastjson.JSON;
  4 +import com.alibaba.fastjson.JSONObject;
  5 +import com.zhonglai.luhui.camera.config.SysConfig;
  6 +import com.zhonglai.luhui.camera.mqtt.MqttService;
  7 +import com.zhonglai.luhui.camera.rtspwebrtc.WebRtcService;
  8 +import org.eclipse.paho.client.mqttv3.MqttException;
  9 +import org.slf4j.Logger;
  10 +import org.slf4j.LoggerFactory;
  11 +
  12 +public class AnalysisPut implements AnalysisCommd{
  13 + private final Logger log = LoggerFactory.getLogger(this.getClass());
  14 + private String reStr;
  15 +
  16 + private String time;
  17 +
  18 + public AnalysisPut(String time,JSONObject data)
  19 + {
  20 + this.time = time;
  21 + if(null != data && data.size() != 0)
  22 + {
  23 + for (String key : data.keySet())
  24 + {
  25 + switch (key)
  26 + {
  27 + case "startStream":
  28 + reStr = startStream(data);
  29 + return;
  30 + case "stopStream":
  31 + reStr = stopStream(data);
  32 + return;
  33 + default:
  34 + JSONObject jsonObject = new JSONObject();
  35 + jsonObject.put("code",0);
  36 + jsonObject.put("msg","未知的指令:"+key);
  37 + reStr = jsonObject.toJSONString();
  38 + return;
  39 + }
  40 + }
  41 + }
  42 + }
  43 +
  44 + private String startStream(JSONObject data)
  45 + {
  46 + String deviceSerial = data.getString("startStream");
  47 + if (null != deviceSerial && !"".equals(deviceSerial))
  48 + {
  49 + String auto_close = "true";
  50 + if(data.containsKey("autoClose") && !data.getBoolean("autoClose"))
  51 + {
  52 + auto_close = "false";
  53 + }
  54 + JSONObject rtspUrl = WebRtcService.startStreamBySerial(deviceSerial,auto_close);
  55 + return rtspUrl.toJSONString();
  56 + }
  57 + JSONObject jsonObject = new JSONObject();
  58 + jsonObject.put("code",0);
  59 + jsonObject.put("msg","摄像头序列号不能为空");
  60 + return jsonObject.toJSONString();
  61 + }
  62 +
  63 + private String stopStream(JSONObject data)
  64 + {
  65 + String deviceSerial = data.getString("stopStream");
  66 + if (null != deviceSerial && !"".equals(deviceSerial))
  67 + {
  68 + String str = WebRtcService.stopStream(deviceSerial,SysConfig.webrtc_app,SysConfig.getWebrtcSecret());
  69 + JSONObject jsonObject = JSON.parseObject(str);
  70 + if(jsonObject.containsKey("code") && jsonObject.getInteger("code")==0)
  71 + {
  72 + jsonObject.put("code",1);
  73 + return jsonObject.toJSONString();
  74 + }
  75 + jsonObject.put("code",0);
  76 + System.out.println(str);
  77 + return jsonObject.toJSONString();
  78 + }
  79 + JSONObject jsonObject = new JSONObject();
  80 + jsonObject.put("code",0);
  81 + jsonObject.put("msg","摄像头序列号不能为空");
  82 + return jsonObject.toJSONString();
  83 + }
  84 + @Override
  85 + public void returnData(MqttService mqttService) {
  86 + String topic = "PUT_REQ/"+time;
  87 + try {
  88 + log.info("发送指令返回数据:【{}】【{}】",topic,reStr);
  89 + mqttService.publish(topic, reStr);
  90 + } catch (MqttException e) {
  91 + System.err.println(e);
  92 + }
  93 + }
  94 +}
  1 +package com.zhonglai.luhui.camera.mqtt.cmmd;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import com.zhonglai.luhui.camera.config.SysConfig;
  5 +import com.zhonglai.luhui.camera.mqtt.MqttService;
  6 +import com.zhonglai.luhui.camera.rtspwebrtc.WebRtcService;
  7 +import org.eclipse.paho.client.mqttv3.MqttException;
  8 +import org.slf4j.Logger;
  9 +import org.slf4j.LoggerFactory;
  10 +
  11 +public class AnalysisRead implements AnalysisCommd{
  12 + private final Logger log = LoggerFactory.getLogger(this.getClass());
  13 + private String reStr;
  14 +
  15 + private String time;
  16 +
  17 + public AnalysisRead(String time,JSONObject data)
  18 + {
  19 + this.time = time;
  20 + if(null != data && data.size() != 0)
  21 + {
  22 + for (String key : data.keySet())
  23 + {
  24 + switch (key)
  25 + {
  26 + case "getPlayUrl":
  27 + reStr = getPlayUrl(data);
  28 + break;
  29 + case "getSecret":
  30 + reStr = getSecret(data);
  31 + break;
  32 + default:
  33 + JSONObject jsonObject = new JSONObject();
  34 + jsonObject.put("code",0);
  35 + jsonObject.put("msg","未知的指令:"+key);
  36 + reStr = jsonObject.toJSONString();
  37 + break;
  38 + }
  39 + }
  40 + }
  41 + }
  42 +
  43 + private String getSecret(JSONObject data)
  44 + {
  45 + String type = data.getString("getSecret");
  46 + switch (type)
  47 + {
  48 + case "memory":
  49 + JSONObject jsonObject = new JSONObject();
  50 + jsonObject.put("code",1);
  51 + jsonObject.put("secret",SysConfig.getWebrtcSecret());
  52 + return jsonObject.toJSONString();
  53 + default:
  54 + return null;
  55 + }
  56 + }
  57 +
  58 + private String getPlayUrl(JSONObject data)
  59 + {
  60 + String deviceSerial = data.getString("getPlayUrl");
  61 + String localip = WebRtcService.getLocalIpAddress();
  62 + String playurl = WebRtcService.getPlayUrl(localip, SysConfig.webrtc_app, deviceSerial);
  63 + JSONObject jsonObject = new JSONObject();
  64 + jsonObject.put("code",1);
  65 + jsonObject.put("playurl",playurl);
  66 + return jsonObject.toJSONString();
  67 + }
  68 + @Override
  69 + public void returnData(MqttService mqttService) {
  70 + String topic = "READ_REQ/"+time;
  71 + try {
  72 + log.info("发送指令返回数据:【{}】【{}】",topic,reStr);
  73 + mqttService.publish(topic, reStr);
  74 + } catch (MqttException e) {
  75 + System.err.println(e);
  76 + }
  77 + }
  78 +}
  1 +package com.zhonglai.luhui.camera.rtspwebrtc;
  2 +
  3 +import com.zhonglai.luhui.camera.App;
  4 +import com.zhonglai.luhui.camera.config.SysConfig;
  5 +import org.slf4j.Logger;
  6 +import org.slf4j.LoggerFactory;
  7 +
  8 +import java.io.BufferedReader;
  9 +import java.io.InputStreamReader;
  10 +import java.util.Properties;
  11 +
  12 +public class DockerSecretFetcher {
  13 + private static Logger logger = LoggerFactory.getLogger(App.class);
  14 + public static String getZLMSecret() {
  15 + String[] command = {
  16 + "docker", "exec", "zlmediakit",
  17 + "grep", "^secret=", "/opt/media/conf/config.ini"
  18 + };
  19 +
  20 + logger.info("正在通过指令{}获取操作令牌...",command);
  21 + ProcessBuilder processBuilder = new ProcessBuilder(command);
  22 + processBuilder.redirectErrorStream(true); // 合并错误流和标准输出流
  23 +
  24 + try {
  25 + Process process = processBuilder.start();
  26 +
  27 + try (BufferedReader reader = new BufferedReader(
  28 + new InputStreamReader(process.getInputStream()))) {
  29 + String line;
  30 + while ((line = reader.readLine()) != null) {
  31 + logger.info("执行指令返回的数据:{}",line);
  32 + if (line.startsWith("secret=")) {
  33 + return line.substring("secret=".length()).trim();
  34 + }
  35 + }
  36 + }
  37 +
  38 + int exitCode = process.waitFor();
  39 + if (exitCode != 0) {
  40 + logger.info("命令执行失败,退出码:"+exitCode);
  41 + }
  42 + } catch (Exception e) {
  43 + logger.info("拿操作令牌异常,去配置里面拿:",e);
  44 + Properties properties = SysConfig.loadProperties();
  45 + return properties.getProperty("webrtc.secret");
  46 + }
  47 +
  48 + return null; // 未找到 secret 或执行失败
  49 + }
  50 +
  51 +}
1 package com.zhonglai.luhui.camera.rtspwebrtc; 1 package com.zhonglai.luhui.camera.rtspwebrtc;
2 2
3 import cn.hutool.http.HttpUtil; 3 import cn.hutool.http.HttpUtil;
  4 +import com.alibaba.fastjson.JSON;
  5 +import com.alibaba.fastjson.JSONObject;
  6 +import com.zhonglai.luhui.camera.App;
  7 +import com.zhonglai.luhui.camera.config.SysConfig;
  8 +import org.slf4j.Logger;
  9 +import org.slf4j.LoggerFactory;
  10 +
  11 +import java.net.DatagramSocket;
  12 +import java.net.InetAddress;
  13 +import java.net.NetworkInterface;
  14 +import java.util.Enumeration;
4 15
5 public class WebRtcService { 16 public class WebRtcService {
6 - private static final String ZLM_API = "http://192.168.0.103:180/index/api";  
7 - public static String startStream(String stream,String rtspUrl,String app) 17 + private static Logger logger = LoggerFactory.getLogger(App.class);
  18 +
  19 + private static String localIp;
  20 +
  21 + public static JSONObject startStream(String stream,String rtspUrl,String app,String secret,String auto_close)
  22 + {
  23 + StringBuffer stringBuffer = getZlmApi();
  24 + stringBuffer.append("/addStreamProxy?");
  25 + stringBuffer.append("secret=");
  26 + stringBuffer.append(secret);
  27 + stringBuffer.append("&vhost=__defaultVhost__");
  28 + stringBuffer.append("&app=");
  29 + stringBuffer.append(app);
  30 + stringBuffer.append("&stream=");
  31 + stringBuffer.append(stream);
  32 + stringBuffer.append("&url=");
  33 + stringBuffer.append(rtspUrl);
  34 + stringBuffer.append("&enable_auto_close=1");
  35 + stringBuffer.append("&retry_count=-1&rtp_type=0&timeout_sec=10&enable_hls=false&enable_hls_fmp4=false&enable_mp4=false&enable_rtsp=true&enable_rtmp=false&enable_ts=false&enable_fmp4=true&hls_demand=false&rtsp_demand=false&rtmp_demand=false&ts_demand=false&fmp4_demand=false&enable_audio=true&add_mute_audio=true&mp4_max_second=10&mp4_as_player=false&auto_close="+auto_close);
  36 + logger.info("添加流的接口请求:"+stringBuffer.toString());
  37 + String str = HttpUtil.get(stringBuffer.toString());
  38 + JSONObject jsonObject = JSON.parseObject(str);
  39 + if(jsonObject.containsKey("code") && jsonObject.getInteger("code")==0)
8 { 40 {
9 - String url = ZLM_API + "/addStreamProxy?vhost=__defaultVhost__&app=" + app +  
10 - "&stream=" + stream + "&url=" + rtspUrl + "&enable_rtsp=1&enable_auto_close=1&enable_mp4=0&secret=Gbc0ThIWCTdlAHlyNVY4sJinYkXjAMBg"; 41 + jsonObject.put("code",1);
  42 + String localip = WebRtcService.getLocalIpAddress();
  43 + String playurl = WebRtcService.getPlayUrl(localip, SysConfig.webrtc_app, stream);
  44 + jsonObject.getJSONObject("data").put("playurl",playurl);
  45 + return jsonObject;
  46 + }
  47 + jsonObject.put("code",0);
  48 + System.out.println(str);
  49 + return jsonObject;
  50 + }
  51 +
  52 + public static String stopStream( String stream,String app,String secret) {
  53 + String url = getZlmApi() + "/close_stream?schema=rtsp&vhost=__defaultVhost__&app=" + app + "&stream=" + stream+"&force=1&secret="+secret;
11 String str = HttpUtil.get(url); 54 String str = HttpUtil.get(url);
12 System.out.println(str); 55 System.out.println(str);
13 return str; 56 return str;
14 } 57 }
15 58
16 - public static String stopStream( String stream,String app) {  
17 - String url = ZLM_API + "/close_stream?schema=rtsp&vhost=__defaultVhost__&app=" + app + "&stream=" + stream+"&force=1&secret=Gbc0ThIWCTdlAHlyNVY4sJinYkXjAMBg"; 59 + private static StringBuffer getZlmApi()
  60 + {
  61 + return new StringBuffer().append("http://").append(SysConfig.webrtc_host).append("/index/api");
  62 + }
  63 +
  64 + public static JSONObject startStreamBySerial(String deviceSerial,String auto_close)
  65 + {
  66 + String str = HttpUtil.get(SysConfig.yuerleApiUrl+"?deviceSerial="+deviceSerial);
  67 + JSONObject jsonObject = JSON.parseObject(str);
  68 + if(jsonObject.containsKey("code") && jsonObject.getInteger("code")==1 && null != jsonObject.get("data"))
  69 + {
  70 + String enable_rtsp = jsonObject.getString("data");
  71 + logger.info("令牌{}获取到设备{}的rtsp地址{}",SysConfig.getWebrtcSecret(),deviceSerial,enable_rtsp);
  72 + return WebRtcService.startStream(deviceSerial,enable_rtsp,SysConfig.webrtc_app,SysConfig.getWebrtcSecret(),auto_close);
  73 + }
  74 + return jsonObject;
  75 + }
  76 +
  77 +
  78 + public static String getPlayUrl(String ip,String app,String stream)
  79 + {
  80 + return "https://"+ip+"/index/api/webrtc?app="+app+"&stream="+stream+"&type=play";
  81 + }
  82 +
  83 + public static boolean isMediaOnline(String stream,String app,String secret) {
  84 + String url = getZlmApi() + "/isMediaOnline?secret="+secret+"&schema=rtsp&vhost=__defaultVhost__&app="+app+"&stream="+stream;
18 String str = HttpUtil.get(url); 85 String str = HttpUtil.get(url);
19 System.out.println(str); 86 System.out.println(str);
20 - return str; 87 + return JSON.parseObject(str).containsKey("online") && JSON.parseObject(str).getBoolean("online");
21 } 88 }
22 89
  90 + /**
  91 + * 获取本机IP
  92 + * @return
  93 + */
  94 + public static String getLocalIpAddress() {
  95 + if(null != localIp)
  96 + {
  97 + return localIp;
  98 + }
  99 + try {
  100 + // 构造一个连接外部地址的 socket(这里用 Google 的公共 DNS IP)
  101 + try (DatagramSocket socket = new DatagramSocket()) {
  102 + socket.connect(InetAddress.getByName("8.8.8.8"), 10002);
  103 + InetAddress localAddress = socket.getLocalAddress();
  104 + return SysConfig.webrtc_host=localIp=localAddress.getHostAddress();
  105 + }
  106 + } catch (Exception e) {
  107 + e.printStackTrace();
  108 + return null;
  109 + }
  110 + }
  111 +
  112 +
23 public static void main(String[] args) { 113 public static void main(String[] args) {
24 -// startStream("cam1","rtsp://admin:Luhui586@192.168.0.101:554/h264/ch1/main/av_stream","live");  
25 - stopStream("live","cam1"); 114 + SysConfig.init();
  115 + System.out.println(WebRtcService.startStream("BA8609485","rtsp://admin:GCQGTC@192.168.0.101:554/h264/ch1/main/av_stream","yuerle","keXTvTDSHAxFDpBA0MDAHhxWeVXLQmUq","true"));
26 } 116 }
27 } 117 }
1 -{  
2 - "password": "Admin12345",  
3 - "port": 8000,  
4 - "ip": "192.168.30.188",  
5 - "username": "admin",  
6 - "status": "未处理"  
7 -}  
1 -{  
2 - "szSipAuthenticateID": "34020000001320000001",  
3 - "wServerSipPort": "5060",  
4 - "wLocalSipPort": "5060",  
5 - "byStreamType": "0",  
6 - "byEnable": "1",  
7 - "dwRegisterInterval": "60",  
8 - "szDeviceDomain": "abc",  
9 - "dwRegisterValid": "3600",  
10 - "byTransProtocol": "0",  
11 - "byProtocolVersion": "2",  
12 - "szServerID": "34020000002000000001",  
13 - "szSipAuthenticatePasswd": "12345678",  
14 - "dwAutoAllocChannelID": "0",  
15 - "szServerDomain": "3402000000",  
16 - "byHeartbeatInterval": "60",  
17 - "byDeviceStatus": "1",  
18 - "szSipServerAddress": "10.1.1.1",  
19 - "szSipUserName": "34020000001320000001",  
20 - "byMaxHeartbeatTimeOut": "3"  
21 -}  
1 -{  
2 - "struEventRecordPara": {  
3 - "byPicQuality": 0,  
4 - "byVideoEncType": 0,  
5 - "byBitrateType": 0,  
6 - "byStreamType": 1,  
7 - "byres": "",  
8 - "wIntervalFrameI": 0,  
9 - "byIntervalBPFrame": 0,  
10 - "dwVideoFrameRate": 0,  
11 - "byENumber": 0,  
12 - "dwVideoBitrate": 0,  
13 - "byAudioEncType": 0,  
14 - "byResolution": 0  
15 - },  
16 - "struRes": {  
17 - "byPicQuality": 0,  
18 - "byVideoEncType": 0,  
19 - "byBitrateType": 0,  
20 - "byStreamType": 1,  
21 - "byres": "",  
22 - "wIntervalFrameI": 0,  
23 - "byIntervalBPFrame": 0,  
24 - "dwVideoFrameRate": 0,  
25 - "byENumber": 0,  
26 - "dwVideoBitrate": 0,  
27 - "byAudioEncType": 0,  
28 - "byResolution": 0  
29 - },  
30 - "struNetPara": {  
31 - "byPicQuality": 2,  
32 - "byVideoEncType": 1,  
33 - "byBitrateType": 1,  
34 - "byStreamType": 0,  
35 - "byres": "",  
36 - "wIntervalFrameI": 50,  
37 - "byIntervalBPFrame": 2,  
38 - "dwVideoFrameRate": 0,  
39 - "byENumber": 0,  
40 - "dwVideoBitrate": 19,  
41 - "byAudioEncType": 0,  
42 - "byResolution": 3  
43 - },  
44 - "struNormHighRecordPara": {  
45 - "byPicQuality": 2,  
46 - "byVideoEncType": 1,  
47 - "byBitrateType": 1,  
48 - "byStreamType": 0,  
49 - "byres": "",  
50 - "wIntervalFrameI": 50,  
51 - "byIntervalBPFrame": 2,  
52 - "dwVideoFrameRate": 0,  
53 - "byENumber": 0,  
54 - "dwVideoBitrate": 25,  
55 - "byAudioEncType": 0,  
56 - "byResolution": 27  
57 - },  
58 - "dwSize": 116  
59 -}  
1 -#base  
2 -IP=ip  
3 -\u7528\u6237\u540D=username  
4 -\u5BC6\u7801=password  
5 -\u7AEF\u53E3=port  
6 -\u64CD\u4F5C\u72B6\u6001=status  
7 -\u9519\u8BEF\u4FE1\u606F=msg  
8 -  
9 - #aisle  
10 - \u901A\u9053\u540D\u79F0=chanName  
11 -  
12 -28181\u534F\u8BAE\u4F7F\u80FD=byEnable  
13 -\u670D\u52A1\u5668\u57DF =szServerDomain  
14 -\u6700\u5927\u5FC3\u8DF3\u8D85\u65F6\u6B21\u6570=byMaxHeartbeatTimeOut  
15 -SIP\u7528\u6237\u540D=szSipUserName  
16 -SIP\u7528\u6237\u8BA4\u8BC1\u5BC6\u7801=szSipAuthenticatePasswd  
17 -\u6CE8\u518C\u6709\u6548\u671F=dwRegisterValid  
18 -\u5FC3\u8DF3\u95F4\u9694=byHeartbeatInterval  
19 -\u670D\u52A1\u5668ID=szServerID  
20 -\u53D6\u6D41\u7C7B\u578B\uFF1A0-\u4E3B\u7801\u6D41\uFF0C1-\u5B50\u7801\u6D41\uFF0C2-\u4E09\u7801\u6D41=byStreamType  
21 -\u670D\u52A1\u5668SIP\u7AEF\u53E3=wServerSipPort  
22 -\u8BBE\u5907\u662F\u5426\u5728\u7EBF\u72B6\u6001\uFF1A0-\u4FDD\u7559\uFF0C1-\u5728\u7EBF\uFF0C2-\u79BB\u7EBF =byDeviceStatus  
23 -\u534F\u8BAE\u7248\u672C\uFF1A0-GB/T28181-2011\uFF0C1-GB/T28181-2015\uFF0C2-GB/T28181-2016=byProtocolVersion  
24 -\u662F\u5426\u81EA\u52A8\u5206\u914D\u901A\u9053ID\uFF0C\u6309\u4F4D\u8868\u793A\uFF0C\u53D6\u503C\uFF1A0-\u624B\u52A8\u914D\u7F6E\uFF0C1-\u81EA\u52A8\u5206\u914D=dwAutoAllocChannelID  
25 -SIP\u670D\u52A1\u5668\u5730\u5740=szSipServerAddress  
26 -SIP\u7528\u6237\u8BA4\u8BC1ID(\u6CE8\u518C\u7528\u6237\u540D)=szSipAuthenticateID  
27 -\u6CE8\u518C\u95F4\u9694\uFF08\u6CE8\u518C\u5931\u8D25\u540E\u518D\u6B21\u6CE8\u518C\u7684\u65F6\u95F4\u95F4\u9694\uFF09=dwRegisterInterval  
28 -\u8BBE\u5907SIP\u7AEF\u53E3=wLocalSipPort  
29 -\u4F20\u8F93\u534F\u8BAE(0-UDP\uFF0C1-TCP)=byTransProtocol  
1 - #base  
2 - ip=IP  
3 - username=\u7528\u6237\u540D  
4 - password=\u5BC6\u7801  
5 - port=\u7AEF\u53E3  
6 - msg=\u9519\u8BEF\u4FE1\u606F  
7 - status=\u64CD\u4F5C\u72B6\u6001  
8 -  
9 - #aisle  
10 - chanName=\u901A\u9053\u540D\u79F0  
11 -  
12 - #GBT28181  
13 - byEnable=28181\u534F\u8BAE\u4F7F\u80FD  
14 - byTransProtocol=\u4F20\u8F93\u534F\u8BAE(0-UDP\uFF0C1-TCP)  
15 - wLocalSipPort=\u8BBE\u5907SIP\u7AEF\u53E3  
16 - szServerID=\u670D\u52A1\u5668ID  
17 - szServerDomain=\u670D\u52A1\u5668\u57DF  
18 - szSipServerAddress=SIP\u670D\u52A1\u5668\u5730\u5740  
19 - wServerSipPort=\u670D\u52A1\u5668SIP\u7AEF\u53E3  
20 - byProtocolVersion=\u534F\u8BAE\u7248\u672C\uFF1A0-GB/T28181-2011\uFF0C1-GB/T28181-2015\uFF0C2-GB/T28181-2016  
21 - szSipUserName=SIP\u7528\u6237\u540D  
22 - szSipAuthenticateID=SIP\u7528\u6237\u8BA4\u8BC1ID(\u6CE8\u518C\u7528\u6237\u540D)  
23 - szSipAuthenticatePasswd=SIP\u7528\u6237\u8BA4\u8BC1\u5BC6\u7801  
24 - dwRegisterValid=\u6CE8\u518C\u6709\u6548\u671F  
25 - byHeartbeatInterval=\u5FC3\u8DF3\u95F4\u9694  
26 - byMaxHeartbeatTimeOut=\u6700\u5927\u5FC3\u8DF3\u8D85\u65F6\u6B21\u6570  
27 - byStreamType=\u53D6\u6D41\u7C7B\u578B\uFF1A0-\u4E3B\u7801\u6D41\uFF0C1-\u5B50\u7801\u6D41\uFF0C2-\u4E09\u7801\u6D41  
28 - byDeviceStatus=\u8BBE\u5907\u662F\u5426\u5728\u7EBF\u72B6\u6001\uFF1A0-\u4FDD\u7559\uFF0C1-\u5728\u7EBF\uFF0C2-\u79BB\u7EBF  
29 - dwRegisterInterval=\u6CE8\u518C\u95F4\u9694\uFF08\u6CE8\u518C\u5931\u8D25\u540E\u518D\u6B21\u6CE8\u518C\u7684\u65F6\u95F4\u95F4\u9694\uFF09  
30 - dwAutoAllocChannelID=\u662F\u5426\u81EA\u52A8\u5206\u914D\u901A\u9053ID\uFF0C\u6309\u4F4D\u8868\u793A\uFF0C\u53D6\u503C\uFF1A0-\u624B\u52A8\u914D\u7F6E\uFF0C1-\u81EA\u52A8\u5206\u914D  
31 -  
32 -  
33 -  
34 -  
35 -  
36 -  
37 -  
38 -  
39 -  
40 -  
  1 +
  2 +docker run -d -p 1935:1935 -p 80:80 -p 443:443 -p 8554:554 -p 10000:10000 -p 10000:10000/udp -p 8000:8000/udp --name zlmediakit --restart=always 3471609dacbf
  3 +docker exec zlmediakit grep '^secret=' /opt/media/conf/config.ini
1 -HK_NET_ERROR_0=\u6CA1\u6709\u9519\u8BEF\u3002  
2 -HK_NET_ERROR_1=\u7528\u6237\u540D\u5BC6\u7801\u9519\u8BEF\u3002\u6CE8\u518C\u65F6\u8F93\u5165\u7684\u7528\u6237\u540D\u6216\u8005\u5BC6\u7801\u9519\u8BEF\u3002  
3 -HK_NET_ERROR_2=\u6743\u9650\u4E0D\u8DB3\u3002\u4E00\u822C\u548C\u901A\u9053\u76F8\u5173\uFF0C\u4F8B\u5982\u6709\u9884\u89C8\u901A\u90531\u6743\u9650\uFF0C\u65E0\u9884\u89C8\u901A\u90532\u6743\u9650\uFF0C\u5373\u6709\u9884\u89C8\u6743\u9650\u4F46\u4E0D\u5B8C\u5168\uFF0C\u9884\u89C8\u901A\u90532\u8FD4\u56DE\u6B64\u9519\u8BEF\u3002  
4 -HK_NET_ERROR_3=SDK\u672A\u521D\u59CB\u5316\u3002  
5 -HK_NET_ERROR_4=\u901A\u9053\u53F7\u9519\u8BEF\u3002\u8BBE\u5907\u6CA1\u6709\u5BF9\u5E94\u7684\u901A\u9053\u53F7\u3002  
6 -HK_NET_ERROR_5=\u8BBE\u5907\u603B\u7684\u8FDE\u63A5\u6570\u8D85\u8FC7\u6700\u5927\u3002  
7 -HK_NET_ERROR_6=\u7248\u672C\u4E0D\u5339\u914D\u3002SDK\u548C\u8BBE\u5907\u7684\u7248\u672C\u4E0D\u5339\u914D\u3002  
8 -HK_NET_ERROR_7=\u8FDE\u63A5\u8BBE\u5907\u5931\u8D25\u3002\u8BBE\u5907\u4E0D\u5728\u7EBF\u6216\u7F51\u7EDC\u539F\u56E0\u5F15\u8D77\u7684\u8FDE\u63A5\u8D85\u65F6\u7B49\u3002  
9 -HK_NET_ERROR_8=\u5411\u8BBE\u5907\u53D1\u9001\u5931\u8D25\u3002  
10 -HK_NET_ERROR_9=\u4ECE\u8BBE\u5907\u63A5\u6536\u6570\u636E\u5931\u8D25\u3002  
11 -HK_NET_ERROR_10=\u4ECE\u8BBE\u5907\u63A5\u6536\u6570\u636E\u8D85\u65F6\u3002  
12 -HK_NET_ERROR_11=\u4F20\u9001\u7684\u6570\u636E\u6709\u8BEF\u3002\u53D1\u9001\u7ED9\u8BBE\u5907\u6216\u8005\u4ECE\u8BBE\u5907\u63A5\u6536\u5230\u7684\u6570\u636E\u9519\u8BEF\uFF0C\u5982\u8FDC\u7A0B\u53C2\u6570\u914D\u7F6E\u65F6\u8F93\u5165\u8BBE\u5907\u4E0D\u652F\u6301\u7684\u503C\u3002  
13 -HK_NET_ERROR_12=\u8C03\u7528\u6B21\u5E8F\u9519\u8BEF\u3002  
14 -HK_NET_ERROR_13=\u65E0\u6B64\u6743\u9650\u3002\u7528\u6237\u5BF9\u67D0\u4E2A\u529F\u80FD\u6A21\u5757\u7684\u6743\u9650\uFF0C\u4F8B\u5982\u65E0\u9884\u89C8\u6743\u9650\u7528\u6237\u9884\u89C8\u8FD4\u56DE\u6B64\u9519\u8BEF\u3002  
15 -HK_NET_ERROR_14=\u8BBE\u5907\u547D\u4EE4\u6267\u884C\u8D85\u65F6\u3002  
16 -HK_NET_ERROR_15=\u4E32\u53E3\u53F7\u9519\u8BEF\u3002\u6307\u5B9A\u7684\u8BBE\u5907\u4E32\u53E3\u53F7\u4E0D\u5B58\u5728\u3002  
17 -HK_NET_ERROR_16=\u62A5\u8B66\u7AEF\u53E3\u9519\u8BEF\u3002\u6307\u5B9A\u7684\u8BBE\u5907\u62A5\u8B66\u8F93\u5165\u6216\u8005\u8F93\u51FA\u7AEF\u53E3\u4E0D\u5B58\u5728\u3002  
18 -HK_NET_ERROR_17=\u53C2\u6570\u9519\u8BEF\u3002SDK\u63A5\u53E3\u4E2D\u7ED9\u5165\u7684\u8F93\u5165\u6216\u8F93\u51FA\u53C2\u6570\u4E3A\u7A7A\uFF0C\u6216\u8005\u53C2\u6570\u683C\u5F0F\u6216\u503C\u4E0D\u7B26\u5408\u8981\u6C42\u3002  
19 -HK_NET_ERROR_18=\u8BBE\u5907\u901A\u9053\u5904\u4E8E\u9519\u8BEF\u72B6\u6001  
20 -HK_NET_ERROR_19=\u8BBE\u5907\u65E0\u786C\u76D8\u3002\u5F53\u8BBE\u5907\u65E0\u786C\u76D8\u65F6\uFF0C\u5BF9\u8BBE\u5907\u7684\u5F55\u50CF\u6587\u4EF6\u3001\u786C\u76D8\u914D\u7F6E\u7B49\u64CD\u4F5C\u5931\u8D25\u3002  
21 -HK_NET_ERROR_20=\u786C\u76D8\u53F7\u9519\u8BEF\u3002\u5F53\u5BF9\u8BBE\u5907\u8FDB\u884C\u786C\u76D8\u7BA1\u7406\u64CD\u4F5C\u65F6\uFF0C\u6307\u5B9A\u7684\u786C\u76D8\u53F7\u4E0D\u5B58\u5728\u65F6\u8FD4\u56DE\u8BE5\u9519\u8BEF\u3002  
22 -HK_NET_ERROR_21=\u8BBE\u5907\u786C\u76D8\u6EE1\u3002  
23 -HK_NET_ERROR_22=\u8BBE\u5907\u786C\u76D8\u51FA\u9519  
24 -HK_NET_ERROR_23=\u8BBE\u5907\u4E0D\u652F\u6301\u3002  
25 -HK_NET_ERROR_24=\u8BBE\u5907\u5FD9\u3002  
26 -HK_NET_ERROR_25=\u8BBE\u5907\u4FEE\u6539\u4E0D\u6210\u529F\u3002  
27 -HK_NET_ERROR_26=\u5BC6\u7801\u8F93\u5165\u683C\u5F0F\u4E0D\u6B63\u786E  
28 -HK_NET_ERROR_27=\u786C\u76D8\u6B63\u5728\u683C\u5F0F\u5316\uFF0C\u4E0D\u80FD\u542F\u52A8\u64CD\u4F5C\u3002  
29 -HK_NET_ERROR_28=\u8BBE\u5907\u8D44\u6E90\u4E0D\u8DB3\u3002  
30 -HK_NET_ERROR_29=\u8BBE\u5907\u64CD\u4F5C\u5931\u8D25\u3002  
31 -HK_NET_ERROR_30=\u8BED\u97F3\u5BF9\u8BB2\u3001\u8BED\u97F3\u5E7F\u64AD\u64CD\u4F5C\u4E2D\u91C7\u96C6\u672C\u5730\u97F3\u9891\u6216\u6253\u5F00\u97F3\u9891\u8F93\u51FA\u5931\u8D25\u3002  
32 -HK_NET_ERROR_31=\u8BBE\u5907\u8BED\u97F3\u5BF9\u8BB2\u88AB\u5360\u7528\u3002  
33 -HK_NET_ERROR_32=\u65F6\u95F4\u8F93\u5165\u4E0D\u6B63\u786E\u3002  
34 -HK_NET_ERROR_33=\u56DE\u653E\u65F6\u8BBE\u5907\u6CA1\u6709\u6307\u5B9A\u7684\u6587\u4EF6\u3002  
35 -HK_NET_ERROR_34=\u521B\u5EFA\u6587\u4EF6\u51FA\u9519\u3002\u672C\u5730\u5F55\u50CF\u3001\u4FDD\u5B58\u56FE\u7247\u3001\u83B7\u53D6\u914D\u7F6E\u6587\u4EF6\u548C\u8FDC\u7A0B\u4E0B\u8F7D\u5F55\u50CF\u65F6\u521B\u5EFA\u6587\u4EF6\u5931\u8D25\u3002  
36 -HK_NET_ERROR_35=\u6253\u5F00\u6587\u4EF6\u51FA\u9519\u3002\u53EF\u80FD\u56E0\u4E3A\u6587\u4EF6\u4E0D\u5B58\u5728\u6216\u8005\u8DEF\u5F84\u9519\u8BEF\u3002  
37 -HK_NET_ERROR_36=\u4E0A\u6B21\u7684\u64CD\u4F5C\u8FD8\u6CA1\u6709\u5B8C\u6210\u3002  
38 -HK_NET_ERROR_37=\u83B7\u53D6\u5F53\u524D\u64AD\u653E\u7684\u65F6\u95F4\u51FA\u9519\u3002  
39 -HK_NET_ERROR_38=\u64AD\u653E\u51FA\u9519\u3002  
40 -HK_NET_ERROR_39=\u6587\u4EF6\u683C\u5F0F\u4E0D\u6B63\u786E\u3002  
41 -HK_NET_ERROR_40=\u8DEF\u5F84\u9519\u8BEF  
42 -HK_NET_ERROR_41=SDK\u8D44\u6E90\u5206\u914D\u9519\u8BEF\u3002  
43 -HK_NET_ERROR_42=\u58F0\u5361\u6A21\u5F0F\u9519\u8BEF\u3002\u5F53\u524D\u6253\u5F00\u58F0\u97F3\u64AD\u653E\u6A21\u5F0F\u4E0E\u5B9E\u9645\u8BBE\u7F6E\u7684\u6A21\u5F0F\u4E0D\u7B26\u51FA\u9519\u3002  
44 -HK_NET_ERROR_43=\u7F13\u51B2\u533A\u592A\u5C0F\u3002\u63A5\u6536\u8BBE\u5907\u6570\u636E\u7684\u7F13\u51B2\u533A\u6216\u5B58\u653E\u56FE\u7247\u7F13\u51B2\u533A\u4E0D\u8DB3\u3002  
45 -HK_NET_ERROR_44=\u521B\u5EFASOCKET\u51FA\u9519\u3002  
46 -HK_NET_ERROR_45=\u8BBE\u7F6ESOCKET\u51FA\u9519\u3002  
47 -HK_NET_ERROR_46=\u4E2A\u6570\u8FBE\u5230\u6700\u5927\u3002\u5206\u914D\u7684\u6CE8\u518C\u8FDE\u63A5\u6570\u3001\u9884\u89C8\u8FDE\u63A5\u6570\u8D85\u8FC7SDK\u652F\u6301\u7684\u6700\u5927\u6570\u3002  
48 -HK_NET_ERROR_47=\u7528\u6237\u4E0D\u5B58\u5728\u3002\u6CE8\u518C\u7684\u7528\u6237ID\u5DF2\u6CE8\u9500\u6216\u4E0D\u53EF\u7528\u3002  
49 -HK_NET_ERROR_48=\u5199FLASH\u51FA\u9519\u3002\u8BBE\u5907\u5347\u7EA7\u65F6\u5199FLASH\u5931\u8D25\u3002  
50 -HK_NET_ERROR_49=\u8BBE\u5907\u5347\u7EA7\u5931\u8D25\u3002\u7F51\u7EDC\u6216\u5347\u7EA7\u6587\u4EF6\u8BED\u8A00\u4E0D\u5339\u914D\u7B49\u539F\u56E0\u5347\u7EA7\u5931\u8D25\u3002  
51 -HK_NET_ERROR_50=\u89E3\u7801\u5361\u5DF2\u7ECF\u521D\u59CB\u5316\u8FC7\u3002  
52 -HK_NET_ERROR_51=\u8C03\u7528\u64AD\u653E\u5E93\u4E2D\u67D0\u4E2A\u51FD\u6570\u5931\u8D25\u3002  
53 -HK_NET_ERROR_52=\u767B\u5F55\u8BBE\u5907\u7684\u7528\u6237\u6570\u8FBE\u5230\u6700\u5927\u3002  
54 -HK_NET_ERROR_53=\u83B7\u5F97\u672C\u5730PC\u7684IP\u5730\u5740\u6216\u7269\u7406\u5730\u5740\u5931\u8D25\u3002  
55 -HK_NET_ERROR_54=\u8BBE\u5907\u8BE5\u901A\u9053\u6CA1\u6709\u542F\u52A8\u7F16\u7801\u3002  
56 -HK_NET_ERROR_55=IP\u5730\u5740\u4E0D\u5339\u914D\u3002  
57 -HK_NET_ERROR_56=MAC\u5730\u5740\u4E0D\u5339\u914D\u3002  
58 -HK_NET_ERROR_57=\u5347\u7EA7\u6587\u4EF6\u8BED\u8A00\u4E0D\u5339\u914D\u3002  
59 -HK_NET_ERROR_58=\u64AD\u653E\u5668\u8DEF\u6570\u8FBE\u5230\u6700\u5927\u3002  
60 -HK_NET_ERROR_59=\u5907\u4EFD\u8BBE\u5907\u4E2D\u6CA1\u6709\u8DB3\u591F\u7A7A\u95F4\u8FDB\u884C\u5907\u4EFD\u3002  
61 -HK_NET_ERROR_60=\u6CA1\u6709\u627E\u5230\u6307\u5B9A\u7684\u5907\u4EFD\u8BBE\u5907\u3002  
62 -HK_NET_ERROR_61=\u56FE\u50CF\u7D20\u4F4D\u6570\u4E0D\u7B26\uFF0C\u965024\u8272\u3002  
63 -HK_NET_ERROR_62=\u56FE\u7247\u9AD8*\u5BBD\u8D85\u9650\uFF0C\u9650128*256\u3002  
64 -HK_NET_ERROR_63=\u56FE\u7247\u5927\u5C0F\u8D85\u9650\uFF0C\u9650100K\u3002  
65 -HK_NET_ERROR_64=\u8F7D\u5165\u5F53\u524D\u76EE\u5F55\u4E0B\u64AD\u653E\u5E93(PlayCtrl.dll\u3001SuperRender.dll\u3001AudioRender.dll)\u51FA\u9519\u3002  
66 -HK_NET_ERROR_65=\u627E\u4E0D\u5230Player Sdk\u4E2D\u67D0\u4E2A\u51FD\u6570\u5165\u53E3\u3002  
67 -HK_NET_ERROR_66=\u8F7D\u5165\u5F53\u524D\u76EE\u5F55\u4E0BDSsdk\u51FA\u9519\u3002  
68 -HK_NET_ERROR_67=\u627E\u4E0D\u5230DsSdk\u4E2D\u67D0\u4E2A\u51FD\u6570\u5165\u53E3\u3002  
69 -HK_NET_ERROR_68=\u8C03\u7528\u786C\u89E3\u7801\u5E93DsSdk\u4E2D\u67D0\u4E2A\u51FD\u6570\u5931\u8D25\u3002  
70 -HK_NET_ERROR_69=\u58F0\u5361\u88AB\u72EC\u5360\u3002  
71 -HK_NET_ERROR_70=\u52A0\u5165\u591A\u64AD\u7EC4\u5931\u8D25\u3002  
72 -HK_NET_ERROR_71=\u5EFA\u7ACB\u65E5\u5FD7\u6587\u4EF6\u76EE\u5F55\u5931\u8D25\u3002  
73 -HK_NET_ERROR_72=\u7ED1\u5B9A\u5957\u63A5\u5B57\u5931\u8D25\u3002  
74 -HK_NET_ERROR_73=socket\u8FDE\u63A5\u4E2D\u65AD\uFF0C\u6B64\u9519\u8BEF\u901A\u5E38\u662F\u7531\u4E8E\u8FDE\u63A5\u4E2D\u65AD\u6216\u76EE\u7684\u5730\u4E0D\u53EF\u8FBE\u3002  
75 -HK_NET_ERROR_74=\u6CE8\u9500\u65F6\u7528\u6237ID\u6B63\u5728\u8FDB\u884C\u67D0\u64CD\u4F5C\u3002  
76 -HK_NET_ERROR_75=\u76D1\u542C\u5931\u8D25\u3002  
77 -HK_NET_ERROR_76=\u7A0B\u5E8F\u5F02\u5E38\u3002  
78 -HK_NET_ERROR_77=\u5199\u6587\u4EF6\u5931\u8D25\u3002\u672C\u5730\u5F55\u50CF\u3001\u8FDC\u7A0B\u4E0B\u8F7D\u5F55\u50CF\u3001\u4E0B\u8F7D\u56FE\u7247\u7B49\u64CD\u4F5C\u65F6\u5199\u6587\u4EF6\u5931\u8D25\u3002  
79 -HK_NET_ERROR_78=\u7981\u6B62\u683C\u5F0F\u5316\u53EA\u8BFB\u786C\u76D8\u3002  
80 -HK_NET_ERROR_79=\u8FDC\u7A0B\u7528\u6237\u914D\u7F6E\u7ED3\u6784\u4E2D\u5B58\u5728\u76F8\u540C\u7684\u7528\u6237\u540D\u3002  
81 -HK_NET_ERROR_80=\u5BFC\u5165\u53C2\u6570\u65F6\u8BBE\u5907\u578B\u53F7\u4E0D\u5339\u914D\u3002  
82 -HK_NET_ERROR_81=\u5BFC\u5165\u53C2\u6570\u65F6\u8BED\u8A00\u4E0D\u5339\u914D\u3002  
83 -HK_NET_ERROR_82=\u5BFC\u5165\u53C2\u6570\u65F6\u8F6F\u4EF6\u7248\u672C\u4E0D\u5339\u914D\u3002  
84 -HK_NET_ERROR_83=\u9884\u89C8\u65F6\u5916\u63A5IP\u901A\u9053\u4E0D\u5728\u7EBF\u3002  
85 -HK_NET_ERROR_84=\u52A0\u8F7D\u6807\u51C6\u534F\u8BAE\u901A\u8BAF\u5E93(StreamTransClient.dll)\u5931\u8D25\u3002  
86 -HK_NET_ERROR_85=\u52A0\u8F7D\u8F6C\u5C01\u88C5\u5E93(SystemTransform.dll)\u5931\u8D25\u3002  
87 -HK_NET_ERROR_86=\u8D85\u51FA\u6700\u5927\u7684IP\u63A5\u5165\u901A\u9053\u6570\u3002  
88 -HK_NET_ERROR_87=\u6DFB\u52A0\u5F55\u50CF\u6807\u7B7E\u6216\u8005\u5176\u4ED6\u64CD\u4F5C\u8D85\u51FA\u6700\u591A\u652F\u6301\u7684\u4E2A\u6570\u3002  
89 -HK_NET_ERROR_88=\u56FE\u50CF\u589E\u5F3A\u4EEA\uFF0C\u53C2\u6570\u6A21\u5F0F\u9519\u8BEF\uFF08\u7528\u4E8E\u786C\u4EF6\u8BBE\u7F6E\u65F6\uFF0C\u5BA2\u6237\u7AEF\u8FDB\u884C\u8F6F\u4EF6\u8BBE\u7F6E\u65F6\u9519\u8BEF\u503C\uFF09\u3002  
90 -HK_NET_ERROR_89=\u7801\u5206\u5668\u4E0D\u5728\u7EBF\u3002  
91 -HK_NET_ERROR_90=\u8BBE\u5907\u6B63\u5728\u5907\u4EFD\u3002  
92 -HK_NET_ERROR_91=\u901A\u9053\u4E0D\u652F\u6301\u8BE5\u64CD\u4F5C\u3002  
93 -HK_NET_ERROR_92=\u9AD8\u5EA6\u7EBF\u4F4D\u7F6E\u592A\u96C6\u4E2D\u6216\u957F\u5EA6\u7EBF\u4E0D\u591F\u503E\u659C\u3002  
94 -HK_NET_ERROR_93=\u53D6\u6D88\u6807\u5B9A\u51B2\u7A81\uFF0C\u5982\u679C\u8BBE\u7F6E\u4E86\u89C4\u5219\u53CA\u5168\u5C40\u7684\u5B9E\u9645\u5927\u5C0F\u5C3A\u5BF8\u8FC7\u6EE4\u3002  
95 -HK_NET_ERROR_94=\u6807\u5B9A\u70B9\u8D85\u51FA\u8303\u56F4\u3002  
96 -HK_NET_ERROR_95=\u5C3A\u5BF8\u8FC7\u6EE4\u5668\u4E0D\u7B26\u5408\u8981\u6C42\u3002  
97 -HK_NET_ERROR_96=\u8BBE\u5907\u6CA1\u6709\u6CE8\u518C\u5230ddns\u4E0A\u3002  
98 -HK_NET_ERROR_97=DDNS \u670D\u52A1\u5668\u5185\u90E8\u9519\u8BEF\u3002  
99 -HK_NET_ERROR_98=\u6B64\u529F\u80FD\u4E0D\u652F\u6301\u8BE5\u64CD\u4F5C\u7CFB\u7EDF\u3002  
100 -HK_NET_ERROR_99=\u89E3\u7801\u901A\u9053\u7ED1\u5B9A\u663E\u793A\u8F93\u51FA\u6B21\u6570\u53D7\u9650\u3002  
101 -HK_NET_ERROR_100=\u52A0\u8F7D\u5F53\u524D\u76EE\u5F55\u4E0B\u7684\u8BED\u97F3\u5BF9\u8BB2\u5E93\u5931\u8D25\u3002  
102 -HK_NET_ERROR_101=\u6CA1\u6709\u6B63\u786E\u7684\u5347\u7EA7\u5305\u3002  
103 -HK_NET_ERROR_102=\u7528\u6237\u8FD8\u6CA1\u767B\u5F55\u6210\u529F\u3002  
104 -HK_NET_ERROR_103=\u6B63\u5728\u4F7F\u7528\u65E5\u5FD7\u5F00\u5173\u6587\u4EF6\u3002  
105 -HK_NET_ERROR_104=\u7AEF\u53E3\u6C60\u4E2D\u7528\u4E8E\u7ED1\u5B9A\u7684\u7AEF\u53E3\u5DF2\u8017\u5C3D\u3002  
106 -HK_NET_ERROR_105=\u7801\u6D41\u5C01\u88C5\u683C\u5F0F\u9519\u8BEF\u3002  
107 -HK_NET_ERROR_106=IP\u63A5\u5165\u914D\u7F6E\u65F6IPID\u6709\u8BEF\u3002  
108 -HK_NET_ERROR_107=\u9884\u89C8\u7EC4\u4EF6\u52A0\u8F7D\u5931\u8D25\u3002  
109 -HK_NET_ERROR_108=\u8BED\u97F3\u7EC4\u4EF6\u52A0\u8F7D\u5931\u8D25\u3002  
110 -HK_NET_ERROR_109=\u62A5\u8B66\u7EC4\u4EF6\u52A0\u8F7D\u5931\u8D25\u3002  
111 -HK_NET_ERROR_110=\u56DE\u653E\u7EC4\u4EF6\u52A0\u8F7D\u5931\u8D25\u3002  
112 -HK_NET_ERROR_111=\u663E\u793A\u7EC4\u4EF6\u52A0\u8F7D\u5931\u8D25\u3002  
113 -HK_NET_ERROR_112=\u884C\u4E1A\u5E94\u7528\u7EC4\u4EF6\u52A0\u8F7D\u5931\u8D25\u3002  
114 -HK_NET_ERROR_113=\u901A\u7528\u914D\u7F6E\u7BA1\u7406\u7EC4\u4EF6\u52A0\u8F7D\u5931\u8D25\u3002  
115 -HK_NET_ERROR_114=\u8BBE\u5907\u914D\u7F6E\u6838\u5FC3\u7EC4\u4EF6\u52A0\u8F7D\u5931\u8D25\u3002  
116 -HK_NET_ERROR_121=\u5355\u72EC\u52A0\u8F7D\u7EC4\u4EF6\u65F6\uFF0C\u7EC4\u4EF6\u4E0Ecore\u7248\u672C\u4E0D\u5339\u914D\u3002  
117 -HK_NET_ERROR_122=\u9884\u89C8\u7EC4\u4EF6\u4E0Ecore\u7248\u672C\u4E0D\u5339\u914D\u3002  
118 -HK_NET_ERROR_123=\u8BED\u97F3\u7EC4\u4EF6\u4E0Ecore\u7248\u672C\u4E0D\u5339\u914D\u3002  
119 -HK_NET_ERROR_124=\u62A5\u8B66\u7EC4\u4EF6\u4E0Ecore\u7248\u672C\u4E0D\u5339\u914D\u3002  
120 -HK_NET_ERROR_125=\u56DE\u653E\u7EC4\u4EF6\u4E0Ecore\u7248\u672C\u4E0D\u5339\u914D\u3002  
121 -HK_NET_ERROR_126=\u663E\u793A\u7EC4\u4EF6\u4E0Ecore\u7248\u672C\u4E0D\u5339\u914D\u3002  
122 -HK_NET_ERROR_127=\u884C\u4E1A\u5E94\u7528\u7EC4\u4EF6\u4E0Ecore\u7248\u672C\u4E0D\u5339\u914D\u3002  
123 -HK_NET_ERROR_128=\u901A\u7528\u914D\u7F6E\u7BA1\u7406\u7EC4\u4EF6\u4E0Ecore\u7248\u672C\u4E0D\u5339\u914D\u3002  
124 -HK_NET_ERROR_136=\u9884\u89C8\u7EC4\u4EF6\u4E0EHCNetSDK\u7248\u672C\u4E0D\u5339\u914D\u3002  
125 -HK_NET_ERROR_137=\u8BED\u97F3\u7EC4\u4EF6\u4E0EHCNetSDK\u7248\u672C\u4E0D\u5339\u914D\u3002  
126 -HK_NET_ERROR_138=\u62A5\u8B66\u7EC4\u4EF6\u4E0EHCNetSDK\u7248\u672C\u4E0D\u5339\u914D\u3002  
127 -HK_NET_ERROR_139=\u56DE\u653E\u7EC4\u4EF6\u4E0EHCNetSDK\u7248\u672C\u4E0D\u5339\u914D\u3002  
128 -HK_NET_ERROR_140=\u663E\u793A\u7EC4\u4EF6\u4E0EHCNetSDK\u7248\u672C\u4E0D\u5339\u914D\u3002  
129 -HK_NET_ERROR_141=\u884C\u4E1A\u5E94\u7528\u7EC4\u4EF6\u4E0EHCNetSDK\u7248\u672C\u4E0D\u5339\u914D\u3002  
130 -HK_NET_ERROR_142=\u901A\u7528\u914D\u7F6E\u7BA1\u7406\u7EC4\u4EF6\u4E0EHCNetSDK\u7248\u672C\u4E0D\u5339\u914D\u3002  
131 -HK_NET_ERROR_150=\u522B\u540D\u91CD\u590D\uFF08HiDDNS\u7684\u914D\u7F6E\uFF09\u3002  
132 -HK_NET_ERROR_152=\u7528\u6237\u540D\u4E0D\u5B58\u5728\uFF08V5.1.7~V5.3.1\u7248\u672C\u7684IPC\u3001IPD\u7684\u9519\u8BEF\u7801\uFF09\u3002  
133 -HK_NET_ERROR_153=\u7528\u6237\u540D\u88AB\u9501\u5B9A\u3002  
134 -HK_NET_ERROR_154=\u65E0\u6548\u7528\u6237ID\u3002  
135 -HK_NET_ERROR_155=\u767B\u5F55\u7248\u672C\u4F4E\u3002  
136 -HK_NET_ERROR_156=\u52A0\u8F7Dlibeay32.dll\u5E93\u5931\u8D25\u3002  
137 -HK_NET_ERROR_157=\u52A0\u8F7Dssleay32.dll\u5E93\u5931\u8D25\u3002  
138 -HK_NET_ERROR_158=\u52A0\u8F7Dlibiconv.dll\u5E93\u5931\u8D25\u3002  
139 -HK_NET_ERROR_165=\u8FDE\u63A5\u6D4B\u8BD5\u670D\u52A1\u5668\u5931\u8D25\u3002  
140 -HK_NET_ERROR_166=NAS\u670D\u52A1\u5668\u6302\u8F7D\u76EE\u5F55\u5931\u8D25\uFF0C\u76EE\u5F55\u65E0\u6548\u6216\u8005\u7528\u6237\u540D\u5BC6\u7801\u9519\u8BEF\u3002  
141 -HK_NET_ERROR_167=NAS\u670D\u52A1\u5668\u6302\u8F7D\u76EE\u5F55\u5931\u8D25\uFF0C\u6CA1\u6709\u6743\u9650\u3002  
142 -HK_NET_ERROR_168=\u670D\u52A1\u5668\u4F7F\u7528\u57DF\u540D\uFF0C\u4F46\u662F\u6CA1\u6709\u914D\u7F6EDNS\uFF0C\u53EF\u80FD\u9020\u6210\u57DF\u540D\u65E0\u6548\u3002  
143 -HK_NET_ERROR_169=\u6CA1\u6709\u914D\u7F6E\u7F51\u5173\uFF0C\u53EF\u80FD\u9020\u6210\u53D1\u9001\u90AE\u4EF6\u5931\u8D25\u3002  
144 -HK_NET_ERROR_170=\u7528\u6237\u540D\u5BC6\u7801\u4E0D\u6B63\u786E\uFF0C\u6D4B\u8BD5\u670D\u52A1\u5668\u7684\u7528\u6237\u540D\u6216\u5BC6\u7801\u9519\u8BEF\u3002  
145 -HK_NET_ERROR_171=\u8BBE\u5907\u548Csmtp\u670D\u52A1\u5668\u4EA4\u4E92\u5F02\u5E38\u3002  
146 -HK_NET_ERROR_172=FTP\u670D\u52A1\u5668\u521B\u5EFA\u76EE\u5F55\u5931\u8D25\u3002  
147 -HK_NET_ERROR_173=FTP\u670D\u52A1\u5668\u6CA1\u6709\u5199\u5165\u6743\u9650\u3002  
148 -HK_NET_ERROR_174=IP\u51B2\u7A81\u3002  
149 -HK_NET_ERROR_175=\u5B58\u50A8\u6C60\u7A7A\u95F4\u5DF2\u6EE1\u3002  
150 -HK_NET_ERROR_176=\u4E91\u670D\u52A1\u5668\u5B58\u50A8\u6C60\u65E0\u6548\uFF0C\u6CA1\u6709\u914D\u7F6E\u5B58\u50A8\u6C60\u6216\u8005\u5B58\u50A8\u6C60ID\u9519\u8BEF\u3002  
151 -HK_NET_ERROR_177=\u751F\u6548\u9700\u8981\u91CD\u542F\u3002  
152 -HK_NET_ERROR_178=\u65AD\u7F51\u7EED\u4F20\u5E03\u9632\u8FDE\u63A5\u5DF2\u7ECF\u5B58\u5728\uFF08\u79C1\u6709SDK\u534F\u8BAE\u5E03\u9632\u8FDE\u63A5\u5DF2\u7ECF\u5EFA\u7ACB\u7684\u60C5\u51B5\u4E0B\uFF0C\u91CD\u590D\u5E03\u9632\u4E14\u9009\u62E9\u65AD\u7F51\u7EED\u4F20\u529F\u80FD\u65F6\u8FD4\u56DE\u8BE5\u9519\u8BEF\uFF09\u3002  
153 -HK_NET_ERROR_179=\u65AD\u7F51\u7EED\u4F20\u4E0A\u4F20\u8FDE\u63A5\u5DF2\u7ECF\u5B58\u5728\uFF08EHOME\u534F\u8BAE\u548C\u79C1\u6709SDK\u534F\u8BAE\u4E0D\u80FD\u540C\u65F6\u652F\u6301\u65AD\u7F51\u7EED\u4F20\uFF0C\u5176\u4E2D\u4E00\u79CD\u534F\u8BAE\u5DF2\u7ECF\u5EFA\u8BAE\u8FDE\u63A5\uFF0C\u53E6\u5916\u4E00\u4E2A\u8FDE\u63A5\u5EFA\u7ACB\u65F6\u8FD4\u56DE\u8BE5\u9519\u8BEF\uFF09\u3002  
154 -HK_NET_ERROR_180=\u5BFC\u5165\u6587\u4EF6\u683C\u5F0F\u4E0D\u6B63\u786E\u3002  
155 -HK_NET_ERROR_181=\u5BFC\u5165\u6587\u4EF6\u5185\u5BB9\u4E0D\u6B63\u786E\u3002  
156 -HK_NET_ERROR_182=HRUDP\u8FDE\u63A5\u6570\u8D85\u8FC7\u8BBE\u5907\u9650\u5236\u3002  
1 -HK_SADP_ERROR_0=\u6CA1\u6709\u9519\u8BEF  
2 -HK_SADP_ERROR_2001=\u8D44\u6E90\u5206\u914D\u9519\u8BEF  
3 -HK_SADP_ERROR_2002=SADP \u672A\u542F\u52A8  
4 -HK_SADP_ERROR_2003=\u65E0\u7F51\u5361  
5 -HK_SADP_ERROR_2004=\u83B7\u53D6\u7F51\u5361\u4FE1\u606F\u5931\u8D25  
6 -HK_SADP_ERROR_2005=\u53C2\u6570\u9519\u8BEF  
7 -HK_SADP_ERROR_2006=\u6253\u5F00\u7F51\u5361\u5931\u8D25  
8 -HK_SADP_ERROR_2007=\u53D1\u9001\u6570\u636E\u5931\u8D25  
9 -HK_SADP_ERROR_2008=\u7CFB\u7EDF\u63A5\u53E3\u8C03\u7528\u5931\u8D25  
10 -HK_SADP_ERROR_2009=\u8BBE\u5907\u62D2\u7EDD\u5904\u7406  
11 -HK_SADP_ERROR_2010=\u5B89\u88C5 NPF \u670D\u52A1\u5931\u8D25  
12 -HK_SADP_ERROR_2011=\u8BBE\u5907\u54CD\u5E94\u8D85\u65F6  
13 -HK_SADP_ERROR_2012=\u521B\u5EFA socket \u5931\u8D25  
14 -HK_SADP_ERROR_2013=\u7ED1\u5B9A socket \u5931\u8D25  
15 -HK_SADP_ERROR_2014=\u52A0\u5165\u591A\u64AD\u7EC4\u5931\u8D25  
16 -HK_SADP_ERROR_2015=\u53D1\u9001\u51FA\u9519  
17 -HK_SADP_ERROR_2016=\u63A5\u6536\u51FA\u9519  
18 -HK_SADP_ERROR_2017=\u591A\u64AD XML \u89E3\u6790\u51FA\u9519  
19 -HK_SADP_ERROR_2018=\u8BBE\u5907\u9501\u5B9A  
20 -HK_SADP_ERROR_2019=\u8BBE\u5907\u672A\u6FC0\u6D3B  
21 -HK_SADP_ERROR_2020=\u98CE\u9669\u9AD8\u7684\u5BC6\u7801  
22 -HK_SADP_ERROR_2021=\u8BBE\u5907\u5DF2\u6FC0\u6D3B  
23 -HK_SADP_ERROR_8888=\u672A\u77E5\u9519\u8BEF  
1 -<!DOCTYPE html>  
2 -<html>  
3 -<head>  
4 - <title>多路摄像头实时播放</title>  
5 - <script src="https://cdn.jsdelivr.net/npm/zlmrtc4player"></script>  
6 - <style>  
7 - .grid {  
8 - display: grid;  
9 - grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));  
10 - gap: 10px;  
11 - }  
12 - video {  
13 - width: 100%;  
14 - height: auto;  
15 - background: black;  
16 - }  
17 - </style>  
18 -</head>  
19 -<body>  
20 - <h2>摄像头分屏实时播放</h2>  
21 - <div class="grid" id="videoGrid"></div>  
22 - <script>  
23 - const videoGrid = document.getElementById("videoGrid");  
24 - function playStream(videoEl, app, stream, retryCount = 0) {  
25 - const maxRetries = 5;  
26 - const retryDelay = 3000;  
27 - const player = new ZLMRTCClient.Endpoint({  
28 - video: videoEl,  
29 - protocol: location.protocol === "https:" ? "wss" : "ws",  
30 - host: location.hostname,  
31 - port: 80,  
32 - app,  
33 - stream  
34 - });  
35 - player.play().catch(() => {  
36 - if (retryCount < maxRetries) {  
37 - console.warn(`播放失败,重试第 ${retryCount + 1} 次:${stream}`);  
38 - setTimeout(() => playStream(videoEl, app, stream, retryCount + 1), retryDelay);  
39 - } else {  
40 - console.error(`播放失败:${stream},已达最大重试次数`);  
41 - }  
42 - });  
43 - }  
44 - cameras = [  
45 - {  
46 - name: '摄像头1',  
47 - app: 'live',  
48 - stream: 'cam1'  
49 - }  
50 - ];  
51 - cameras => {  
52 - cameras.forEach(cam => {  
53 - const container = document.createElement('div');  
54 - const label = document.createElement('p');  
55 - label.textContent = cam.name;  
56 - const video = document.createElement('video');  
57 - video.autoplay = true;  
58 - video.muted = true;  
59 - video.playsInline = true;  
60 - video.controls = true;  
61 - container.appendChild(label);  
62 - container.appendChild(video);  
63 - videoGrid.appendChild(container);  
64 - });  
65 - }  
66 - </script>  
67 -</body>  
68 -</html>  
  1 +<html>
  2 + <meta charset="utf-8">
  3 + <head>
  4 + <title>ZLM RTC demo</title>
  5 + <script src="./ZLMRTCClient.js"></script>
  6 + <script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
  7 + <script>
  8 + // VConsole will be exported to `window.VConsole` by default.
  9 + var vConsole = new window.VConsole();
  10 + </script>
  11 + <style>
  12 + video {
  13 + width: 40vw;
  14 + max-height: 50vh;
  15 + height: 22.5vw; /* 默认和宽:高为 16:9 */
  16 + object-fit: contain;
  17 + background-color: grey;
  18 + }
  19 + </style>
  20 + </head>
  21 +
  22 + <body>
  23 + <div style="text-align: center;">
  24 + <div>
  25 + <video id='video' controls autoplay>
  26 + Your browser is too old which doesn't support HTML5 video.
  27 + </video>
  28 +
  29 + <video id='selfVideo' controls autoplay>
  30 + Your browser is too old which doesn't support HTML5 video.
  31 + </video>
  32 + </div>
  33 +
  34 + <div style="float: left; width:30%;">
  35 + <span>已存在的流列表,点击自动播放:</span>
  36 + <ol id="olstreamlist">
  37 + <li>初始演示</li>
  38 + <li>每秒自动刷新</li>
  39 + </ol>
  40 + </div>
  41 +
  42 + <div style="float: right; width: 70%">
  43 + <p>
  44 + <label for="streamUrl">url:</label>
  45 + <input type="text" style="co; width:70%" id='streamUrl' value="https://192.168.0.100/index/api/webrtc?app=yuerle&stream=BA8609485&type=play">
  46 + </p>
  47 +
  48 + <p>
  49 + <label for="simulcast">simulcast:</label>
  50 + <input type="checkbox" id='simulcast'>
  51 + </p>
  52 + <p>
  53 + <label for="useCamera">useCamera:</label>
  54 + <input type="checkbox" id='useCamera' checked="checked">
  55 + </p>
  56 +
  57 +
  58 + <p>
  59 + <label for="audioEnable">audioEnable:</label>
  60 + <input type="checkbox" id='audioEnable' checked="checked">
  61 + </p>
  62 +
  63 + <p>
  64 + <label for="videoEnable">videoEnable:</label>
  65 + <input type="checkbox" id='videoEnable' checked="checked">
  66 + </p>
  67 +
  68 + <p>
  69 + <label for="method">method(play or push or echo):</label>
  70 + <input type="radio" name="method" value="echo" >echo
  71 + <input type="radio" name="method" value="push" >push
  72 + <input type="radio" name="method" value="play" checked = true>play
  73 + </p>
  74 + <p>
  75 + <label for="resolution">resolution:</label>
  76 + <select id="resolution">
  77 + </select>
  78 + </p>
  79 + <p>
  80 + <label for="datachannel">datachannel:</label>
  81 + <input id='datachannel' name="datachannel" type="checkbox" value="0">
  82 + </p>
  83 + <button onclick="start()">开始(start)</button>
  84 + <button onclick="stop()">停止(stop)</button>
  85 +
  86 + <p>
  87 + <label for="msgsend">msgsend:</label>
  88 + <input type="text" id='msgsend' value="hello word !">
  89 + </p>
  90 + <p>
  91 + <label for="msgrecv">msgrecv:</label>
  92 + <input type="text" id='msgrecv' disabled>
  93 + </p>
  94 + <button onclick="send()">发送(send by datachannel)</button>
  95 + <button onclick="close()">关闭(close datachannel)</button>
  96 +
  97 + <p>
  98 + <label for="videoDevice">videodevice:</label>
  99 + <select id="videoDevice">
  100 + </select>
  101 + </p>
  102 +
  103 + <p>
  104 + <label for="audioDevice">audiodevice:</label>
  105 + <select id="audioDevice">
  106 + </select>
  107 + </p>
  108 +
  109 + <p>
  110 + <label for="switchDevice">switchDevice:</label>
  111 + <input type="checkbox" id='switchDevice' checked="checked">
  112 + </p>
  113 + <button onclick="switchVideo()">切换视频(switch video)</button>
  114 + <button onclick="switchAudio()">切换音频(switch audio)</button>
  115 + </div>
  116 + </div>
  117 +
  118 + <script>
  119 + var player = null;
  120 + var recvOnly = true;
  121 + var resArr = [];
  122 +
  123 + var ishttps = 'https:' === document.location.protocol;
  124 + var isLocal = "file:" === document.location.protocol;
  125 +
  126 + const searchParams = new URL(document.location.href).searchParams;
  127 + let type = searchParams.get('type');
  128 + if (!['echo','push','play'].includes(type)) {
  129 + type = 'play';
  130 + }
  131 + recvOnly = type === 'play';
  132 + const apiPath = `/index/api/webrtc?app=${searchParams.get('app') ?? 'live'}&stream=${searchParams.get('stream') ?? 'test'}&type=${type}`;
  133 +
  134 + if(!ishttps && !isLocal){
  135 + alert('本demo需要在https的网站访问, 如果你要推流的话(this demo must access in site of https if you want to push stream)');
  136 + }
  137 +
  138 + const apiHost = isLocal ? "http://127.0.0.1" : `${document.location.protocol}//${window.location.host}`;
  139 + var url = apiHost + apiPath;
  140 +
  141 + document.getElementById('streamUrl').value = url;
  142 + document.getElementsByName("method").forEach((el,idx) => {
  143 + el.checked = el.value === type;
  144 + el.onclick = function(e) {
  145 + const url = new URL(document.getElementById('streamUrl').value);
  146 + url.searchParams.set("type",el.value);
  147 + document.getElementById('streamUrl').value = url.toString();
  148 + recvOnly = 'play' === el.value;
  149 + };
  150 + });
  151 +
  152 + ZLMRTCClient.GetAllScanResolution().forEach((r,i) => {
  153 + opt = document.createElement('option');
  154 + opt.text = `${r.label}(${r.width}x${r.height})`;
  155 + opt.value = r;
  156 + if (1080*720 <= r.width * r.height && r.width * r.height <= 1280*720) {
  157 + opt.selected = true;
  158 + }
  159 + document.getElementById("resolution").add(opt,null);
  160 + });
  161 +
  162 + ZLMRTCClient.GetAllMediaDevice().then(devices=>{
  163 + devices.forEach(device=>{
  164 + opt = document.createElement('option');
  165 + opt.text = device.label + ":"+device.deviceId
  166 + opt.value = JSON.stringify(device)
  167 + if(device.kind == 'videoinput'){
  168 + document.getElementById("videoDevice").add(opt,null)
  169 + }else if(device.kind == 'audioinput'){
  170 + document.getElementById("audioDevice").add(opt,null)
  171 + }else if(device.kind == 'audiooutput'){
  172 + // useless
  173 + //console.error('not support device')
  174 + }
  175 + })
  176 + }).catch(e=>{
  177 + console.error(e);
  178 + })
  179 +
  180 + function start_play(){
  181 + let elr = document.getElementById("resolution");
  182 + let res = elr.options[elr.selectedIndex].text.match(/\d+/g);
  183 + let h = parseInt(res.pop());
  184 + let w = parseInt(res.pop());
  185 +
  186 + const url = new URL(document.getElementById('streamUrl').value);
  187 + const newUrl = new URL(window.location.href);
  188 + let count = 0;
  189 + if (url.searchParams.has('app')) {
  190 + newUrl.searchParams.set('app', url.searchParams.get('app'));
  191 + count++;
  192 + }
  193 + if (url.searchParams.has('stream')) {
  194 + newUrl.searchParams.set('stream', url.searchParams.get('stream'));
  195 + count++;
  196 + }
  197 + if (url.searchParams.has('type')) {
  198 + newUrl.searchParams.set('type', url.searchParams.get('type'));
  199 + count++;
  200 + }
  201 + if (count > 0) {
  202 + window.history.pushState(null, null, newUrl);
  203 + }
  204 +
  205 + let elv = document.getElementById("videoDevice");
  206 + let ela = document.getElementById("audioDevice");
  207 +
  208 + let vdevid = ''
  209 + let adevid = ''
  210 +
  211 + if (!recvOnly) {
  212 + if (elv.selectedIndex !== -1) {
  213 + vdevid = JSON.parse(elv.options[elv.selectedIndex].value).deviceId
  214 + }
  215 + if (ela.selectedIndex !== -1) {
  216 + adevid = JSON.parse(ela.options[ela.selectedIndex].value).deviceId
  217 + }
  218 + }
  219 +
  220 + player = new ZLMRTCClient.Endpoint(
  221 + {
  222 + element: document.getElementById('video'),// video 标签
  223 + debug: true,// 是否打印日志
  224 + zlmsdpUrl:document.getElementById('streamUrl').value,//流地址
  225 + simulcast:document.getElementById('simulcast').checked,
  226 + useCamera:document.getElementById('useCamera').checked,
  227 + audioEnable:document.getElementById('audioEnable').checked,
  228 + videoEnable:document.getElementById('videoEnable').checked,
  229 + recvOnly:recvOnly,
  230 + resolution:{w,h},
  231 + usedatachannel:document.getElementById('datachannel').checked,
  232 + videoId:vdevid, // 不填选择默认的
  233 + audioId:adevid, // 不填选择默认的
  234 + }
  235 + );
  236 +
  237 + player.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR,function(e)
  238 + {
  239 + // ICE 协商出错
  240 + console.log('ICE 协商出错');
  241 + });
  242 +
  243 + player.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS,function(s)
  244 + {
  245 + //获取到了远端流,可以播放,如果element 为null 或者不传,可以在这里播放(如下注释代码)
  246 + /*
  247 + document.getElementById('video').srcObject=s;
  248 + */
  249 + console.log('播放成功',s);
  250 + });
  251 +
  252 + player.on(ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED,function(e)
  253 + {
  254 + // offer anwser 交换失败
  255 + console.log('offer anwser 交换失败',e);
  256 + stop();
  257 + });
  258 +
  259 + player.on(ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM,function(s)
  260 + {
  261 + // 获取到了本地流
  262 + document.getElementById('selfVideo').srcObject=s;
  263 + document.getElementById('selfVideo').muted = true;
  264 + //console.log('offer anwser 交换失败',e)
  265 + });
  266 +
  267 + player.on(ZLMRTCClient.Events.CAPTURE_STREAM_FAILED,function(s)
  268 + {
  269 + // 获取本地流失败
  270 + console.log('获取本地流失败');
  271 + });
  272 +
  273 + player.on(ZLMRTCClient.Events.WEBRTC_ON_CONNECTION_STATE_CHANGE,function(state)
  274 + {
  275 + // RTC 状态变化 ,详情参考 https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState
  276 + console.log('当前状态==>',state);
  277 + });
  278 +
  279 + player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_OPEN,function(event)
  280 + {
  281 + console.log('rtc datachannel 打开 :',event);
  282 + });
  283 +
  284 + player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_MSG,function(event)
  285 + {
  286 + console.log('rtc datachannel 消息 :',event.data);
  287 + document.getElementById('msgrecv').value = event.data;
  288 + });
  289 + player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_ERR,function(event)
  290 + {
  291 + console.log('rtc datachannel 错误 :',event);
  292 + });
  293 + player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_CLOSE,function(event)
  294 + {
  295 + console.log('rtc datachannel 关闭 :',event);
  296 + });
  297 + }
  298 +
  299 + function start()
  300 + {
  301 + stop();
  302 + let elr = document.getElementById("resolution");
  303 + let res = elr.options[elr.selectedIndex].text.match(/\d+/g);
  304 + let h = parseInt(res.pop());
  305 + let w = parseInt(res.pop());
  306 +
  307 + if(document.getElementById('useCamera').checked && !recvOnly)
  308 + {
  309 + ZLMRTCClient.isSupportResolution(w,h).then(e=>{
  310 + start_play();
  311 + }).catch(e=>{
  312 + alert("not support resolution");
  313 + });
  314 + }else{
  315 + start_play();
  316 + }
  317 + }
  318 +
  319 + function stop()
  320 + {
  321 + if(player)
  322 + {
  323 + player.close();
  324 + player = null;
  325 + var remote = document.getElementById('video');
  326 + if(remote)
  327 + {
  328 + remote.srcObject = null;
  329 + remote.load();
  330 + }
  331 + var local = document.getElementById('selfVideo');
  332 + local.srcObject = null;
  333 + local.load();
  334 + }
  335 + }
  336 +
  337 + function send(){
  338 + if(player){
  339 + //send msg refernece https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/send
  340 + player.sendMsg(document.getElementById('msgsend').value);
  341 + }
  342 + }
  343 +
  344 + function close(){
  345 + if(player){
  346 + player.closeDataChannel();
  347 + }
  348 + }
  349 +
  350 + function on_click_to_play(app, stream) {
  351 + console.log(`on_click_to_play: ${app}/${stream}`);
  352 + var url = `${document.location.protocol}//${window.location.host}/index/api/webrtc?app=${app}&stream=${stream}&type=play`;
  353 + document.getElementById('streamUrl').value = url;
  354 + start();
  355 + }
  356 +
  357 + function clearStreamList() {
  358 + let content = document.getElementById("olstreamlist");
  359 + while (content.hasChildNodes()) {
  360 + content.removeChild(content.firstChild);
  361 + }
  362 + }
  363 +
  364 + function fillStreamList(json) {
  365 + clearStreamList();
  366 + if (json.code != 0 || !json.data) {
  367 + return;
  368 + }
  369 + let ss = {};
  370 + for (let o of json.data) {
  371 + if (ss[o.app]) {
  372 + ss[o.app].add(o.stream);
  373 + } else {
  374 + let set = new Set();
  375 + set.add(o.stream);
  376 + ss[o.app] = set;
  377 + }
  378 + }
  379 +
  380 + for (let o in ss) {
  381 + let app = o;
  382 + for (let s of ss[o]) {
  383 + if (s) {
  384 + //console.log(app, s);
  385 + let content = document.getElementById("olstreamlist");
  386 + let child = `<li app="${app}" stream="${s}" onmouseover="this.style.color='blue';" onclick="on_click_to_play('${app}', '${s}')">${app}/${s}</li>`;
  387 + content.insertAdjacentHTML("beforeend", child);
  388 + }
  389 + }
  390 + }
  391 + }
  392 +
  393 + async function getData(url) {
  394 + const response = await fetch(url, {
  395 + method: 'GET'
  396 + });
  397 + const data = await response.json();
  398 + //console.log(data);
  399 + return data;
  400 + }
  401 +
  402 + function get_media_list() {
  403 + let url = document.location.protocol+"//"+window.location.host+"/index/api/getMediaList?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc";
  404 + let json = getData(url);
  405 + json.then((json)=> fillStreamList(json));
  406 + }
  407 +
  408 + setInterval(() => {
  409 + // get_media_list();
  410 + }, 5000);
  411 +
  412 + function switchVideo(){
  413 + if(player){
  414 + // first arg bool false mean switch to screen video , second ignore
  415 + // true mean switch to video , second is camera deviceid
  416 + let elv = document.getElementById("videoDevice");
  417 + let vdevid = JSON.parse(elv.options[elv.selectedIndex].value).deviceId
  418 + player.switchVideo(document.getElementById('switchDevice').checked,vdevid).then(()=>{
  419 + // switch video successful
  420 +
  421 + }).catch(e=>{
  422 + // switch video failed
  423 + console.error(e);
  424 + })
  425 + }
  426 +
  427 + }
  428 +
  429 + function switchAudio(){
  430 + if(player){
  431 + // first arg bool false mean switch to screen audio , second ignore
  432 + // true mean switch to mic , second is mic deviceid
  433 + let ela = document.getElementById("audioDevice");
  434 + let adevid = JSON.parse(ela.options[ela.selectedIndex].value).deviceId
  435 + player.switcAudio(document.getElementById('switchDevice').checked,adevid).then(()=>{
  436 + // switch audio successful
  437 +
  438 + }).catch(e=>{
  439 + // switch audio failed
  440 + console.error(e);
  441 + })
  442 + }
  443 + }
  444 +
  445 + </script>
  446 +
  447 + </body>
  448 +
  449 + <script>
  450 +
  451 + </script>
  452 +
  453 +</html>
  1 +感谢[big panda](<2381267071@qq.com>) 开发并贡献此webrtc js测试客户端,
  2 +其开源项目地址为:https://gitee.com/xiongguangjie/zlmrtcclient.js
  1 +mqtt.broker=tcp://iot.yu2le.com:1883
  2 +mqtt.username=lh_hk_encoder
  3 +mqtt.password=Luhui586
  4 +mqtt.clientId=9ca6fa549193430e9904553d0c0e3a62
  5 +mqtt.subTopic=PUT/+,READ/+
  6 +
  7 +yuerle.api.url=https://ly.api.yu2le.com/bigScreen/getYsLocalIp
  8 +
  9 +webrtc.host=192.168.0.100
  10 +webrtc.app=yuerle
  11 +webrtc.secret=keXTvTDSHAxFDpBA0MDAHhxWeVXLQmUq
  12 +
  13 +camera.serial=BA8609485
  14 +
  15 +sys.task.interval=60
@@ -2,6 +2,7 @@ package com.zhonglai.luhui.device.protocol.wp6.analysis.topic; @@ -2,6 +2,7 @@ package com.zhonglai.luhui.device.protocol.wp6.analysis.topic;
2 2
3 import com.google.gson.JsonObject; 3 import com.google.gson.JsonObject;
4 import com.ruoyi.common.utils.GsonConstructor; 4 import com.ruoyi.common.utils.GsonConstructor;
  5 +import com.zhonglai.luhui.device.analysis.comm.dto.ApiClientRePlyDto;
5 import com.zhonglai.luhui.device.analysis.dto.MessageCode; 6 import com.zhonglai.luhui.device.analysis.dto.MessageCode;
6 import com.zhonglai.luhui.device.protocol.factory.dto.AnalysisResult; 7 import com.zhonglai.luhui.device.protocol.factory.dto.AnalysisResult;
7 8
@@ -14,12 +15,12 @@ public class PutReq { @@ -14,12 +15,12 @@ public class PutReq {
14 public AnalysisResult analysisPayload(String payload) 15 public AnalysisResult analysisPayload(String payload)
15 { 16 {
16 JsonObject jsonObject = GsonConstructor.get().fromJson(payload, JsonObject.class); 17 JsonObject jsonObject = GsonConstructor.get().fromJson(payload, JsonObject.class);
17 - return new AnalysisResult(false, true, jsonObject, message -> { 18 + ApiClientRePlyDto noticeMessage = new ApiClientRePlyDto();
18 if(jsonObject.has("code") && "1".equals(jsonObject.get("code").getAsString())) 19 if(jsonObject.has("code") && "1".equals(jsonObject.get("code").getAsString()))
19 { 20 {
20 - message.setCode(MessageCode.DEFAULT_SUCCESS_CODE);  
21 - message.setMessage("操作成功"); 21 + noticeMessage.setCode(MessageCode.DEFAULT_SUCCESS_CODE.code);
  22 + noticeMessage.setMessage("操作成功");
22 } 23 }
23 - }); 24 + return new AnalysisResult(false, true, jsonObject, noticeMessage);
24 } 25 }
25 } 26 }
@@ -2,6 +2,7 @@ package com.zhonglai.luhui.device.protocol.wp6.analysis.topic; @@ -2,6 +2,7 @@ package com.zhonglai.luhui.device.protocol.wp6.analysis.topic;
2 2
3 import com.google.gson.JsonObject; 3 import com.google.gson.JsonObject;
4 import com.ruoyi.common.utils.GsonConstructor; 4 import com.ruoyi.common.utils.GsonConstructor;
  5 +import com.zhonglai.luhui.device.analysis.comm.dto.ApiClientRePlyDto;
5 import com.zhonglai.luhui.device.analysis.dto.MessageCode; 6 import com.zhonglai.luhui.device.analysis.dto.MessageCode;
6 import com.zhonglai.luhui.device.protocol.factory.dto.AnalysisResult; 7 import com.zhonglai.luhui.device.protocol.factory.dto.AnalysisResult;
7 8
@@ -21,16 +22,16 @@ public class ReadReq { @@ -21,16 +22,16 @@ public class ReadReq {
21 { 22 {
22 rJsonObject = jsonObject.getAsJsonObject("data"); 23 rJsonObject = jsonObject.getAsJsonObject("data");
23 } 24 }
24 - return new AnalysisResult(false, true, rJsonObject, message -> { 25 + ApiClientRePlyDto noticeMessage = new ApiClientRePlyDto();
25 if(jsonObject.has("code") && "1".equals(jsonObject.get("code").getAsString())) 26 if(jsonObject.has("code") && "1".equals(jsonObject.get("code").getAsString()))
26 { 27 {
27 if(jsonObject.has("data") && null != jsonObject.get("data") && jsonObject.get("data").isJsonObject()) 28 if(jsonObject.has("data") && null != jsonObject.get("data") && jsonObject.get("data").isJsonObject())
28 { 29 {
29 - message.setData(GsonConstructor.get().fromJson(jsonObject.getAsJsonObject("data").toString(), HashMap.class)); 30 + noticeMessage.setData(GsonConstructor.get().fromJson(jsonObject.getAsJsonObject("data").toString(), HashMap.class));
30 } 31 }
31 - message.setCode(MessageCode.DEFAULT_SUCCESS_CODE);  
32 - message.setMessage("操作成功"); 32 + noticeMessage.setCode(MessageCode.DEFAULT_SUCCESS_CODE.code);
  33 + noticeMessage.setMessage("操作成功");
33 } 34 }
34 - }); 35 + return new AnalysisResult(false, true, rJsonObject, noticeMessage);
35 } 36 }
36 } 37 }
@@ -7,6 +7,8 @@ import com.zhonglai.luhui.device.analysis.dto.Message; @@ -7,6 +7,8 @@ import com.zhonglai.luhui.device.analysis.dto.Message;
7 import com.zhonglai.luhui.device.analysis.dto.MessageCode; 7 import com.zhonglai.luhui.device.analysis.dto.MessageCode;
8 import com.zhonglai.luhui.device.protocol.factory.dto.AnalysisResult; 8 import com.zhonglai.luhui.device.protocol.factory.dto.AnalysisResult;
9 9
  10 +import java.util.HashMap;
  11 +
10 public class PutReq { 12 public class PutReq {
11 public AnalysisResult analysisPayload(byte[] payload) 13 public AnalysisResult analysisPayload(byte[] payload)
12 { 14 {
@@ -16,12 +18,16 @@ public class PutReq { @@ -16,12 +18,16 @@ public class PutReq {
16 public AnalysisResult analysisPayload(String payload) 18 public AnalysisResult analysisPayload(String payload)
17 { 19 {
18 JsonObject jsonObject = GsonConstructor.get().fromJson(payload, JsonObject.class); 20 JsonObject jsonObject = GsonConstructor.get().fromJson(payload, JsonObject.class);
19 - return new AnalysisResult(false, true, jsonObject, message -> { 21 + ApiClientRePlyDto message = new ApiClientRePlyDto();
20 if(jsonObject.has("code") && "1".equals(jsonObject.get("code").getAsString())) 22 if(jsonObject.has("code") && "1".equals(jsonObject.get("code").getAsString()))
21 { 23 {
22 - message.setCode(MessageCode.DEFAULT_SUCCESS_CODE); 24 + if (jsonObject.has("data"))
  25 + {
  26 + message.setData(GsonConstructor.get().fromJson(jsonObject.getAsJsonObject("data"), HashMap.class));
  27 + }
  28 + message.setCode(MessageCode.DEFAULT_SUCCESS_CODE.code);
23 message.setMessage("操作成功"); 29 message.setMessage("操作成功");
24 } 30 }
25 - }); 31 + return new AnalysisResult(false, true, jsonObject, message);
26 } 32 }
27 } 33 }
@@ -54,16 +54,13 @@ public class PLC004ProtocolParserFactoryImpl implements ProtocolParserFactory { @@ -54,16 +54,13 @@ public class PLC004ProtocolParserFactoryImpl implements ProtocolParserFactory {
54 } 54 }
55 } 55 }
56 JsonObject jsonObject = GsonConstructor.get().fromJson(new String(payload),JsonObject.class); 56 JsonObject jsonObject = GsonConstructor.get().fromJson(new String(payload),JsonObject.class);
57 - return new AnalysisResult(false, true, data, new ApiClientRePlyDto() {  
58 - @Override  
59 - public void setReplyMessage(Message message) { 57 + ApiClientRePlyDto apiClientRePlyDto = new ApiClientRePlyDto();
60 if(jsonObject.has("result") && "1".equals(jsonObject.get("result").getAsString())) 58 if(jsonObject.has("result") && "1".equals(jsonObject.get("result").getAsString()))
61 { 59 {
62 - message.setCode(MessageCode.DEFAULT_SUCCESS_CODE);  
63 - message.setMessage("操作成功");  
64 - } 60 + apiClientRePlyDto.setCode(MessageCode.DEFAULT_SUCCESS_CODE.code);
  61 + apiClientRePlyDto.setMessage("操作成功");
65 } 62 }
66 - }); 63 + return new AnalysisResult(false, true, data, apiClientRePlyDto);
67 default: 64 default:
68 return new AnalysisResult(false,false,null); 65 return new AnalysisResult(false,false,null);
69 } 66 }
@@ -30,12 +30,9 @@ public class CkaDtSndR { @@ -30,12 +30,9 @@ public class CkaDtSndR {
30 30
31 Map<String,Object> wmap = new HashMap<>(); 31 Map<String,Object> wmap = new HashMap<>();
32 wmap.put("1",map); 32 wmap.put("1",map);
33 - return new AnalysisResult(false, true, jsonObject, new ApiClientRePlyDto() {  
34 - @Override  
35 - public void setReplyMessage(Message message) {  
36 - message.setCode(MessageCode.DEFAULT_SUCCESS_CODE);  
37 - message.setData(wmap);  
38 - }  
39 - }); 33 + ApiClientRePlyDto apiClientRePlyDto = new ApiClientRePlyDto();
  34 + apiClientRePlyDto.setCode(MessageCode.DEFAULT_SUCCESS_CODE.code);
  35 + apiClientRePlyDto.setData(wmap);
  36 + return new AnalysisResult(false, true, jsonObject, apiClientRePlyDto);
40 } 37 }
41 } 38 }
@@ -92,13 +92,10 @@ public class CkaDtSndS { @@ -92,13 +92,10 @@ public class CkaDtSndS {
92 senserData.addProperty("111",qiexiangbaohu); 92 senserData.addProperty("111",qiexiangbaohu);
93 if(DeviceCommandListenService.hasClienConnection(clientid)) 93 if(DeviceCommandListenService.hasClienConnection(clientid))
94 { 94 {
95 - return new AnalysisResult(true,true,jsonObject,new ApiClientRePlyDto() {  
96 - @Override  
97 - public void setReplyMessage(Message message) {  
98 - message.setCode(MessageCode.DEFAULT_SUCCESS_CODE);  
99 - message.setData(JSONObject.parseObject(jsonObject.toString(),HashMap.class));  
100 - }  
101 - }); 95 + ApiClientRePlyDto apiClientRePlyDto = new ApiClientRePlyDto();
  96 + apiClientRePlyDto.setCode(MessageCode.DEFAULT_SUCCESS_CODE.code);
  97 + apiClientRePlyDto.setData(JSONObject.parseObject(jsonObject.toString(),HashMap.class));
  98 + return new AnalysisResult(true,true,jsonObject, apiClientRePlyDto);
102 } 99 }
103 return new AnalysisResult(true,false,jsonObject); 100 return new AnalysisResult(true,false,jsonObject);
104 } 101 }
@@ -29,8 +29,6 @@ public class PersistenceDBService { @@ -29,8 +29,6 @@ public class PersistenceDBService {
29 private static Map<Integer, IotProtocolClass> iotProtocolClassMap = new HashMap<>(); 29 private static Map<Integer, IotProtocolClass> iotProtocolClassMap = new HashMap<>();
30 @Autowired 30 @Autowired
31 private DefaultDbService defaultDbService; 31 private DefaultDbService defaultDbService;
32 - @Autowired  
33 - private PersistenceDBService persistenceDBService;  
34 32
35 /** 33 /**
36 * 更新数据库 34 * 更新数据库
@@ -63,7 +61,7 @@ public class PersistenceDBService { @@ -63,7 +61,7 @@ public class PersistenceDBService {
63 ParserDeviceHostDto parserDeviceHostDto = protocolPurificationModel.getParserDeviceHostDto(); 61 ParserDeviceHostDto parserDeviceHostDto = protocolPurificationModel.getParserDeviceHostDto();
64 if (parserDeviceHostDto.getIotProduct().getIs_sync_db()==1 && null !=parserDeviceHostDto.getIotProduct().getSync_db() && 0!=parserDeviceHostDto.getIotProduct().getSync_db()) 62 if (parserDeviceHostDto.getIotProduct().getIs_sync_db()==1 && null !=parserDeviceHostDto.getIotProduct().getSync_db() && 0!=parserDeviceHostDto.getIotProduct().getSync_db())
65 { 63 {
66 - ProtocolSyncFactory protocolSyncFactory = PluginsClassLoader.getJarClass(ProtocolSyncFactory.class,persistenceDBService.getClassnameFromIotProtocolClassId(parserDeviceHostDto.getIotProduct().getSync_db())); 64 + ProtocolSyncFactory protocolSyncFactory = PluginsClassLoader.getJarClass(ProtocolSyncFactory.class,getClassnameFromIotProtocolClassId(parserDeviceHostDto.getIotProduct().getSync_db()));
67 // ProtocolSyncFactory protocolSyncFactory = getProtocolSyncService(persistenceDBService.getClassnameFromIotProtocolClassId(parserDeviceHostDto.getIotProduct().getSync_db())); 65 // ProtocolSyncFactory protocolSyncFactory = getProtocolSyncService(persistenceDBService.getClassnameFromIotProtocolClassId(parserDeviceHostDto.getIotProduct().getSync_db()));
68 if(null != protocolSyncFactory) 66 if(null != protocolSyncFactory)
69 { 67 {
1 package com.zhonglai.luhui.lsy.plc.service.service.topic; 1 package com.zhonglai.luhui.lsy.plc.service.service.topic;
2 2
3 import com.alibaba.fastjson.JSONObject; 3 import com.alibaba.fastjson.JSONObject;
  4 +import com.zhonglai.luhui.device.analysis.comm.dto.ApiClientRePlyDto;
4 import com.zhonglai.luhui.device.analysis.comm.dto.ServerDto; 5 import com.zhonglai.luhui.device.analysis.comm.dto.ServerDto;
5 import com.zhonglai.luhui.device.analysis.comm.dto.business.BusinessDto; 6 import com.zhonglai.luhui.device.analysis.comm.dto.business.BusinessDto;
6 import com.zhonglai.luhui.device.analysis.comm.factory.BusinessAgreement; 7 import com.zhonglai.luhui.device.analysis.comm.factory.BusinessAgreement;
@@ -21,18 +22,18 @@ public class PutReqTopic implements BusinessAgreement<PutReqDto> { @@ -21,18 +22,18 @@ public class PutReqTopic implements BusinessAgreement<PutReqDto> {
21 22
22 @Override 23 @Override
23 public ServerDto analysis(Topic topic, PutReqDto data) throws Exception { 24 public ServerDto analysis(Topic topic, PutReqDto data) throws Exception {
24 - clienNoticeService.replySendMessage(topic, message -> {  
25 - message.setData(data.getTime());  
26 - message.setCode(MessageCode.DEFAULT_FAIL_CODE);  
27 - message.setMessage(data.getMsg()); 25 + ApiClientRePlyDto apiClientRePlyDto = new ApiClientRePlyDto();
  26 + apiClientRePlyDto.setData(data.getTime());
  27 + apiClientRePlyDto.setCode(MessageCode.DEFAULT_FAIL_CODE.code);
  28 + apiClientRePlyDto.setMessage(data.getMsg());
28 switch (data.getResult()) 29 switch (data.getResult())
29 { 30 {
30 case "1": 31 case "1":
31 - message.setCode(MessageCode.DEFAULT_SUCCESS_CODE);  
32 - message.setMessage("成功"); 32 + apiClientRePlyDto.setCode(MessageCode.DEFAULT_SUCCESS_CODE.code);
  33 + apiClientRePlyDto.setMessage("成功");
33 break; 34 break;
34 } 35 }
35 - }); 36 + clienNoticeService.replySendMessage(topic, apiClientRePlyDto);
36 return null; 37 return null;
37 } 38 }
38 39
@@ -19,8 +19,8 @@ spring: @@ -19,8 +19,8 @@ spring:
19 19
20 mqtt: 20 mqtt:
21 #链接地址 21 #链接地址
22 - broker: tcp://175.24.61.68:1883  
23 -# broker: tcp://8.129.82.37:1883 22 +# broker: tcp://175.24.61.68:1883
  23 + broker: tcp://8.129.82.37:1883
24 #唯一标识 24 #唯一标识
25 clientId: ${random.uuid} 25 clientId: ${random.uuid}
26 topicconfig: "/{{roleid}}/{{username}}/{{clientid}}/{{payloadtype}}/{{topicType}}/{{messageid}}" 26 topicconfig: "/{{roleid}}/{{username}}/{{clientid}}/{{payloadtype}}/{{topicType}}/{{messageid}}"
@@ -29,7 +29,7 @@ mqtt: @@ -29,7 +29,7 @@ mqtt:
29 client: 29 client:
30 #客户端操作时间 30 #客户端操作时间
31 operationTime: 10 31 operationTime: 10
32 - productids: 9 32 + productids: 13
33 33
34 #rocketmq配置信息 34 #rocketmq配置信息
35 rocketmq: 35 rocketmq:
1 package com.zhonglai.luhui.mqtt.service.topic; 1 package com.zhonglai.luhui.mqtt.service.topic;
2 2
3 import com.alibaba.fastjson.JSONObject; 3 import com.alibaba.fastjson.JSONObject;
  4 +import com.zhonglai.luhui.device.analysis.comm.dto.ApiClientRePlyDto;
4 import com.zhonglai.luhui.device.analysis.comm.dto.ServerDto; 5 import com.zhonglai.luhui.device.analysis.comm.dto.ServerDto;
5 import com.zhonglai.luhui.device.analysis.comm.dto.business.BusinessDto; 6 import com.zhonglai.luhui.device.analysis.comm.dto.business.BusinessDto;
6 import com.zhonglai.luhui.device.analysis.comm.factory.BusinessAgreement; 7 import com.zhonglai.luhui.device.analysis.comm.factory.BusinessAgreement;
@@ -22,18 +23,18 @@ public class PutReqTopic implements BusinessAgreement<PutReqDto> { @@ -22,18 +23,18 @@ public class PutReqTopic implements BusinessAgreement<PutReqDto> {
22 @Override 23 @Override
23 public ServerDto analysis(Topic topic, PutReqDto data) throws Exception { 24 public ServerDto analysis(Topic topic, PutReqDto data) throws Exception {
24 data.setMessageid(topic.getMessageid()); 25 data.setMessageid(topic.getMessageid());
25 - clienNoticeService.replySendMessage(topic, message -> {  
26 - message.setData(data.getData());  
27 - message.setCode(MessageCode.DEFAULT_SUCCESS_CODE);  
28 - message.setMessage("成功"); 26 + ApiClientRePlyDto apiClientRePlyDto = new ApiClientRePlyDto();
  27 + apiClientRePlyDto.setData(data.getData());
  28 + apiClientRePlyDto.setCode(MessageCode.DEFAULT_SUCCESS_CODE.code);
  29 + apiClientRePlyDto.setMessage("成功");
29 switch (data.getCode()) 30 switch (data.getCode())
30 { 31 {
31 case 0: 32 case 0:
32 - message.setCode(MessageCode.DEFAULT_FAIL_CODE);  
33 - message.setMessage("失败"); 33 + apiClientRePlyDto.setCode(MessageCode.DEFAULT_FAIL_CODE.code);
  34 + apiClientRePlyDto.setMessage("失败");
34 break; 35 break;
35 } 36 }
36 - }); 37 + clienNoticeService.replySendMessage(topic, apiClientRePlyDto);
37 return null; 38 return null;
38 } 39 }
39 40
@@ -6,6 +6,7 @@ import com.google.gson.JsonElement; @@ -6,6 +6,7 @@ import com.google.gson.JsonElement;
6 import com.google.gson.JsonObject; 6 import com.google.gson.JsonObject;
7 import com.google.gson.JsonParser; 7 import com.google.gson.JsonParser;
8 import com.ruoyi.common.utils.GsonConstructor; 8 import com.ruoyi.common.utils.GsonConstructor;
  9 +import com.zhonglai.luhui.device.analysis.comm.dto.ApiClientRePlyDto;
9 import com.zhonglai.luhui.device.analysis.comm.dto.thingsmodels.ThingsModelItemBase; 10 import com.zhonglai.luhui.device.analysis.comm.dto.thingsmodels.ThingsModelItemBase;
10 import com.zhonglai.luhui.device.analysis.comm.service.BusinessDataUpdateService; 11 import com.zhonglai.luhui.device.analysis.comm.service.BusinessDataUpdateService;
11 import com.zhonglai.luhui.device.analysis.dto.topic.AddPostDto; 12 import com.zhonglai.luhui.device.analysis.dto.topic.AddPostDto;
@@ -97,25 +98,27 @@ public class ReadReqTopic implements BusinessAgreement<ReadReqDto> { @@ -97,25 +98,27 @@ public class ReadReqTopic implements BusinessAgreement<ReadReqDto> {
97 } 98 }
98 data.setData(vjsonObject); 99 data.setData(vjsonObject);
99 } 100 }
100 - clienNoticeService.replySendMessage(topic, message -> { 101 +
  102 + ApiClientRePlyDto apiClientRePlyDto = new ApiClientRePlyDto();
101 if(null != data.getData()) 103 if(null != data.getData())
102 { 104 {
103 - message.setData(JSONObject.parseObject(data.getData().toJSONString(), HashMap.class)); 105 + apiClientRePlyDto.setData(JSONObject.parseObject(data.getData().toJSONString(), HashMap.class));
104 } 106 }
105 - message.setCode(MessageCode.DEFAULT_SUCCESS_CODE);  
106 - message.setMessage("成功");  
107 - }); 107 + apiClientRePlyDto.setCode(MessageCode.DEFAULT_SUCCESS_CODE.code);
  108 + apiClientRePlyDto.setMessage("成功");
  109 +
  110 + clienNoticeService.replySendMessage(topic, apiClientRePlyDto);
108 return serverDto; 111 return serverDto;
109 }else if(0==data.getCode()) 112 }else if(0==data.getCode())
110 { 113 {
111 - clienNoticeService.replySendMessage(topic, message -> { 114 + ApiClientRePlyDto apiClientRePlyDto = new ApiClientRePlyDto();
112 if(null != data.getData()) 115 if(null != data.getData())
113 { 116 {
114 - message.setData(JSONObject.parseObject(data.getData().toJSONString(), HashMap.class)); 117 + apiClientRePlyDto.setData(JSONObject.parseObject(data.getData().toJSONString(), HashMap.class));
115 } 118 }
116 - message.setCode(MessageCode.DEFAULT_FAIL_CODE);  
117 - message.setMessage("失败");  
118 - }); 119 + apiClientRePlyDto.setCode(MessageCode.DEFAULT_FAIL_CODE.code);
  120 + apiClientRePlyDto.setMessage("失败");
  121 + clienNoticeService.replySendMessage(topic,apiClientRePlyDto);
119 return null; 122 return null;
120 } 123 }
121 return null; 124 return null;
@@ -21,11 +21,11 @@ spring: @@ -21,11 +21,11 @@ spring:
21 redis: 21 redis:
22 database: 1 22 database: 1
23 # Redis服务器地址 写你的ip 23 # Redis服务器地址 写你的ip
24 - host: 47.112.163.61 24 + host: 119.23.218.181
25 # Redis服务器连接端口 25 # Redis服务器连接端口
26 - port: 9527 26 + port: 6379
27 # Redis服务器连接密码(默认为空) 27 # Redis服务器连接密码(默认为空)
28 - password: Luhui586 28 + password:
29 # 连接池最大连接数(使用负值表示没有限制 类似于mysql的连接池 29 # 连接池最大连接数(使用负值表示没有限制 类似于mysql的连接池
30 jedis: 30 jedis:
31 pool: 31 pool:
@@ -41,7 +41,7 @@ spring: @@ -41,7 +41,7 @@ spring:
41 41
42 mqtt: 42 mqtt:
43 #链接地址 43 #链接地址
44 - broker: tcp://175.24.61.68:1883 44 + broker: tcp://iot.yu2le.com:1883
45 #唯一标识 45 #唯一标识
46 clientId: ${random.uuid} 46 clientId: ${random.uuid}
47 #公司id 47 #公司id
@@ -49,7 +49,7 @@ mqtt: @@ -49,7 +49,7 @@ mqtt:
49 mqtt_usernames: 6_WP 49 mqtt_usernames: 6_WP
50 #订阅的topic 50 #订阅的topic
51 topics: ADD_POST,ALL_POST,DB_TOPIC_DISTRIBUTE,GET/+,online,PUT_REQ/+,READ_REQ/+ 51 topics: ADD_POST,ALL_POST,DB_TOPIC_DISTRIBUTE,GET/+,online,PUT_REQ/+,READ_REQ/+
52 - sub_clientid: '+' 52 + sub_clientid: '866520067506865'
53 topicconfig: "/{{roleid}}/{{username}}/{{clientid}}/{{payloadtype}}/{{topicType}}/{{messageid}}" 53 topicconfig: "/{{roleid}}/{{username}}/{{clientid}}/{{payloadtype}}/{{topicType}}/{{messageid}}"
54 top_return_map: '{"PUT":"PUT_REQ","READ":"READ_REQ"}' 54 top_return_map: '{"PUT":"PUT_REQ","READ":"READ_REQ"}'
55 username: sysuser 55 username: sysuser
@@ -68,5 +68,5 @@ sys: @@ -68,5 +68,5 @@ sys:
68 rocketmq: 68 rocketmq:
69 #nameservice服务器地址(多个以英文逗号隔开) 69 #nameservice服务器地址(多个以英文逗号隔开)
70 name-server: 8.129.224.117:9876 70 name-server: 8.129.224.117:9876
71 - send-topic: lh-mqtt-service-deviceCommand-test1 71 + send-topic: lh-mqtt-service-deviceCommand-test
72 send-tag: 1 72 send-tag: 1
@@ -37,6 +37,7 @@ @@ -37,6 +37,7 @@
37 <module>lh-superweb-jar</module> 37 <module>lh-superweb-jar</module>
38 <module>lh-ssh-service-lesten</module> 38 <module>lh-ssh-service-lesten</module>
39 <module>lh-deviceInfo-sync</module> 39 <module>lh-deviceInfo-sync</module>
  40 + <module>lh-camera</module>
40 </modules> 41 </modules>
41 42
42 <properties> 43 <properties>
  1 +<!DOCTYPE html>
  2 +<html>
  3 +<head>
  4 + <meta charset="UTF-8">
  5 + <title>摄像头直播</title>
  6 + <script src="js/hls.js"></script>
  7 + <style>
  8 + body { font-family: sans-serif; }
  9 + .cam-container { margin-bottom: 40px; }
  10 + </style>
  11 +</head>
  12 +<body>
  13 +<h1>摄像头直播页面</h1>
  14 +
  15 +<h2>选择摄像头</h2>
  16 +<select id="cameraSelect"></select>
  17 +
  18 +<div id="video-container"></div>
  19 +
  20 +<h2>系统资源占用</h2>
  21 +<pre id="sys-info">Loading...</pre>
  22 +
  23 +<script>
  24 + // 动态加载摄像头列表
  25 + async function loadCameras() {
  26 + try {
  27 + const res = await fetch('/cameras');
  28 + const cameras = await res.json();
  29 +
  30 + const select = document.getElementById('cameraSelect');
  31 + select.innerHTML = ''; // 清空现有选项
  32 +
  33 + cameras.forEach(camera => {
  34 + const option = document.createElement('option');
  35 + option.value = camera.name;
  36 + option.textContent = camera.name;
  37 + select.appendChild(option);
  38 + });
  39 +
  40 + // 更新视频流显示
  41 + select.addEventListener('change', updateVideoStream);
  42 + updateVideoStream(); // 默认加载第一个摄像头
  43 + } catch (err) {
  44 + console.error('Failed to load cameras:', err);
  45 + }
  46 + }
  47 +
  48 + // 更新视频流
  49 + function updateVideoStream() {
  50 + const cameraName = document.getElementById('cameraSelect').value;
  51 + const source = `http://192.168.0.103/DS-2XC3046-LR/SX20250425AACHFZ4535655/index.m3u8`;
  52 +
  53 + // 创建视频元素
  54 + const video = document.createElement('video');
  55 + video.controls = true;
  56 + video.autoplay = true;
  57 + video.width = 640;
  58 + video.height = 360;
  59 +
  60 + if (Hls.isSupported()) {
  61 + const hls = new Hls();
  62 + hls.loadSource(source);
  63 + hls.attachMedia(video);
  64 + } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
  65 + video.src = source;
  66 + }
  67 +
  68 + // 更新视频容器
  69 + const container = document.getElementById('video-container');
  70 + container.innerHTML = ''; // 清空现有视频
  71 + container.appendChild(video);
  72 + }
  73 +
  74 + // 初始化摄像头选择框
  75 + loadCameras();
  76 +</script>
  77 +</body>
  78 +</html>
此 diff 太大无法显示。
  1 +!function(){"use strict";(e=>{const t="single-file-lazy-load",n="single-file-load-image",i="single-file-request-get-adopted-stylesheets",r={family:"font-family",style:"font-style",weight:"font-weight",stretch:"font-stretch",unicodeRange:"unicode-range",variant:"font-variant",featureSettings:"font-feature-settings"},o=e.fetch.bind(e),l=e.CustomEvent,s=e.document,d=e.screen,a=e.Element,c=e.UIEvent,g=e.Event,f=e.FileReader,_=e.Blob,m=e.JSON,u=e.MutationObserver,h=e.URL,p=new Map,y=new Map;let E;function v(){s.addEventListener("single-file-load-deferred-images-start",(()=>w())),s.addEventListener("single-file-load-deferred-images-keep-zoom-level-start",(()=>w(!0))),s.addEventListener("single-file-load-deferred-images-end",(()=>F())),s.addEventListener("single-file-load-deferred-images-keep-zoom-level-end",(()=>F(!0))),s.addEventListener("single-file-load-deferred-images-reset",b),s.addEventListener("single-file-load-deferred-images-keep-zoom-level-reset",(()=>{const e=s.documentElement.style.getPropertyValue("-sf-transform"),t=s.documentElement.style.getPropertyPriority("-sf-transform"),n=s.documentElement.style.getPropertyValue("-sf-transform-origin"),i=s.documentElement.style.getPropertyPriority("-sf-transform-origin"),r=s.documentElement.style.getPropertyValue("-sf-min-height"),o=s.documentElement.style.getPropertyPriority("-sf-min-height");s.documentElement.style.setProperty("transform",e,t),s.documentElement.style.setProperty("transform-origin",n,i),s.documentElement.style.setProperty("min-height",r,o),s.documentElement.style.removeProperty("-sf-transform"),s.documentElement.style.removeProperty("-sf-transform-origin"),s.documentElement.style.removeProperty("-sf-min-height"),b()})),s.addEventListener("single-file-dispatch-scroll-event-start",(()=>{E=!0})),s.addEventListener("single-file-dispatch-scroll-event-end",(()=>{E=!1})),s.addEventListener("single-file-block-cookies-start",(()=>{try{s.__defineGetter__("cookie",(()=>{throw new Error("document.cookie temporary blocked by SingleFile")}))}catch(e){}})),s.addEventListener("single-file-block-cookies-end",(()=>{delete s.cookie})),s.addEventListener("single-file-block-storage-start",(()=>{e._singleFile_localStorage||(e._singleFile_localStorage=e.localStorage,e.__defineGetter__("localStorage",(()=>{throw new Error("localStorage temporary blocked by SingleFile")}))),e._singleFile_indexedDB||(e._singleFile_indexedDB=e.indexedDB,e.__defineGetter__("indexedDB",(()=>{throw new Error("indexedDB temporary blocked by SingleFile")})))})),s.addEventListener("single-file-block-storage-end",(()=>{e._singleFile_localStorage&&(delete e.localStorage,e.localStorage=e._singleFile_localStorage,delete e._singleFile_localStorage),e._singleFile_indexedDB||(delete e.indexedDB,e.indexedDB=e._singleFile_indexedDB,delete e._singleFile_indexedDB)})),s.addEventListener("single-file-request-fetch-supported",(()=>s.dispatchEvent(new l("single-file-response-fetch-supported")))),s.addEventListener("single-file-request-fetch",(async e=>{const{url:t,options:n}=m.parse(e.detail);let i;try{const e=await o(t,n);i={url:t,response:await e.arrayBuffer(),headers:[...e.headers],status:e.status}}catch(e){i={url:t,error:e&&(e.message||e.toString())}}s.dispatchEvent(new l("single-file-response-fetch",{detail:i}))})),s.addEventListener(i,S),s.addEventListener("single-file-bootstrap",(t=>{try{e.bootstrap&&t.detail.data&&e.bootstrap(t.detail.data)}catch(e){}}))}function w(i){const r=s.scrollingElement||s.documentElement,o=r.clientHeight,c=r.clientWidth,f=Math.max(r.scrollHeight-o,o),_=Math.max(r.scrollWidth-c,c);if(s.querySelectorAll("[loading=lazy]").forEach((e=>{e.loading="eager",e.setAttribute(t,"")})),r.__defineGetter__("clientHeight",(()=>f)),r.__defineGetter__("clientWidth",(()=>_)),d.__defineGetter__("height",(()=>f)),d.__defineGetter__("width",(()=>_)),e._singleFile_innerHeight=e.innerHeight,e._singleFile_innerWidth=e.innerWidth,e.__defineGetter__("innerHeight",(()=>f)),e.__defineGetter__("innerWidth",(()=>_)),i||e._singleFile_getBoundingClientRect||(e._singleFile_getBoundingClientRect=a.prototype.getBoundingClientRect,a.prototype.getBoundingClientRect=function(){const t=e._singleFile_getBoundingClientRect.call(this);return this==r&&(t.__defineGetter__("height",(()=>f)),t.__defineGetter__("bottom",(()=>f+t.top)),t.__defineGetter__("width",(()=>_)),t.__defineGetter__("right",(()=>_+t.left))),t}),!e._singleFileImage){const t=e.Image;e._singleFileImage=e.Image,e.__defineGetter__("Image",(function(){return function(){const e=new t(...arguments),i=new t(...arguments);return i.__defineSetter__("src",(t=>{e.src=t,s.dispatchEvent(new l(n,{detail:e.src}))})),i.__defineGetter__("src",(()=>e.src)),i.__defineSetter__("srcset",(t=>{s.dispatchEvent(new l(n)),e.srcset=t})),i.__defineGetter__("srcset",(()=>e.srcset)),i.__defineGetter__("height",(()=>e.height)),i.__defineGetter__("width",(()=>e.width)),i.__defineGetter__("naturalHeight",(()=>e.naturalHeight)),i.__defineGetter__("naturalWidth",(()=>e.naturalWidth)),e.decode&&i.__defineGetter__("decode",(()=>()=>e.decode())),e.onload=e.onloadend=e.onerror=t=>{s.dispatchEvent(new l("single-file-image-loaded",{detail:e.src})),i.dispatchEvent(new g(t.type,t))},i}}))}let m,u;i?(m=o/f,u=c/_):(m=(o+e.scrollY)/f,u=(c+e.scrollX)/_);const h=Math.min(m,u);if(h<1){const e=s.documentElement.style.getPropertyValue("transform"),t=s.documentElement.style.getPropertyPriority("transform"),n=s.documentElement.style.getPropertyValue("transform-origin"),r=s.documentElement.style.getPropertyPriority("transform-origin"),o=s.documentElement.style.getPropertyValue("min-height"),l=s.documentElement.style.getPropertyPriority("min-height");s.documentElement.style.setProperty("transform-origin",(m<1?"50%":"0")+" "+(u<1?"50%":"0")+" 0","important"),s.documentElement.style.setProperty("transform","scale3d("+h+", "+h+", 1)","important"),s.documentElement.style.setProperty("min-height",100/h+"vh","important"),B(),i?(s.documentElement.style.setProperty("-sf-transform",e,t),s.documentElement.style.setProperty("-sf-transform-origin",n,r),s.documentElement.style.setProperty("-sf-min-height",o,l)):(s.documentElement.style.setProperty("transform",e,t),s.documentElement.style.setProperty("transform-origin",n,r),s.documentElement.style.setProperty("min-height",o,l))}if(!i){B();const e=r.getBoundingClientRect();window==window.top&&[...p].forEach((([t,n])=>{const i=n.options&&n.options.root&&n.options.root.getBoundingClientRect,r=i&&n.options.root.getBoundingClientRect(),o=y.get(t);if(o){const l=o.map((t=>{const n=t.getBoundingClientRect();return{target:t,intersectionRatio:1,boundingClientRect:n,intersectionRect:n,isIntersecting:!0,rootBounds:i?r:e,time:0}})).filter((e=>e.boundingClientRect.width&&e.boundingClientRect.height));l.length&&n.callback.call(t,l,t)}}))}}function F(n){s.querySelectorAll("["+t+"]").forEach((e=>{e.loading="lazy",e.removeAttribute(t)})),n||e._singleFile_getBoundingClientRect&&(a.prototype.getBoundingClientRect=e._singleFile_getBoundingClientRect,delete e._singleFile_getBoundingClientRect),e._singleFileImage&&(delete e.Image,e.Image=e._singleFileImage,delete e._singleFileImage),n||B()}function b(){const t=s.scrollingElement||s.documentElement;null!=e._singleFile_innerHeight&&(delete e.innerHeight,e.innerHeight=e._singleFile_innerHeight,delete e._singleFile_innerHeight),null!=e._singleFile_innerWidth&&(delete e.innerWidth,e.innerWidth=e._singleFile_innerWidth,delete e._singleFile_innerWidth),delete t.clientHeight,delete t.clientWidth,delete d.height,delete d.width}if(v(),new u(v).observe(s,{childList:!0}),e.CSS&&e.CSS.paintWorklet&&e.CSS.paintWorklet.addModule){const t=e.CSS.paintWorklet.addModule;e.CSS.paintWorklet.addModule=function(n,i){const r=t.apply(e.CSS.paintWorklet,arguments);return n=new h(n,s.baseURI).href,s.dispatchEvent(new l("single-file-new-worklet",{detail:{moduleURL:n,options:i}})),r}}if(e.FontFace){const t=e.FontFace;e.FontFace=function(){return P(...arguments).then((e=>s.dispatchEvent(new l("single-file-new-font-face",{detail:e})))),new t(...arguments)},e.FontFace.prototype=t.prototype,e.FontFace.toString=function(){return"function FontFace() { [native code] }"};const n=s.fonts.delete;s.fonts.delete=function(e){return P(e.family).then((e=>s.dispatchEvent(new l("single-file-delete-font",{detail:e})))),n.call(s.fonts,e)},s.fonts.delete.toString=function(){return"function delete() { [native code] }"};const i=s.fonts.clear;s.fonts.clear=function(){return s.dispatchEvent(new l("single-file-clear-fonts")),i.call(s.fonts)},s.fonts.clear.toString=function(){return"function clear() { [native code] }"}}if(e.IntersectionObserver){const t=e.IntersectionObserver;e.IntersectionObserver=function(){const e=new t(...arguments),n=t.prototype.observe||e.observe,i=t.prototype.unobserve||e.unobserve,r=arguments[0],o=arguments[1];return n&&(e.observe=function(t){let i=y.get(e);return i||(i=[],y.set(e,i)),i.push(t),n.call(e,t)}),i&&(e.unobserve=function(t){let n=y.get(e);return n&&(n=n.filter((e=>e!=t)),n.length?y.set(e,n):(y.delete(e),p.delete(e))),i.call(e,t)}),p.set(e,{callback:r,options:o}),e},e.IntersectionObserver.prototype=t.prototype,e.IntersectionObserver.toString=function(){return"function IntersectionObserver() { [native code] }"}}function S(e){const t=e.target.shadowRoot;if(e.stopPropagation(),t){t.addEventListener(i,S,{capture:!0}),t.addEventListener("single-file-unregister-request-get-adopted-stylesheets",(()=>t.removeEventListener(i,S)),{once:!0});const e=Array.from(t.adoptedStyleSheets).map((e=>Array.from(e.cssRules).map((e=>e.cssText)).join("\n")));e.length&&t.dispatchEvent(new l("single-file-response-get-adopted-stylesheets",{detail:{adoptedStyleSheets:e}}))}}async function P(e,t,n){const i={};return i["font-family"]=e,i.src=t,n&&Object.keys(n).forEach((e=>{r[e]&&(i[r[e]]=n[e])})),new Promise((e=>{if(i.src instanceof ArrayBuffer){const t=new f;t.readAsDataURL(new _([i.src])),t.addEventListener("load",(()=>{i.src="url("+t.result+")",e(i)}))}else e(i)}))}function B(){try{e.dispatchEvent(new c("resize")),E&&e.dispatchEvent(new c("scroll"))}catch(e){}}})("object"==typeof globalThis?globalThis:window)}();