Commit ec95a429859e2819772231e70dcd80cb976c81d2

Authored by 648540858
2 parents f275daa3 bb49f1f0

Merge branch 'main' into main2

# Conflicts:
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
#	src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
#	src/main/resources/all-application.yml
#	web_src/src/components/dialog/devicePlayer.vue
Showing 85 changed files with 2636 additions and 1854 deletions
README.md
1 -![logo](https://raw.githubusercontent.com/648540858/wvp-GB28181-pro/wvp-28181-2.0/web_src/static/logo.png) 1 +![logo](doc/_media/logo.png)
2 # 撘蝞勗28181悅閫像 2 # 撘蝞勗28181悅閫像
3 3
4 [![Build Status](https://travis-ci.org/xia-chu/ZLMediaKit.svg?branch=master)](https://travis-ci.org/xia-chu/ZLMediaKit) 4 [![Build Status](https://travis-ci.org/xia-chu/ZLMediaKit.svg?branch=master)](https://travis-ci.org/xia-chu/ZLMediaKit)
@@ -17,7 +17,7 @@ WEB VIDEO PLATFORM銝銝芸鈭B28181-2016蝞勗 @@ -17,7 +17,7 @@ WEB VIDEO PLATFORM銝銝芸鈭B28181-2016蝞勗
17 # 摨嚗 17 # 摨嚗
18 辣仍閫 18 辣仍閫
19 像VR蝑挽憭 19 像VR蝑挽憭
20 -漣 20 +漣像蝥扯楊蝵
21 tsp/rtmp蝑蓮像 21 tsp/rtmp蝑蓮像
22 tsp/rtmp蝑瘚蓮像 22 tsp/rtmp蝑瘚蓮像
23 23
@@ -31,62 +31,49 @@ WEB VIDEO PLATFORM銝銝芸鈭B28181-2016蝞勗 @@ -31,62 +31,49 @@ WEB VIDEO PLATFORM銝銝芸鈭B28181-2016蝞勗
31 https://gitee.com/pan648540858/wvp-GB28181-pro.git 31 https://gitee.com/pan648540858/wvp-GB28181-pro.git
32 32
33 # 33 #
34 -![build_1.png](https://images.gitee.com/uploads/images/2022/0304/101513_79632720_1018729.png "2022-03-04_09-51.png")  
35 -![build_1.png](https://images.gitee.com/uploads/images/2022/0304/103025_5df016f9_1018729.png "2022-03-04_10-27.png")  
36 -![build_1.png](https://images.gitee.com/uploads/images/2022/0304/101706_088fbafa_1018729.png "2022-03-04_09-52_1.png")  
37 -![build_1.png](https://images.gitee.com/uploads/images/2022/0304/101756_3d662828_1018729.png "2022-03-04_10-00_1.png")  
38 -![build_1.png](https://images.gitee.com/uploads/images/2022/0304/101823_19050c66_1018729.png "2022-03-04_10-12_1.png")  
39 -![build_1.png](https://images.gitee.com/uploads/images/2022/0304/101848_e5a39557_1018729.png "2022-03-04_10-12_2.png")  
40 -![build_1.png](https://images.gitee.com/uploads/images/2022/0304/101919_ee5b8c79_1018729.png "2022-03-04_10-13.png")  
41 -  
42 -# 1.0 蝖  
43 -1. 閫;  
44 -2. 鈭嚗憬嚗;  
45 -3. 閫挽憭縑郊;  
46 -4. 蝳餃蝥輻;  
47 -5. 敶霂V嚗鈭VR\DVR嚗翰餈eek;  
48 -6. 犖閫瘚;  
49 -7. DPCP銝斤縑隞支芋撘;  
50 -8. eb, 銝閬蝵脣垢, wvp蔭辣蝵, vp銝韏琿蝵;  
51 -9. 像, 笆憭批像憭折挽憭餈;  
52 -10. 蝝,;  
53 -11. 蔭ZLM慦, 蔭憸憸;  
54 -12. udp憭垢璅∪, dp璅∪扯;  
55 -13. 憸挽蝵;  
56 -14. 敶霂;  
57 -15. dp/tcp芋撘;  
58 -16. 颲RTSPTMPTTP-FLVebsocket-FLVLS憭悅瘚  
59 -17.  
60 -18. 蝵蝵, vp銝lm蝵  
61 -19. h265, g.711撘(閬loseWaitRTPInfo霈曆蛹false)  
62 -20. 霅虫縑憭垢霅虫縑  
63 -  
64 -# 1.0  
65 -1. eb, 銝閬蝵脣垢, wvp蔭辣蝵, vp銝韏琿蝵;  
66 -2. 像, 笆憭批像憭折挽憭餈;  
67 -3. 蝝,;  
68 -4. 蔭ZLM慦, 蔭憸憸;  
69 -5. udp憭垢璅∪, dp璅∪扯;  
70 -6. 憸挽蝵;  
71 -7. 敶霂;  
72 -8. dp/tcp芋撘;  
73 -9. 颲RTSPTMPTTP-FLVebsocket-FLVLS憭悅瘚  
74 -10.  
75 -11. 蝵蝵, vp銝lm蝵  
76 -12. h265, g.711撘  
77 -13. 摰嚗瘚嚗誨絲. ( [IKI](https://github.com/648540858/wvp-GB28181-pro/wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E5%9B%BA%E5%AE%9A%E6%92%AD%E6%94%BE%E5%9C%B0%E5%9D%80%E4%B8%8E%E8%87%AA%E5%8A%A8%E7%82%B9%E6%92%AD)嚗  
78 -14. 霅虫縑憭垢霅虫縑  
79 -15. 恥瘜  
80 - - [X] 蝘餃雿蔭霈a  
81 - - [X] 蝘餃雿蔭憭  
82 - - [X] 霅虫辣霈a  
83 - - [X] 霅虫辣憭  
84 - - [X] 霈曉敶恥  
85 - - [X] 霈曉敶憭  
86 -16. 蝘餃雿蔭霂W蝷綽蔭辣霈曄蔭蝘餃雿蔭摮  
87 -  
88 -# 2.0  
89 -- [X] 漣 34 +![index](doc/_media/index.png "index.png")
  35 +![2](doc/_media/2.png "2.png")
  36 +![3](doc/_media/3.png "3.png")
  37 +![3-1](doc/_media/3-1.png "3-1.png")
  38 +![3-2](doc/_media/3-2.png "3-2.png")
  39 +![3-3](doc/_media/3-3.png "3-3.png")
  40 +![build_1](https://images.gitee.com/uploads/images/2022/0304/101919_ee5b8c79_1018729.png "2022-03-04_10-13.png")
  41 +
  42 +#
  43 +- [X] eb
  44 +- [X] 摰寞扯憟
  45 +- [X] 摮嚗WGS84CJ02銝斤頂嚗僎銝頧砍蛹頂餈內
  46 +- [X] 霈曉
  47 + - [X] 閫
  48 + - [X] 頝舀嚗憭挽憭鈭扯
  49 + - [X] 鈭嚗霈曉蓮
  50 + - [X] 憸蔭雿霂g蝙銝挽蝵
  51 + - [X] 霂﹫VR/IPC銝嚗銝蝸
  52 + - [X] 犖閫瘚
  53 + - [X] 閫挽憭縑郊
  54 + - [X] 蝳餃蝥輻
  55 + - [X] 颲RTSPTMPTTP-FLVebsocket-FLVLS憭悅瘚
  56 + - [X] 銝芣閫仍嚗敶誑隞颱
  57 + - [X] DPCP銝斤縑隞支芋撘
  58 + - [X] DPCP銝斤芋撘
  59 + - [X] 蝝,
  60 + - [X] 敶霂
  61 + - [X] 誘憸甇X敶勗
  62 + - [X]
  63 + - [X] H264265
  64 + - [X] 霅虫縑憭垢霅虫縑
  65 + - [X] 恥瘜
  66 + - [X] 蝘餃雿蔭霈a
  67 + - [X] 蝘餃雿蔭憭
  68 + - [X] 霅虫辣霈a
  69 + - [X] 霅虫辣憭
  70 + - [X] 霈曉敶恥
  71 + - [X] 霈曉敶憭
  72 + - [X] 蝘餃雿蔭霂W蝷
  73 + - [X] 瘛餃挽憭挽憭挽蝵桀
  74 +- [X] 像撖寞
  75 +- [X] 漣
  76 + - [X] 漣
90 - [X] WEB瘛餃漣撟喳 77 - [X] WEB瘛餃漣撟喳
91 - [X] 瘜典 78 - [X] 瘜典
92 - [X] 敹歲靽暑 79 - [X] 敹歲靽暑
@@ -101,61 +88,33 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git @@ -101,61 +88,33 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
101 - [X] 敶恥 88 - [X] 敶恥
102 - [X] 敶 89 - [X] 敶
103 - [X] GPS霈a嚗瘚 90 - [X] GPS霈a嚗瘚
104 -- [X] 瘛餃挽憭挽憭挽蝵桀  
105 -- [X] 瘛餃TSP閫  
106 -- [X] 瘛餃  
107 -- [X] 瘛餃TMP閫  
108 -- [X] 鈭垢敶閬蝵脣蝙嚗 91 +- [X] 蔭ZLM慦, 蔭憸憸;
109 - [X] 憭嚗韐蝸雿雿輻 92 - [X] 憭嚗韐蝸雿雿輻
110 -- [X] WEB蝡舀H264銝265嚗憸.711A/G.711U/AAC,閬虜蝻撘  
111 -- [X] 摮  
112 -- [X] WGS84CJ02銝斤頂  
113 -  
114 -[//]: # (# docker敹恍)  
115 -  
116 -[//]: # (ocker-compose蛹輕銝嚗洵銝之摰嗡蝙嚗輕銝之摰嗉扇敺撈銝泅tar )  
117 -  
118 -[//]: # (https://github.com/SaltFish001/wvp_pro_compose)  
119 -  
120 -[//]: # ([https://github.com/SaltFish001/wvp_pro_compose](https://github.com/SaltFish001/wvp_pro_compose))  
121 -  
122 -[//]: # (餈雿輕銝芷摮銝憸)  
123 -  
124 -[//]: # (```shell)  
125 -  
126 -[//]: # (docker pull 648540858/wvp_pro)  
127 -  
128 -[//]: # ()  
129 -[//]: # (docker run --env WVP_IP="雿P" -it -p 18080:18080 -p 30000-30500:30000-30500/udp -p 30000-30500:30000-30500/tcp -p 80:80 -p 5060:5060 -p 5060:5060/udp 648540858/wvp_pro)  
130 -  
131 -[//]: # (```)  
132 -  
133 -[//]: # (docker雿輻霂行https://hub.docker.com/r/648540858/wvp_pro](https://hub.docker.com/r/648540858/wvp_pro))  
134 -  
135 -# gitee郊隞  
136 -https://gitee.com/pan648540858/wvp-GB28181-pro.git  
137 -  
138 -# 憸 93 +- [X] udp憭垢璅∪, dp璅∪扯;
  94 +- [X] 蝵蝵莎
  95 +- [X] vp銝lm蝵莎像撟嗅
  96 +- [X] TSP/RTMP嚗蛹撘隞像
  97 +- [X] 瘚TSP/RTMP嚗蛹撘隞像
  98 +- [X] 瘚
  99 +- [X]
  100 +- [X] 鈭垢敶瘚/隞/隞亙鈭垢嚗蝸
  101 +
  102 +
  103 +# 憸圾
139 暻餌鈭挽憭摰寞改隞仿閬之挽憭瘚挽憭偌撟單隞仿憸 104 暻餌鈭挽憭摰寞改隞仿閬之挽憭瘚挽憭偌撟單隞仿憸
140 1. iki嚗粉隞亙葬雿憸 105 1. iki嚗粉隞亙葬雿憸
141 2. 揣issues嚗之 106 2. 揣issues嚗之
142 -3. Q蝢歹之敹撈嚗撣歇蝏粉鈭iki揣鈭ssues 107 +3. Q蝢歹901799015嚗之敹撈嚗撣歇蝏粉鈭iki揣鈭ssues
143 4. 雿隞亥窈雿蛹雿圾蝑晶 108 4. 雿隞亥窈雿蛹雿圾蝑晶
144 5. 雿隞交憸挽憭隞交摰寞憸 109 5. 雿隞交憸挽憭隞交摰寞憸
145 110
146 -  
147 -#  
148 -蝘摰之摰嗅之銝瓷移憸隞乩晶圾蝑隞交R  
149 -嚗笆隞遣霈桀隞交SSUE嚗隞亙黎銝韏瑁賑甈Z頞憿寧銝剜犖  
150 -  
151 -  
152 -  
153 # 雿輻撣桀 111 # 雿輻撣桀
154 QQ蝢: 901799015, ZLM雿輻﹝[https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit) 112 QQ蝢: 901799015, ZLM雿輻﹝[https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit)
155 QQ蝘縑銝銝, 蝎曉.甈Z之摰嗅蝢日悄霈.閫★撖嫣葬嚗洽餈tar漱pr 113 QQ蝘縑銝銝, 蝎曉.甈Z之摰嗅蝢日悄霈.閫★撖嫣葬嚗洽餈tar漱pr
156 114
157 # 悅 115 # 悅
158 憿寧誨蝙摰賣IT悅嚗靽縑銝隞亥摨鈭★ 雿憿寧銋蝣蝙鈭鈭隞皞誨銝窈銵隞嚗 鈭蝙憿寧漣熒噩蛹銝璁憿寧嚗窈銵 雿輻憿寧隞嚗砲悅銝剖銵冽憿寧靘洵銝摨悅 116 憿寧誨蝙摰賣IT悅嚗靽縑銝隞亥摨鈭★ 雿憿寧銋蝣蝙鈭鈭隞皞誨銝窈銵隞嚗 鈭蝙憿寧漣熒噩蛹銝璁憿寧嚗窈銵 雿輻憿寧隞嚗砲悅銝剖銵冽憿寧靘洵銝摨悅
  117 +
159 # 靚 118 # 靚
160 陝雿憭(https://github.com/xia-chu) 皞獢,撟嗅撘葉蝏葬 119 陝雿憭(https://github.com/xia-chu) 皞獢,撟嗅撘葉蝏葬
161 陝雿dexter langhuihui](https://github.com/langhuihui) 撘皞末EB 120 陝雿dexter langhuihui](https://github.com/langhuihui) 撘皞末EB
doc/_content/broadcast.md 0 → 100644
  1 +# 原理图
  2 +
  3 +## 使用ffmpeg测试语音对讲原理
  4 +```plantuml
  5 +@startuml
  6 +"FFMPEG" -> "ZLMediaKit": 推流到zlm
  7 +"WVP-PRO" <- "ZLMediaKit": 通知收到语音对讲推流,携带设备和通道信息
  8 +"WVP-PRO" -> "设备": 开始语音对讲
  9 +"WVP-PRO" <-- "设备": 语音对讲建立成功,携带收流端口
  10 +"WVP-PRO" -> "ZLMediaKit": 通知zlm将流推送到设备收流端口
  11 +"ZLMediaKit" -> "设备": 向设备推流
  12 +@enduml
  13 +```
  14 +
  15 +## 使用网页测试语音对讲原理
  16 +```plantuml
  17 +@startuml
  18 +"前端页面" -> "WVP-PRO": 请求推流地址
  19 +"前端页面" <-- "WVP-PRO": 返回推流地址
  20 +"前端页面" -> "ZLMediaKit": 使用webrtc推流到zlm,以下过程相同
  21 +"WVP-PRO" <- "ZLMediaKit": 通知收到语音对讲推流,携带设备和通道信息
  22 +"WVP-PRO" -> "设备": 开始语音对讲
  23 +"WVP-PRO" <-- "设备": 语音对讲建立成功,携带收流端口
  24 +"WVP-PRO" -> "ZLMediaKit": 通知zlm将流推送到设备收流端口
  25 +"ZLMediaKit" -> "设备": 向设备推流
  26 +@enduml
  27 +```
0 \ No newline at end of file 28 \ No newline at end of file
doc/_media/2.png 0 → 100644

469 KB

doc/_media/3-1.png 0 → 100644

136 KB

doc/_media/3-2.png 0 → 100644

650 KB

doc/_media/3-3.png 0 → 100644

1.04 MB

doc/_media/3.png 0 → 100644

146 KB

doc/_media/index.png 0 → 100644

154 KB

@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 11
12 <groupId>com.genersoft</groupId> 12 <groupId>com.genersoft</groupId>
13 <artifactId>wvp-pro</artifactId> 13 <artifactId>wvp-pro</artifactId>
14 - <version>2.6.6</version> 14 + <version>2.6.7</version>
15 <name>web video platform</name> 15 <name>web video platform</name>
16 <description>国标28181视频平台</description> 16 <description>国标28181视频平台</description>
17 17
sql/mysql.sql
@@ -54,7 +54,7 @@ CREATE TABLE `device` ( @@ -54,7 +54,7 @@ CREATE TABLE `device` (
54 `localIp` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, 54 `localIp` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
55 PRIMARY KEY (`id`), 55 PRIMARY KEY (`id`),
56 UNIQUE KEY `device_deviceId_uindex` (`deviceId`) 56 UNIQUE KEY `device_deviceId_uindex` (`deviceId`)
57 -) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 57 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
58 /*!40101 SET character_set_client = @saved_cs_client */; 58 /*!40101 SET character_set_client = @saved_cs_client */;
59 59
60 -- 60 --
@@ -86,7 +86,7 @@ CREATE TABLE `device_alarm` ( @@ -86,7 +86,7 @@ CREATE TABLE `device_alarm` (
86 `alarmType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, 86 `alarmType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
87 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, 87 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
88 PRIMARY KEY (`id`) USING BTREE 88 PRIMARY KEY (`id`) USING BTREE
89 -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 89 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
90 /*!40101 SET character_set_client = @saved_cs_client */; 90 /*!40101 SET character_set_client = @saved_cs_client */;
91 91
92 -- 92 --
@@ -146,7 +146,7 @@ CREATE TABLE `device_channel` ( @@ -146,7 +146,7 @@ CREATE TABLE `device_channel` (
146 PRIMARY KEY (`id`), 146 PRIMARY KEY (`id`),
147 UNIQUE KEY `device_channel_id_uindex` (`id`), 147 UNIQUE KEY `device_channel_id_uindex` (`id`),
148 UNIQUE KEY `device_channel_pk` (`channelId`,`deviceId`) 148 UNIQUE KEY `device_channel_pk` (`channelId`,`deviceId`)
149 -) ENGINE=InnoDB AUTO_INCREMENT=74416 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 149 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
150 /*!40101 SET character_set_client = @saved_cs_client */; 150 /*!40101 SET character_set_client = @saved_cs_client */;
151 151
152 -- 152 --
@@ -183,7 +183,7 @@ CREATE TABLE `device_mobile_position` ( @@ -183,7 +183,7 @@ CREATE TABLE `device_mobile_position` (
183 `latitudeWgs84` double DEFAULT NULL, 183 `latitudeWgs84` double DEFAULT NULL,
184 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, 184 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
185 PRIMARY KEY (`id`) 185 PRIMARY KEY (`id`)
186 -) ENGINE=InnoDB AUTO_INCREMENT=55589 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 186 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
187 /*!40101 SET character_set_client = @saved_cs_client */; 187 /*!40101 SET character_set_client = @saved_cs_client */;
188 188
189 -- 189 --
@@ -216,7 +216,7 @@ CREATE TABLE `gb_stream` ( @@ -216,7 +216,7 @@ CREATE TABLE `gb_stream` (
216 PRIMARY KEY (`gbStreamId`) USING BTREE, 216 PRIMARY KEY (`gbStreamId`) USING BTREE,
217 UNIQUE KEY `app` (`app`,`stream`) USING BTREE, 217 UNIQUE KEY `app` (`app`,`stream`) USING BTREE,
218 UNIQUE KEY `gbId` (`gbId`) USING BTREE 218 UNIQUE KEY `gbId` (`gbId`) USING BTREE
219 -) ENGINE=InnoDB AUTO_INCREMENT=331060 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 219 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
220 /*!40101 SET character_set_client = @saved_cs_client */; 220 /*!40101 SET character_set_client = @saved_cs_client */;
221 221
222 -- 222 --
@@ -246,7 +246,7 @@ CREATE TABLE `log` ( @@ -246,7 +246,7 @@ CREATE TABLE `log` (
246 `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, 246 `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
247 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, 247 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
248 PRIMARY KEY (`id`) USING BTREE 248 PRIMARY KEY (`id`) USING BTREE
249 -) ENGINE=InnoDB AUTO_INCREMENT=760908 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 249 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
250 /*!40101 SET character_set_client = @saved_cs_client */; 250 /*!40101 SET character_set_client = @saved_cs_client */;
251 251
252 -- 252 --
@@ -338,7 +338,7 @@ CREATE TABLE `parent_platform` ( @@ -338,7 +338,7 @@ CREATE TABLE `parent_platform` (
338 PRIMARY KEY (`id`), 338 PRIMARY KEY (`id`),
339 UNIQUE KEY `parent_platform_id_uindex` (`id`), 339 UNIQUE KEY `parent_platform_id_uindex` (`id`),
340 UNIQUE KEY `parent_platform_pk` (`serverGBId`) 340 UNIQUE KEY `parent_platform_pk` (`serverGBId`)
341 -) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 341 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
342 /*!40101 SET character_set_client = @saved_cs_client */; 342 /*!40101 SET character_set_client = @saved_cs_client */;
343 343
344 -- 344 --
@@ -390,7 +390,7 @@ CREATE TABLE `platform_gb_channel` ( @@ -390,7 +390,7 @@ CREATE TABLE `platform_gb_channel` (
390 `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, 390 `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
391 `deviceChannelId` int NOT NULL, 391 `deviceChannelId` int NOT NULL,
392 PRIMARY KEY (`id`) 392 PRIMARY KEY (`id`)
393 -) ENGINE=InnoDB AUTO_INCREMENT=3146 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 393 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
394 /*!40101 SET character_set_client = @saved_cs_client */; 394 /*!40101 SET character_set_client = @saved_cs_client */;
395 395
396 -- 396 --
@@ -410,13 +410,13 @@ DROP TABLE IF EXISTS `platform_gb_stream`; @@ -410,13 +410,13 @@ DROP TABLE IF EXISTS `platform_gb_stream`;
410 /*!40101 SET @saved_cs_client = @@character_set_client */; 410 /*!40101 SET @saved_cs_client = @@character_set_client */;
411 /*!50503 SET character_set_client = utf8mb4 */; 411 /*!50503 SET character_set_client = utf8mb4 */;
412 CREATE TABLE `platform_gb_stream` ( 412 CREATE TABLE `platform_gb_stream` (
  413 + `id` int NOT NULL AUTO_INCREMENT,
413 `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, 414 `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
414 `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, 415 `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
415 `gbStreamId` int NOT NULL, 416 `gbStreamId` int NOT NULL,
416 - `id` int NOT NULL AUTO_INCREMENT,  
417 PRIMARY KEY (`id`), 417 PRIMARY KEY (`id`),
418 UNIQUE KEY `platform_gb_stream_pk` (`platformId`,`catalogId`,`gbStreamId`) 418 UNIQUE KEY `platform_gb_stream_pk` (`platformId`,`catalogId`,`gbStreamId`)
419 -) ENGINE=InnoDB AUTO_INCREMENT=391772 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 419 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
420 /*!40101 SET character_set_client = @saved_cs_client */; 420 /*!40101 SET character_set_client = @saved_cs_client */;
421 421
422 -- 422 --
@@ -458,7 +458,7 @@ CREATE TABLE `stream_proxy` ( @@ -458,7 +458,7 @@ CREATE TABLE `stream_proxy` (
458 `enable_disable_none_reader` bit(1) DEFAULT NULL, 458 `enable_disable_none_reader` bit(1) DEFAULT NULL,
459 PRIMARY KEY (`id`), 459 PRIMARY KEY (`id`),
460 UNIQUE KEY `stream_proxy_pk` (`app`,`stream`) 460 UNIQUE KEY `stream_proxy_pk` (`app`,`stream`)
461 -) ENGINE=InnoDB AUTO_INCREMENT=568 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 461 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
462 /*!40101 SET character_set_client = @saved_cs_client */; 462 /*!40101 SET character_set_client = @saved_cs_client */;
463 463
464 -- 464 --
@@ -495,7 +495,7 @@ CREATE TABLE `stream_push` ( @@ -495,7 +495,7 @@ CREATE TABLE `stream_push` (
495 `self` int DEFAULT NULL, 495 `self` int DEFAULT NULL,
496 PRIMARY KEY (`id`), 496 PRIMARY KEY (`id`),
497 UNIQUE KEY `stream_push_pk` (`app`,`stream`) 497 UNIQUE KEY `stream_push_pk` (`app`,`stream`)
498 -) ENGINE=InnoDB AUTO_INCREMENT=361492 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 498 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
499 /*!40101 SET character_set_client = @saved_cs_client */; 499 /*!40101 SET character_set_client = @saved_cs_client */;
500 500
501 -- 501 --
@@ -524,7 +524,7 @@ CREATE TABLE `user` ( @@ -524,7 +524,7 @@ CREATE TABLE `user` (
524 `pushKey` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, 524 `pushKey` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
525 PRIMARY KEY (`id`) USING BTREE, 525 PRIMARY KEY (`id`) USING BTREE,
526 UNIQUE KEY `user_username_uindex` (`username`) USING BTREE 526 UNIQUE KEY `user_username_uindex` (`username`) USING BTREE
527 -) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 527 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
528 /*!40101 SET character_set_client = @saved_cs_client */; 528 /*!40101 SET character_set_client = @saved_cs_client */;
529 529
530 -- 530 --
@@ -533,7 +533,7 @@ CREATE TABLE `user` ( @@ -533,7 +533,7 @@ CREATE TABLE `user` (
533 533
534 LOCK TABLES `user` WRITE; 534 LOCK TABLES `user` WRITE;
535 /*!40000 ALTER TABLE `user` DISABLE KEYS */; 535 /*!40000 ALTER TABLE `user` DISABLE KEYS */;
536 -INSERT INTO `user` VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021 - 04 - 13 14:14:57','2021 - 04 - 13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3'); 536 +INSERT INTO `user` VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3');
537 /*!40000 ALTER TABLE `user` ENABLE KEYS */; 537 /*!40000 ALTER TABLE `user` ENABLE KEYS */;
538 UNLOCK TABLES; 538 UNLOCK TABLES;
539 539
@@ -551,7 +551,7 @@ CREATE TABLE `user_role` ( @@ -551,7 +551,7 @@ CREATE TABLE `user_role` (
551 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, 551 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
552 `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, 552 `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
553 PRIMARY KEY (`id`) USING BTREE 553 PRIMARY KEY (`id`) USING BTREE
554 -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; 554 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
555 /*!40101 SET character_set_client = @saved_cs_client */; 555 /*!40101 SET character_set_client = @saved_cs_client */;
556 556
557 -- 557 --
sql/update.sql
1 -alter table media_server  
2 - drop column streamNoneReaderDelayMS;  
3 -  
4 -alter table media_server  
5 - drop column sendRtpPortRange;  
6 -  
7 -alter table stream_proxy  
8 - add enable_disable_none_reader bit(1) default null;  
9 - 1 +-- 2.6.6->2.6.7
10 alter table device 2 alter table device
11 - add mediaServerId varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'auto';  
12 -  
13 -alter table device  
14 - add custom_name varchar(255) default null;  
15 -  
16 -alter table device  
17 - add sdpIp varchar(50) default null;  
18 -  
19 -alter table device  
20 - add localIp varchar(50) default null;  
21 -  
22 -alter table device  
23 - add password varchar(255) default null;  
24 -  
25 -alter table device  
26 - modify ip varchar(50) null;  
27 -  
28 -alter table device  
29 - modify port int null;  
30 -  
31 -alter table device  
32 - modify expires int null;  
33 -  
34 -alter table device  
35 - modify subscribeCycleForCatalog int null;  
36 -  
37 -alter table device  
38 - modify hostAddress varchar(50) null;  
39 -  
40 -alter table stream_proxy  
41 - change enable_hls enable_audio bit null;  
42 -  
43 - 3 + add keepaliveIntervalTime int default null;
44 \ No newline at end of file 4 \ No newline at end of file
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
@@ -71,6 +71,8 @@ public class VideoManagerConstants { @@ -71,6 +71,8 @@ public class VideoManagerConstants {
71 public static final String SYSTEM_INFO_DISK_PREFIX = "VMP_SYSTEM_INFO_DISK_"; 71 public static final String SYSTEM_INFO_DISK_PREFIX = "VMP_SYSTEM_INFO_DISK_";
72 public static final String BROADCAST_WAITE_INVITE = "task_broadcast_waite_invite_"; 72 public static final String BROADCAST_WAITE_INVITE = "task_broadcast_waite_invite_";
73 73
  74 + public static final String REGISTER_EXPIRE_TASK_KEY_PREFIX = "VMP_device_register_expire_";
  75 +
74 76
75 77
76 78
src/main/java/com/genersoft/iot/vmp/conf/ApiAccessFilter.java
@@ -10,6 +10,7 @@ import org.slf4j.Logger; @@ -10,6 +10,7 @@ import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory; 10 import org.slf4j.LoggerFactory;
11 import org.springframework.beans.factory.annotation.Autowired; 11 import org.springframework.beans.factory.annotation.Autowired;
12 import org.springframework.http.HttpStatus; 12 import org.springframework.http.HttpStatus;
  13 +import org.springframework.util.ObjectUtils;
13 import org.springframework.web.filter.OncePerRequestFilter; 14 import org.springframework.web.filter.OncePerRequestFilter;
14 15
15 import javax.servlet.*; 16 import javax.servlet.*;
@@ -51,6 +52,9 @@ public class ApiAccessFilter extends OncePerRequestFilter { @@ -51,6 +52,9 @@ public class ApiAccessFilter extends OncePerRequestFilter {
51 52
52 LogDto logDto = new LogDto(); 53 LogDto logDto = new LogDto();
53 logDto.setName(uriName); 54 logDto.setName(uriName);
  55 + if (ObjectUtils.isEmpty(username)) {
  56 + username = "";
  57 + }
54 logDto.setUsername(username); 58 logDto.setUsername(username);
55 logDto.setAddress(servletRequest.getRemoteAddr()); 59 logDto.setAddress(servletRequest.getRemoteAddr());
56 logDto.setResult(HttpStatus.valueOf(servletResponse.getStatus()).toString()); 60 logDto.setResult(HttpStatus.valueOf(servletResponse.getStatus()).toString());
src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
@@ -35,6 +35,8 @@ public class UserSetting { @@ -35,6 +35,8 @@ public class UserSetting {
35 35
36 private Boolean useSourceIpAsStreamIp = Boolean.FALSE; 36 private Boolean useSourceIpAsStreamIp = Boolean.FALSE;
37 37
  38 + private Boolean sipUseSourceIpAsRemoteAddress = Boolean.FALSE;
  39 +
38 private Boolean streamOnDemand = Boolean.TRUE; 40 private Boolean streamOnDemand = Boolean.TRUE;
39 41
40 private Boolean pushAuthority = Boolean.TRUE; 42 private Boolean pushAuthority = Boolean.TRUE;
@@ -45,6 +47,8 @@ public class UserSetting { @@ -45,6 +47,8 @@ public class UserSetting {
45 47
46 private Boolean pushStreamAfterAck = Boolean.FALSE; 48 private Boolean pushStreamAfterAck = Boolean.FALSE;
47 49
  50 + private Boolean sipLog = Boolean.FALSE;
  51 +
48 private String serverId = "000000"; 52 private String serverId = "000000";
49 53
50 private String thirdPartyGBIdReg = "[\\s\\S]*"; 54 private String thirdPartyGBIdReg = "[\\s\\S]*";
@@ -216,4 +220,20 @@ public class UserSetting { @@ -216,4 +220,20 @@ public class UserSetting {
216 public void setPushStreamAfterAck(Boolean pushStreamAfterAck) { 220 public void setPushStreamAfterAck(Boolean pushStreamAfterAck) {
217 this.pushStreamAfterAck = pushStreamAfterAck; 221 this.pushStreamAfterAck = pushStreamAfterAck;
218 } 222 }
  223 +
  224 + public Boolean getSipUseSourceIpAsRemoteAddress() {
  225 + return sipUseSourceIpAsRemoteAddress;
  226 + }
  227 +
  228 + public void setSipUseSourceIpAsRemoteAddress(Boolean sipUseSourceIpAsRemoteAddress) {
  229 + this.sipUseSourceIpAsRemoteAddress = sipUseSourceIpAsRemoteAddress;
  230 + }
  231 +
  232 + public Boolean getSipLog() {
  233 + return sipLog;
  234 + }
  235 +
  236 + public void setSipLog(Boolean sipLog) {
  237 + this.sipLog = sipLog;
  238 + }
219 } 239 }
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
1 package com.genersoft.iot.vmp.gb28181; 1 package com.genersoft.iot.vmp.gb28181;
2 2
3 import com.genersoft.iot.vmp.conf.SipConfig; 3 import com.genersoft.iot.vmp.conf.SipConfig;
  4 +import com.genersoft.iot.vmp.conf.UserSetting;
4 import com.genersoft.iot.vmp.gb28181.conf.DefaultProperties; 5 import com.genersoft.iot.vmp.gb28181.conf.DefaultProperties;
5 import com.genersoft.iot.vmp.gb28181.transmit.ISIPProcessorObserver; 6 import com.genersoft.iot.vmp.gb28181.transmit.ISIPProcessorObserver;
6 import gov.nist.javax.sip.SipProviderImpl; 7 import gov.nist.javax.sip.SipProviderImpl;
@@ -29,6 +30,9 @@ public class SipLayer implements CommandLineRunner { @@ -29,6 +30,9 @@ public class SipLayer implements CommandLineRunner {
29 @Autowired 30 @Autowired
30 private ISIPProcessorObserver sipProcessorObserver; 31 private ISIPProcessorObserver sipProcessorObserver;
31 32
  33 + @Autowired
  34 + private UserSetting userSetting;
  35 +
32 private final Map<String, SipProviderImpl> tcpSipProviderMap = new ConcurrentHashMap<>(); 36 private final Map<String, SipProviderImpl> tcpSipProviderMap = new ConcurrentHashMap<>();
33 private final Map<String, SipProviderImpl> udpSipProviderMap = new ConcurrentHashMap<>(); 37 private final Map<String, SipProviderImpl> udpSipProviderMap = new ConcurrentHashMap<>();
34 38
@@ -61,7 +65,7 @@ public class SipLayer implements CommandLineRunner { @@ -61,7 +65,7 @@ public class SipLayer implements CommandLineRunner {
61 private void addListeningPoint(String monitorIp, int port){ 65 private void addListeningPoint(String monitorIp, int port){
62 SipStackImpl sipStack; 66 SipStackImpl sipStack;
63 try { 67 try {
64 - sipStack = (SipStackImpl)sipFactory.createSipStack(DefaultProperties.getProperties(monitorIp, false)); 68 + sipStack = (SipStackImpl)sipFactory.createSipStack(DefaultProperties.getProperties(monitorIp, false, userSetting.getSipLog()));
65 } catch (PeerUnavailableException e) { 69 } catch (PeerUnavailableException e) {
66 logger.error("[Sip Server] SIP服务启动失败, 监听地址{}失败,请检查ip是否正确", monitorIp); 70 logger.error("[Sip Server] SIP服务启动失败, 监听地址{}失败,请检查ip是否正确", monitorIp);
67 return; 71 return;
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
@@ -94,6 +94,13 @@ public class Device { @@ -94,6 +94,13 @@ public class Device {
94 @Schema(description = "心跳时间") 94 @Schema(description = "心跳时间")
95 private String keepaliveTime; 95 private String keepaliveTime;
96 96
  97 +
  98 + /**
  99 + * 心跳间隔
  100 + */
  101 + @Schema(description = "心跳间隔")
  102 + private int keepaliveIntervalTime;
  103 +
97 /** 104 /**
98 * 通道个数 105 * 通道个数
99 */ 106 */
@@ -414,4 +421,12 @@ public class Device { @@ -414,4 +421,12 @@ public class Device {
414 public void setLocalIp(String localIp) { 421 public void setLocalIp(String localIp) {
415 this.localIp = localIp; 422 this.localIp = localIp;
416 } 423 }
  424 +
  425 + public int getKeepaliveIntervalTime() {
  426 + return keepaliveIntervalTime;
  427 + }
  428 +
  429 + public void setKeepaliveIntervalTime(int keepaliveIntervalTime) {
  430 + this.keepaliveIntervalTime = keepaliveIntervalTime;
  431 + }
417 } 432 }
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RemoteAddressInfo.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.bean;
  2 +
  3 +public class RemoteAddressInfo {
  4 + private String ip;
  5 + private int port;
  6 +
  7 + public RemoteAddressInfo(String ip, int port) {
  8 + this.ip = ip;
  9 + this.port = port;
  10 + }
  11 +
  12 + public String getIp() {
  13 + return ip;
  14 + }
  15 +
  16 + public void setIp(String ip) {
  17 + this.ip = ip;
  18 + }
  19 +
  20 + public int getPort() {
  21 + return port;
  22 + }
  23 +
  24 + public void setPort(int port) {
  25 + this.port = port;
  26 + }
  27 +}
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SipTransactionInfo.java
@@ -9,14 +9,15 @@ public class SipTransactionInfo { @@ -9,14 +9,15 @@ public class SipTransactionInfo {
9 private String toTag; 9 private String toTag;
10 private String viaBranch; 10 private String viaBranch;
11 11
12 - private boolean fromServer; 12 + // 自己是否媒体流发送者
  13 + private boolean asSender;
13 14
14 - public SipTransactionInfo(SIPResponse response, boolean fromServer) { 15 + public SipTransactionInfo(SIPResponse response, boolean asSender) {
15 this.callId = response.getCallIdHeader().getCallId(); 16 this.callId = response.getCallIdHeader().getCallId();
16 this.fromTag = response.getFromTag(); 17 this.fromTag = response.getFromTag();
17 this.toTag = response.getToTag(); 18 this.toTag = response.getToTag();
18 this.viaBranch = response.getTopmostViaHeader().getBranch(); 19 this.viaBranch = response.getTopmostViaHeader().getBranch();
19 - this.fromServer = fromServer; 20 + this.asSender = asSender;
20 } 21 }
21 22
22 public SipTransactionInfo(SIPResponse response) { 23 public SipTransactionInfo(SIPResponse response) {
@@ -24,7 +25,7 @@ public class SipTransactionInfo { @@ -24,7 +25,7 @@ public class SipTransactionInfo {
24 this.fromTag = response.getFromTag(); 25 this.fromTag = response.getFromTag();
25 this.toTag = response.getToTag(); 26 this.toTag = response.getToTag();
26 this.viaBranch = response.getTopmostViaHeader().getBranch(); 27 this.viaBranch = response.getTopmostViaHeader().getBranch();
27 - this.fromServer = true; 28 + this.asSender = false;
28 } 29 }
29 30
30 public SipTransactionInfo() { 31 public SipTransactionInfo() {
@@ -62,11 +63,11 @@ public class SipTransactionInfo { @@ -62,11 +63,11 @@ public class SipTransactionInfo {
62 this.viaBranch = viaBranch; 63 this.viaBranch = viaBranch;
63 } 64 }
64 65
65 - public boolean isFromServer() {  
66 - return fromServer; 66 + public boolean isAsSender() {
  67 + return asSender;
67 } 68 }
68 69
69 - public void setFromServer(boolean fromServer) {  
70 - this.fromServer = fromServer; 70 + public void setAsSender(boolean asSender) {
  71 + this.asSender = asSender;
71 } 72 }
72 } 73 }
src/main/java/com/genersoft/iot/vmp/gb28181/conf/DefaultProperties.java
1 package com.genersoft.iot.vmp.gb28181.conf; 1 package com.genersoft.iot.vmp.gb28181.conf;
2 2
  3 +import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd.AlarmNotifyMessageHandler;
  4 +import org.slf4j.Logger;
  5 +import org.slf4j.LoggerFactory;
  6 +
3 import java.util.Properties; 7 import java.util.Properties;
4 8
5 /** 9 /**
@@ -8,10 +12,11 @@ import java.util.Properties; @@ -8,10 +12,11 @@ import java.util.Properties;
8 */ 12 */
9 public class DefaultProperties { 13 public class DefaultProperties {
10 14
11 - public static Properties getProperties(String ip, boolean isDebug) { 15 + public static Properties getProperties(String ip, boolean isDebug, boolean sipLog) {
12 Properties properties = new Properties(); 16 Properties properties = new Properties();
13 properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP"); 17 properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
14 properties.setProperty("javax.sip.IP_ADDRESS", ip); 18 properties.setProperty("javax.sip.IP_ADDRESS", ip);
  19 + // 关闭自动会话
15 properties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off"); 20 properties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off");
16 /** 21 /**
17 * 完整配置参考 gov.nist.javax.sip.SipStackImpl,需要下载源码 22 * 完整配置参考 gov.nist.javax.sip.SipStackImpl,需要下载源码
@@ -26,7 +31,7 @@ public class DefaultProperties { @@ -26,7 +31,7 @@ public class DefaultProperties {
26 // 接收所有notify请求,即使没有订阅 31 // 接收所有notify请求,即使没有订阅
27 properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true"); 32 properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true");
28 properties.setProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING", "false"); 33 properties.setProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING", "false");
29 - properties.setProperty("gov.nist.javax.sip.CANCEL_CLIENT_TRANSACTION_CHECKED", "false"); 34 + properties.setProperty("gov.nist.javax.sip.CANCEL_CLIENT_TRANSACTION_CHECKED", "true");
30 // 为_NULL _对话框传递_终止的_事件 35 // 为_NULL _对话框传递_终止的_事件
31 properties.setProperty("gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG", "true"); 36 properties.setProperty("gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG", "true");
32 // 会话清理策略 37 // 会话清理策略
@@ -35,11 +40,38 @@ public class DefaultProperties { @@ -35,11 +40,38 @@ public class DefaultProperties {
35 properties.setProperty("gov.nist.javax.sip.RELIABLE_CONNECTION_KEEP_ALIVE_TIMEOUT", "60"); 40 properties.setProperty("gov.nist.javax.sip.RELIABLE_CONNECTION_KEEP_ALIVE_TIMEOUT", "60");
36 // 获取实际内容长度,不使用header中的长度信息 41 // 获取实际内容长度,不使用header中的长度信息
37 properties.setProperty("gov.nist.javax.sip.COMPUTE_CONTENT_LENGTH_FROM_MESSAGE_BODY", "true"); 42 properties.setProperty("gov.nist.javax.sip.COMPUTE_CONTENT_LENGTH_FROM_MESSAGE_BODY", "true");
  43 + // 线程可重入
  44 + properties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true");
  45 + // 定义应用程序打算多久审计一次 SIP 堆栈,了解其内部线程的健康状况(该属性指定连续审计之间的时间(以毫秒为单位))
  46 + properties.setProperty("gov.nist.javax.sip.THREAD_AUDIT_INTERVAL_IN_MILLISECS", "30000");
38 47
39 /** 48 /**
40 * sip_server_log.log 和 sip_debug_log.log ERROR, INFO, WARNING, OFF, DEBUG, TRACE 49 * sip_server_log.log 和 sip_debug_log.log ERROR, INFO, WARNING, OFF, DEBUG, TRACE
41 */ 50 */
42 - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "ERROR"); 51 + Logger logger = LoggerFactory.getLogger(AlarmNotifyMessageHandler.class);
  52 + if (sipLog) {
  53 + if (logger.isDebugEnabled()) {
  54 + System.out.println("DEBUG");
  55 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "DEBUG");
  56 + }else if (logger.isInfoEnabled()) {
  57 + System.out.println("INFO1");
  58 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "INFO");
  59 + }else if (logger.isWarnEnabled()) {
  60 + System.out.println("WARNING");
  61 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "WARNING");
  62 + }else if (logger.isErrorEnabled()) {
  63 + System.out.println("ERROR");
  64 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "ERROR");
  65 + }else {
  66 + System.out.println("INFO2");
  67 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "INFO");
  68 + }
  69 + logger.info("[SIP日志]级别为: {}", properties.getProperty("gov.nist.javax.sip.TRACE_LEVEL"));
  70 + }else {
  71 + logger.info("[SIP日志]已关闭");
  72 + }
  73 +
  74 +
43 75
44 return properties; 76 return properties;
45 } 77 }
src/main/java/com/genersoft/iot/vmp/gb28181/conf/SipLoggerPass.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.gb28181.conf;  
2 -  
3 -import gov.nist.core.StackLogger;  
4 -  
5 -import java.util.Properties;  
6 -  
7 -/**  
8 - * sip日志格式化  
9 - * 暂不使用  
10 - */  
11 -public class SipLoggerPass implements StackLogger {  
12 -  
13 - @Override  
14 - public void logStackTrace() {  
15 -  
16 - }  
17 -  
18 - @Override  
19 - public void logStackTrace(int traceLevel) {  
20 -  
21 - }  
22 -  
23 - @Override  
24 - public int getLineCount() {  
25 - return 0;  
26 - }  
27 -  
28 - @Override  
29 - public void logException(Throwable ex) {  
30 -  
31 - }  
32 -  
33 - @Override  
34 - public void logDebug(String message) {  
35 -  
36 - }  
37 -  
38 - @Override  
39 - public void logDebug(String message, Exception ex) {  
40 -  
41 - }  
42 -  
43 - @Override  
44 - public void logTrace(String message) {  
45 -  
46 - }  
47 -  
48 - @Override  
49 - public void logFatalError(String message) {  
50 -  
51 - }  
52 -  
53 - @Override  
54 - public void logError(String message) {  
55 -  
56 - }  
57 -  
58 - @Override  
59 - public boolean isLoggingEnabled() {  
60 - return false;  
61 - }  
62 -  
63 - @Override  
64 - public boolean isLoggingEnabled(int logLevel) {  
65 - return false;  
66 - }  
67 -  
68 - @Override  
69 - public void logError(String message, Exception ex) {  
70 -  
71 - }  
72 -  
73 - @Override  
74 - public void logWarning(String string) {  
75 -  
76 - }  
77 -  
78 - @Override  
79 - public void logInfo(String string) {  
80 -  
81 - }  
82 -  
83 - @Override  
84 - public void disableLogging() {  
85 -  
86 - }  
87 -  
88 - @Override  
89 - public void enableLogging() {  
90 -  
91 - }  
92 -  
93 - @Override  
94 - public void setBuildTimeStamp(String buildTimeStamp) {  
95 -  
96 - }  
97 -  
98 - @Override  
99 - public void setStackProperties(Properties stackProperties) {  
100 -  
101 - }  
102 -  
103 - @Override  
104 - public String getLoggerName() {  
105 - return null;  
106 - }  
107 -}  
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
@@ -13,7 +13,7 @@ import org.springframework.util.ObjectUtils; @@ -13,7 +13,7 @@ import org.springframework.util.ObjectUtils;
13 import java.util.ArrayList; 13 import java.util.ArrayList;
14 import java.util.List; 14 import java.util.List;
15 15
16 -/** 16 +/**
17 * @description:视频流session管理器,管理视频预览、预览回放的通信句柄 17 * @description:视频流session管理器,管理视频预览、预览回放的通信句柄
18 * @author: swwheihei 18 * @author: swwheihei
19 * @date: 2020年5月13日 下午4:03:02 19 * @date: 2020年5月13日 下午4:03:02
@@ -51,6 +51,7 @@ public class VideoStreamSessionManager { @@ -51,6 +51,7 @@ public class VideoStreamSessionManager {
51 ssrcTransaction.setSsrc(ssrc); 51 ssrcTransaction.setSsrc(ssrc);
52 ssrcTransaction.setMediaServerId(mediaServerId); 52 ssrcTransaction.setMediaServerId(mediaServerId);
53 ssrcTransaction.setType(type); 53 ssrcTransaction.setType(type);
  54 +
54 RedisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId() 55 RedisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId()
55 + "_" + deviceId + "_" + channelId + "_" + callId + "_" + stream, ssrcTransaction); 56 + "_" + deviceId + "_" + channelId + "_" + callId + "_" + stream, ssrcTransaction);
56 } 57 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
@@ -170,11 +170,11 @@ public class SIPRequestHeaderProvider { @@ -170,11 +170,11 @@ public class SIPRequestHeaderProvider {
170 //from 170 //from
171 SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain()); 171 SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain());
172 Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI); 172 Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI);
173 - FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, transactionInfo.isFromServer()?transactionInfo.getFromTag():transactionInfo.getToTag()); 173 + FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, transactionInfo.getFromTag());
174 //to 174 //to
175 SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId,device.getHostAddress()); 175 SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId,device.getHostAddress());
176 Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); 176 Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI);
177 - ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress,transactionInfo.isFromServer()?transactionInfo.getToTag():transactionInfo.getFromTag()); 177 + ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress, transactionInfo.getToTag());
178 178
179 //Forwards 179 //Forwards
180 MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); 180 MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70);
@@ -186,11 +186,6 @@ public class SIPRequestHeaderProvider { @@ -186,11 +186,6 @@ public class SIPRequestHeaderProvider {
186 186
187 request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); 187 request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil));
188 188
189 - Address concatAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), sipLayer.getLocalIp(device.getLocalIp())+":"+sipConfig.getPort()));  
190 - request.addHeader(sipLayer.getSipFactory().createHeaderFactory().createContactHeader(concatAddress));  
191 -  
192 - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil));  
193 -  
194 return request; 189 return request;
195 } 190 }
196 191
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -574,10 +574,11 @@ public class SIPCommander implements ISIPCommander { @@ -574,10 +574,11 @@ public class SIPCommander implements ISIPCommander {
574 if (inviteStreamCallback != null) { 574 if (inviteStreamCallback != null) {
575 inviteStreamCallback.call(new InviteStreamInfo(mediaServerItem, null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId(), "rtp", ssrcInfo.getStream())); 575 inviteStreamCallback.call(new InviteStreamInfo(mediaServerItem, null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId(), "rtp", ssrcInfo.getStream()));
576 } 576 }
  577 +
577 sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, okEvent -> { 578 sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, okEvent -> {
578 ResponseEvent responseEvent = (ResponseEvent) okEvent.event; 579 ResponseEvent responseEvent = (ResponseEvent) okEvent.event;
579 SIPResponse response = (SIPResponse) responseEvent.getResponse(); 580 SIPResponse response = (SIPResponse) responseEvent.getResponse();
580 - streamSession.put(device.getDeviceId(), channelId,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), response, VideoStreamSessionManager.SessionType.download); 581 + streamSession.put(device.getDeviceId(), channelId, response.getCallIdHeader().getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), response, VideoStreamSessionManager.SessionType.download);
581 }); 582 });
582 } 583 }
583 584
@@ -655,7 +656,12 @@ public class SIPCommander implements ISIPCommander { @@ -655,7 +656,12 @@ public class SIPCommander implements ISIPCommander {
655 */ 656 */
656 @Override 657 @Override
657 public void streamByeCmd(Device device, String channelId, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException { 658 public void streamByeCmd(Device device, String channelId, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException {
658 - SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, callId, stream); 659 + SsrcTransaction ssrcTransaction;
  660 + if (callId != null) {
  661 + ssrcTransaction = streamSession.getSsrcTransaction(null, null, callId, null);
  662 + }else {
  663 + ssrcTransaction = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, null, stream);
  664 + }
659 if (ssrcTransaction == null) { 665 if (ssrcTransaction == null) {
660 throw new SsrcTransactionNotFoundException(device.getDeviceId(), channelId, callId, stream); 666 throw new SsrcTransactionNotFoundException(device.getDeviceId(), channelId, callId, stream);
661 } 667 }
@@ -769,7 +775,7 @@ public class SIPCommander implements ISIPCommander { @@ -769,7 +775,7 @@ public class SIPCommander implements ISIPCommander {
769 cmdXml.append("<GuardCmd>" + guardCmdStr + "</GuardCmd>\r\n"); 775 cmdXml.append("<GuardCmd>" + guardCmdStr + "</GuardCmd>\r\n");
770 cmdXml.append("</Control>\r\n"); 776 cmdXml.append("</Control>\r\n");
771 777
772 - 778 +
773 779
774 Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); 780 Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()));
775 sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent); 781 sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
@@ -307,19 +307,20 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -307,19 +307,20 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
307 * @return 307 * @return
308 */ 308 */
309 @Override 309 @Override
310 - public void deviceStatusResponse(ParentPlatform parentPlatform, String sn, String fromTag) throws SipException, InvalidArgumentException, ParseException { 310 + public void deviceStatusResponse(ParentPlatform parentPlatform,String channelId, String sn, String fromTag,int status) throws SipException, InvalidArgumentException, ParseException {
311 if (parentPlatform == null) { 311 if (parentPlatform == null) {
312 return ; 312 return ;
313 } 313 }
  314 + String statusStr = (status==1)?"ONLINE":"OFFLINE";
314 String characterSet = parentPlatform.getCharacterSet(); 315 String characterSet = parentPlatform.getCharacterSet();
315 StringBuffer deviceStatusXml = new StringBuffer(600); 316 StringBuffer deviceStatusXml = new StringBuffer(600);
316 deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n"); 317 deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
317 deviceStatusXml.append("<Response>\r\n"); 318 deviceStatusXml.append("<Response>\r\n");
318 deviceStatusXml.append("<CmdType>DeviceStatus</CmdType>\r\n"); 319 deviceStatusXml.append("<CmdType>DeviceStatus</CmdType>\r\n");
319 deviceStatusXml.append("<SN>" +sn + "</SN>\r\n"); 320 deviceStatusXml.append("<SN>" +sn + "</SN>\r\n");
320 - deviceStatusXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n"); 321 + deviceStatusXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
321 deviceStatusXml.append("<Result>OK</Result>\r\n"); 322 deviceStatusXml.append("<Result>OK</Result>\r\n");
322 - deviceStatusXml.append("<Online>ONLINE</Online>\r\n"); 323 + deviceStatusXml.append("<Online>"+statusStr+"</Online>\r\n");
323 deviceStatusXml.append("<Status>OK</Status>\r\n"); 324 deviceStatusXml.append("<Status>OK</Status>\r\n");
324 deviceStatusXml.append("</Response>\r\n"); 325 deviceStatusXml.append("</Response>\r\n");
325 326
@@ -327,7 +328,6 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -327,7 +328,6 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
327 328
328 Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader); 329 Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, deviceStatusXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
329 sipSender.transmitRequest(parentPlatform.getDeviceIp(), request); 330 sipSender.transmitRequest(parentPlatform.getDeviceIp(), request);
330 -  
331 } 331 }
332 332
333 @Override 333 @Override
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
2 2
3 import com.genersoft.iot.vmp.conf.SipConfig; 3 import com.genersoft.iot.vmp.conf.SipConfig;
  4 +import com.genersoft.iot.vmp.conf.UserSetting;
4 import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper; 5 import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper;
5 import com.genersoft.iot.vmp.gb28181.bean.Device; 6 import com.genersoft.iot.vmp.gb28181.bean.Device;
  7 +import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo;
6 import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate; 8 import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate;
7 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; 9 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
8 import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; 10 import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
9 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; 11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
10 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; 12 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
  13 +import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
11 import com.genersoft.iot.vmp.service.IDeviceService; 14 import com.genersoft.iot.vmp.service.IDeviceService;
12 import com.genersoft.iot.vmp.utils.DateUtil; 15 import com.genersoft.iot.vmp.utils.DateUtil;
13 import gov.nist.javax.sip.RequestEventExt; 16 import gov.nist.javax.sip.RequestEventExt;
@@ -59,6 +62,9 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen @@ -59,6 +62,9 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
59 @Autowired 62 @Autowired
60 private SIPSender sipSender; 63 private SIPSender sipSender;
61 64
  65 + @Autowired
  66 + private UserSetting userSetting;
  67 +
62 @Override 68 @Override
63 public void afterPropertiesSet() throws Exception { 69 public void afterPropertiesSet() throws Exception {
64 // 添加消息处理的订阅 70 // 添加消息处理的订阅
@@ -128,15 +134,9 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen @@ -128,15 +134,9 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
128 // 添加Expires头 134 // 添加Expires头
129 response.addHeader(request.getExpires()); 135 response.addHeader(request.getExpires());
130 136
131 - // 获取到通信地址等信息  
132 - ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);  
133 - String received = viaHeader.getReceived();  
134 - int rPort = viaHeader.getRPort();  
135 - // 解析本地地址替代  
136 - if (ObjectUtils.isEmpty(received) || rPort == -1) {  
137 - received = viaHeader.getHost();  
138 - rPort = viaHeader.getPort();  
139 - } 137 + RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request,
  138 + userSetting.getSipUseSourceIpAsRemoteAddress());
  139 +
140 if (device == null) { 140 if (device == null) {
141 device = new Device(); 141 device = new Device();
142 device.setStreamMode("UDP"); 142 device.setStreamMode("UDP");
@@ -146,9 +146,9 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen @@ -146,9 +146,9 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
146 device.setDeviceId(deviceId); 146 device.setDeviceId(deviceId);
147 device.setOnline(0); 147 device.setOnline(0);
148 } 148 }
149 - device.setIp(received);  
150 - device.setPort(rPort);  
151 - device.setHostAddress(received.concat(":").concat(String.valueOf(rPort))); 149 + device.setIp(remoteAddressInfo.getIp());
  150 + device.setPort(remoteAddressInfo.getPort());
  151 + device.setHostAddress(remoteAddressInfo.getIp().concat(":").concat(String.valueOf(remoteAddressInfo.getPort())));
152 device.setLocalIp(request.getLocalAddress().getHostAddress()); 152 device.setLocalIp(request.getLocalAddress().getHostAddress());
153 if (request.getExpires().getExpires() == 0) { 153 if (request.getExpires().getExpires() == 0) {
154 // 注销成功 154 // 注销成功
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/MessageRequestProcessor.java
@@ -67,6 +67,7 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement @@ -67,6 +67,7 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
67 @Override 67 @Override
68 public void process(RequestEvent evt) { 68 public void process(RequestEvent evt) {
69 SIPRequest sipRequest = (SIPRequest)evt.getRequest(); 69 SIPRequest sipRequest = (SIPRequest)evt.getRequest();
  70 + logger.info("接收到消息:" + evt.getRequest());
70 logger.debug("接收到消息:" + evt.getRequest()); 71 logger.debug("接收到消息:" + evt.getRequest());
71 String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); 72 String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
72 CallIdHeader callIdHeader = sipRequest.getCallIdHeader(); 73 CallIdHeader callIdHeader = sipRequest.getCallIdHeader();
@@ -94,7 +95,7 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement @@ -94,7 +95,7 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
94 if (device == null && parentPlatform == null) { 95 if (device == null && parentPlatform == null) {
95 // 不存在则回复404 96 // 不存在则回复404
96 responseAck(request, Response.NOT_FOUND, "device "+ deviceId +" not found"); 97 responseAck(request, Response.NOT_FOUND, "device "+ deviceId +" not found");
97 - logger.warn("[设备未找到 ]: {}", deviceId); 98 + logger.warn("[设备未找到 ]deviceId: {}, callId: {}", deviceId, callIdHeader.getCallId());
98 if (sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()) != null){ 99 if (sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()) != null){
99 DeviceNotFoundEvent deviceNotFoundEvent = new DeviceNotFoundEvent(evt.getDialog()); 100 DeviceNotFoundEvent deviceNotFoundEvent = new DeviceNotFoundEvent(evt.getDialog());
100 deviceNotFoundEvent.setCallId(callIdHeader.getCallId()); 101 deviceNotFoundEvent.setCallId(callIdHeader.getCallId());
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd;
2 2
  3 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
  4 +import com.genersoft.iot.vmp.conf.DynamicTask;
  5 +import com.genersoft.iot.vmp.conf.UserSetting;
3 import com.genersoft.iot.vmp.gb28181.bean.Device; 6 import com.genersoft.iot.vmp.gb28181.bean.Device;
4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 7 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
5 -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; 8 +import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo;
6 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; 9 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
7 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; 10 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
8 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; 11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;
  12 +import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
9 import com.genersoft.iot.vmp.service.IDeviceService; 13 import com.genersoft.iot.vmp.service.IDeviceService;
10 -import com.genersoft.iot.vmp.storager.IRedisCatchStorage;  
11 -import com.genersoft.iot.vmp.storager.IVideoManagerStorage;  
12 import com.genersoft.iot.vmp.utils.DateUtil; 14 import com.genersoft.iot.vmp.utils.DateUtil;
13 import gov.nist.javax.sip.message.SIPRequest; 15 import gov.nist.javax.sip.message.SIPRequest;
14 import org.dom4j.Element; 16 import org.dom4j.Element;
@@ -17,13 +19,10 @@ import org.slf4j.LoggerFactory; @@ -17,13 +19,10 @@ import org.slf4j.LoggerFactory;
17 import org.springframework.beans.factory.InitializingBean; 19 import org.springframework.beans.factory.InitializingBean;
18 import org.springframework.beans.factory.annotation.Autowired; 20 import org.springframework.beans.factory.annotation.Autowired;
19 import org.springframework.stereotype.Component; 21 import org.springframework.stereotype.Component;
20 -import org.springframework.util.ObjectUtils;  
21 -import org.springframework.util.StringUtils;  
22 22
23 import javax.sip.InvalidArgumentException; 23 import javax.sip.InvalidArgumentException;
24 import javax.sip.RequestEvent; 24 import javax.sip.RequestEvent;
25 import javax.sip.SipException; 25 import javax.sip.SipException;
26 -import javax.sip.header.ViaHeader;  
27 import javax.sip.message.Response; 26 import javax.sip.message.Response;
28 import java.text.ParseException; 27 import java.text.ParseException;
29 28
@@ -33,6 +32,7 @@ import java.text.ParseException; @@ -33,6 +32,7 @@ import java.text.ParseException;
33 @Component 32 @Component
34 public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { 33 public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
35 34
  35 +
36 private Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class); 36 private Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class);
37 private final static String cmdType = "Keepalive"; 37 private final static String cmdType = "Keepalive";
38 38
@@ -42,6 +42,12 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp @@ -42,6 +42,12 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
42 @Autowired 42 @Autowired
43 private IDeviceService deviceService; 43 private IDeviceService deviceService;
44 44
  45 + @Autowired
  46 + private UserSetting userSetting;
  47 +
  48 + @Autowired
  49 + private DynamicTask dynamicTask;
  50 +
45 @Override 51 @Override
46 public void afterPropertiesSet() throws Exception { 52 public void afterPropertiesSet() throws Exception {
47 notifyMessageHandler.addHandler(cmdType, this); 53 notifyMessageHandler.addHandler(cmdType, this);
@@ -53,26 +59,27 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp @@ -53,26 +59,27 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
53 // 未注册的设备不做处理 59 // 未注册的设备不做处理
54 return; 60 return;
55 } 61 }
  62 + SIPRequest request = (SIPRequest) evt.getRequest();
56 // 回复200 OK 63 // 回复200 OK
57 try { 64 try {
58 - responseAck((SIPRequest) evt.getRequest(), Response.OK); 65 + responseAck(request, Response.OK);
59 } catch (SipException | InvalidArgumentException | ParseException e) { 66 } catch (SipException | InvalidArgumentException | ParseException e) {
60 - logger.error("[命令发送失败] 国标级联 心跳回复: {}", e.getMessage()); 67 + logger.error("[命令发送失败] 心跳回复: {}", e.getMessage());
61 } 68 }
62 - // 判断RPort是否改变,改变则说明路由nat信息变化,修改设备信息  
63 - // 获取到通信地址等信息  
64 - ViaHeader viaHeader = (ViaHeader) evt.getRequest().getHeader(ViaHeader.NAME);  
65 - String received = viaHeader.getReceived();  
66 - int rPort = viaHeader.getRPort();  
67 - // 解析本地地址替代  
68 - if (ObjectUtils.isEmpty(received) || rPort == -1) {  
69 - received = viaHeader.getHost();  
70 - rPort = viaHeader.getPort(); 69 +
  70 + RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress());
  71 + if (!device.getIp().equalsIgnoreCase(remoteAddressInfo.getIp()) || device.getPort() != remoteAddressInfo.getPort()) {
  72 + device.setPort(remoteAddressInfo.getPort());
  73 + device.setHostAddress(remoteAddressInfo.getIp().concat(":").concat(String.valueOf(remoteAddressInfo.getPort())));
  74 + device.setIp(remoteAddressInfo.getIp());
71 } 75 }
72 - if (device.getPort() != rPort) {  
73 - device.setPort(rPort);  
74 - device.setHostAddress(received.concat(":").concat(String.valueOf(rPort))); 76 + if (device.getKeepaliveTime() == null) {
  77 + device.setKeepaliveIntervalTime(60);
  78 + }else {
  79 + long lastTime = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(device.getKeepaliveTime());
  80 + device.setKeepaliveIntervalTime(new Long(System.currentTimeMillis()/1000-lastTime).intValue());
75 } 81 }
  82 +
76 device.setKeepaliveTime(DateUtil.getNow()); 83 device.setKeepaliveTime(DateUtil.getNow());
77 84
78 if (device.getOnline() == 1) { 85 if (device.getOnline() == 1) {
@@ -80,9 +87,15 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp @@ -80,9 +87,15 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
80 }else { 87 }else {
81 // 对于已经离线的设备判断他的注册是否已经过期 88 // 对于已经离线的设备判断他的注册是否已经过期
82 if (!deviceService.expire(device)){ 89 if (!deviceService.expire(device)){
  90 + device.setOnline(0);
83 deviceService.online(device); 91 deviceService.online(device);
84 } 92 }
85 } 93 }
  94 + // 刷新过期任务
  95 + String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId();
  96 + // 如果三次心跳失败,则设置设备离线
  97 + dynamicTask.startDelay(registerExpireTaskKey, ()-> deviceService.offline(device.getDeviceId()), device.getKeepaliveIntervalTime()*1000*3);
  98 +
86 } 99 }
87 100
88 @Override 101 @Override
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/DeviceStatusQueryMessageHandler.java
@@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query. @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.
2 2
3 import com.genersoft.iot.vmp.conf.SipConfig; 3 import com.genersoft.iot.vmp.conf.SipConfig;
4 import com.genersoft.iot.vmp.gb28181.bean.Device; 4 import com.genersoft.iot.vmp.gb28181.bean.Device;
  5 +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
5 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 6 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
6 import com.genersoft.iot.vmp.gb28181.event.EventPublisher; 7 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
7 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; 8 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
@@ -24,6 +25,8 @@ import javax.sip.header.FromHeader; @@ -24,6 +25,8 @@ import javax.sip.header.FromHeader;
24 import javax.sip.message.Response; 25 import javax.sip.message.Response;
25 import java.text.ParseException; 26 import java.text.ParseException;
26 27
  28 +import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
  29 +
27 @Component 30 @Component
28 public class DeviceStatusQueryMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { 31 public class DeviceStatusQueryMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
29 32
@@ -62,13 +65,19 @@ public class DeviceStatusQueryMessageHandler extends SIPRequestProcessorParent i @@ -62,13 +65,19 @@ public class DeviceStatusQueryMessageHandler extends SIPRequestProcessorParent i
62 FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME); 65 FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
63 // 回复200 OK 66 // 回复200 OK
64 try { 67 try {
65 - responseAck((SIPRequest) evt.getRequest(), Response.OK); 68 + responseAck((SIPRequest) evt.getRequest(), Response.OK);
66 } catch (SipException | InvalidArgumentException | ParseException e) { 69 } catch (SipException | InvalidArgumentException | ParseException e) {
67 logger.error("[命令发送失败] 国标级联 DeviceStatus查询回复200OK: {}", e.getMessage()); 70 logger.error("[命令发送失败] 国标级联 DeviceStatus查询回复200OK: {}", e.getMessage());
68 } 71 }
69 String sn = rootElement.element("SN").getText(); 72 String sn = rootElement.element("SN").getText();
  73 + String channelId = getText(rootElement, "DeviceID");
  74 + DeviceChannel deviceChannel = storager.queryChannelInParentPlatform(parentPlatform.getServerGBId(), channelId);
  75 + if (deviceChannel ==null){
  76 + logger.error("[平台没有该通道的使用权限]:platformId"+parentPlatform.getServerGBId()+" deviceID:"+channelId);
  77 + return;
  78 + }
70 try { 79 try {
71 - cmderFroPlatform.deviceStatusResponse(parentPlatform, sn, fromHeader.getTag()); 80 + cmderFroPlatform.deviceStatusResponse(parentPlatform,channelId, sn, fromHeader.getTag(),deviceChannel.getStatus());
72 } catch (SipException | InvalidArgumentException | ParseException e) { 81 } catch (SipException | InvalidArgumentException | ParseException e) {
73 logger.error("[命令发送失败] 国标级联 DeviceStatus查询回复: {}", e.getMessage()); 82 logger.error("[命令发送失败] 国标级联 DeviceStatus查询回复: {}", e.getMessage());
74 } 83 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/BroadcastResponseMessageHandler.java
@@ -63,7 +63,12 @@ public class BroadcastResponseMessageHandler extends SIPRequestProcessorParent i @@ -63,7 +63,12 @@ public class BroadcastResponseMessageHandler extends SIPRequestProcessorParent i
63 return; 63 return;
64 } 64 }
65 String result = getText(rootElement, "Result"); 65 String result = getText(rootElement, "Result");
66 - logger.info("[语音广播]回复:{}, {}/{}", result, device.getDeviceId(), channelId ); 66 + Element infoElement = rootElement.element("Info");
  67 + String reason = null;
  68 + if (infoElement != null) {
  69 + reason = getText(infoElement, "Reason");
  70 + }
  71 + logger.info("[语音广播]回复:{}, {}/{}", reason == null? result : result + ": " + reason, device.getDeviceId(), channelId );
67 72
68 // 回复200 OK 73 // 回复200 OK
69 responseAck(request, Response.OK); 74 responseAck(request, Response.OK);
src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java
1 package com.genersoft.iot.vmp.gb28181.utils; 1 package com.genersoft.iot.vmp.gb28181.utils;
2 2
  3 +import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo;
3 import com.genersoft.iot.vmp.utils.GitUtil; 4 import com.genersoft.iot.vmp.utils.GitUtil;
4 import gov.nist.javax.sip.address.AddressImpl; 5 import gov.nist.javax.sip.address.AddressImpl;
5 import gov.nist.javax.sip.address.SipUri; 6 import gov.nist.javax.sip.address.SipUri;
6 import gov.nist.javax.sip.header.Subject; 7 import gov.nist.javax.sip.header.Subject;
  8 +import gov.nist.javax.sip.message.SIPRequest;
7 import org.springframework.util.ObjectUtils; 9 import org.springframework.util.ObjectUtils;
8 10
9 import javax.sip.PeerUnavailableException; 11 import javax.sip.PeerUnavailableException;
@@ -139,4 +141,31 @@ public class SipUtils { @@ -139,4 +141,31 @@ public class SipUtils {
139 int typeCodeFromGbCode = getTypeCodeFromGbCode(deviceId); 141 int typeCodeFromGbCode = getTypeCodeFromGbCode(deviceId);
140 return typeCodeFromGbCode > 130 && typeCodeFromGbCode < 199; 142 return typeCodeFromGbCode > 130 && typeCodeFromGbCode < 199;
141 } 143 }
  144 + /**
  145 + * 从请求中获取设备ip地址和端口号
  146 + * @param request 请求
  147 + * @param sipUseSourceIpAsRemoteAddress false 从via中获取地址, true 直接获取远程地址
  148 + * @return 地址信息
  149 + */
  150 + public static RemoteAddressInfo getRemoteAddressFromRequest(SIPRequest request, boolean sipUseSourceIpAsRemoteAddress) {
  151 +
  152 + String remoteAddress;
  153 + int remotePort;
  154 + if (sipUseSourceIpAsRemoteAddress) {
  155 + remoteAddress = request.getRemoteAddress().getHostAddress();
  156 + remotePort = request.getRemotePort();
  157 + }else {
  158 + // 判断RPort是否改变,改变则说明路由nat信息变化,修改设备信息
  159 + // 获取到通信地址等信息
  160 + remoteAddress = request.getTopmostViaHeader().getReceived();
  161 + remotePort = request.getTopmostViaHeader().getRPort();
  162 + // 解析本地地址替代
  163 + if (ObjectUtils.isEmpty(remoteAddress) || remotePort == -1) {
  164 + remoteAddress = request.getTopmostViaHeader().getHost();
  165 + remotePort = request.getTopmostViaHeader().getPort();
  166 + }
  167 + }
  168 +
  169 + return new RemoteAddressInfo(remoteAddress, remotePort);
  170 + }
142 } 171 }
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -19,6 +19,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.hook.*; @@ -19,6 +19,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.hook.*;
19 import com.genersoft.iot.vmp.service.*; 19 import com.genersoft.iot.vmp.service.*;
20 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 20 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
21 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 21 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
  22 +import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
22 import org.slf4j.Logger; 23 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory; 24 import org.slf4j.LoggerFactory;
24 import org.springframework.beans.factory.annotation.Autowired; 25 import org.springframework.beans.factory.annotation.Autowired;
@@ -347,7 +348,7 @@ public class ZLMHttpHookListener { @@ -347,7 +348,7 @@ public class ZLMHttpHookListener {
347 } 348 }
348 } 349 }
349 }else if ("broadcast".equals(param.getApp())){ 350 }else if ("broadcast".equals(param.getApp())){
350 - // 语音喊话推流 stream需要满足格式deviceId_channelId 351 + // 语音对讲推流 stream需要满足格式deviceId_channelId
351 if (param.isRegist() && param.getStream().indexOf("_") > 0) { 352 if (param.isRegist() && param.getStream().indexOf("_") > 0) {
352 String[] streamArray = param.getStream().split("_"); 353 String[] streamArray = param.getStream().split("_");
353 if (streamArray.length == 2) { 354 if (streamArray.length == 2) {
@@ -355,8 +356,7 @@ public class ZLMHttpHookListener { @@ -355,8 +356,7 @@ public class ZLMHttpHookListener {
355 String channelId = streamArray[1]; 356 String channelId = streamArray[1];
356 Device device = deviceService.getDevice(deviceId); 357 Device device = deviceService.getDevice(deviceId);
357 if (device != null) { 358 if (device != null) {
358 - DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);  
359 - if (deviceChannel != null) { 359 + if (param.isRegist()) {
360 if (audioBroadcastManager.exit(deviceId, channelId)) { 360 if (audioBroadcastManager.exit(deviceId, channelId)) {
361 // 直接推流 361 // 直接推流
362 SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, param.getStream(), null); 362 SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, param.getStream(), null);
@@ -381,18 +381,17 @@ public class ZLMHttpHookListener { @@ -381,18 +381,17 @@ public class ZLMHttpHookListener {
381 logger.error("[命令发送失败] 语音喊话: {}", e.getMessage()); 381 logger.error("[命令发送失败] 语音喊话: {}", e.getMessage());
382 } 382 }
383 } 383 }
384 -  
385 }else { 384 }else {
386 - logger.info("[语音对讲] 未找到通道:{}", channelId); 385 + // 流注销
  386 + playService.stopAudioBroadcast(deviceId, channelId);
387 } 387 }
388 - }else{ 388 + } else{
389 logger.info("[语音对讲] 未找到设备:{}", deviceId); 389 logger.info("[语音对讲] 未找到设备:{}", deviceId);
390 } 390 }
391 }else { 391 }else {
392 logger.info("[语音喊话] 推流格式有误, 格式为: broadcast/设备编号_通道编号 "); 392 logger.info("[语音喊话] 推流格式有误, 格式为: broadcast/设备编号_通道编号 ");
393 } 393 }
394 } 394 }
395 -  
396 }else if ("talk".equals(param.getApp())){ 395 }else if ("talk".equals(param.getApp())){
397 // 语音喊话推流 stream需要满足格式deviceId_channelId 396 // 语音喊话推流 stream需要满足格式deviceId_channelId
398 if (param.isRegist() && param.getStream().indexOf("_") > 0) { 397 if (param.isRegist() && param.getStream().indexOf("_") > 0) {
@@ -444,7 +443,7 @@ public class ZLMHttpHookListener { @@ -444,7 +443,7 @@ public class ZLMHttpHookListener {
444 } 443 }
445 StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaServerItem, 444 StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaServerItem,
446 param.getApp(), param.getStream(), param.getTracks(), callId); 445 param.getApp(), param.getStream(), param.getTracks(), callId);
447 - param.setStreamInfo(streamInfoByAppAndStream); 446 + param.setStreamInfo(new StreamContent(streamInfoByAppAndStream));
448 redisCatchStorage.addStream(mediaServerItem, type, param.getApp(), param.getStream(), param); 447 redisCatchStorage.addStream(mediaServerItem, type, param.getApp(), param.getStream(), param);
449 if (param.getOriginType() == OriginType.RTSP_PUSH.ordinal() 448 if (param.getOriginType() == OriginType.RTSP_PUSH.ordinal()
450 || param.getOriginType() == OriginType.RTMP_PUSH.ordinal() 449 || param.getOriginType() == OriginType.RTMP_PUSH.ordinal()
@@ -462,7 +461,7 @@ public class ZLMHttpHookListener { @@ -462,7 +461,7 @@ public class ZLMHttpHookListener {
462 } 461 }
463 GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream()); 462 GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream());
464 if (gbStream != null) { 463 if (gbStream != null) {
465 -// eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF); 464 +// eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF);
466 } 465 }
467 zlmMediaListManager.removeMedia(param.getApp(), param.getStream()); 466 zlmMediaListManager.removeMedia(param.getApp(), param.getStream());
468 } 467 }
@@ -531,7 +530,7 @@ public class ZLMHttpHookListener { @@ -531,7 +530,7 @@ public class ZLMHttpHookListener {
531 logger.info("[ZLM HOOK]流无人观看:{]->{}->{}/{}" + param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); 530 logger.info("[ZLM HOOK]流无人观看:{]->{}->{}/{}" + param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream());
532 JSONObject ret = new JSONObject(); 531 JSONObject ret = new JSONObject();
533 ret.put("code", 0); 532 ret.put("code", 0);
534 - // 录像下载 533 + // 国标类型的流
535 if ("rtp".equals(param.getApp())){ 534 if ("rtp".equals(param.getApp())){
536 ret.put("close", userSetting.getStreamOnDemand()); 535 ret.put("close", userSetting.getStreamOnDemand());
537 // 国标流, 点播/录像回放/录像下载 536 // 国标流, 点播/录像回放/录像下载
@@ -638,7 +637,7 @@ public class ZLMHttpHookListener { @@ -638,7 +637,7 @@ public class ZLMHttpHookListener {
638 @ResponseBody 637 @ResponseBody
639 @PostMapping(value = "/on_stream_not_found", produces = "application/json;charset=UTF-8") 638 @PostMapping(value = "/on_stream_not_found", produces = "application/json;charset=UTF-8")
640 public JSONObject onStreamNotFound(@RequestBody OnStreamNotFoundHookParam param){ 639 public JSONObject onStreamNotFound(@RequestBody OnStreamNotFoundHookParam param){
641 - logger.info("[ZLM HOOK] 流未找到:{}->{}->{}/{}" + param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); 640 + logger.info("[ZLM HOOK] 流未找到:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream());
642 taskExecutor.execute(()->{ 641 taskExecutor.execute(()->{
643 MediaServerItem mediaInfo = mediaServerService.getOne(param.getMediaServerId()); 642 MediaServerItem mediaInfo = mediaServerService.getOne(param.getMediaServerId());
644 if (userSetting.isAutoApplyPlay() && mediaInfo != null) { 643 if (userSetting.isAutoApplyPlay() && mediaInfo != null) {
@@ -706,7 +705,7 @@ public class ZLMHttpHookListener { @@ -706,7 +705,7 @@ public class ZLMHttpHookListener {
706 @PostMapping(value = "/on_send_rtp_stopped", produces = "application/json;charset=UTF-8") 705 @PostMapping(value = "/on_send_rtp_stopped", produces = "application/json;charset=UTF-8")
707 public JSONObject onSendRtpStopped(HttpServletRequest request, @RequestBody OnSendRtpStoppedHookParam param){ 706 public JSONObject onSendRtpStopped(HttpServletRequest request, @RequestBody OnSendRtpStoppedHookParam param){
708 707
709 - logger.info("[ZLM HOOK] 发送rtp被动关闭:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream()); 708 + logger.info("[ZLM HOOK] rtp发送关闭:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream());
710 709
711 JSONObject ret = new JSONObject(); 710 JSONObject ret = new JSONObject();
712 ret.put("code", 0); 711 ret.put("code", 0);
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamChangedHookParam.java
1 package com.genersoft.iot.vmp.media.zlm.dto.hook; 1 package com.genersoft.iot.vmp.media.zlm.dto.hook;
2 2
3 -import com.genersoft.iot.vmp.common.StreamInfo; 3 +import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
4 4
5 import java.util.List; 5 import java.util.List;
6 6
@@ -291,7 +291,7 @@ public class OnStreamChangedHookParam extends HookParam{ @@ -291,7 +291,7 @@ public class OnStreamChangedHookParam extends HookParam{
291 } 291 }
292 } 292 }
293 293
294 - private StreamInfo streamInfo; 294 + private StreamContent streamInfo;
295 295
296 public String getApp() { 296 public String getApp() {
297 return app; 297 return app;
@@ -407,11 +407,11 @@ public class OnStreamChangedHookParam extends HookParam{ @@ -407,11 +407,11 @@ public class OnStreamChangedHookParam extends HookParam{
407 this.docker = docker; 407 this.docker = docker;
408 } 408 }
409 409
410 - public StreamInfo getStreamInfo() { 410 + public StreamContent getStreamInfo() {
411 return streamInfo; 411 return streamInfo;
412 } 412 }
413 413
414 - public void setStreamInfo(StreamInfo streamInfo) { 414 + public void setStreamInfo(StreamContent streamInfo) {
415 this.streamInfo = streamInfo; 415 this.streamInfo = streamInfo;
416 } 416 }
417 417
src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
@@ -37,7 +37,7 @@ public interface IMediaServerService { @@ -37,7 +37,7 @@ public interface IMediaServerService {
37 */ 37 */
38 void zlmServerOffline(String mediaServerId); 38 void zlmServerOffline(String mediaServerId);
39 39
40 - MediaServerItem getMediaServerForMinimumLoad(); 40 + MediaServerItem getMediaServerForMinimumLoad(Boolean hasAssist);
41 41
42 void setZLMConfig(MediaServerItem mediaServerItem, boolean restart); 42 void setZLMConfig(MediaServerItem mediaServerItem, boolean restart);
43 43
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
@@ -40,15 +40,20 @@ public interface IPlayService { @@ -40,15 +40,20 @@ public interface IPlayService {
40 40
41 MediaServerItem getNewMediaServerItem(Device device); 41 MediaServerItem getNewMediaServerItem(Device device);
42 42
  43 + /**
  44 + * 获取包含assist服务的节点
  45 + */
  46 + MediaServerItem getNewMediaServerItemHasAssist(Device device);
  47 +
43 void onPublishHandlerForDownload(InviteStreamInfo inviteStreamInfo, String deviceId, String channelId, String toString); 48 void onPublishHandlerForDownload(InviteStreamInfo inviteStreamInfo, String deviceId, String channelId, String toString);
44 49
45 - DeferredResult<WVPResult<StreamInfo>> playBack(String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);  
46 - DeferredResult<WVPResult<StreamInfo>> playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack); 50 + void playBack(String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback playBackCallback);
  51 + void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
47 52
48 void zlmServerOffline(String mediaServerId); 53 void zlmServerOffline(String mediaServerId);
49 54
50 - DeferredResult<WVPResult<StreamInfo>> download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);  
51 - DeferredResult<WVPResult<StreamInfo>> download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack); 55 + void download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback playBackCallback);
  56 + void download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
52 57
53 StreamInfo getDownLoadInfo(String deviceId, String channelId, String stream); 58 StreamInfo getDownLoadInfo(String deviceId, String channelId, String stream);
54 59
src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackCallback.java
1 package com.genersoft.iot.vmp.service.bean; 1 package com.genersoft.iot.vmp.service.bean;
2 2
3 -import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;  
4 -import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 3 +public interface PlayBackCallback<T> {
5 4
6 -public interface PlayBackCallback {  
7 -  
8 - void call(PlayBackResult<RequestMessage> msg); 5 + void call(PlayBackResult<T> msg);
9 6
10 } 7 }
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceChannelServiceImpl.java
@@ -99,7 +99,7 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService { @@ -99,7 +99,7 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
99 HashMap<String, DeviceChannel> channelsInStore = new HashMap<>(); 99 HashMap<String, DeviceChannel> channelsInStore = new HashMap<>();
100 Device device = deviceMapper.getDeviceByDeviceId(deviceId); 100 Device device = deviceMapper.getDeviceByDeviceId(deviceId);
101 if (channels != null && channels.size() > 0) { 101 if (channels != null && channels.size() > 0) {
102 - List<DeviceChannel> channelList = channelMapper.queryChannels(deviceId, null, null, null, null); 102 + List<DeviceChannel> channelList = channelMapper.queryChannels(deviceId, null, null, null, null,null);
103 if (channelList.size() == 0) { 103 if (channelList.size() == 0) {
104 for (DeviceChannel channel : channels) { 104 for (DeviceChannel channel : channels) {
105 channel.setDeviceId(deviceId); 105 channel.setDeviceId(deviceId);
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
1 package com.genersoft.iot.vmp.service.impl; 1 package com.genersoft.iot.vmp.service.impl;
2 2
  3 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
3 import com.genersoft.iot.vmp.conf.DynamicTask; 4 import com.genersoft.iot.vmp.conf.DynamicTask;
4 import com.genersoft.iot.vmp.conf.UserSetting; 5 import com.genersoft.iot.vmp.conf.UserSetting;
5 import com.genersoft.iot.vmp.gb28181.bean.*; 6 import com.genersoft.iot.vmp.gb28181.bean.*;
@@ -46,8 +47,6 @@ public class DeviceServiceImpl implements IDeviceService { @@ -46,8 +47,6 @@ public class DeviceServiceImpl implements IDeviceService {
46 47
47 private final static Logger logger = LoggerFactory.getLogger(DeviceServiceImpl.class); 48 private final static Logger logger = LoggerFactory.getLogger(DeviceServiceImpl.class);
48 49
49 - private final String registerExpireTaskKeyPrefix = "device-register-expire-";  
50 -  
51 @Autowired 50 @Autowired
52 private DynamicTask dynamicTask; 51 private DynamicTask dynamicTask;
53 52
@@ -108,7 +107,10 @@ public class DeviceServiceImpl implements IDeviceService { @@ -108,7 +107,10 @@ public class DeviceServiceImpl implements IDeviceService {
108 redisCatchStorage.clearCatchByDeviceId(device.getDeviceId()); 107 redisCatchStorage.clearCatchByDeviceId(device.getDeviceId());
109 } 108 }
110 device.setUpdateTime(now); 109 device.setUpdateTime(now);
111 - 110 + if (device.getKeepaliveIntervalTime() == 0) {
  111 + // 默认心跳间隔60
  112 + device.setKeepaliveIntervalTime(60);
  113 + }
112 // 第一次上线 或则设备之前是离线状态--进行通道同步和设备信息查询 114 // 第一次上线 或则设备之前是离线状态--进行通道同步和设备信息查询
113 if (device.getCreateTime() == null) { 115 if (device.getCreateTime() == null) {
114 device.setOnline(1); 116 device.setOnline(1);
@@ -123,7 +125,6 @@ public class DeviceServiceImpl implements IDeviceService { @@ -123,7 +125,6 @@ public class DeviceServiceImpl implements IDeviceService {
123 } 125 }
124 sync(device); 126 sync(device);
125 }else { 127 }else {
126 -  
127 if(device.getOnline() == 0){ 128 if(device.getOnline() == 0){
128 device.setOnline(1); 129 device.setOnline(1);
129 device.setCreateTime(now); 130 device.setCreateTime(now);
@@ -160,18 +161,19 @@ public class DeviceServiceImpl implements IDeviceService { @@ -160,18 +161,19 @@ public class DeviceServiceImpl implements IDeviceService {
160 addMobilePositionSubscribe(device); 161 addMobilePositionSubscribe(device);
161 } 162 }
162 // 刷新过期任务 163 // 刷新过期任务
163 - String registerExpireTaskKey = registerExpireTaskKeyPrefix + device.getDeviceId();  
164 - dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId()), device.getExpires() * 1000); 164 + String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId();
  165 + // 如果第一次注册那么必须在60 * 3时间内收到一个心跳,否则设备离线
  166 + dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId()), device.getKeepaliveIntervalTime() * 1000 * 3);
165 } 167 }
166 168
167 @Override 169 @Override
168 public void offline(String deviceId) { 170 public void offline(String deviceId) {
169 - logger.info("[设备离线], device:{}", deviceId); 171 + logger.error("[设备离线], device:{}", deviceId);
170 Device device = deviceMapper.getDeviceByDeviceId(deviceId); 172 Device device = deviceMapper.getDeviceByDeviceId(deviceId);
171 if (device == null) { 173 if (device == null) {
172 return; 174 return;
173 } 175 }
174 - String registerExpireTaskKey = registerExpireTaskKeyPrefix + deviceId; 176 + String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + deviceId;
175 dynamicTask.stop(registerExpireTaskKey); 177 dynamicTask.stop(registerExpireTaskKey);
176 device.setOnline(0); 178 device.setOnline(0);
177 redisCatchStorage.updateDevice(device); 179 redisCatchStorage.updateDevice(device);
@@ -356,7 +358,6 @@ public class DeviceServiceImpl implements IDeviceService { @@ -356,7 +358,6 @@ public class DeviceServiceImpl implements IDeviceService {
356 device.setUpdateTime(DateUtil.getNow()); 358 device.setUpdateTime(DateUtil.getNow());
357 if (deviceMapper.update(device) > 0) { 359 if (deviceMapper.update(device) > 0) {
358 redisCatchStorage.updateDevice(device); 360 redisCatchStorage.updateDevice(device);
359 -  
360 } 361 }
361 } 362 }
362 363
@@ -432,7 +433,7 @@ public class DeviceServiceImpl implements IDeviceService { @@ -432,7 +433,7 @@ public class DeviceServiceImpl implements IDeviceService {
432 if (parentId.length() < 14 ) { 433 if (parentId.length() < 14 ) {
433 return null; 434 return null;
434 } 435 }
435 - List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null); 436 + List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null,null);
436 List<BaseTree<DeviceChannel>> trees = transportChannelsToTree(deviceChannels, parentId); 437 List<BaseTree<DeviceChannel>> trees = transportChannelsToTree(deviceChannels, parentId);
437 return trees; 438 return trees;
438 } 439 }
@@ -477,7 +478,7 @@ public class DeviceServiceImpl implements IDeviceService { @@ -477,7 +478,7 @@ public class DeviceServiceImpl implements IDeviceService {
477 if (parentId.length() < 14 ) { 478 if (parentId.length() < 14 ) {
478 return null; 479 return null;
479 } 480 }
480 - List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null); 481 + List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, parentId, null, null, null,null);
481 return deviceChannels; 482 return deviceChannels;
482 } 483 }
483 484
@@ -541,7 +542,7 @@ public class DeviceServiceImpl implements IDeviceService { @@ -541,7 +542,7 @@ public class DeviceServiceImpl implements IDeviceService {
541 } 542 }
542 }else { 543 }else {
543 if (haveChannel) { 544 if (haveChannel) {
544 - List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, null, null, null, null); 545 + List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, null, null, null, null,null);
545 if (deviceChannels != null && deviceChannels.size() > 0) { 546 if (deviceChannels != null && deviceChannels.size() > 0) {
546 result.addAll(deviceChannels); 547 result.addAll(deviceChannels);
547 } 548 }
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
@@ -501,7 +501,7 @@ public class MediaServerServiceImpl implements IMediaServerService { @@ -501,7 +501,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
501 * @return MediaServerItem 501 * @return MediaServerItem
502 */ 502 */
503 @Override 503 @Override
504 - public MediaServerItem getMediaServerForMinimumLoad() { 504 + public MediaServerItem getMediaServerForMinimumLoad(Boolean hasAssist) {
505 String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId(); 505 String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
506 506
507 if (RedisUtil.zSize(key) == null || RedisUtil.zSize(key) == 0) { 507 if (RedisUtil.zSize(key) == null || RedisUtil.zSize(key) == 0) {
@@ -514,9 +514,31 @@ public class MediaServerServiceImpl implements IMediaServerService { @@ -514,9 +514,31 @@ public class MediaServerServiceImpl implements IMediaServerService {
514 // 获取分数最低的,及并发最低的 514 // 获取分数最低的,及并发最低的
515 Set<Object> objects = RedisUtil.zRange(key, 0, -1); 515 Set<Object> objects = RedisUtil.zRange(key, 0, -1);
516 ArrayList<Object> mediaServerObjectS = new ArrayList<>(objects); 516 ArrayList<Object> mediaServerObjectS = new ArrayList<>(objects);
  517 + MediaServerItem mediaServerItem = null;
  518 + if (hasAssist == null) {
  519 + String mediaServerId = (String)mediaServerObjectS.get(0);
  520 + mediaServerItem = getOne(mediaServerId);
  521 + }else if (hasAssist) {
  522 + for (Object mediaServerObject : mediaServerObjectS) {
  523 + String mediaServerId = (String)mediaServerObject;
  524 + MediaServerItem serverItem = getOne(mediaServerId);
  525 + if (serverItem.getRecordAssistPort() > 0) {
  526 + mediaServerItem = serverItem;
  527 + break;
  528 + }
  529 + }
  530 + }else if (!hasAssist) {
  531 + for (Object mediaServerObject : mediaServerObjectS) {
  532 + String mediaServerId = (String)mediaServerObject;
  533 + MediaServerItem serverItem = getOne(mediaServerId);
  534 + if (serverItem.getRecordAssistPort() == 0) {
  535 + mediaServerItem = serverItem;
  536 + break;
  537 + }
  538 + }
  539 + }
517 540
518 - String mediaServerId = (String)mediaServerObjectS.get(0);  
519 - return getOne(mediaServerId); 541 + return mediaServerItem;
520 } 542 }
521 543
522 /** 544 /**
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
@@ -157,14 +157,7 @@ public class PlatformServiceImpl implements IPlatformService { @@ -157,14 +157,7 @@ public class PlatformServiceImpl implements IPlatformService {
157 dynamicTask.startCron(registerTaskKey, 157 dynamicTask.startCron(registerTaskKey,
158 // 注册失败(注册成功时由程序直接调用了online方法) 158 // 注册失败(注册成功时由程序直接调用了online方法)
159 ()-> { 159 ()-> {
160 - try {  
161 - logger.info("[国标级联] 平台:{}注册即将到期,重新注册", parentPlatform.getServerGBId());  
162 - commanderForPlatform.register(parentPlatform, eventResult -> {  
163 - offline(parentPlatform, false);  
164 - },null);  
165 - } catch (InvalidArgumentException | ParseException | SipException e) {  
166 - logger.error("[命令发送失败] 国标级联定时注册: {}", e.getMessage());  
167 - } 160 + registerTask(parentPlatform);
168 }, 161 },
169 (parentPlatform.getExpires() - 10) *1000); 162 (parentPlatform.getExpires() - 10) *1000);
170 } 163 }
@@ -216,6 +209,28 @@ public class PlatformServiceImpl implements IPlatformService { @@ -216,6 +209,28 @@ public class PlatformServiceImpl implements IPlatformService {
216 } 209 }
217 } 210 }
218 211
  212 + private void registerTask(ParentPlatform parentPlatform){
  213 + try {
  214 + // 设置超时重发, 后续从底层支持消息重发
  215 + String key = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId() + "_timeout";
  216 + if (dynamicTask.isAlive(key)) {
  217 + return;
  218 + }
  219 + dynamicTask.startDelay(key, ()->{
  220 + registerTask(parentPlatform);
  221 + }, 1000);
  222 + logger.info("[国标级联] 平台:{}注册即将到期,重新注册", parentPlatform.getServerGBId());
  223 + commanderForPlatform.register(parentPlatform, eventResult -> {
  224 + dynamicTask.stop(key);
  225 + offline(parentPlatform, false);
  226 + },eventResult -> {
  227 + dynamicTask.stop(key);
  228 + });
  229 + } catch (InvalidArgumentException | ParseException | SipException e) {
  230 + logger.error("[命令发送失败] 国标级联定时注册: {}", e.getMessage());
  231 + }
  232 + }
  233 +
219 @Override 234 @Override
220 public void offline(ParentPlatform parentPlatform, boolean stopRegister) { 235 public void offline(ParentPlatform parentPlatform, boolean stopRegister) {
221 logger.info("[平台离线]:{}", parentPlatform.getServerGBId()); 236 logger.info("[平台离线]:{}", parentPlatform.getServerGBId());
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -39,6 +39,7 @@ import com.genersoft.iot.vmp.utils.DateUtil; @@ -39,6 +39,7 @@ import com.genersoft.iot.vmp.utils.DateUtil;
39 import com.genersoft.iot.vmp.utils.redis.RedisUtil; 39 import com.genersoft.iot.vmp.utils.redis.RedisUtil;
40 import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult; 40 import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
41 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; 41 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  42 +import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
42 import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 43 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
43 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.AudioBroadcastEvent; 44 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.AudioBroadcastEvent;
44 import gov.nist.javax.sip.message.SIPResponse; 45 import gov.nist.javax.sip.message.SIPResponse;
@@ -49,7 +50,6 @@ import org.springframework.beans.factory.annotation.Qualifier; @@ -49,7 +50,6 @@ import org.springframework.beans.factory.annotation.Qualifier;
49 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 50 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
50 import org.springframework.stereotype.Service; 51 import org.springframework.stereotype.Service;
51 import org.springframework.util.ObjectUtils; 52 import org.springframework.util.ObjectUtils;
52 -import org.springframework.web.context.request.async.DeferredResult;  
53 53
54 import javax.sip.InvalidArgumentException; 54 import javax.sip.InvalidArgumentException;
55 import javax.sip.ResponseEvent; 55 import javax.sip.ResponseEvent;
@@ -454,6 +454,9 @@ public class PlayServiceImpl implements IPlayService { @@ -454,6 +454,9 @@ public class PlayServiceImpl implements IPlayService {
454 mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); 454 mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
455 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); 455 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
456 mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); 456 mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
  457 + // 取消订阅消息监听
  458 + HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId());
  459 + subscribe.removeSubscribe(hookSubscribe);
457 } 460 }
458 } 461 }
459 }, userSetting.getPlayTimeout()); 462 }, userSetting.getPlayTimeout());
@@ -463,7 +466,6 @@ public class PlayServiceImpl implements IPlayService { @@ -463,7 +466,6 @@ public class PlayServiceImpl implements IPlayService {
463 dynamicTask.stop(timeOutTaskKey); 466 dynamicTask.stop(timeOutTaskKey);
464 // 释放ssrc 467 // 释放ssrc
465 mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); 468 mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
466 -  
467 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); 469 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
468 470
469 RequestMessage msg = new RequestMessage(); 471 RequestMessage msg = new RequestMessage();
@@ -481,7 +483,7 @@ public class PlayServiceImpl implements IPlayService { @@ -481,7 +483,7 @@ public class PlayServiceImpl implements IPlayService {
481 onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId); 483 onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId);
482 hookEvent.response(mediaServerItemInuse, response); 484 hookEvent.response(mediaServerItemInuse, response);
483 logger.info("[点播成功] deviceId: {}, channelId: {}", device.getDeviceId(), channelId); 485 logger.info("[点播成功] deviceId: {}, channelId: {}", device.getDeviceId(), channelId);
484 - String streamUrl = String.format("rtsp://127.0.0.1:%s/%s/%s", mediaServerItemInuse.getRtspPort(), "rtp", ssrcInfo.getStream()); 486 + String streamUrl = String.format("http://127.0.0.1:%s/%s/%s.live.flv", mediaServerItemInuse.getHttpPort(), "rtp", ssrcInfo.getStream());
485 String path = "snap"; 487 String path = "snap";
486 String fileName = device.getDeviceId() + "_" + channelId + ".jpg"; 488 String fileName = device.getDeviceId() + "_" + channelId + ".jpg";
487 // 请求截图 489 // 请求截图
@@ -589,14 +591,10 @@ public class PlayServiceImpl implements IPlayService { @@ -589,14 +591,10 @@ public class PlayServiceImpl implements IPlayService {
589 } 591 }
590 } 592 }
591 593
592 - private void onPublishHandlerForPlayback(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String uuid) {  
593 - RequestMessage msg = new RequestMessage();  
594 - msg.setKey(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId);  
595 - if (!ObjectUtils.isEmpty(uuid)) {  
596 - msg.setId(uuid);  
597 - }  
598 - StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId); 594 + private void onPublishHandlerForPlayback(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, PlayBackCallback playBackCallback) {
599 595
  596 + StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId);
  597 + PlayBackResult<StreamInfo> playBackResult = new PlayBackResult<>();
600 if (streamInfo != null) { 598 if (streamInfo != null) {
601 DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); 599 DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
602 if (deviceChannel != null) { 600 if (deviceChannel != null) {
@@ -605,17 +603,16 @@ public class PlayServiceImpl implements IPlayService { @@ -605,17 +603,16 @@ public class PlayServiceImpl implements IPlayService {
605 } 603 }
606 redisCatchStorage.startPlay(streamInfo); 604 redisCatchStorage.startPlay(streamInfo);
607 605
608 - WVPResult wvpResult = new WVPResult();  
609 - wvpResult.setCode(ErrorCode.SUCCESS.getCode());  
610 - wvpResult.setMsg(ErrorCode.SUCCESS.getMsg());  
611 - wvpResult.setData(streamInfo);  
612 - msg.setData(wvpResult);  
613 606
614 - resultHolder.invokeAllResult(msg); 607 + playBackResult.setCode(ErrorCode.SUCCESS.getCode());
  608 + playBackResult.setMsg(ErrorCode.SUCCESS.getMsg());
  609 + playBackResult.setData(streamInfo);
  610 + playBackCallback.call(playBackResult);
615 } else { 611 } else {
616 logger.warn("录像回放调用失败!"); 612 logger.warn("录像回放调用失败!");
617 - msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), "录像回放调用失败!"));  
618 - resultHolder.invokeAllResult(msg); 613 + playBackResult.setCode(ErrorCode.ERROR100.getCode());
  614 + playBackResult.setMsg("录像回放调用失败!");
  615 + playBackCallback.call(playBackResult);
619 } 616 }
620 } 617 }
621 618
@@ -626,7 +623,7 @@ public class PlayServiceImpl implements IPlayService { @@ -626,7 +623,7 @@ public class PlayServiceImpl implements IPlayService {
626 } 623 }
627 MediaServerItem mediaServerItem; 624 MediaServerItem mediaServerItem;
628 if (ObjectUtils.isEmpty(device.getMediaServerId()) || "auto".equals(device.getMediaServerId())) { 625 if (ObjectUtils.isEmpty(device.getMediaServerId()) || "auto".equals(device.getMediaServerId())) {
629 - mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(); 626 + mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(null);
630 } else { 627 } else {
631 mediaServerItem = mediaServerService.getOne(device.getMediaServerId()); 628 mediaServerItem = mediaServerService.getOne(device.getMediaServerId());
632 } 629 }
@@ -637,45 +634,56 @@ public class PlayServiceImpl implements IPlayService { @@ -637,45 +634,56 @@ public class PlayServiceImpl implements IPlayService {
637 } 634 }
638 635
639 @Override 636 @Override
640 - public DeferredResult<WVPResult<StreamInfo>> playBack(String deviceId, String channelId, String startTime, 637 + public MediaServerItem getNewMediaServerItemHasAssist(Device device) {
  638 + if (device == null) {
  639 + return null;
  640 + }
  641 + MediaServerItem mediaServerItem;
  642 + if (ObjectUtils.isEmpty(device.getMediaServerId()) || "auto".equals(device.getMediaServerId())) {
  643 + mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(true);
  644 + } else {
  645 + mediaServerItem = mediaServerService.getOne(device.getMediaServerId());
  646 + }
  647 + if (mediaServerItem == null) {
  648 + logger.warn("[获取可用的ZLM节点]未找到可使用的ZLM...");
  649 + }
  650 + return mediaServerItem;
  651 + }
  652 +
  653 + @Override
  654 + public void playBack(String deviceId, String channelId, String startTime,
641 String endTime, InviteStreamCallback inviteStreamCallback, 655 String endTime, InviteStreamCallback inviteStreamCallback,
642 PlayBackCallback callback) { 656 PlayBackCallback callback) {
643 Device device = storager.queryVideoDevice(deviceId); 657 Device device = storager.queryVideoDevice(deviceId);
644 if (device == null) { 658 if (device == null) {
645 - return null; 659 + return;
646 } 660 }
647 MediaServerItem newMediaServerItem = getNewMediaServerItem(device); 661 MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
648 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, device.isSsrcCheck(), true); 662 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, device.isSsrcCheck(), true);
649 663
650 - return playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, inviteStreamCallback, callback); 664 + playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, inviteStreamCallback, callback);
651 } 665 }
652 666
653 @Override 667 @Override
654 - public DeferredResult<WVPResult<StreamInfo>> playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, 668 + public void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,
655 String deviceId, String channelId, String startTime, 669 String deviceId, String channelId, String startTime,
656 String endTime, InviteStreamCallback infoCallBack, 670 String endTime, InviteStreamCallback infoCallBack,
657 PlayBackCallback playBackCallback) { 671 PlayBackCallback playBackCallback) {
658 if (mediaServerItem == null || ssrcInfo == null) { 672 if (mediaServerItem == null || ssrcInfo == null) {
659 - return null; 673 + return;
660 } 674 }
661 - String uuid = UUID.randomUUID().toString();  
662 - String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId; 675 +
663 Device device = storager.queryVideoDevice(deviceId); 676 Device device = storager.queryVideoDevice(deviceId);
664 if (device == null) { 677 if (device == null) {
665 throw new ControllerException(ErrorCode.ERROR100.getCode(), "设备: " + deviceId + "不存在"); 678 throw new ControllerException(ErrorCode.ERROR100.getCode(), "设备: " + deviceId + "不存在");
666 } 679 }
667 - DeferredResult<WVPResult<StreamInfo>> result = new DeferredResult<>(30000L);  
668 - resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId, uuid, result);  
669 - RequestMessage requestMessage = new RequestMessage();  
670 - requestMessage.setId(uuid);  
671 - requestMessage.setKey(key);  
672 - PlayBackResult<RequestMessage> playBackResult = new PlayBackResult<>(); 680 +
  681 + PlayBackResult<StreamInfo> playBackResult = new PlayBackResult<>();
673 String playBackTimeOutTaskKey = UUID.randomUUID().toString(); 682 String playBackTimeOutTaskKey = UUID.randomUUID().toString();
674 dynamicTask.startDelay(playBackTimeOutTaskKey, () -> { 683 dynamicTask.startDelay(playBackTimeOutTaskKey, () -> {
675 logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId)); 684 logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId));
676 playBackResult.setCode(ErrorCode.ERROR100.getCode()); 685 playBackResult.setCode(ErrorCode.ERROR100.getCode());
677 playBackResult.setMsg("回放超时"); 686 playBackResult.setMsg("回放超时");
678 - playBackResult.setData(requestMessage);  
679 687
680 try { 688 try {
681 cmder.streamByeCmd(device, channelId, ssrcInfo.getStream(), null); 689 cmder.streamByeCmd(device, channelId, ssrcInfo.getStream(), null);
@@ -687,19 +695,14 @@ public class PlayServiceImpl implements IPlayService { @@ -687,19 +695,14 @@ public class PlayServiceImpl implements IPlayService {
687 mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); 695 mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
688 streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); 696 streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
689 } 697 }
690 -  
691 // 回复之前所有的点播请求 698 // 回复之前所有的点播请求
692 playBackCallback.call(playBackResult); 699 playBackCallback.call(playBackResult);
693 - result.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "回放超时"));  
694 - resultHolder.exist(DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId, uuid);  
695 }, userSetting.getPlayTimeout()); 700 }, userSetting.getPlayTimeout());
696 701
697 SipSubscribe.Event errorEvent = event -> { 702 SipSubscribe.Event errorEvent = event -> {
698 dynamicTask.stop(playBackTimeOutTaskKey); 703 dynamicTask.stop(playBackTimeOutTaskKey);
699 - requestMessage.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg)));  
700 playBackResult.setCode(ErrorCode.ERROR100.getCode()); 704 playBackResult.setCode(ErrorCode.ERROR100.getCode());
701 playBackResult.setMsg(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg)); 705 playBackResult.setMsg(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg));
702 - playBackResult.setData(requestMessage);  
703 playBackResult.setEvent(event); 706 playBackResult.setEvent(event);
704 playBackCallback.call(playBackResult); 707 playBackCallback.call(playBackResult);
705 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); 708 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
@@ -717,11 +720,9 @@ public class PlayServiceImpl implements IPlayService { @@ -717,11 +720,9 @@ public class PlayServiceImpl implements IPlayService {
717 return; 720 return;
718 } 721 }
719 redisCatchStorage.startPlayback(streamInfo, inviteStreamInfo.getCallId()); 722 redisCatchStorage.startPlayback(streamInfo, inviteStreamInfo.getCallId());
720 - WVPResult<StreamInfo> success = WVPResult.success(streamInfo);  
721 - requestMessage.setData(success);  
722 playBackResult.setCode(ErrorCode.SUCCESS.getCode()); 723 playBackResult.setCode(ErrorCode.SUCCESS.getCode());
723 playBackResult.setMsg(ErrorCode.SUCCESS.getMsg()); 724 playBackResult.setMsg(ErrorCode.SUCCESS.getMsg());
724 - playBackResult.setData(requestMessage); 725 + playBackResult.setData(streamInfo);
725 playBackResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem()); 726 playBackResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem());
726 playBackResult.setResponse(inviteStreamInfo.getResponse()); 727 playBackResult.setResponse(inviteStreamInfo.getResponse());
727 playBackCallback.call(playBackResult); 728 playBackCallback.call(playBackResult);
@@ -768,7 +769,7 @@ public class PlayServiceImpl implements IPlayService { @@ -768,7 +769,7 @@ public class PlayServiceImpl implements IPlayService {
768 logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + response.toJSONString()); 769 logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + response.toJSONString());
769 dynamicTask.stop(playBackTimeOutTaskKey); 770 dynamicTask.stop(playBackTimeOutTaskKey);
770 // hook响应 771 // hook响应
771 - onPublishHandlerForPlayback(mediaServerItemInUse, response, device.getDeviceId(), channelId, uuid); 772 + onPublishHandlerForPlayback(mediaServerItemInUse, response, device.getDeviceId(), channelId, playBackCallback);
772 hookEvent.call(new InviteStreamInfo(mediaServerItem, null, eventResult.callId, "rtp", ssrcInfo.getStream())); 773 hookEvent.call(new InviteStreamInfo(mediaServerItem, null, eventResult.callId, "rtp", ssrcInfo.getStream()));
773 }); 774 });
774 } 775 }
@@ -788,50 +789,45 @@ public class PlayServiceImpl implements IPlayService { @@ -788,50 +789,45 @@ public class PlayServiceImpl implements IPlayService {
788 eventResult.msg = "命令发送失败"; 789 eventResult.msg = "命令发送失败";
789 errorEvent.response(eventResult); 790 errorEvent.response(eventResult);
790 } 791 }
791 - return result;  
792 } 792 }
793 793
794 794
795 795
796 @Override 796 @Override
797 - public DeferredResult<WVPResult<StreamInfo>> download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack) { 797 + public void download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback playBackCallback) {
798 Device device = storager.queryVideoDevice(deviceId); 798 Device device = storager.queryVideoDevice(deviceId);
799 if (device == null) { 799 if (device == null) {
800 - return null; 800 + return;
  801 + }
  802 + MediaServerItem newMediaServerItem = getNewMediaServerItemHasAssist(device);
  803 + if (newMediaServerItem == null) {
  804 + PlayBackResult<StreamInfo> downloadResult = new PlayBackResult<>();
  805 + downloadResult.setCode(ErrorCode.ERROR100.getCode());
  806 + downloadResult.setMsg("未找到assist服务");
  807 + playBackCallback.call(downloadResult);
  808 + return;
801 } 809 }
802 - MediaServerItem newMediaServerItem = getNewMediaServerItem(device);  
803 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, device.isSsrcCheck(), true); 810 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, device.isSsrcCheck(), true);
804 811
805 - return download(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, downloadSpeed, infoCallBack, hookCallBack); 812 + download(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, downloadSpeed, infoCallBack, playBackCallback);
806 } 813 }
807 814
  815 +
808 @Override 816 @Override
809 - public DeferredResult<WVPResult<StreamInfo>> download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack) { 817 + public void download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack) {
810 if (mediaServerItem == null || ssrcInfo == null) { 818 if (mediaServerItem == null || ssrcInfo == null) {
811 - return null; 819 + return;
812 } 820 }
813 - String uuid = UUID.randomUUID().toString();  
814 - String key = DeferredResultHolder.CALLBACK_CMD_DOWNLOAD + deviceId + channelId;  
815 - DeferredResult<WVPResult<StreamInfo>> result = new DeferredResult<>(30000L); 821 +
816 Device device = storager.queryVideoDevice(deviceId); 822 Device device = storager.queryVideoDevice(deviceId);
817 if (device == null) { 823 if (device == null) {
818 throw new ControllerException(ErrorCode.ERROR400.getCode(), "设备:" + deviceId + "不存在"); 824 throw new ControllerException(ErrorCode.ERROR400.getCode(), "设备:" + deviceId + "不存在");
819 } 825 }
820 -  
821 - resultHolder.put(key, uuid, result);  
822 - RequestMessage requestMessage = new RequestMessage();  
823 - requestMessage.setId(uuid);  
824 - requestMessage.setKey(key);  
825 - WVPResult<StreamInfo> wvpResult = new WVPResult<>();  
826 - requestMessage.setData(wvpResult);  
827 - PlayBackResult<RequestMessage> downloadResult = new PlayBackResult<>();  
828 - downloadResult.setData(requestMessage); 826 + PlayBackResult<StreamInfo> downloadResult = new PlayBackResult<>();
829 827
830 String downLoadTimeOutTaskKey = UUID.randomUUID().toString(); 828 String downLoadTimeOutTaskKey = UUID.randomUUID().toString();
831 dynamicTask.startDelay(downLoadTimeOutTaskKey, () -> { 829 dynamicTask.startDelay(downLoadTimeOutTaskKey, () -> {
832 logger.warn(String.format("录像下载请求超时,deviceId:%s ,channelId:%s", deviceId, channelId)); 830 logger.warn(String.format("录像下载请求超时,deviceId:%s ,channelId:%s", deviceId, channelId));
833 - wvpResult.setCode(ErrorCode.ERROR100.getCode());  
834 - wvpResult.setMsg("录像下载请求超时");  
835 downloadResult.setCode(ErrorCode.ERROR100.getCode()); 831 downloadResult.setCode(ErrorCode.ERROR100.getCode());
836 downloadResult.setMsg("录像下载请求超时"); 832 downloadResult.setMsg("录像下载请求超时");
837 hookCallBack.call(downloadResult); 833 hookCallBack.call(downloadResult);
@@ -846,16 +842,12 @@ public class PlayServiceImpl implements IPlayService { @@ -846,16 +842,12 @@ public class PlayServiceImpl implements IPlayService {
846 mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); 842 mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
847 streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); 843 streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
848 } 844 }
849 - // 回复之前所有的点播请求  
850 - hookCallBack.call(downloadResult);  
851 }, userSetting.getPlayTimeout()); 845 }, userSetting.getPlayTimeout());
852 846
853 SipSubscribe.Event errorEvent = event -> { 847 SipSubscribe.Event errorEvent = event -> {
854 dynamicTask.stop(downLoadTimeOutTaskKey); 848 dynamicTask.stop(downLoadTimeOutTaskKey);
855 downloadResult.setCode(ErrorCode.ERROR100.getCode()); 849 downloadResult.setCode(ErrorCode.ERROR100.getCode());
856 downloadResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg)); 850 downloadResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg));
857 - wvpResult.setCode(ErrorCode.ERROR100.getCode());  
858 - wvpResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg));  
859 downloadResult.setEvent(event); 851 downloadResult.setEvent(event);
860 hookCallBack.call(downloadResult); 852 hookCallBack.call(downloadResult);
861 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); 853 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
@@ -870,11 +862,9 @@ public class PlayServiceImpl implements IPlayService { @@ -870,11 +862,9 @@ public class PlayServiceImpl implements IPlayService {
870 streamInfo.setStartTime(startTime); 862 streamInfo.setStartTime(startTime);
871 streamInfo.setEndTime(endTime); 863 streamInfo.setEndTime(endTime);
872 redisCatchStorage.startDownload(streamInfo, inviteStreamInfo.getCallId()); 864 redisCatchStorage.startDownload(streamInfo, inviteStreamInfo.getCallId());
873 - wvpResult.setCode(ErrorCode.SUCCESS.getCode());  
874 - wvpResult.setMsg(ErrorCode.SUCCESS.getMsg());  
875 - wvpResult.setData(streamInfo);  
876 downloadResult.setCode(ErrorCode.SUCCESS.getCode()); 865 downloadResult.setCode(ErrorCode.SUCCESS.getCode());
877 downloadResult.setMsg(ErrorCode.SUCCESS.getMsg()); 866 downloadResult.setMsg(ErrorCode.SUCCESS.getMsg());
  867 + downloadResult.setData(streamInfo);
878 downloadResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem()); 868 downloadResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem());
879 downloadResult.setResponse(inviteStreamInfo.getResponse()); 869 downloadResult.setResponse(inviteStreamInfo.getResponse());
880 hookCallBack.call(downloadResult); 870 hookCallBack.call(downloadResult);
@@ -886,7 +876,6 @@ public class PlayServiceImpl implements IPlayService { @@ -886,7 +876,6 @@ public class PlayServiceImpl implements IPlayService {
886 eventResult.msg = "命令发送失败"; 876 eventResult.msg = "命令发送失败";
887 errorEvent.response(eventResult); 877 errorEvent.response(eventResult);
888 } 878 }
889 - return result;  
890 } 879 }
891 880
892 @Override 881 @Override
@@ -906,7 +895,10 @@ public class PlayServiceImpl implements IPlayService { @@ -906,7 +895,10 @@ public class PlayServiceImpl implements IPlayService {
906 } 895 }
907 if (mediaServerItem.getRecordAssistPort() > 0) { 896 if (mediaServerItem.getRecordAssistPort() > 0) {
908 JSONObject jsonObject = assistRESTfulUtils.fileDuration(mediaServerItem, streamInfo.getApp(), streamInfo.getStream(), null); 897 JSONObject jsonObject = assistRESTfulUtils.fileDuration(mediaServerItem, streamInfo.getApp(), streamInfo.getStream(), null);
909 - if (jsonObject != null && jsonObject.getInteger("code") == 0) { 898 + if (jsonObject == null) {
  899 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "连接Assist服务失败");
  900 + }
  901 + if (jsonObject.getInteger("code") == 0) {
910 long duration = jsonObject.getLong("data"); 902 long duration = jsonObject.getLong("data");
911 903
912 if (duration == 0) { 904 if (duration == 0) {
@@ -1004,7 +996,7 @@ public class PlayServiceImpl implements IPlayService { @@ -1004,7 +996,7 @@ public class PlayServiceImpl implements IPlayService {
1004 logger.warn("开启语音广播的时候未找到通道: {}", channelId); 996 logger.warn("开启语音广播的时候未找到通道: {}", channelId);
1005 return null; 997 return null;
1006 } 998 }
1007 - MediaServerItem mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(); 999 + MediaServerItem mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(null);
1008 String app = "broadcast"; 1000 String app = "broadcast";
1009 // TODO 从sip user agent中判断是什么品牌设备,大华默认使用talk模式,其他使用broadcast模式 1001 // TODO 从sip user agent中判断是什么品牌设备,大华默认使用talk模式,其他使用broadcast模式
1010 // String app = "talk"; 1002 // String app = "talk";
@@ -1013,7 +1005,7 @@ public class PlayServiceImpl implements IPlayService { @@ -1013,7 +1005,7 @@ public class PlayServiceImpl implements IPlayService {
1013 AudioBroadcastResult audioBroadcastResult = new AudioBroadcastResult(); 1005 AudioBroadcastResult audioBroadcastResult = new AudioBroadcastResult();
1014 audioBroadcastResult.setApp(app); 1006 audioBroadcastResult.setApp(app);
1015 audioBroadcastResult.setStream(stream); 1007 audioBroadcastResult.setStream(stream);
1016 - audioBroadcastResult.setStreamInfo(mediaService.getStreamInfoByAppAndStream(mediaServerItem, app, stream, null, null, null,false)); 1008 + audioBroadcastResult.setStreamInfo(new StreamContent(mediaService.getStreamInfoByAppAndStream(mediaServerItem, app, stream, null, null, null,false)));
1017 audioBroadcastResult.setCodec("G.711"); 1009 audioBroadcastResult.setCodec("G.711");
1018 return audioBroadcastResult; 1010 return audioBroadcastResult;
1019 } 1011 }
@@ -1103,6 +1095,12 @@ public class PlayServiceImpl implements IPlayService { @@ -1103,6 +1095,12 @@ public class PlayServiceImpl implements IPlayService {
1103 param.put("app", sendRtpItem.getApp()); 1095 param.put("app", sendRtpItem.getApp());
1104 param.put("stream", sendRtpItem.getStreamId()); 1096 param.put("stream", sendRtpItem.getStreamId());
1105 zlmresTfulUtils.stopSendRtp(mediaInfo, param); 1097 zlmresTfulUtils.stopSendRtp(mediaInfo, param);
  1098 + try {
  1099 + cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null);
  1100 + } catch (InvalidArgumentException | ParseException | SipException |
  1101 + SsrcTransactionNotFoundException e) {
  1102 + logger.error("[消息发送失败] 发送语音喊话BYE失败");
  1103 + }
1106 } 1104 }
1107 1105
1108 audioBroadcastManager.del(deviceId, channelId); 1106 audioBroadcastManager.del(deviceId, channelId);
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
@@ -90,7 +90,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -90,7 +90,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
90 public StreamInfo save(StreamProxyItem param) { 90 public StreamInfo save(StreamProxyItem param) {
91 MediaServerItem mediaInfo; 91 MediaServerItem mediaInfo;
92 if (ObjectUtils.isEmpty(param.getMediaServerId()) || "auto".equals(param.getMediaServerId())){ 92 if (ObjectUtils.isEmpty(param.getMediaServerId()) || "auto".equals(param.getMediaServerId())){
93 - mediaInfo = mediaServerService.getMediaServerForMinimumLoad(); 93 + mediaInfo = mediaServerService.getMediaServerForMinimumLoad(null);
94 }else { 94 }else {
95 mediaInfo = mediaServerService.getOne(param.getMediaServerId()); 95 mediaInfo = mediaServerService.getOne(param.getMediaServerId());
96 } 96 }
src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java
@@ -117,7 +117,7 @@ public class RedisGbPlayMsgListener implements MessageListener { @@ -117,7 +117,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
117 Message msg = taskQueue.poll(); 117 Message msg = taskQueue.poll();
118 try { 118 try {
119 JSONObject msgJSON = JSON.parseObject(msg.getBody(), JSONObject.class); 119 JSONObject msgJSON = JSON.parseObject(msg.getBody(), JSONObject.class);
120 - WvpRedisMsg wvpRedisMsg = JSON.toJavaObject(msgJSON, WvpRedisMsg.class); 120 + WvpRedisMsg wvpRedisMsg = JSON.to(WvpRedisMsg.class, msgJSON);
121 if (!userSetting.getServerId().equals(wvpRedisMsg.getToId())) { 121 if (!userSetting.getServerId().equals(wvpRedisMsg.getToId())) {
122 continue; 122 continue;
123 } 123 }
@@ -126,11 +126,11 @@ public class RedisGbPlayMsgListener implements MessageListener { @@ -126,11 +126,11 @@ public class RedisGbPlayMsgListener implements MessageListener {
126 126
127 switch (wvpRedisMsg.getCmd()){ 127 switch (wvpRedisMsg.getCmd()){
128 case WvpRedisMsgCmd.GET_SEND_ITEM: 128 case WvpRedisMsgCmd.GET_SEND_ITEM:
129 - RequestSendItemMsg content = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestSendItemMsg.class); 129 + RequestSendItemMsg content = JSON.to(RequestSendItemMsg.class, wvpRedisMsg.getContent());
130 requestSendItemMsgHand(content, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial()); 130 requestSendItemMsgHand(content, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial());
131 break; 131 break;
132 case WvpRedisMsgCmd.REQUEST_PUSH_STREAM: 132 case WvpRedisMsgCmd.REQUEST_PUSH_STREAM:
133 - RequestPushStreamMsg param = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestPushStreamMsg.class);; 133 + RequestPushStreamMsg param = JSON.to(RequestPushStreamMsg.class, wvpRedisMsg.getContent());
134 requestPushStreamMsgHand(param, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial()); 134 requestPushStreamMsgHand(param, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial());
135 break; 135 break;
136 default: 136 default:
@@ -142,12 +142,12 @@ public class RedisGbPlayMsgListener implements MessageListener { @@ -142,12 +142,12 @@ public class RedisGbPlayMsgListener implements MessageListener {
142 switch (wvpRedisMsg.getCmd()){ 142 switch (wvpRedisMsg.getCmd()){
143 case WvpRedisMsgCmd.GET_SEND_ITEM: 143 case WvpRedisMsgCmd.GET_SEND_ITEM:
144 144
145 - WVPResult content = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class); 145 + WVPResult content = JSON.to(WVPResult.class, wvpRedisMsg.getContent());
146 146
147 String key = wvpRedisMsg.getSerial(); 147 String key = wvpRedisMsg.getSerial();
148 switch (content.getCode()) { 148 switch (content.getCode()) {
149 case 0: 149 case 0:
150 - ResponseSendItemMsg responseSendItemMsg =JSON.toJavaObject((JSONObject)content.getData(), ResponseSendItemMsg.class); 150 + ResponseSendItemMsg responseSendItemMsg =JSON.to(ResponseSendItemMsg.class, content.getData());
151 PlayMsgCallback playMsgCallback = callbacks.get(key); 151 PlayMsgCallback playMsgCallback = callbacks.get(key);
152 if (playMsgCallback != null) { 152 if (playMsgCallback != null) {
153 callbacksForError.remove(key); 153 callbacksForError.remove(key);
@@ -172,7 +172,7 @@ public class RedisGbPlayMsgListener implements MessageListener { @@ -172,7 +172,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
172 } 172 }
173 break; 173 break;
174 case WvpRedisMsgCmd.REQUEST_PUSH_STREAM: 174 case WvpRedisMsgCmd.REQUEST_PUSH_STREAM:
175 - WVPResult wvpResult = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class); 175 + WVPResult wvpResult = JSON.to(WVPResult.class, wvpRedisMsg.getContent());
176 String serial = wvpRedisMsg.getSerial(); 176 String serial = wvpRedisMsg.getSerial();
177 switch (wvpResult.getCode()) { 177 switch (wvpResult.getCode()) {
178 case 0: 178 case 0:
@@ -199,6 +199,7 @@ public class RedisGbPlayMsgListener implements MessageListener { @@ -199,6 +199,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
199 default: 199 default:
200 break; 200 break;
201 } 201 }
  202 +
202 } 203 }
203 }catch (Exception e) { 204 }catch (Exception e) {
204 logger.warn("[RedisGbPlayMsg] 发现未处理的异常, {}",e.getMessage()); 205 logger.warn("[RedisGbPlayMsg] 发现未处理的异常, {}",e.getMessage());
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorage.java
@@ -59,7 +59,7 @@ public interface IVideoManagerStorage { @@ -59,7 +59,7 @@ public interface IVideoManagerStorage {
59 */ 59 */
60 public PageInfo queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, Boolean online, Boolean catalogUnderDevice, int page, int count); 60 public PageInfo queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, Boolean online, Boolean catalogUnderDevice, int page, int count);
61 61
62 - public List<DeviceChannel> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, String query, Boolean hasSubChannel, Boolean online, int start, int limit); 62 + public List<DeviceChannel> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, String query, Boolean hasSubChannel, Boolean online, int start, int limit,List<String> channelIds);
63 63
64 64
65 /** 65 /**
@@ -68,7 +68,7 @@ public interface IVideoManagerStorage { @@ -68,7 +68,7 @@ public interface IVideoManagerStorage {
68 * @param deviceId 设备ID 68 * @param deviceId 设备ID
69 * @return 69 * @return
70 */ 70 */
71 - public List<DeviceChannel> queryChannelsByDeviceId(String deviceId); 71 + public List<DeviceChannel> queryChannelsByDeviceId(String deviceId,Boolean online,List<String> channelIds);
72 public List<DeviceChannel> queryOnlineChannelsByDeviceId(String deviceId); 72 public List<DeviceChannel> queryOnlineChannelsByDeviceId(String deviceId);
73 73
74 /** 74 /**
@@ -91,14 +91,14 @@ public interface IVideoManagerStorage { @@ -91,14 +91,14 @@ public interface IVideoManagerStorage {
91 * @param count 每页数量 91 * @param count 每页数量
92 * @return List<Device> 设备对象数组 92 * @return List<Device> 设备对象数组
93 */ 93 */
94 - public PageInfo<Device> queryVideoDeviceList(int page, int count); 94 + public PageInfo<Device> queryVideoDeviceList(int page, int count,Boolean online);
95 95
96 /** 96 /**
97 * 获取多个设备 97 * 获取多个设备
98 * 98 *
99 * @return List<Device> 设备对象数组 99 * @return List<Device> 设备对象数组
100 */ 100 */
101 - public List<Device> queryVideoDeviceList(); 101 + public List<Device> queryVideoDeviceList(Boolean online);
102 102
103 103
104 104
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceAlarmMapper.java
@@ -16,19 +16,19 @@ import java.util.List; @@ -16,19 +16,19 @@ import java.util.List;
16 public interface DeviceAlarmMapper { 16 public interface DeviceAlarmMapper {
17 17
18 @Insert("INSERT INTO device_alarm (deviceId, channelId, alarmPriority, alarmMethod, alarmTime, alarmDescription, longitude, latitude, alarmType , createTime ) " + 18 @Insert("INSERT INTO device_alarm (deviceId, channelId, alarmPriority, alarmMethod, alarmTime, alarmDescription, longitude, latitude, alarmType , createTime ) " +
19 - "VALUES ('${deviceId}', '${channelId}', '${alarmPriority}', '${alarmMethod}', '${alarmTime}', '${alarmDescription}', ${longitude}, ${latitude}, '${alarmType}', '${createTime}')") 19 + "VALUES (#{deviceId}, #{channelId}, #{alarmPriority}, #{alarmMethod}, #{alarmTime}, #{alarmDescription}, #{longitude}, #{latitude}, #{alarmType}, #{createTime})")
20 int add(DeviceAlarm alarm); 20 int add(DeviceAlarm alarm);
21 21
22 22
23 @Select(value = {" <script>" + 23 @Select(value = {" <script>" +
24 " SELECT * FROM device_alarm " + 24 " SELECT * FROM device_alarm " +
25 " WHERE 1=1 " + 25 " WHERE 1=1 " +
26 - " <if test=\"deviceId != null\" > AND deviceId = '${deviceId}'</if>" +  
27 - " <if test=\"alarmPriority != null\" > AND alarmPriority = '${alarmPriority}' </if>" +  
28 - " <if test=\"alarmMethod != null\" > AND alarmMethod = '${alarmMethod}' </if>" +  
29 - " <if test=\"alarmType != null\" > AND alarmType = '${alarmType}' </if>" +  
30 - " <if test=\"startTime != null\" > AND alarmTime &gt;= '${startTime}' </if>" +  
31 - " <if test=\"endTime != null\" > AND alarmTime &lt;= '${endTime}' </if>" + 26 + " <if test=\"deviceId != null\" > AND deviceId = #{deviceId}</if>" +
  27 + " <if test=\"alarmPriority != null\" > AND alarmPriority = #{alarmPriority} </if>" +
  28 + " <if test=\"alarmMethod != null\" > AND alarmMethod = #{alarmMethod} </if>" +
  29 + " <if test=\"alarmType != null\" > AND alarmType = #{alarmType} </if>" +
  30 + " <if test=\"startTime != null\" > AND alarmTime &gt;= #{startTime} </if>" +
  31 + " <if test=\"endTime != null\" > AND alarmTime &lt;= #{endTime} </if>" +
32 " ORDER BY alarmTime ASC " + 32 " ORDER BY alarmTime ASC " +
33 " </script>"}) 33 " </script>"})
34 List<DeviceAlarm> query(String deviceId, String alarmPriority, String alarmMethod, 34 List<DeviceAlarm> query(String deviceId, String alarmPriority, String alarmMethod,
@@ -38,10 +38,10 @@ public interface DeviceAlarmMapper { @@ -38,10 +38,10 @@ public interface DeviceAlarmMapper {
38 @Delete(" <script>" + 38 @Delete(" <script>" +
39 "DELETE FROM device_alarm WHERE 1=1 " + 39 "DELETE FROM device_alarm WHERE 1=1 " +
40 " <if test=\"deviceIdList != null and id == null \" > AND deviceId in " + 40 " <if test=\"deviceIdList != null and id == null \" > AND deviceId in " +
41 - "<foreach collection='deviceIdList' item='item' open='(' separator=',' close=')' > '${item}'</foreach>" + 41 + "<foreach collection='deviceIdList' item='item' open='(' separator=',' close=')' > #{item}</foreach>" +
42 "</if>" + 42 "</if>" +
43 - " <if test=\"time != null and id == null \" > AND alarmTime &lt;= '${time}'</if>" +  
44 - " <if test=\"id != null\" > AND id = ${id}</if>" + 43 + " <if test=\"time != null and id == null \" > AND alarmTime &lt;= #{time}</if>" +
  44 + " <if test=\"id != null\" > AND id = #{id}</if>" +
45 " </script>" 45 " </script>"
46 ) 46 )
47 int clearAlarmBeforeTime(Integer id, List<String> deviceIdList, String time); 47 int clearAlarmBeforeTime(Integer id, List<String> deviceIdList, String time);
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
@@ -20,46 +20,46 @@ public interface DeviceChannelMapper { @@ -20,46 +20,46 @@ public interface DeviceChannelMapper {
20 "address, parental, parentId, safetyWay, registerWay, certNum, certifiable, errCode, secrecy, " + 20 "address, parental, parentId, safetyWay, registerWay, certNum, certifiable, errCode, secrecy, " +
21 "ipAddress, port, password, PTZType, status, streamId, longitude, latitude, longitudeGcj02, latitudeGcj02, " + 21 "ipAddress, port, password, PTZType, status, streamId, longitude, latitude, longitudeGcj02, latitudeGcj02, " +
22 "longitudeWgs84, latitudeWgs84, hasAudio, createTime, updateTime, businessGroupId, gpsTime) " + 22 "longitudeWgs84, latitudeWgs84, hasAudio, createTime, updateTime, businessGroupId, gpsTime) " +
23 - "VALUES ('${channelId}', '${deviceId}', '${name}', '${manufacture}', '${model}', '${owner}', '${civilCode}', '${block}'," +  
24 - "'${address}', ${parental}, '${parentId}', ${safetyWay}, ${registerWay}, '${certNum}', ${certifiable}, ${errCode}, '${secrecy}', " +  
25 - "'${ipAddress}', ${port}, '${password}', ${PTZType}, ${status}, '${streamId}', ${longitude}, ${latitude}, ${longitudeGcj02}, " +  
26 - "${latitudeGcj02}, ${longitudeWgs84}, ${latitudeWgs84}, ${hasAudio}, '${createTime}', '${updateTime}', '${businessGroupId}', '${gpsTime}')") 23 + "VALUES (#{channelId}, #{deviceId}, #{name}, #{manufacture}, #{model}, #{owner}, #{civilCode}, #{block}," +
  24 + "#{address}, #{parental}, #{parentId}, #{safetyWay}, #{registerWay}, #{certNum}, #{certifiable}, #{errCode}, #{secrecy}, " +
  25 + "#{ipAddress}, #{port}, #{password}, #{PTZType}, #{status}, #{streamId}, #{longitude}, #{latitude}, #{longitudeGcj02}, " +
  26 + "#{latitudeGcj02}, #{longitudeWgs84}, #{latitudeWgs84}, #{hasAudio}, #{createTime}, #{updateTime}, #{businessGroupId}, #{gpsTime})")
27 int add(DeviceChannel channel); 27 int add(DeviceChannel channel);
28 28
29 @Update(value = {" <script>" + 29 @Update(value = {" <script>" +
30 "UPDATE device_channel " + 30 "UPDATE device_channel " +
31 - "SET updateTime='${updateTime}'" +  
32 - "<if test='name != null'>, name='${name}'</if>" +  
33 - "<if test='manufacture != null'>, manufacture='${manufacture}'</if>" +  
34 - "<if test='model != null'>, model='${model}'</if>" +  
35 - "<if test='owner != null'>, owner='${owner}'</if>" +  
36 - "<if test='civilCode != null'>, civilCode='${civilCode}'</if>" +  
37 - "<if test='block != null'>, block='${block}'</if>" +  
38 - "<if test='address != null'>, address='${address}'</if>" +  
39 - "<if test='parental != null'>, parental=${parental}</if>" +  
40 - "<if test='parentId != null'>, parentId='${parentId}'</if>" +  
41 - "<if test='safetyWay != null'>, safetyWay=${safetyWay}</if>" +  
42 - "<if test='registerWay != null'>, registerWay=${registerWay}</if>" +  
43 - "<if test='certNum != null'>, certNum='${certNum}'</if>" +  
44 - "<if test='certifiable != null'>, certifiable=${certifiable}</if>" +  
45 - "<if test='errCode != null'>, errCode=${errCode}</if>" +  
46 - "<if test='secrecy != null'>, secrecy='${secrecy}'</if>" +  
47 - "<if test='ipAddress != null'>, ipAddress='${ipAddress}'</if>" +  
48 - "<if test='port != null'>, port=${port}</if>" +  
49 - "<if test='password != null'>, password='${password}'</if>" +  
50 - "<if test='PTZType != null'>, PTZType=${PTZType}</if>" +  
51 - "<if test='status != null'>, status='${status}'</if>" +  
52 - "<if test='streamId != null'>, streamId='${streamId}'</if>" +  
53 - "<if test='hasAudio != null'>, hasAudio=${hasAudio}</if>" +  
54 - "<if test='longitude != null'>, longitude=${longitude}</if>" +  
55 - "<if test='latitude != null'>, latitude=${latitude}</if>" +  
56 - "<if test='longitudeGcj02 != null'>, longitudeGcj02=${longitudeGcj02}</if>" +  
57 - "<if test='latitudeGcj02 != null'>, latitudeGcj02=${latitudeGcj02}</if>" +  
58 - "<if test='longitudeWgs84 != null'>, longitudeWgs84=${longitudeWgs84}</if>" +  
59 - "<if test='latitudeWgs84 != null'>, latitudeWgs84=${latitudeWgs84}</if>" + 31 + "SET updateTime=#{updateTime}" +
  32 + "<if test='name != null'>, name=#{name}</if>" +
  33 + "<if test='manufacture != null'>, manufacture=#{manufacture}</if>" +
  34 + "<if test='model != null'>, model=#{model}</if>" +
  35 + "<if test='owner != null'>, owner=#{owner}</if>" +
  36 + "<if test='civilCode != null'>, civilCode=#{civilCode}</if>" +
  37 + "<if test='block != null'>, block=#{block}</if>" +
  38 + "<if test='address != null'>, address=#{address}</if>" +
  39 + "<if test='parental != null'>, parental=#{parental}</if>" +
  40 + "<if test='parentId != null'>, parentId=#{parentId}</if>" +
  41 + "<if test='safetyWay != null'>, safetyWay=#{safetyWay}</if>" +
  42 + "<if test='registerWay != null'>, registerWay=#{registerWay}</if>" +
  43 + "<if test='certNum != null'>, certNum=#{certNum}</if>" +
  44 + "<if test='certifiable != null'>, certifiable=#{certifiable}</if>" +
  45 + "<if test='errCode != null'>, errCode=#{errCode}</if>" +
  46 + "<if test='secrecy != null'>, secrecy=#{secrecy}</if>" +
  47 + "<if test='ipAddress != null'>, ipAddress=#{ipAddress}</if>" +
  48 + "<if test='port != null'>, port=#{port}</if>" +
  49 + "<if test='password != null'>, password=#{password}</if>" +
  50 + "<if test='PTZType != null'>, PTZType=#{PTZType}</if>" +
  51 + "<if test='status != null'>, status=#{status}</if>" +
  52 + "<if test='streamId != null'>, streamId=#{streamId}</if>" +
  53 + "<if test='hasAudio != null'>, hasAudio=#{hasAudio}</if>" +
  54 + "<if test='longitude != null'>, longitude=#{longitude}</if>" +
  55 + "<if test='latitude != null'>, latitude=#{latitude}</if>" +
  56 + "<if test='longitudeGcj02 != null'>, longitudeGcj02=#{longitudeGcj02}</if>" +
  57 + "<if test='latitudeGcj02 != null'>, latitudeGcj02=#{latitudeGcj02}</if>" +
  58 + "<if test='longitudeWgs84 != null'>, longitudeWgs84=#{longitudeWgs84}</if>" +
  59 + "<if test='latitudeWgs84 != null'>, latitudeWgs84=#{latitudeWgs84}</if>" +
60 "<if test='businessGroupId != null'>, businessGroupId=#{businessGroupId}</if>" + 60 "<if test='businessGroupId != null'>, businessGroupId=#{businessGroupId}</if>" +
61 "<if test='gpsTime != null'>, gpsTime=#{gpsTime}</if>" + 61 "<if test='gpsTime != null'>, gpsTime=#{gpsTime}</if>" +
62 - "WHERE deviceId='${deviceId}' AND channelId='${channelId}'"+ 62 + "WHERE deviceId=#{deviceId} AND channelId=#{channelId}"+
63 " </script>"}) 63 " </script>"})
64 int update(DeviceChannel channel); 64 int update(DeviceChannel channel);
65 65
@@ -70,15 +70,18 @@ public interface DeviceChannelMapper { @@ -70,15 +70,18 @@ public interface DeviceChannelMapper {
70 "device_channel dc " + 70 "device_channel dc " +
71 "WHERE " + 71 "WHERE " +
72 "dc.deviceId = #{deviceId} " + 72 "dc.deviceId = #{deviceId} " +
73 - " <if test='query != null'> AND (dc.channelId LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " + 73 +" <if test='query != null'> AND (dc.channelId LIKE concat('%',#{query},'%') OR dc.name LIKE concat('%',#{query},'%') OR dc.name LIKE concat('%',#{query},'%'))</if> " +
74 " <if test='parentChannelId != null'> AND (dc.parentId=#{parentChannelId} OR dc.civilCode = #{parentChannelId}) </if> " + 74 " <if test='parentChannelId != null'> AND (dc.parentId=#{parentChannelId} OR dc.civilCode = #{parentChannelId}) </if> " +
75 " <if test='online == true' > AND dc.status=1</if>" + 75 " <if test='online == true' > AND dc.status=1</if>" +
76 " <if test='online == false' > AND dc.status=0</if>" + 76 " <if test='online == false' > AND dc.status=0</if>" +
77 " <if test='hasSubChannel == true' > AND dc.subCount > 0 </if>" + 77 " <if test='hasSubChannel == true' > AND dc.subCount > 0 </if>" +
78 " <if test='hasSubChannel == false' > AND dc.subCount = 0 </if>" + 78 " <if test='hasSubChannel == false' > AND dc.subCount = 0 </if>" +
  79 + "<if test='channelIds != null'> AND dc.channelId in <foreach item='item' index='index' collection='channelIds' open='(' separator=',' close=')'>" +
  80 + "#{item} " +
  81 + "</foreach> </if>" +
79 "ORDER BY dc.channelId " + 82 "ORDER BY dc.channelId " +
80 " </script>"}) 83 " </script>"})
81 - List<DeviceChannel> queryChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, Boolean online); 84 + List<DeviceChannel> queryChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, Boolean online,List<String> channelIds);
82 85
83 @Select("SELECT * FROM device_channel WHERE deviceId=#{deviceId} AND channelId=#{channelId}") 86 @Select("SELECT * FROM device_channel WHERE deviceId=#{deviceId} AND channelId=#{channelId}")
84 DeviceChannel queryChannel(String deviceId, String channelId); 87 DeviceChannel queryChannel(String deviceId, String channelId);
@@ -110,7 +113,7 @@ public interface DeviceChannelMapper { @@ -110,7 +113,7 @@ public interface DeviceChannelMapper {
110 " LEFT JOIN device de ON dc.deviceId = de.deviceId " + 113 " LEFT JOIN device de ON dc.deviceId = de.deviceId " +
111 " LEFT JOIN platform_gb_channel pgc on pgc.deviceChannelId = dc.id " + 114 " LEFT JOIN platform_gb_channel pgc on pgc.deviceChannelId = dc.id " +
112 " WHERE 1=1 " + 115 " WHERE 1=1 " +
113 - " <if test='query != null'> AND (dc.channelId LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " + 116 + " <if test='query != null'> AND (dc.channelId LIKE concat('%',#{query},'%') OR dc.name LIKE concat('%',#{query},'%') OR dc.name LIKE concat('%',#{query},'%'))</if> " +
114 " <if test='online == true' > AND dc.status=1</if> " + 117 " <if test='online == true' > AND dc.status=1</if> " +
115 " <if test='online == false' > AND dc.status=0</if> " + 118 " <if test='online == false' > AND dc.status=0</if> " +
116 " <if test='hasSubChannel!= null and hasSubChannel == true' > AND dc.subCount > 0</if> " + 119 " <if test='hasSubChannel!= null and hasSubChannel == true' > AND dc.subCount > 0</if> " +
@@ -151,14 +154,14 @@ public interface DeviceChannelMapper { @@ -151,14 +154,14 @@ public interface DeviceChannelMapper {
151 " longitudeWgs84, latitudeWgs84, hasAudio, createTime, updateTime, businessGroupId, gpsTime) " + 154 " longitudeWgs84, latitudeWgs84, hasAudio, createTime, updateTime, businessGroupId, gpsTime) " +
152 "values " + 155 "values " +
153 "<foreach collection='addChannels' index='index' item='item' separator=','> " + 156 "<foreach collection='addChannels' index='index' item='item' separator=','> " +
154 - "('${item.channelId}', '${item.deviceId}', '${item.name}', '${item.manufacture}', '${item.model}', " +  
155 - "'${item.owner}', '${item.civilCode}', '${item.block}',${item.subCount}," +  
156 - "'${item.address}', ${item.parental}, '${item.parentId}', ${item.safetyWay}, ${item.registerWay}, " +  
157 - "'${item.certNum}', ${item.certifiable}, ${item.errCode}, '${item.secrecy}', " +  
158 - "'${item.ipAddress}', ${item.port}, '${item.password}', ${item.PTZType}, ${item.status}, " +  
159 - "'${item.streamId}', ${item.longitude}, ${item.latitude},${item.longitudeGcj02}, " +  
160 - "${item.latitudeGcj02},${item.longitudeWgs84}, ${item.latitudeWgs84}, ${item.hasAudio},'${item.createTime}', '${item.updateTime}', " +  
161 - "'${item.businessGroupId}', '${item.gpsTime}') " + 157 + "(#{item.channelId}, #{item.deviceId}, #{item.name}, #{item.manufacture}, #{item.model}, " +
  158 + "#{item.owner}, #{item.civilCode}, #{item.block},#{item.subCount}," +
  159 + "#{item.address}, #{item.parental}, #{item.parentId}, #{item.safetyWay}, #{item.registerWay}, " +
  160 + "#{item.certNum}, #{item.certifiable}, #{item.errCode}, #{item.secrecy}, " +
  161 + "#{item.ipAddress}, #{item.port}, #{item.password}, #{item.PTZType}, #{item.status}, " +
  162 + "#{item.streamId}, #{item.longitude}, #{item.latitude},#{item.longitudeGcj02}, " +
  163 + "#{item.latitudeGcj02},#{item.longitudeWgs84}, #{item.latitudeWgs84}, #{item.hasAudio}, now(), now(), " +
  164 + "#{item.businessGroupId}, #{item.gpsTime}) " +
162 "</foreach> " + 165 "</foreach> " +
163 "ON DUPLICATE KEY UPDATE " + 166 "ON DUPLICATE KEY UPDATE " +
164 "updateTime=VALUES(updateTime), " + 167 "updateTime=VALUES(updateTime), " +
@@ -203,39 +206,39 @@ public interface DeviceChannelMapper { @@ -203,39 +206,39 @@ public interface DeviceChannelMapper {
203 "<foreach collection='updateChannels' item='item' separator=';'>" + 206 "<foreach collection='updateChannels' item='item' separator=';'>" +
204 " UPDATE" + 207 " UPDATE" +
205 " device_channel" + 208 " device_channel" +
206 - " SET updateTime='${item.updateTime}'" +  
207 - "<if test='item.name != null'>, name='${item.name}'</if>" +  
208 - "<if test='item.manufacture != null'>, manufacture='${item.manufacture}'</if>" +  
209 - "<if test='item.model != null'>, model='${item.model}'</if>" +  
210 - "<if test='item.owner != null'>, owner='${item.owner}'</if>" +  
211 - "<if test='item.civilCode != null'>, civilCode='${item.civilCode}'</if>" +  
212 - "<if test='item.block != null'>, block='${item.block}'</if>" +  
213 - "<if test='item.subCount != null'>, block=${item.subCount}</if>" +  
214 - "<if test='item.address != null'>, address='${item.address}'</if>" +  
215 - "<if test='item.parental != null'>, parental=${item.parental}</if>" +  
216 - "<if test='item.parentId != null'>, parentId='${item.parentId}'</if>" +  
217 - "<if test='item.safetyWay != null'>, safetyWay=${item.safetyWay}</if>" +  
218 - "<if test='item.registerWay != null'>, registerWay=${item.registerWay}</if>" +  
219 - "<if test='item.certNum != null'>, certNum='${item.certNum}'</if>" +  
220 - "<if test='item.certifiable != null'>, certifiable=${item.certifiable}</if>" +  
221 - "<if test='item.errCode != null'>, errCode=${item.errCode}</if>" +  
222 - "<if test='item.secrecy != null'>, secrecy='${item.secrecy}'</if>" +  
223 - "<if test='item.ipAddress != null'>, ipAddress='${item.ipAddress}'</if>" +  
224 - "<if test='item.port != null'>, port=${item.port}</if>" +  
225 - "<if test='item.password != null'>, password='${item.password}'</if>" +  
226 - "<if test='item.PTZType != null'>, PTZType=${item.PTZType}</if>" +  
227 - "<if test='item.status != null'>, status='${item.status}'</if>" +  
228 - "<if test='item.streamId != null'>, streamId='${item.streamId}'</if>" +  
229 - "<if test='item.hasAudio != null'>, hasAudio=${item.hasAudio}</if>" +  
230 - "<if test='item.longitude != null'>, longitude=${item.longitude}</if>" +  
231 - "<if test='item.latitude != null'>, latitude=${item.latitude}</if>" +  
232 - "<if test='item.longitudeGcj02 != null'>, longitudeGcj02=${item.longitudeGcj02}</if>" +  
233 - "<if test='item.latitudeGcj02 != null'>, latitudeGcj02=${item.latitudeGcj02}</if>" +  
234 - "<if test='item.longitudeWgs84 != null'>, longitudeWgs84=${item.longitudeWgs84}</if>" +  
235 - "<if test='item.latitudeWgs84 != null'>, latitudeWgs84=${item.latitudeWgs84}</if>" + 209 + " SET updateTime=#{item.updateTime}" +
  210 + "<if test='item.name != null'>, name=#{item.name}</if>" +
  211 + "<if test='item.manufacture != null'>, manufacture=#{item.manufacture}</if>" +
  212 + "<if test='item.model != null'>, model=#{item.model}</if>" +
  213 + "<if test='item.owner != null'>, owner=#{item.owner}</if>" +
  214 + "<if test='item.civilCode != null'>, civilCode=#{item.civilCode}</if>" +
  215 + "<if test='item.block != null'>, block=#{item.block}</if>" +
  216 + "<if test='item.subCount != null'>, block=#{item.subCount}</if>" +
  217 + "<if test='item.address != null'>, address=#{item.address}</if>" +
  218 + "<if test='item.parental != null'>, parental=#{item.parental}</if>" +
  219 + "<if test='item.parentId != null'>, parentId=#{item.parentId}</if>" +
  220 + "<if test='item.safetyWay != null'>, safetyWay=#{item.safetyWay}</if>" +
  221 + "<if test='item.registerWay != null'>, registerWay=#{item.registerWay}</if>" +
  222 + "<if test='item.certNum != null'>, certNum=#{item.certNum}</if>" +
  223 + "<if test='item.certifiable != null'>, certifiable=#{item.certifiable}</if>" +
  224 + "<if test='item.errCode != null'>, errCode=#{item.errCode}</if>" +
  225 + "<if test='item.secrecy != null'>, secrecy=#{item.secrecy}</if>" +
  226 + "<if test='item.ipAddress != null'>, ipAddress=#{item.ipAddress}</if>" +
  227 + "<if test='item.port != null'>, port=#{item.port}</if>" +
  228 + "<if test='item.password != null'>, password=#{item.password}</if>" +
  229 + "<if test='item.PTZType != null'>, PTZType=#{item.PTZType}</if>" +
  230 + "<if test='item.status != null'>, status=#{item.status}</if>" +
  231 + "<if test='item.streamId != null'>, streamId=#{item.streamId}</if>" +
  232 + "<if test='item.hasAudio != null'>, hasAudio=#{item.hasAudio}</if>" +
  233 + "<if test='item.longitude != null'>, longitude=#{item.longitude}</if>" +
  234 + "<if test='item.latitude != null'>, latitude=#{item.latitude}</if>" +
  235 + "<if test='item.longitudeGcj02 != null'>, longitudeGcj02=#{item.longitudeGcj02}</if>" +
  236 + "<if test='item.latitudeGcj02 != null'>, latitudeGcj02=#{item.latitudeGcj02}</if>" +
  237 + "<if test='item.longitudeWgs84 != null'>, longitudeWgs84=#{item.longitudeWgs84}</if>" +
  238 + "<if test='item.latitudeWgs84 != null'>, latitudeWgs84=#{item.latitudeWgs84}</if>" +
236 "<if test='item.businessGroupId != null'>, businessGroupId=#{item.businessGroupId}</if>" + 239 "<if test='item.businessGroupId != null'>, businessGroupId=#{item.businessGroupId}</if>" +
237 "<if test='item.gpsTime != null'>, gpsTime=#{item.gpsTime}</if>" + 240 "<if test='item.gpsTime != null'>, gpsTime=#{item.gpsTime}</if>" +
238 - "WHERE deviceId='${item.deviceId}' AND channelId='${item.channelId}'"+ 241 + "WHERE deviceId=#{item.deviceId} AND channelId=#{item.channelId}"+
239 "</foreach>" + 242 "</foreach>" +
240 "</script>"}) 243 "</script>"})
241 int batchUpdate(List<DeviceChannel> updateChannels); 244 int batchUpdate(List<DeviceChannel> updateChannels);
@@ -248,17 +251,20 @@ public interface DeviceChannelMapper { @@ -248,17 +251,20 @@ public interface DeviceChannelMapper {
248 "device_channel dc1 " + 251 "device_channel dc1 " +
249 "WHERE " + 252 "WHERE " +
250 "dc1.deviceId = #{deviceId} " + 253 "dc1.deviceId = #{deviceId} " +
251 - " <if test='query != null'> AND (dc1.channelId LIKE '%${query}%' OR dc1.name LIKE '%${query}%' OR dc1.name LIKE '%${query}%')</if> " + 254 + " <if test='query != null'> AND (dc1.channelId LIKE concat('%',#{query},'%') OR dc1.name LIKE concat('%',#{query},'%') OR dc1.name LIKE concat('%',#{query},'%'))</if> " +
252 " <if test='parentChannelId != null'> AND dc1.parentId=#{parentChannelId} </if> " + 255 " <if test='parentChannelId != null'> AND dc1.parentId=#{parentChannelId} </if> " +
253 " <if test='online == true' > AND dc1.status=1</if>" + 256 " <if test='online == true' > AND dc1.status=1</if>" +
254 " <if test='online == false' > AND dc1.status=0</if>" + 257 " <if test='online == false' > AND dc1.status=0</if>" +
255 " <if test='hasSubChannel == true' > AND dc1.subCount >0</if>" + 258 " <if test='hasSubChannel == true' > AND dc1.subCount >0</if>" +
256 " <if test='hasSubChannel == false' > AND dc1.subCount=0</if>" + 259 " <if test='hasSubChannel == false' > AND dc1.subCount=0</if>" +
  260 + "<if test='channelIds != null'> AND dc1.channelId in <foreach item='item' index='index' collection='channelIds' open='(' separator=',' close=')'>" +
  261 + "#{item} " +
  262 + "</foreach> </if>" +
257 "ORDER BY dc1.channelId ASC " + 263 "ORDER BY dc1.channelId ASC " +
258 "Limit #{limit} OFFSET #{start}" + 264 "Limit #{limit} OFFSET #{start}" +
259 " </script>"}) 265 " </script>"})
260 List<DeviceChannel> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, String parentChannelId, String query, 266 List<DeviceChannel> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, String parentChannelId, String query,
261 - Boolean hasSubChannel, Boolean online, int start, int limit); 267 + Boolean hasSubChannel, Boolean online, int start, int limit,List<String> channelIds);
262 268
263 @Select("SELECT * FROM device_channel WHERE deviceId=#{deviceId} AND status=1") 269 @Select("SELECT * FROM device_channel WHERE deviceId=#{deviceId} AND status=1")
264 List<DeviceChannel> queryOnlineChannelsByDeviceId(String deviceId); 270 List<DeviceChannel> queryOnlineChannelsByDeviceId(String deviceId);
@@ -286,13 +292,13 @@ public interface DeviceChannelMapper { @@ -286,13 +292,13 @@ public interface DeviceChannelMapper {
286 @Update(value = {" <script>" + 292 @Update(value = {" <script>" +
287 "UPDATE device_channel " + 293 "UPDATE device_channel " +
288 "SET " + 294 "SET " +
289 - "latitude=${latitude}, " +  
290 - "longitude=${longitude}, " +  
291 - "longitudeGcj02=${longitudeGcj02}, " +  
292 - "latitudeGcj02=${latitudeGcj02}, " +  
293 - "longitudeWgs84=${longitudeWgs84}, " +  
294 - "latitudeWgs84=${latitudeWgs84}, " +  
295 - "gpsTime='${gpsTime}' " + 295 + "latitude=#{latitude}, " +
  296 + "longitude=#{longitude}, " +
  297 + "longitudeGcj02=#{longitudeGcj02}, " +
  298 + "latitudeGcj02=#{latitudeGcj02}, " +
  299 + "longitudeWgs84=#{longitudeWgs84}, " +
  300 + "latitudeWgs84=#{latitudeWgs84}, " +
  301 + "gpsTime=#{gpsTime} " +
296 "WHERE deviceId=#{deviceId} " + 302 "WHERE deviceId=#{deviceId} " +
297 " <if test='channelId != null' > AND channelId=#{channelId}</if>" + 303 " <if test='channelId != null' > AND channelId=#{channelId}</if>" +
298 " </script>"}) 304 " </script>"})
@@ -309,10 +315,10 @@ public interface DeviceChannelMapper { @@ -309,10 +315,10 @@ public interface DeviceChannelMapper {
309 "select * " + 315 "select * " +
310 "from device_channel " + 316 "from device_channel " +
311 "where deviceId=#{deviceId}" + 317 "where deviceId=#{deviceId}" +
312 - " <if test='parentId != null and length != null' > and parentId = #{parentId} or left(channelId, ${parentId.length()}) = #{parentId} and length(channelId)=${length} </if>" +  
313 - " <if test='parentId == null and length != null' > and parentId = #{parentId} or length(channelId)=${length} </if>" + 318 + " <if test='parentId != null and length != null' > and parentId = #{parentId} or left(channelId, #{parentId.length()}) = #{parentId} and length(channelId)=#{length} </if>" +
  319 + " <if test='parentId == null and length != null' > and parentId = #{parentId} or length(channelId)=#{length} </if>" +
314 " <if test='parentId == null and length == null' > and parentId = #{parentId} </if>" + 320 " <if test='parentId == null and length == null' > and parentId = #{parentId} </if>" +
315 - " <if test='parentId != null and length == null' > and parentId = #{parentId} or left(channelId, ${parentId.length()}) = #{parentId} </if>" + 321 + " <if test='parentId != null and length == null' > and parentId = #{parentId} or left(channelId, #{parentId.length()}) = #{parentId} </if>" +
316 " </script>"}) 322 " </script>"})
317 List<DeviceChannel> getChannelsWithCivilCodeAndLength(String deviceId, String parentId, Integer length); 323 List<DeviceChannel> getChannelsWithCivilCodeAndLength(String deviceId, String parentId, Integer length);
318 324
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
@@ -61,6 +61,7 @@ public interface DeviceMapper { @@ -61,6 +61,7 @@ public interface DeviceMapper {
61 "expires," + 61 "expires," +
62 "registerTime," + 62 "registerTime," +
63 "keepaliveTime," + 63 "keepaliveTime," +
  64 + "keepaliveIntervalTime," +
64 "createTime," + 65 "createTime," +
65 "updateTime," + 66 "updateTime," +
66 "charset," + 67 "charset," +
@@ -88,6 +89,7 @@ public interface DeviceMapper { @@ -88,6 +89,7 @@ public interface DeviceMapper {
88 "#{expires}," + 89 "#{expires}," +
89 "#{registerTime}," + 90 "#{registerTime}," +
90 "#{keepaliveTime}," + 91 "#{keepaliveTime}," +
  92 + "#{keepaliveIntervalTime}," +
91 "#{createTime}," + 93 "#{createTime}," +
92 "#{updateTime}," + 94 "#{updateTime}," +
93 "#{charset}," + 95 "#{charset}," +
@@ -104,25 +106,28 @@ public interface DeviceMapper { @@ -104,25 +106,28 @@ public interface DeviceMapper {
104 106
105 @Update(value = {" <script>" + 107 @Update(value = {" <script>" +
106 "UPDATE device " + 108 "UPDATE device " +
107 - "SET updateTime='${updateTime}'" +  
108 - "<if test=\"name != null\">, name='${name}'</if>" +  
109 - "<if test=\"manufacturer != null\">, manufacturer='${manufacturer}'</if>" +  
110 - "<if test=\"model != null\">, model='${model}'</if>" +  
111 - "<if test=\"firmware != null\">, firmware='${firmware}'</if>" +  
112 - "<if test=\"transport != null\">, transport='${transport}'</if>" +  
113 - "<if test=\"ip != null\">, ip='${ip}'</if>" +  
114 - "<if test=\"localIp != null\">, localIp='${localIp}'</if>" +  
115 - "<if test=\"port != null\">, port=${port}</if>" +  
116 - "<if test=\"hostAddress != null\">, hostAddress='${hostAddress}'</if>" +  
117 - "<if test=\"online != null\">, online=${online}</if>" +  
118 - "<if test=\"registerTime != null\">, registerTime='${registerTime}'</if>" +  
119 - "<if test=\"keepaliveTime != null\">, keepaliveTime='${keepaliveTime}'</if>" +  
120 - "<if test=\"expires != null\">, expires=${expires}</if>" +  
121 - "WHERE deviceId='${deviceId}'"+ 109 + "SET updateTime=#{updateTime}" +
  110 + "<if test=\"name != null\">, name=#{name}</if>" +
  111 + "<if test=\"manufacturer != null\">, manufacturer=#{manufacturer}</if>" +
  112 + "<if test=\"model != null\">, model=#{model}</if>" +
  113 + "<if test=\"firmware != null\">, firmware=#{firmware}</if>" +
  114 + "<if test=\"transport != null\">, transport=#{transport}</if>" +
  115 + "<if test=\"ip != null\">, ip=#{ip}</if>" +
  116 + "<if test=\"localIp != null\">, localIp=#{localIp}</if>" +
  117 + "<if test=\"port != null\">, port=#{port}</if>" +
  118 + "<if test=\"hostAddress != null\">, hostAddress=#{hostAddress}</if>" +
  119 + "<if test=\"online != null\">, online=#{online}</if>" +
  120 + "<if test=\"registerTime != null\">, registerTime=#{registerTime}</if>" +
  121 + "<if test=\"keepaliveTime != null\">, keepaliveTime=#{keepaliveTime}</if>" +
  122 + "<if test=\"keepaliveIntervalTime != null\">, keepaliveIntervalTime=#{keepaliveIntervalTime}</if>" +
  123 + "<if test=\"expires != null\">, expires=#{expires}</if>" +
  124 + "WHERE deviceId=#{deviceId}"+
122 " </script>"}) 125 " </script>"})
123 int update(Device device); 126 int update(Device device);
124 127
125 - @Select("SELECT " + 128 + @Select(
  129 + " <script>" +
  130 + "SELECT " +
126 "deviceId, " + 131 "deviceId, " +
127 "coalesce(custom_name, name) as name, " + 132 "coalesce(custom_name, name) as name, " +
128 "password, " + 133 "password, " +
@@ -150,8 +155,11 @@ public interface DeviceMapper { @@ -150,8 +155,11 @@ public interface DeviceMapper {
150 "geoCoordSys," + 155 "geoCoordSys," +
151 "treeType," + 156 "treeType," +
152 "online," + 157 "online," +
153 - "(SELECT count(0) FROM device_channel WHERE deviceId=de.deviceId) as channelCount FROM device de")  
154 - List<Device> getDevices(); 158 + "(SELECT count(0) FROM device_channel WHERE deviceId=de.deviceId) as channelCount FROM device de" +
  159 + "<if test=\"online != null\"> where online=${online}</if>"+
  160 + " </script>"
  161 + )
  162 + List<Device> getDevices(Boolean online);
155 163
156 @Delete("DELETE FROM device WHERE deviceId=#{deviceId}") 164 @Delete("DELETE FROM device WHERE deviceId=#{deviceId}")
157 int del(String deviceId); 165 int del(String deviceId);
@@ -217,28 +225,28 @@ public interface DeviceMapper { @@ -217,28 +225,28 @@ public interface DeviceMapper {
217 "geoCoordSys," + 225 "geoCoordSys," +
218 "treeType," + 226 "treeType," +
219 "online" + 227 "online" +
220 - " FROM device WHERE ip = #{host} AND port=${port}") 228 + " FROM device WHERE ip = #{host} AND port=#{port}")
221 Device getDeviceByHostAndPort(String host, int port); 229 Device getDeviceByHostAndPort(String host, int port);
222 230
223 @Update(value = {" <script>" + 231 @Update(value = {" <script>" +
224 "UPDATE device " + 232 "UPDATE device " +
225 - "SET updateTime='${updateTime}'" +  
226 - "<if test=\"name != null\">, custom_name='${name}'</if>" +  
227 - "<if test=\"password != null\">, password='${password}'</if>" +  
228 - "<if test=\"streamMode != null\">, streamMode='${streamMode}'</if>" +  
229 - "<if test=\"ip != null\">, ip='${ip}'</if>" +  
230 - "<if test=\"sdpIp != null\">, sdpIp='${sdpIp}'</if>" +  
231 - "<if test=\"port != null\">, port=${port}</if>" +  
232 - "<if test=\"charset != null\">, charset='${charset}'</if>" +  
233 - "<if test=\"subscribeCycleForCatalog != null\">, subscribeCycleForCatalog=${subscribeCycleForCatalog}</if>" +  
234 - "<if test=\"subscribeCycleForMobilePosition != null\">, subscribeCycleForMobilePosition=${subscribeCycleForMobilePosition}</if>" +  
235 - "<if test=\"mobilePositionSubmissionInterval != null\">, mobilePositionSubmissionInterval=${mobilePositionSubmissionInterval}</if>" +  
236 - "<if test=\"subscribeCycleForAlarm != null\">, subscribeCycleForAlarm=${subscribeCycleForAlarm}</if>" +  
237 - "<if test=\"ssrcCheck != null\">, ssrcCheck=${ssrcCheck}</if>" + 233 + "SET updateTime=#{updateTime}" +
  234 + "<if test=\"name != null\">, custom_name=#{name}</if>" +
  235 + "<if test=\"password != null\">, password=#{password}</if>" +
  236 + "<if test=\"streamMode != null\">, streamMode=#{streamMode}</if>" +
  237 + "<if test=\"ip != null\">, ip=#{ip}</if>" +
  238 + "<if test=\"sdpIp != null\">, sdpIp=#{sdpIp}</if>" +
  239 + "<if test=\"port != null\">, port=#{port}</if>" +
  240 + "<if test=\"charset != null\">, charset=#{charset}</if>" +
  241 + "<if test=\"subscribeCycleForCatalog != null\">, subscribeCycleForCatalog=#{subscribeCycleForCatalog}</if>" +
  242 + "<if test=\"subscribeCycleForMobilePosition != null\">, subscribeCycleForMobilePosition=#{subscribeCycleForMobilePosition}</if>" +
  243 + "<if test=\"mobilePositionSubmissionInterval != null\">, mobilePositionSubmissionInterval=#{mobilePositionSubmissionInterval}</if>" +
  244 + "<if test=\"subscribeCycleForAlarm != null\">, subscribeCycleForAlarm=#{subscribeCycleForAlarm}</if>" +
  245 + "<if test=\"ssrcCheck != null\">, ssrcCheck=#{ssrcCheck}</if>" +
238 "<if test=\"geoCoordSys != null\">, geoCoordSys=#{geoCoordSys}</if>" + 246 "<if test=\"geoCoordSys != null\">, geoCoordSys=#{geoCoordSys}</if>" +
239 "<if test=\"treeType != null\">, treeType=#{treeType}</if>" + 247 "<if test=\"treeType != null\">, treeType=#{treeType}</if>" +
240 "<if test=\"mediaServerId != null\">, mediaServerId=#{mediaServerId}</if>" + 248 "<if test=\"mediaServerId != null\">, mediaServerId=#{mediaServerId}</if>" +
241 - "WHERE deviceId='${deviceId}'"+ 249 + "WHERE deviceId=#{deviceId}"+
242 " </script>"}) 250 " </script>"})
243 int updateCustom(Device device); 251 int updateCustom(Device device);
244 252
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMobilePositionMapper.java
@@ -9,7 +9,7 @@ import org.apache.ibatis.annotations.*; @@ -9,7 +9,7 @@ import org.apache.ibatis.annotations.*;
9 public interface DeviceMobilePositionMapper { 9 public interface DeviceMobilePositionMapper {
10 10
11 @Insert("INSERT INTO device_mobile_position (deviceId,channelId, deviceName, time, longitude, latitude, altitude, speed, direction, reportSource, longitudeGcj02, latitudeGcj02, longitudeWgs84, latitudeWgs84, createTime) " + 11 @Insert("INSERT INTO device_mobile_position (deviceId,channelId, deviceName, time, longitude, latitude, altitude, speed, direction, reportSource, longitudeGcj02, latitudeGcj02, longitudeWgs84, latitudeWgs84, createTime) " +
12 - "VALUES ('${deviceId}','${channelId}', '${deviceName}', '${time}', ${longitude}, ${latitude}, ${altitude}, ${speed}, ${direction}, '${reportSource}', ${longitudeGcj02}, ${latitudeGcj02}, ${longitudeWgs84}, ${latitudeWgs84}, '${createTime}')") 12 + "VALUES (#{deviceId},#{channelId}, #{deviceName}, #{time}, #{longitude}, #{latitude}, #{altitude}, #{speed}, #{direction}, #{reportSource}, #{longitudeGcj02}, #{latitudeGcj02}, #{longitudeWgs84}, #{latitudeWgs84}, #{createTime})")
13 int insertNewPosition(MobilePosition mobilePosition); 13 int insertNewPosition(MobilePosition mobilePosition);
14 14
15 @Select(value = {" <script>" + 15 @Select(value = {" <script>" +
src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
@@ -16,9 +16,9 @@ public interface GbStreamMapper { @@ -16,9 +16,9 @@ public interface GbStreamMapper {
16 16
17 @Insert("REPLACE INTO gb_stream (app, stream, gbId, name, " + 17 @Insert("REPLACE INTO gb_stream (app, stream, gbId, name, " +
18 "longitude, latitude, streamType, mediaServerId, createTime) VALUES" + 18 "longitude, latitude, streamType, mediaServerId, createTime) VALUES" +
19 - "('${app}', '${stream}', '${gbId}', '${name}', " +  
20 - "'${longitude}', '${latitude}', '${streamType}', " +  
21 - "'${mediaServerId}', '${createTime}')") 19 + "(#{app}, #{stream}, #{gbId}, #{name}, " +
  20 + "#{longitude}, #{latitude}, #{streamType}, " +
  21 + "#{mediaServerId}, #{createTime})")
22 @Options(useGeneratedKeys = true, keyProperty = "gbStreamId", keyColumn = "gbStreamId") 22 @Options(useGeneratedKeys = true, keyProperty = "gbStreamId", keyColumn = "gbStreamId")
23 int add(GbStream gbStream); 23 int add(GbStream gbStream);
24 24
@@ -57,7 +57,7 @@ public interface GbStreamMapper { @@ -57,7 +57,7 @@ public interface GbStreamMapper {
57 "(select pgs.gbStreamId from platform_gb_stream pgs where pgs.platformId = #{platformId} and pgs.catalogId=#{catalogId})</if> " + 57 "(select pgs.gbStreamId from platform_gb_stream pgs where pgs.platformId = #{platformId} and pgs.catalogId=#{catalogId})</if> " +
58 " <if test='catalogId == null'> AND gs.gbStreamId not in" + 58 " <if test='catalogId == null'> AND gs.gbStreamId not in" +
59 "(select pgs.gbStreamId from platform_gb_stream pgs where pgs.platformId = #{platformId}) </if> " + 59 "(select pgs.gbStreamId from platform_gb_stream pgs where pgs.platformId = #{platformId}) </if> " +
60 - " <if test='query != null'> AND (gs.app LIKE '%${query}%' OR gs.stream LIKE '%${query}%' OR gs.gbId LIKE '%${query}%' OR gs.name LIKE '%${query}%')</if> " + 60 + " <if test='query != null'> AND (gs.app LIKE concat('%',#{query},'%') OR gs.stream LIKE concat('%',#{query},'%') OR gs.gbId LIKE concat('%',#{query},'%') OR gs.name LIKE concat('%',#{query},'%'))</if> " +
61 " <if test='mediaServerId != null' > AND gs.mediaServerId=#{mediaServerId} </if>" + 61 " <if test='mediaServerId != null' > AND gs.mediaServerId=#{mediaServerId} </if>" +
62 " order by gs.gbStreamId asc " + 62 " order by gs.gbStreamId asc " +
63 "</script>") 63 "</script>")
@@ -71,7 +71,7 @@ public interface GbStreamMapper { @@ -71,7 +71,7 @@ public interface GbStreamMapper {
71 71
72 @Select("SELECT gs.*, pgs.platformId as platformId, pgs.catalogId as catalogId FROM gb_stream gs " + 72 @Select("SELECT gs.*, pgs.platformId as platformId, pgs.catalogId as catalogId FROM gb_stream gs " +
73 "LEFT JOIN platform_gb_stream pgs ON gs.gbStreamId = pgs.gbStreamId " + 73 "LEFT JOIN platform_gb_stream pgs ON gs.gbStreamId = pgs.gbStreamId " +
74 - "WHERE gs.gbId = '${gbId}' AND pgs.platformId = '${platformId}'") 74 + "WHERE gs.gbId = #{gbId} AND pgs.platformId = #{platformId}")
75 GbStream queryStreamInPlatform(String platformId, String gbId); 75 GbStream queryStreamInPlatform(String platformId, String gbId);
76 76
77 @Select("<script> "+ 77 @Select("<script> "+
@@ -122,9 +122,9 @@ public interface GbStreamMapper { @@ -122,9 +122,9 @@ public interface GbStreamMapper {
122 "longitude, latitude, streamType, mediaServerId, createTime)" + 122 "longitude, latitude, streamType, mediaServerId, createTime)" +
123 "values " + 123 "values " +
124 "<foreach collection='subList' index='index' item='item' separator=','> " + 124 "<foreach collection='subList' index='index' item='item' separator=','> " +
125 - "('${item.app}', '${item.stream}', '${item.gbId}', '${item.name}', " +  
126 - "'${item.longitude}', '${item.latitude}', '${item.streamType}', " +  
127 - "'${item.mediaServerId}', '${item.createTime}') "+ 125 + "(#{item.app}, #{item.stream}, #{item.gbId}, #{item.name}, " +
  126 + "#{item.longitude}, #{item.latitude}, #{item.streamType}, " +
  127 + "#{item.mediaServerId}, #{item.createTime}) "+
128 "</foreach> " + 128 "</foreach> " +
129 "</script>") 129 "</script>")
130 @Options(useGeneratedKeys = true, keyProperty = "gbStreamId", keyColumn = "gbStreamId") 130 @Options(useGeneratedKeys = true, keyProperty = "gbStreamId", keyColumn = "gbStreamId")
@@ -134,7 +134,7 @@ public interface GbStreamMapper { @@ -134,7 +134,7 @@ public interface GbStreamMapper {
134 "<foreach collection='gpsMsgInfos' item='item' separator=';'>" + 134 "<foreach collection='gpsMsgInfos' item='item' separator=';'>" +
135 " UPDATE" + 135 " UPDATE" +
136 " gb_stream" + 136 " gb_stream" +
137 - " SET longitude=${item.lng}, latitude=${item.lat} " + 137 + " SET longitude=#{item.lng}, latitude=#{item.lat} " +
138 "WHERE gbId=#{item.id}"+ 138 "WHERE gbId=#{item.id}"+
139 "</foreach>" + 139 "</foreach>" +
140 "</script>"}) 140 "</script>"})
src/main/java/com/genersoft/iot/vmp/storager/dao/LogMapper.java
@@ -18,16 +18,16 @@ import java.util.List; @@ -18,16 +18,16 @@ import java.util.List;
18 public interface LogMapper { 18 public interface LogMapper {
19 19
20 @Insert("insert into log ( name, type, uri, address, result, timing, username, createTime) " + 20 @Insert("insert into log ( name, type, uri, address, result, timing, username, createTime) " +
21 - "values ('${name}', '${type}', '${uri}', '${address}', '${result}', ${timing}, '${username}', '${createTime}')") 21 + "values (#{name}, #{type}, #{uri}, #{address}, #{result}, #{timing}, #{username}, #{createTime})")
22 int add(LogDto logDto); 22 int add(LogDto logDto);
23 23
24 @Select(value = {"<script>" + 24 @Select(value = {"<script>" +
25 " SELECT * FROM log " + 25 " SELECT * FROM log " +
26 " WHERE 1=1 " + 26 " WHERE 1=1 " +
27 - " <if test=\"query != null\"> AND (name LIKE '%${query}%')</if> " +  
28 - " <if test=\"type != null\" > AND type = '${type}'</if>" +  
29 - " <if test=\"startTime != null\" > AND createTime &gt;= '${startTime}' </if>" +  
30 - " <if test=\"endTime != null\" > AND createTime &lt;= '${endTime}' </if>" + 27 + " <if test=\"query != null\"> AND (name LIKE concat('%',#{query},'%'))</if> " +
  28 + " <if test=\"type != null\" > AND type = #{type}</if>" +
  29 + " <if test=\"startTime != null\" > AND createTime &gt;= #{startTime} </if>" +
  30 + " <if test=\"endTime != null\" > AND createTime &lt;= #{endTime} </if>" +
31 " ORDER BY createTime DESC " + 31 " ORDER BY createTime DESC " +
32 " </script>"}) 32 " </script>"})
33 List<LogDto> query(String query, String type, String startTime, String endTime); 33 List<LogDto> query(String query, String type, String startTime, String endTime);
src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java
@@ -35,92 +35,92 @@ public interface MediaServerMapper { @@ -35,92 +35,92 @@ public interface MediaServerMapper {
35 "hookAliveInterval" + 35 "hookAliveInterval" +
36 ") VALUES " + 36 ") VALUES " +
37 "(" + 37 "(" +
38 - "'${id}', " +  
39 - "'${ip}', " +  
40 - "'${hookIp}', " +  
41 - "'${sdpIp}', " +  
42 - "'${streamIp}', " +  
43 - "${httpPort}, " +  
44 - "${httpSSlPort}, " +  
45 - "${rtmpPort}, " +  
46 - "${rtmpSSlPort}, " +  
47 - "${rtpProxyPort}, " +  
48 - "${rtspPort}, " +  
49 - "${rtspSSLPort}, " +  
50 - "${autoConfig}, " +  
51 - "'${secret}', " +  
52 - "${rtpEnable}, " +  
53 - "'${rtpPortRange}', " +  
54 - "${recordAssistPort}, " +  
55 - "${defaultServer}, " +  
56 - "'${createTime}', " +  
57 - "'${updateTime}', " +  
58 - "${hookAliveInterval})") 38 + "#{id}, " +
  39 + "#{ip}, " +
  40 + "#{hookIp}, " +
  41 + "#{sdpIp}, " +
  42 + "#{streamIp}, " +
  43 + "#{httpPort}, " +
  44 + "#{httpSSlPort}, " +
  45 + "#{rtmpPort}, " +
  46 + "#{rtmpSSlPort}, " +
  47 + "#{rtpProxyPort}, " +
  48 + "#{rtspPort}, " +
  49 + "#{rtspSSLPort}, " +
  50 + "#{autoConfig}, " +
  51 + "#{secret}, " +
  52 + "#{rtpEnable}, " +
  53 + "#{rtpPortRange}, " +
  54 + "#{recordAssistPort}, " +
  55 + "#{defaultServer}, " +
  56 + "#{createTime}, " +
  57 + "#{updateTime}, " +
  58 + "#{hookAliveInterval})")
59 int add(MediaServerItem mediaServerItem); 59 int add(MediaServerItem mediaServerItem);
60 60
61 @Update(value = {" <script>" + 61 @Update(value = {" <script>" +
62 "UPDATE media_server " + 62 "UPDATE media_server " +
63 - "SET updateTime='${updateTime}'" +  
64 - "<if test=\"ip != null\">, ip='${ip}'</if>" +  
65 - "<if test=\"hookIp != null\">, hookIp='${hookIp}'</if>" +  
66 - "<if test=\"sdpIp != null\">, sdpIp='${sdpIp}'</if>" +  
67 - "<if test=\"streamIp != null\">, streamIp='${streamIp}'</if>" +  
68 - "<if test=\"httpPort != null\">, httpPort=${httpPort}</if>" +  
69 - "<if test=\"httpSSlPort != null\">, httpSSlPort=${httpSSlPort}</if>" +  
70 - "<if test=\"rtmpPort != null\">, rtmpPort=${rtmpPort}</if>" +  
71 - "<if test=\"rtmpSSlPort != null\">, rtmpSSlPort=${rtmpSSlPort}</if>" +  
72 - "<if test=\"rtpProxyPort != null\">, rtpProxyPort=${rtpProxyPort}</if>" +  
73 - "<if test=\"rtspPort != null\">, rtspPort=${rtspPort}</if>" +  
74 - "<if test=\"rtspSSLPort != null\">, rtspSSLPort=${rtspSSLPort}</if>" +  
75 - "<if test=\"autoConfig != null\">, autoConfig=${autoConfig}</if>" +  
76 - "<if test=\"rtpEnable != null\">, rtpEnable=${rtpEnable}</if>" +  
77 - "<if test=\"rtpPortRange != null\">, rtpPortRange='${rtpPortRange}'</if>" +  
78 - "<if test=\"secret != null\">, secret='${secret}'</if>" +  
79 - "<if test=\"recordAssistPort != null\">, recordAssistPort=${recordAssistPort}</if>" +  
80 - "<if test=\"hookAliveInterval != null\">, hookAliveInterval=${hookAliveInterval}</if>" +  
81 - "WHERE id='${id}'"+ 63 + "SET updateTime=#{updateTime}" +
  64 + "<if test=\"ip != null\">, ip=#{ip}</if>" +
  65 + "<if test=\"hookIp != null\">, hookIp=#{hookIp}</if>" +
  66 + "<if test=\"sdpIp != null\">, sdpIp=#{sdpIp}</if>" +
  67 + "<if test=\"streamIp != null\">, streamIp=#{streamIp}</if>" +
  68 + "<if test=\"httpPort != null\">, httpPort=#{httpPort}</if>" +
  69 + "<if test=\"httpSSlPort != null\">, httpSSlPort=#{httpSSlPort}</if>" +
  70 + "<if test=\"rtmpPort != null\">, rtmpPort=#{rtmpPort}</if>" +
  71 + "<if test=\"rtmpSSlPort != null\">, rtmpSSlPort=#{rtmpSSlPort}</if>" +
  72 + "<if test=\"rtpProxyPort != null\">, rtpProxyPort=#{rtpProxyPort}</if>" +
  73 + "<if test=\"rtspPort != null\">, rtspPort=#{rtspPort}</if>" +
  74 + "<if test=\"rtspSSLPort != null\">, rtspSSLPort=#{rtspSSLPort}</if>" +
  75 + "<if test=\"autoConfig != null\">, autoConfig=#{autoConfig}</if>" +
  76 + "<if test=\"rtpEnable != null\">, rtpEnable=#{rtpEnable}</if>" +
  77 + "<if test=\"rtpPortRange != null\">, rtpPortRange=#{rtpPortRange}</if>" +
  78 + "<if test=\"secret != null\">, secret=#{secret}</if>" +
  79 + "<if test=\"recordAssistPort != null\">, recordAssistPort=#{recordAssistPort}</if>" +
  80 + "<if test=\"hookAliveInterval != null\">, hookAliveInterval=#{hookAliveInterval}</if>" +
  81 + "WHERE id=#{id}"+
82 " </script>"}) 82 " </script>"})
83 int update(MediaServerItem mediaServerItem); 83 int update(MediaServerItem mediaServerItem);
84 84
85 @Update(value = {" <script>" + 85 @Update(value = {" <script>" +
86 "UPDATE media_server " + 86 "UPDATE media_server " +
87 - "SET updateTime='${updateTime}'" +  
88 - "<if test=\"id != null\">, id='${id}'</if>" +  
89 - "<if test=\"hookIp != null\">, hookIp='${hookIp}'</if>" +  
90 - "<if test=\"sdpIp != null\">, sdpIp='${sdpIp}'</if>" +  
91 - "<if test=\"streamIp != null\">, streamIp='${streamIp}'</if>" +  
92 - "<if test=\"httpSSlPort != null\">, httpSSlPort=${httpSSlPort}</if>" +  
93 - "<if test=\"rtmpPort != null\">, rtmpPort=${rtmpPort}</if>" +  
94 - "<if test=\"rtmpSSlPort != null\">, rtmpSSlPort=${rtmpSSlPort}</if>" +  
95 - "<if test=\"rtpProxyPort != null\">, rtpProxyPort=${rtpProxyPort}</if>" +  
96 - "<if test=\"rtspPort != null\">, rtspPort=${rtspPort}</if>" +  
97 - "<if test=\"rtspSSLPort != null\">, rtspSSLPort=${rtspSSLPort}</if>" +  
98 - "<if test=\"autoConfig != null\">, autoConfig=${autoConfig}</if>" +  
99 - "<if test=\"rtpEnable != null\">, rtpEnable=${rtpEnable}</if>" +  
100 - "<if test=\"rtpPortRange != null\">, rtpPortRange='${rtpPortRange}'</if>" +  
101 - "<if test=\"secret != null\">, secret='${secret}'</if>" +  
102 - "<if test=\"recordAssistPort != null\">, recordAssistPort=${recordAssistPort}</if>" +  
103 - "<if test=\"hookAliveInterval != null\">, hookAliveInterval=${hookAliveInterval}</if>" +  
104 - "WHERE ip='${ip}' and httpPort=${httpPort}"+ 87 + "SET updateTime=#{updateTime}" +
  88 + "<if test=\"id != null\">, id=#{id}</if>" +
  89 + "<if test=\"hookIp != null\">, hookIp=#{hookIp}</if>" +
  90 + "<if test=\"sdpIp != null\">, sdpIp=#{sdpIp}</if>" +
  91 + "<if test=\"streamIp != null\">, streamIp=#{streamIp}</if>" +
  92 + "<if test=\"httpSSlPort != null\">, httpSSlPort=#{httpSSlPort}</if>" +
  93 + "<if test=\"rtmpPort != null\">, rtmpPort=#{rtmpPort}</if>" +
  94 + "<if test=\"rtmpSSlPort != null\">, rtmpSSlPort=#{rtmpSSlPort}</if>" +
  95 + "<if test=\"rtpProxyPort != null\">, rtpProxyPort=#{rtpProxyPort}</if>" +
  96 + "<if test=\"rtspPort != null\">, rtspPort=#{rtspPort}</if>" +
  97 + "<if test=\"rtspSSLPort != null\">, rtspSSLPort=#{rtspSSLPort}</if>" +
  98 + "<if test=\"autoConfig != null\">, autoConfig=#{autoConfig}</if>" +
  99 + "<if test=\"rtpEnable != null\">, rtpEnable=#{rtpEnable}</if>" +
  100 + "<if test=\"rtpPortRange != null\">, rtpPortRange=#{rtpPortRange}</if>" +
  101 + "<if test=\"secret != null\">, secret=#{secret}</if>" +
  102 + "<if test=\"recordAssistPort != null\">, recordAssistPort=#{recordAssistPort}</if>" +
  103 + "<if test=\"hookAliveInterval != null\">, hookAliveInterval=#{hookAliveInterval}</if>" +
  104 + "WHERE ip=#{ip} and httpPort=#{httpPort}"+
105 " </script>"}) 105 " </script>"})
106 int updateByHostAndPort(MediaServerItem mediaServerItem); 106 int updateByHostAndPort(MediaServerItem mediaServerItem);
107 107
108 - @Select("SELECT * FROM media_server WHERE id='${id}'") 108 + @Select("SELECT * FROM media_server WHERE id=#{id}")
109 MediaServerItem queryOne(String id); 109 MediaServerItem queryOne(String id);
110 110
111 @Select("SELECT * FROM media_server") 111 @Select("SELECT * FROM media_server")
112 List<MediaServerItem> queryAll(); 112 List<MediaServerItem> queryAll();
113 113
114 - @Delete("DELETE FROM media_server WHERE id='${id}'") 114 + @Delete("DELETE FROM media_server WHERE id=#{id}")
115 void delOne(String id); 115 void delOne(String id);
116 116
117 - @Select("DELETE FROM media_server WHERE ip='${host}' and httpPort=${port}") 117 + @Select("DELETE FROM media_server WHERE ip=#{host} and httpPort=#{port}")
118 void delOneByIPAndPort(String host, int port); 118 void delOneByIPAndPort(String host, int port);
119 119
120 @Delete("DELETE FROM media_server WHERE defaultServer=1") 120 @Delete("DELETE FROM media_server WHERE defaultServer=1")
121 int delDefault(); 121 int delDefault();
122 122
123 - @Select("SELECT * FROM media_server WHERE ip='${host}' and httpPort=${port}") 123 + @Select("SELECT * FROM media_server WHERE ip=#{host} and httpPort=#{port}")
124 MediaServerItem queryOneByHostAndPort(String host, int port); 124 MediaServerItem queryOneByHostAndPort(String host, int port);
125 125
126 @Select("SELECT * FROM media_server WHERE defaultServer=1") 126 @Select("SELECT * FROM media_server WHERE defaultServer=1")
src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java
@@ -17,9 +17,9 @@ public interface ParentPlatformMapper { @@ -17,9 +17,9 @@ public interface ParentPlatformMapper {
17 @Insert("INSERT INTO parent_platform (enable, name, serverGBId, serverGBDomain, serverIP, serverPort, deviceGBId, deviceIp, " + 17 @Insert("INSERT INTO parent_platform (enable, name, serverGBId, serverGBDomain, serverIP, serverPort, deviceGBId, deviceIp, " +
18 " devicePort, username, password, expires, keepTimeout, transport, characterSet, ptz, rtcp, " + 18 " devicePort, username, password, expires, keepTimeout, transport, characterSet, ptz, rtcp, " +
19 " status, startOfflinePush, catalogId, administrativeDivision, catalogGroup, createTime, updateTime, treeType) " + 19 " status, startOfflinePush, catalogId, administrativeDivision, catalogGroup, createTime, updateTime, treeType) " +
20 - " VALUES (${enable}, '${name}', '${serverGBId}', '${serverGBDomain}', '${serverIP}', ${serverPort}, '${deviceGBId}', '${deviceIp}', " +  
21 - " '${devicePort}', '${username}', '${password}', '${expires}', '${keepTimeout}', '${transport}', '${characterSet}', ${ptz}, ${rtcp}, " +  
22 - " ${status}, ${startOfflinePush}, #{catalogId}, #{administrativeDivision}, #{catalogGroup}, #{createTime}, #{updateTime}, #{treeType})") 20 + " VALUES (#{enable}, #{name}, #{serverGBId}, #{serverGBDomain}, #{serverIP}, #{serverPort}, #{deviceGBId}, #{deviceIp}, " +
  21 + " #{devicePort}, #{username}, #{password}, #{expires}, #{keepTimeout}, #{transport}, #{characterSet}, #{ptz}, #{rtcp}, " +
  22 + " #{status}, #{startOfflinePush}, #{catalogId}, #{administrativeDivision}, #{catalogGroup}, #{createTime}, #{updateTime}, #{treeType})")
23 int addParentPlatform(ParentPlatform parentPlatform); 23 int addParentPlatform(ParentPlatform parentPlatform);
24 24
25 @Update("UPDATE parent_platform " + 25 @Update("UPDATE parent_platform " +
@@ -41,7 +41,7 @@ public interface ParentPlatformMapper { @@ -41,7 +41,7 @@ public interface ParentPlatformMapper {
41 "ptz=#{ptz}, " + 41 "ptz=#{ptz}, " +
42 "rtcp=#{rtcp}, " + 42 "rtcp=#{rtcp}, " +
43 "status=#{status}, " + 43 "status=#{status}, " +
44 - "startOfflinePush=${startOfflinePush}, " + 44 + "startOfflinePush=#{startOfflinePush}, " +
45 "catalogGroup=#{catalogGroup}, " + 45 "catalogGroup=#{catalogGroup}, " +
46 "administrativeDivision=#{administrativeDivision}, " + 46 "administrativeDivision=#{administrativeDivision}, " +
47 "createTime=#{createTime}, " + 47 "createTime=#{createTime}, " +
src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformChannelMapper.java
@@ -21,22 +21,22 @@ public interface PlatformChannelMapper { @@ -21,22 +21,22 @@ public interface PlatformChannelMapper {
21 * 查询列表里已经关联的 21 * 查询列表里已经关联的
22 */ 22 */
23 @Select("<script> "+ 23 @Select("<script> "+
24 - "SELECT deviceChannelId FROM platform_gb_channel WHERE platformId='${platformId}' AND deviceChannelId in" +  
25 - "<foreach collection='channelReduces' open='(' item='item' separator=',' close=')'> '${item.id}'</foreach>" + 24 + "SELECT deviceChannelId FROM platform_gb_channel WHERE platformId=#{platformId} AND deviceChannelId in" +
  25 + "<foreach collection='channelReduces' open='(' item='item' separator=',' close=')'> #{item.id}</foreach>" +
26 "</script>") 26 "</script>")
27 List<Integer> findChannelRelatedPlatform(String platformId, List<ChannelReduce> channelReduces); 27 List<Integer> findChannelRelatedPlatform(String platformId, List<ChannelReduce> channelReduces);
28 28
29 @Insert("<script> "+ 29 @Insert("<script> "+
30 "INSERT INTO platform_gb_channel (platformId, deviceChannelId, catalogId) VALUES" + 30 "INSERT INTO platform_gb_channel (platformId, deviceChannelId, catalogId) VALUES" +
31 "<foreach collection='channelReducesToAdd' item='item' separator=','>" + 31 "<foreach collection='channelReducesToAdd' item='item' separator=','>" +
32 - " ('${platformId}', '${item.id}' , '${item.catalogId}' )" + 32 + " (#{platformId}, #{item.id} , #{item.catalogId} )" +
33 "</foreach>" + 33 "</foreach>" +
34 "</script>") 34 "</script>")
35 int addChannels(String platformId, List<ChannelReduce> channelReducesToAdd); 35 int addChannels(String platformId, List<ChannelReduce> channelReducesToAdd);
36 36
37 @Delete("<script> "+ 37 @Delete("<script> "+
38 - "DELETE FROM platform_gb_channel WHERE platformId='${platformId}' AND deviceChannelId in" +  
39 - "<foreach collection='channelReducesToDel' item='item' open='(' separator=',' close=')' > '${item.id}'</foreach>" + 38 + "DELETE FROM platform_gb_channel WHERE platformId=#{platformId} AND deviceChannelId in" +
  39 + "<foreach collection='channelReducesToDel' item='item' open='(' separator=',' close=')' > #{item.id}</foreach>" +
40 "</script>") 40 "</script>")
41 int delChannelForGB(String platformId, List<ChannelReduce> channelReducesToDel); 41 int delChannelForGB(String platformId, List<ChannelReduce> channelReducesToDel);
42 42
@@ -50,14 +50,14 @@ public interface PlatformChannelMapper { @@ -50,14 +50,14 @@ public interface PlatformChannelMapper {
50 int delChannelForDeviceId(String deviceId); 50 int delChannelForDeviceId(String deviceId);
51 51
52 @Delete("<script> "+ 52 @Delete("<script> "+
53 - "DELETE FROM platform_gb_channel WHERE platformId='${platformId}'" + 53 + "DELETE FROM platform_gb_channel WHERE platformId=#{platformId}" +
54 "</script>") 54 "</script>")
55 int cleanChannelForGB(String platformId); 55 int cleanChannelForGB(String platformId);
56 56
57 - @Select("SELECT dc.* FROM platform_gb_channel pgc left join device_channel dc on dc.id = pgc.deviceChannelId WHERE dc.channelId='${channelId}' and pgc.platformId='${platformId}'") 57 + @Select("SELECT dc.* FROM platform_gb_channel pgc left join device_channel dc on dc.id = pgc.deviceChannelId WHERE dc.channelId=#{channelId} and pgc.platformId=#{platformId}")
58 List<DeviceChannel> queryChannelInParentPlatform(String platformId, String channelId); 58 List<DeviceChannel> queryChannelInParentPlatform(String platformId, String channelId);
59 59
60 - @Select("SELECT dc.* FROM platform_gb_channel pgc left join device_channel dc on dc.id = pgc.deviceChannelId WHERE pgc.platformId='${platformId}' and pgc.catalogId=#{catalogId}") 60 + @Select("SELECT dc.* FROM platform_gb_channel pgc left join device_channel dc on dc.id = pgc.deviceChannelId WHERE pgc.platformId=#{platformId} and pgc.catalogId=#{catalogId}")
61 List<DeviceChannel> queryAllChannelInCatalog(String platformId, String catalogId); 61 List<DeviceChannel> queryAllChannelInCatalog(String platformId, String catalogId);
62 62
63 @Select(" select dc.channelId as id, dc.name as name, pgc.platformId as platformId, pgc.catalogId as parentId, 0 as childrenCount, 1 as type " + 63 @Select(" select dc.channelId as id, dc.name as name, pgc.platformId as platformId, pgc.catalogId as parentId, 0 as childrenCount, 1 as type " +
src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformGbStreamMapper.java
@@ -26,7 +26,7 @@ public interface PlatformGbStreamMapper { @@ -26,7 +26,7 @@ public interface PlatformGbStreamMapper {
26 "(gbStreamId, platformId, catalogId) " + 26 "(gbStreamId, platformId, catalogId) " +
27 "values " + 27 "values " +
28 "<foreach collection='streamPushItems' index='index' item='item' separator=','> " + 28 "<foreach collection='streamPushItems' index='index' item='item' separator=','> " +
29 - "(${item.gbStreamId}, '${item.platformId}', '${item.catalogId}')" + 29 + "(#{item.gbStreamId}, #{item.platformId}, #{item.catalogId})" +
30 "</foreach> " + 30 "</foreach> " +
31 "</script>") 31 "</script>")
32 int batchAdd(List<StreamPushItem> streamPushItems); 32 int batchAdd(List<StreamPushItem> streamPushItems);
src/main/java/com/genersoft/iot/vmp/storager/dao/RecordInfoDao.java
@@ -14,10 +14,10 @@ import java.util.List; @@ -14,10 +14,10 @@ import java.util.List;
14 public interface RecordInfoDao { 14 public interface RecordInfoDao {
15 15
16 @Insert("INSERT INTO recordInfo (app, stream, mediaServerId, createTime, type, deviceId, channelId, name) VALUES" + 16 @Insert("INSERT INTO recordInfo (app, stream, mediaServerId, createTime, type, deviceId, channelId, name) VALUES" +
17 - "('${app}', '${stream}', '${mediaServerId}', datetime('now','localtime')), '${type}', '${deviceId}', '${channelId}', '${name}'") 17 + "(#{app}, #{stream}, #{mediaServerId}, datetime('now','localtime')), #{type}, #{deviceId}, #{channelId}, #{name}")
18 int add(RecordInfo recordInfo); 18 int add(RecordInfo recordInfo);
19 19
20 - @Delete("DELETE FROM user WHERE createTime < '${beforeTime}'") 20 + @Delete("DELETE FROM user WHERE createTime < #{beforeTime}")
21 int deleteBefore(String beforeTime); 21 int deleteBefore(String beforeTime);
22 22
23 @Select("select * FROM recordInfo") 23 @Select("select * FROM recordInfo")
src/main/java/com/genersoft/iot/vmp/storager/dao/RoleMapper.java
@@ -12,14 +12,14 @@ import java.util.List; @@ -12,14 +12,14 @@ import java.util.List;
12 public interface RoleMapper { 12 public interface RoleMapper {
13 13
14 @Insert("INSERT INTO user_role (name, authority, createTime, updateTime) VALUES" + 14 @Insert("INSERT INTO user_role (name, authority, createTime, updateTime) VALUES" +
15 - "('${name}', '${authority}', '${createTime}', '${updateTime}')") 15 + "(#{name}, #{authority}, #{createTime}, #{updateTime})")
16 int add(Role role); 16 int add(Role role);
17 17
18 @Update(value = {" <script>" + 18 @Update(value = {" <script>" +
19 "UPDATE user_role " + 19 "UPDATE user_role " +
20 - "SET updateTime='${updateTime}' " +  
21 - "<if test=\"name != null\">, name='${name}'</if>" +  
22 - "<if test=\"authority != null\">, authority='${authority}'</if>" + 20 + "SET updateTime=#{updateTime} " +
  21 + "<if test=\"name != null\">, name=#{name}</if>" +
  22 + "<if test=\"authority != null\">, authority=#{authority}</if>" +
23 "WHERE id != 1 and id=#{id}" + 23 "WHERE id != 1 and id=#{id}" +
24 " </script>"}) 24 " </script>"})
25 int update(Role role); 25 int update(Role role);
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java
@@ -13,9 +13,9 @@ public interface StreamProxyMapper { @@ -13,9 +13,9 @@ public interface StreamProxyMapper {
13 13
14 @Insert("INSERT INTO stream_proxy (type, name, app, stream,mediaServerId, url, src_url, dst_url, " + 14 @Insert("INSERT INTO stream_proxy (type, name, app, stream,mediaServerId, url, src_url, dst_url, " +
15 "timeout_ms, ffmpeg_cmd_key, rtp_type, enable_audio, enable_mp4, enable, status, enable_remove_none_reader, enable_disable_none_reader, createTime) VALUES" + 15 "timeout_ms, ffmpeg_cmd_key, rtp_type, enable_audio, enable_mp4, enable, status, enable_remove_none_reader, enable_disable_none_reader, createTime) VALUES" +
16 - "('${type}','${name}', '${app}', '${stream}', '${mediaServerId}','${url}', '${src_url}', '${dst_url}', " +  
17 - "'${timeout_ms}', '${ffmpeg_cmd_key}', '${rtp_type}', ${enable_audio}, ${enable_mp4}, ${enable}, ${status}, " +  
18 - "${enable_remove_none_reader}, ${enable_disable_none_reader}, '${createTime}' )") 16 + "(#{type}, #{name}, #{app}, #{stream}, #{mediaServerId}, #{url}, #{src_url}, #{dst_url}, " +
  17 + "#{timeout_ms}, #{ffmpeg_cmd_key}, #{rtp_type}, #{enable_audio}, #{enable_mp4}, #{enable}, #{status}, " +
  18 + "#{enable_remove_none_reader}, #{enable_disable_none_reader}, #{createTime} )")
19 int add(StreamProxyItem streamProxyDto); 19 int add(StreamProxyItem streamProxyDto);
20 20
21 @Update("UPDATE stream_proxy " + 21 @Update("UPDATE stream_proxy " +
@@ -45,7 +45,7 @@ public interface StreamProxyMapper { @@ -45,7 +45,7 @@ public interface StreamProxyMapper {
45 @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream order by st.createTime desc") 45 @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream order by st.createTime desc")
46 List<StreamProxyItem> selectAll(); 46 List<StreamProxyItem> selectAll();
47 47
48 - @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream WHERE st.enable=${enable} order by st.createTime desc") 48 + @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream WHERE st.enable=#{enable} order by st.createTime desc")
49 List<StreamProxyItem> selectForEnable(boolean enable); 49 List<StreamProxyItem> selectForEnable(boolean enable);
50 50
51 @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream WHERE st.app=#{app} AND st.stream=#{stream} order by st.createTime desc") 51 @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream WHERE st.app=#{app} AND st.stream=#{stream} order by st.createTime desc")
@@ -53,12 +53,12 @@ public interface StreamProxyMapper { @@ -53,12 +53,12 @@ public interface StreamProxyMapper {
53 53
54 @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st " + 54 @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st " +
55 "LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream " + 55 "LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream " +
56 - "WHERE st.enable=${enable} and st.mediaServerId = #{id} order by st.createTime desc") 56 + "WHERE st.enable=#{enable} and st.mediaServerId = #{id} order by st.createTime desc")
57 List<StreamProxyItem> selectForEnableInMediaServer(String id, boolean enable); 57 List<StreamProxyItem> selectForEnableInMediaServer(String id, boolean enable);
58 58
59 @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st " + 59 @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st " +
60 "LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream " + 60 "LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream " +
61 - "WHERE st.mediaServerId = '${id}' order by st.createTime desc") 61 + "WHERE st.mediaServerId = #{id} order by st.createTime desc")
62 List<StreamProxyItem> selectInMediaServer(String id); 62 List<StreamProxyItem> selectInMediaServer(String id);
63 63
64 @Update("UPDATE stream_proxy " + 64 @Update("UPDATE stream_proxy " +
@@ -67,7 +67,7 @@ public interface StreamProxyMapper { @@ -67,7 +67,7 @@ public interface StreamProxyMapper {
67 void updateStatusByMediaServerId(String mediaServerId, boolean status); 67 void updateStatusByMediaServerId(String mediaServerId, boolean status);
68 68
69 @Update("UPDATE stream_proxy " + 69 @Update("UPDATE stream_proxy " +
70 - "SET status=${status} " + 70 + "SET status=#{status} " +
71 "WHERE app=#{app} AND stream=#{stream}") 71 "WHERE app=#{app} AND stream=#{stream}")
72 int updateStatus(String app, String stream, boolean status); 72 int updateStatus(String app, String stream, boolean status);
73 73
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamPushMapper.java
@@ -17,23 +17,23 @@ public interface StreamPushMapper { @@ -17,23 +17,23 @@ public interface StreamPushMapper {
17 17
18 @Insert("INSERT INTO stream_push (app, stream, totalReaderCount, originType, originTypeStr, " + 18 @Insert("INSERT INTO stream_push (app, stream, totalReaderCount, originType, originTypeStr, " +
19 "pushTime, aliveSecond, mediaServerId, serverId, updateTime, createTime, pushIng, self) VALUES" + 19 "pushTime, aliveSecond, mediaServerId, serverId, updateTime, createTime, pushIng, self) VALUES" +
20 - "('${app}', '${stream}', '${totalReaderCount}', '${originType}', '${originTypeStr}', " +  
21 - "'${pushTime}', '${aliveSecond}', '${mediaServerId}' , '${serverId}' , '${updateTime}' , '${createTime}', " +  
22 - "${pushIng}, ${self} )") 20 + "(#{app}, #{stream}, #{totalReaderCount}, #{originType}, #{originTypeStr}, " +
  21 + "#{pushTime}, #{aliveSecond}, #{mediaServerId} , #{serverId} , #{updateTime} , #{createTime}, " +
  22 + "#{pushIng}, #{self} )")
23 int add(StreamPushItem streamPushItem); 23 int add(StreamPushItem streamPushItem);
24 24
25 25
26 @Update(value = {" <script>" + 26 @Update(value = {" <script>" +
27 "UPDATE stream_push " + 27 "UPDATE stream_push " +
28 - "SET updateTime='${updateTime}'" +  
29 - "<if test=\"mediaServerId != null\">, mediaServerId='${mediaServerId}'</if>" +  
30 - "<if test=\"totalReaderCount != null\">, totalReaderCount='${totalReaderCount}'</if>" +  
31 - "<if test=\"originType != null\">, originType=${originType}</if>" +  
32 - "<if test=\"originTypeStr != null\">, originTypeStr='${originTypeStr}'</if>" +  
33 - "<if test=\"pushTime != null\">, pushTime='${pushTime}'</if>" +  
34 - "<if test=\"aliveSecond != null\">, aliveSecond='${aliveSecond}'</if>" +  
35 - "<if test=\"pushIng != null\">, pushIng=${pushIng}</if>" +  
36 - "<if test=\"self != null\">, self=${self}</if>" + 28 + "SET updateTime=#{updateTime}" +
  29 + "<if test=\"mediaServerId != null\">, mediaServerId=#{mediaServerId}</if>" +
  30 + "<if test=\"totalReaderCount != null\">, totalReaderCount=#{totalReaderCount}</if>" +
  31 + "<if test=\"originType != null\">, originType=#{originType}</if>" +
  32 + "<if test=\"originTypeStr != null\">, originTypeStr=#{originTypeStr}</if>" +
  33 + "<if test=\"pushTime != null\">, pushTime=#{pushTime}</if>" +
  34 + "<if test=\"aliveSecond != null\">, aliveSecond=#{aliveSecond}</if>" +
  35 + "<if test=\"pushIng != null\">, pushIng=#{pushIng}</if>" +
  36 + "<if test=\"self != null\">, self=#{self}</if>" +
37 "WHERE app=#{app} AND stream=#{stream}"+ 37 "WHERE app=#{app} AND stream=#{stream}"+
38 " </script>"}) 38 " </script>"})
39 int update(StreamPushItem streamPushItem); 39 int update(StreamPushItem streamPushItem);
@@ -76,7 +76,7 @@ public interface StreamPushMapper { @@ -76,7 +76,7 @@ public interface StreamPushMapper {
76 "on st.app = gs.app AND st.stream = gs.stream " + 76 "on st.app = gs.app AND st.stream = gs.stream " +
77 "WHERE " + 77 "WHERE " +
78 "1=1 " + 78 "1=1 " +
79 - " <if test='query != null'> AND (st.app LIKE '%${query}%' OR st.stream LIKE '%${query}%' OR gs.gbId LIKE '%${query}%' OR gs.name LIKE '%${query}%')</if> " + 79 + " <if test='query != null'> AND (st.app LIKE concat('%',#{query},'%') OR st.stream LIKE concat('%',#{query},'%') OR gs.gbId LIKE concat('%',#{query},'%') OR gs.name LIKE concat('%',#{query},'%'))</if> " +
80 " <if test='pushing == true' > AND (gs.gbId is null OR st.pushIng=1)</if>" + 80 " <if test='pushing == true' > AND (gs.gbId is null OR st.pushIng=1)</if>" +
81 " <if test='pushing == false' > AND (st.pushIng is null OR st.pushIng=0) </if>" + 81 " <if test='pushing == false' > AND (st.pushIng is null OR st.pushIng=0) </if>" +
82 " <if test='mediaServerId != null' > AND st.mediaServerId=#{mediaServerId} </if>" + 82 " <if test='mediaServerId != null' > AND st.mediaServerId=#{mediaServerId} </if>" +
@@ -94,9 +94,9 @@ public interface StreamPushMapper { @@ -94,9 +94,9 @@ public interface StreamPushMapper {
94 "Insert IGNORE INTO stream_push (app, stream, totalReaderCount, originType, originTypeStr, " + 94 "Insert IGNORE INTO stream_push (app, stream, totalReaderCount, originType, originTypeStr, " +
95 "createTime, aliveSecond, mediaServerId, status, pushIng) " + 95 "createTime, aliveSecond, mediaServerId, status, pushIng) " +
96 "VALUES <foreach collection='streamPushItems' item='item' index='index' separator=','>" + 96 "VALUES <foreach collection='streamPushItems' item='item' index='index' separator=','>" +
97 - "( '${item.app}', '${item.stream}', '${item.totalReaderCount}', #{item.originType}, " +  
98 - "'${item.originTypeStr}',#{item.createTime}, #{item.aliveSecond}, '${item.mediaServerId}', ${item.status} ," +  
99 - " ${item.pushIng} )" + 97 + "( #{item.app}, #{item.stream}, #{item.totalReaderCount}, #{item.originType}, " +
  98 + "#{item.originTypeStr},#{item.createTime}, #{item.aliveSecond}, #{item.mediaServerId}, #{item.status} ," +
  99 + " #{item.pushIng} )" +
100 " </foreach>" + 100 " </foreach>" +
101 "</script>") 101 "</script>")
102 @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id") 102 @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
@@ -115,12 +115,12 @@ public interface StreamPushMapper { @@ -115,12 +115,12 @@ public interface StreamPushMapper {
115 List<StreamPushItem> selectAllByMediaServerIdWithOutGbID(String mediaServerId); 115 List<StreamPushItem> selectAllByMediaServerIdWithOutGbID(String mediaServerId);
116 116
117 @Update("UPDATE stream_push " + 117 @Update("UPDATE stream_push " +
118 - "SET status=${status} " + 118 + "SET status=#{status} " +
119 "WHERE app=#{app} AND stream=#{stream}") 119 "WHERE app=#{app} AND stream=#{stream}")
120 int updateStatus(String app, String stream, boolean status); 120 int updateStatus(String app, String stream, boolean status);
121 121
122 @Update("UPDATE stream_push " + 122 @Update("UPDATE stream_push " +
123 - "SET pushIng=${pushIng} " + 123 + "SET pushIng=#{pushIng} " +
124 "WHERE app=#{app} AND stream=#{stream}") 124 "WHERE app=#{app} AND stream=#{stream}")
125 int updatePushStatus(String app, String stream, boolean pushIng); 125 int updatePushStatus(String app, String stream, boolean pushIng);
126 126
src/main/java/com/genersoft/iot/vmp/storager/dao/UserMapper.java
@@ -11,16 +11,16 @@ import java.util.List; @@ -11,16 +11,16 @@ import java.util.List;
11 public interface UserMapper { 11 public interface UserMapper {
12 12
13 @Insert("INSERT INTO user (username, password, roleId, pushKey, createTime, updateTime) VALUES" + 13 @Insert("INSERT INTO user (username, password, roleId, pushKey, createTime, updateTime) VALUES" +
14 - "('${username}', '${password}', '${role.id}', '${pushKey}', '${createTime}', '${updateTime}')") 14 + "(#{username}, #{password}, #{role.id}, #{pushKey}, #{createTime}, #{updateTime})")
15 int add(User user); 15 int add(User user);
16 16
17 @Update(value = {" <script>" + 17 @Update(value = {" <script>" +
18 "UPDATE user " + 18 "UPDATE user " +
19 - "SET updateTime='${updateTime}' " +  
20 - "<if test=\"pushKey != null\">, pushKey='${pushKey}'</if>" +  
21 - "<if test=\"role != null\">, roleId='${role.id}'</if>" +  
22 - "<if test=\"password != null\">, password='${password}'</if>" +  
23 - "<if test=\"username != null\">, username='${username}'</if>" + 19 + "SET updateTime=#{updateTime} " +
  20 + "<if test=\"pushKey != null\">, pushKey=#{pushKey}</if>" +
  21 + "<if test=\"role != null\">, roleId=#{role.id}</if>" +
  22 + "<if test=\"password != null\">, password=#{password}</if>" +
  23 + "<if test=\"username != null\">, username=#{username}</if>" +
24 "WHERE id=#{id}" + 24 "WHERE id=#{id}" +
25 " </script>"}) 25 " </script>"})
26 int update(User user); 26 int update(User user);
@@ -50,10 +50,10 @@ public interface UserMapper { @@ -50,10 +50,10 @@ public interface UserMapper {
50 @ResultMap(value="roleMap") 50 @ResultMap(value="roleMap")
51 List<User> selectAll(); 51 List<User> selectAll();
52 52
53 - @Select("select * from (select user.*, concat('${callId}_', pushKey) as str1 from user) as u where md5(u.str1) = '${sign}'") 53 + @Select("select * from (select user.*, concat(concat(#{callId}, '_'), pushKey) as str1 from user) as u where md5(u.str1) = #{sign}")
54 List<User> checkPushAuthorityByCallIdAndSign(String callId, String sign); 54 List<User> checkPushAuthorityByCallIdAndSign(String callId, String sign);
55 55
56 - @Select("select * from user where md5(pushKey) = '${sign}'") 56 + @Select("select * from user where md5(pushKey) = #{sign}")
57 List<User> checkPushAuthorityByCallId(String sign); 57 List<User> checkPushAuthorityByCallId(String sign);
58 58
59 @Select("select u.id, u.username,u.pushKey,u.roleId, r.id as roleID, r.name as roleName, r.authority as roleAuthority , r.createTime as roleCreateTime , r.updateTime as roleUpdateTime FROM user u join user_role r on u.roleId=r.id") 59 @Select("select u.id, u.username,u.pushKey,u.roleId, r.id as roleID, r.name as roleName, r.authority as roleAuthority , r.createTime as roleCreateTime , r.updateTime as roleUpdateTime FROM user u join user_role r on u.roleId=r.id")
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java
@@ -224,31 +224,31 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { @@ -224,31 +224,31 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
224 PageHelper.startPage(page, count); 224 PageHelper.startPage(page, count);
225 List<DeviceChannel> all; 225 List<DeviceChannel> all;
226 if (catalogUnderDevice != null && catalogUnderDevice) { 226 if (catalogUnderDevice != null && catalogUnderDevice) {
227 - all = deviceChannelMapper.queryChannels(deviceId, deviceId, query, hasSubChannel, online); 227 + all = deviceChannelMapper.queryChannels(deviceId, deviceId, query, hasSubChannel, online,null);
228 // 海康设备的parentId是SIP id 228 // 海康设备的parentId是SIP id
229 - List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, sipConfig.getId(), query, hasSubChannel, online); 229 + List<DeviceChannel> deviceChannels = deviceChannelMapper.queryChannels(deviceId, sipConfig.getId(), query, hasSubChannel, online,null);
230 all.addAll(deviceChannels); 230 all.addAll(deviceChannels);
231 }else { 231 }else {
232 - all = deviceChannelMapper.queryChannels(deviceId, null, query, hasSubChannel, online); 232 + all = deviceChannelMapper.queryChannels(deviceId, null, query, hasSubChannel, online,null);
233 } 233 }
234 return new PageInfo<>(all); 234 return new PageInfo<>(all);
235 } 235 }
236 236
237 @Override 237 @Override
238 - public List<DeviceChannel> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, String query, Boolean hasSubChannel, Boolean online, int start, int limit) {  
239 - return deviceChannelMapper.queryChannelsByDeviceIdWithStartAndLimit(deviceId, null, query, hasSubChannel, online, start, limit); 238 + public List<DeviceChannel> queryChannelsByDeviceIdWithStartAndLimit(String deviceId, String query, Boolean hasSubChannel, Boolean online, int start, int limit,List<String> channelIds) {
  239 + return deviceChannelMapper.queryChannelsByDeviceIdWithStartAndLimit(deviceId, null, query, hasSubChannel, online, start, limit,channelIds);
240 } 240 }
241 241
242 242
243 @Override 243 @Override
244 - public List<DeviceChannel> queryChannelsByDeviceId(String deviceId) {  
245 - return deviceChannelMapper.queryChannels(deviceId, null,null, null, null); 244 + public List<DeviceChannel> queryChannelsByDeviceId(String deviceId,Boolean online,List<String> channelIds) {
  245 + return deviceChannelMapper.queryChannels(deviceId, null,null, null, online,channelIds);
246 } 246 }
247 247
248 @Override 248 @Override
249 public PageInfo<DeviceChannel> querySubChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, Boolean online, int page, int count) { 249 public PageInfo<DeviceChannel> querySubChannels(String deviceId, String parentChannelId, String query, Boolean hasSubChannel, Boolean online, int page, int count) {
250 PageHelper.startPage(page, count); 250 PageHelper.startPage(page, count);
251 - List<DeviceChannel> all = deviceChannelMapper.queryChannels(deviceId, parentChannelId, query, hasSubChannel, online); 251 + List<DeviceChannel> all = deviceChannelMapper.queryChannels(deviceId, parentChannelId, query, hasSubChannel, online,null);
252 return new PageInfo<>(all); 252 return new PageInfo<>(all);
253 } 253 }
254 254
@@ -271,9 +271,9 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { @@ -271,9 +271,9 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
271 * @return PageInfo<Device> 分页设备对象数组 271 * @return PageInfo<Device> 分页设备对象数组
272 */ 272 */
273 @Override 273 @Override
274 - public PageInfo<Device> queryVideoDeviceList(int page, int count) { 274 + public PageInfo<Device> queryVideoDeviceList(int page, int count,Boolean online) {
275 PageHelper.startPage(page, count); 275 PageHelper.startPage(page, count);
276 - List<Device> all = deviceMapper.getDevices(); 276 + List<Device> all = deviceMapper.getDevices(online);
277 return new PageInfo<>(all); 277 return new PageInfo<>(all);
278 } 278 }
279 279
@@ -283,9 +283,9 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { @@ -283,9 +283,9 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
283 * @return List<Device> 设备对象数组 283 * @return List<Device> 设备对象数组
284 */ 284 */
285 @Override 285 @Override
286 - public List<Device> queryVideoDeviceList() { 286 + public List<Device> queryVideoDeviceList(Boolean online) {
287 287
288 - List<Device> deviceList = deviceMapper.getDevices(); 288 + List<Device> deviceList = deviceMapper.getDevices(online);
289 return deviceList; 289 return deviceList;
290 } 290 }
291 291
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
1 package com.genersoft.iot.vmp.utils.redis; 1 package com.genersoft.iot.vmp.utils.redis;
2 2
3 -import java.util.*;  
4 -import java.util.concurrent.TimeUnit;  
5 -  
6 import com.alibaba.fastjson2.JSONObject; 3 import com.alibaba.fastjson2.JSONObject;
7 import com.genersoft.iot.vmp.utils.SpringBeanFactory; 4 import com.genersoft.iot.vmp.utils.SpringBeanFactory;
8 -import gov.nist.javax.sip.stack.UDPMessageChannel;  
9 import org.springframework.data.redis.core.*; 5 import org.springframework.data.redis.core.*;
10 import org.springframework.util.CollectionUtils; 6 import org.springframework.util.CollectionUtils;
11 7
  8 +import java.util.*;
  9 +import java.util.concurrent.TimeUnit;
  10 +
12 /** 11 /**
13 * Redis工具类 12 * Redis工具类
14 * @author swwheihei 13 * @author swwheihei
src/main/java/com/genersoft/iot/vmp/vmanager/bean/AudioBroadcastResult.java
1 package com.genersoft.iot.vmp.vmanager.bean; 1 package com.genersoft.iot.vmp.vmanager.bean;
2 2
3 -import com.genersoft.iot.vmp.common.StreamInfo;  
4 -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;  
5 -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItemLite;  
6 -  
7 /** 3 /**
8 * @author lin 4 * @author lin
9 */ 5 */
@@ -11,7 +7,7 @@ public class AudioBroadcastResult { @@ -11,7 +7,7 @@ public class AudioBroadcastResult {
11 /** 7 /**
12 * 推流的各个方式流地址 8 * 推流的各个方式流地址
13 */ 9 */
14 - private StreamInfo streamInfo; 10 + private StreamContent streamInfo;
15 11
16 /** 12 /**
17 * 编码格式 13 * 编码格式
@@ -29,11 +25,11 @@ public class AudioBroadcastResult { @@ -29,11 +25,11 @@ public class AudioBroadcastResult {
29 private String stream; 25 private String stream;
30 26
31 27
32 - public StreamInfo getStreamInfo() { 28 + public StreamContent getStreamInfo() {
33 return streamInfo; 29 return streamInfo;
34 } 30 }
35 31
36 - public void setStreamInfo(StreamInfo streamInfo) { 32 + public void setStreamInfo(StreamContent streamInfo) {
37 this.streamInfo = streamInfo; 33 this.streamInfo = streamInfo;
38 } 34 }
39 35
src/main/java/com/genersoft/iot/vmp/vmanager/bean/ErrorCode.java
1 package com.genersoft.iot.vmp.vmanager.bean; 1 package com.genersoft.iot.vmp.vmanager.bean;
2 2
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -  
5 /** 3 /**
6 * 全局错误码 4 * 全局错误码
7 */ 5 */
@@ -9,6 +7,7 @@ public enum ErrorCode { @@ -9,6 +7,7 @@ public enum ErrorCode {
9 SUCCESS(0, "成功"), 7 SUCCESS(0, "成功"),
10 ERROR100(100, "失败"), 8 ERROR100(100, "失败"),
11 ERROR400(400, "参数不全或者错误"), 9 ERROR400(400, "参数不全或者错误"),
  10 + ERROR404(404, "资源未找到"),
12 ERROR403(403, "无权限操作"), 11 ERROR403(403, "无权限操作"),
13 ERROR401(401, "请登录后重新请求"), 12 ERROR401(401, "请登录后重新请求"),
14 ERROR500(500, "系统异常"); 13 ERROR500(500, "系统异常");
src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.bean;
  2 +
  3 +import com.genersoft.iot.vmp.common.StreamInfo;
  4 +
  5 +public class StreamContent {
  6 +
  7 + private String app;
  8 + private String stream;
  9 +
  10 + private String ip;
  11 +
  12 + private String flv;
  13 +
  14 + private String https_flv;
  15 + private String ws_flv;
  16 + private String wss_flv;
  17 + private String fmp4;
  18 + private String https_fmp4;
  19 + private String ws_fmp4;
  20 + private String wss_fmp4;
  21 + private String hls;
  22 + private String https_hls;
  23 + private String ws_hls;
  24 + private String wss_hls;
  25 + private String ts;
  26 + private String https_ts;
  27 + private String ws_ts;
  28 + private String wss_ts;
  29 + private String rtmp;
  30 + private String rtmps;
  31 + private String rtsp;
  32 + private String rtsps;
  33 + private String rtc;
  34 +
  35 + private String rtcs;
  36 + private String mediaServerId;
  37 + private Object tracks;
  38 +
  39 + private String startTime;
  40 +
  41 + private String endTime;
  42 +
  43 + private double progress;
  44 +
  45 + public StreamContent(StreamInfo streamInfo) {
  46 + if (streamInfo == null) {
  47 + return;
  48 + }
  49 + this.app = streamInfo.getApp();
  50 + this.stream = streamInfo.getStream();
  51 + if (streamInfo.getFlv() != null) {
  52 + this.flv = streamInfo.getFlv().getUrl();
  53 + }
  54 + if (streamInfo.getHttps_flv() != null) {
  55 + this.https_flv = streamInfo.getHttps_flv().getUrl();
  56 + }
  57 + if (streamInfo.getWs_flv() != null) {
  58 + this.ws_flv = streamInfo.getWs_flv().getUrl();
  59 + }
  60 + if (streamInfo.getWss_flv() != null) {
  61 + this.wss_flv = streamInfo.getWss_flv().getUrl();
  62 + }
  63 + if (streamInfo.getFmp4() != null) {
  64 + this.fmp4 = streamInfo.getFmp4().getUrl();
  65 + }
  66 + if (streamInfo.getWs_fmp4() != null) {
  67 + this.ws_fmp4 = streamInfo.getWs_fmp4().getUrl();
  68 + }
  69 + if (streamInfo.getWss_fmp4() != null) {
  70 + this.wss_fmp4 = streamInfo.getWss_fmp4().getUrl();
  71 + }
  72 + if (streamInfo.getHls() != null) {
  73 + this.hls = streamInfo.getHls().getUrl();
  74 + }
  75 + if (streamInfo.getHttps_hls() != null) {
  76 + this.https_hls = streamInfo.getHttps_hls().getUrl();
  77 + }
  78 + if (streamInfo.getWs_hls() != null) {
  79 + this.ws_hls = streamInfo.getWs_hls().getUrl();
  80 + }
  81 + if (streamInfo.getWss_hls() != null) {
  82 + this.wss_hls = streamInfo.getWss_hls().getUrl();
  83 + }
  84 + if (streamInfo.getTs() != null) {
  85 + this.ts = streamInfo.getTs().getUrl();
  86 + }
  87 + if (streamInfo.getHttps_ts() != null) {
  88 + this.https_ts = streamInfo.getHttps_ts().getUrl();
  89 + }
  90 + if (streamInfo.getWs_ts() != null) {
  91 + this.ws_ts = streamInfo.getWs_ts().getUrl();
  92 + }
  93 + if (streamInfo.getRtmp() != null) {
  94 + this.rtmp = streamInfo.getRtmp().getUrl();
  95 + }
  96 + if (streamInfo.getRtmps() != null) {
  97 + this.rtmps = streamInfo.getRtmps().getUrl();
  98 + }
  99 + if (streamInfo.getRtsp() != null) {
  100 + this.rtsp = streamInfo.getRtsp().getUrl();
  101 + }
  102 + if (streamInfo.getRtsps() != null) {
  103 + this.rtsps = streamInfo.getRtsps().getUrl();
  104 + }
  105 + if (streamInfo.getRtc() != null) {
  106 + this.rtc = streamInfo.getRtc().getUrl();
  107 + }
  108 + if (streamInfo.getRtcs() != null) {
  109 + this.rtcs = streamInfo.getRtcs().getUrl();
  110 + }
  111 +
  112 + this.mediaServerId = streamInfo.getMediaServerId();
  113 + this.tracks = streamInfo.getTracks();
  114 + this.startTime = streamInfo.getStartTime();
  115 + this.endTime = streamInfo.getEndTime();
  116 + this.progress = streamInfo.getProgress();
  117 + }
  118 +
  119 + public String getApp() {
  120 + return app;
  121 + }
  122 +
  123 + public void setApp(String app) {
  124 + this.app = app;
  125 + }
  126 +
  127 + public String getStream() {
  128 + return stream;
  129 + }
  130 +
  131 + public void setStream(String stream) {
  132 + this.stream = stream;
  133 + }
  134 +
  135 + public String getIp() {
  136 + return ip;
  137 + }
  138 +
  139 + public void setIp(String ip) {
  140 + this.ip = ip;
  141 + }
  142 +
  143 + public String getFlv() {
  144 + return flv;
  145 + }
  146 +
  147 + public void setFlv(String flv) {
  148 + this.flv = flv;
  149 + }
  150 +
  151 + public String getHttps_flv() {
  152 + return https_flv;
  153 + }
  154 +
  155 + public void setHttps_flv(String https_flv) {
  156 + this.https_flv = https_flv;
  157 + }
  158 +
  159 + public String getWs_flv() {
  160 + return ws_flv;
  161 + }
  162 +
  163 + public void setWs_flv(String ws_flv) {
  164 + this.ws_flv = ws_flv;
  165 + }
  166 +
  167 + public String getWss_flv() {
  168 + return wss_flv;
  169 + }
  170 +
  171 + public void setWss_flv(String wss_flv) {
  172 + this.wss_flv = wss_flv;
  173 + }
  174 +
  175 + public String getFmp4() {
  176 + return fmp4;
  177 + }
  178 +
  179 + public void setFmp4(String fmp4) {
  180 + this.fmp4 = fmp4;
  181 + }
  182 +
  183 + public String getHttps_fmp4() {
  184 + return https_fmp4;
  185 + }
  186 +
  187 + public void setHttps_fmp4(String https_fmp4) {
  188 + this.https_fmp4 = https_fmp4;
  189 + }
  190 +
  191 + public String getWs_fmp4() {
  192 + return ws_fmp4;
  193 + }
  194 +
  195 + public void setWs_fmp4(String ws_fmp4) {
  196 + this.ws_fmp4 = ws_fmp4;
  197 + }
  198 +
  199 + public String getWss_fmp4() {
  200 + return wss_fmp4;
  201 + }
  202 +
  203 + public void setWss_fmp4(String wss_fmp4) {
  204 + this.wss_fmp4 = wss_fmp4;
  205 + }
  206 +
  207 + public String getHls() {
  208 + return hls;
  209 + }
  210 +
  211 + public void setHls(String hls) {
  212 + this.hls = hls;
  213 + }
  214 +
  215 + public String getHttps_hls() {
  216 + return https_hls;
  217 + }
  218 +
  219 + public void setHttps_hls(String https_hls) {
  220 + this.https_hls = https_hls;
  221 + }
  222 +
  223 + public String getWs_hls() {
  224 + return ws_hls;
  225 + }
  226 +
  227 + public void setWs_hls(String ws_hls) {
  228 + this.ws_hls = ws_hls;
  229 + }
  230 +
  231 + public String getWss_hls() {
  232 + return wss_hls;
  233 + }
  234 +
  235 + public void setWss_hls(String wss_hls) {
  236 + this.wss_hls = wss_hls;
  237 + }
  238 +
  239 + public String getTs() {
  240 + return ts;
  241 + }
  242 +
  243 + public void setTs(String ts) {
  244 + this.ts = ts;
  245 + }
  246 +
  247 + public String getHttps_ts() {
  248 + return https_ts;
  249 + }
  250 +
  251 + public void setHttps_ts(String https_ts) {
  252 + this.https_ts = https_ts;
  253 + }
  254 +
  255 + public String getWs_ts() {
  256 + return ws_ts;
  257 + }
  258 +
  259 + public void setWs_ts(String ws_ts) {
  260 + this.ws_ts = ws_ts;
  261 + }
  262 +
  263 + public String getWss_ts() {
  264 + return wss_ts;
  265 + }
  266 +
  267 + public void setWss_ts(String wss_ts) {
  268 + this.wss_ts = wss_ts;
  269 + }
  270 +
  271 + public String getRtmp() {
  272 + return rtmp;
  273 + }
  274 +
  275 + public void setRtmp(String rtmp) {
  276 + this.rtmp = rtmp;
  277 + }
  278 +
  279 + public String getRtmps() {
  280 + return rtmps;
  281 + }
  282 +
  283 + public void setRtmps(String rtmps) {
  284 + this.rtmps = rtmps;
  285 + }
  286 +
  287 + public String getRtsp() {
  288 + return rtsp;
  289 + }
  290 +
  291 + public void setRtsp(String rtsp) {
  292 + this.rtsp = rtsp;
  293 + }
  294 +
  295 + public String getRtsps() {
  296 + return rtsps;
  297 + }
  298 +
  299 + public void setRtsps(String rtsps) {
  300 + this.rtsps = rtsps;
  301 + }
  302 +
  303 + public String getRtc() {
  304 + return rtc;
  305 + }
  306 +
  307 + public void setRtc(String rtc) {
  308 + this.rtc = rtc;
  309 + }
  310 +
  311 + public String getRtcs() {
  312 + return rtcs;
  313 + }
  314 +
  315 + public void setRtcs(String rtcs) {
  316 + this.rtcs = rtcs;
  317 + }
  318 +
  319 + public String getMediaServerId() {
  320 + return mediaServerId;
  321 + }
  322 +
  323 + public void setMediaServerId(String mediaServerId) {
  324 + this.mediaServerId = mediaServerId;
  325 + }
  326 +
  327 + public Object getTracks() {
  328 + return tracks;
  329 + }
  330 +
  331 + public void setTracks(Object tracks) {
  332 + this.tracks = tracks;
  333 + }
  334 +
  335 + public String getStartTime() {
  336 + return startTime;
  337 + }
  338 +
  339 + public void setStartTime(String startTime) {
  340 + this.startTime = startTime;
  341 + }
  342 +
  343 + public String getEndTime() {
  344 + return endTime;
  345 + }
  346 +
  347 + public void setEndTime(String endTime) {
  348 + this.endTime = endTime;
  349 + }
  350 +
  351 + public double getProgress() {
  352 + return progress;
  353 + }
  354 +
  355 + public void setProgress(double progress) {
  356 + this.progress = progress;
  357 + }
  358 +}
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceControl.java
@@ -14,7 +14,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; @@ -14,7 +14,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
14 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; 14 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
15 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; 15 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
16 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 16 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
17 -  
18 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; 17 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
19 import io.swagger.v3.oas.annotations.Operation; 18 import io.swagger.v3.oas.annotations.Operation;
20 import io.swagger.v3.oas.annotations.Parameter; 19 import io.swagger.v3.oas.annotations.Parameter;
@@ -22,10 +21,8 @@ import io.swagger.v3.oas.annotations.tags.Tag; @@ -22,10 +21,8 @@ import io.swagger.v3.oas.annotations.tags.Tag;
22 import org.slf4j.Logger; 21 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory; 22 import org.slf4j.LoggerFactory;
24 import org.springframework.beans.factory.annotation.Autowired; 23 import org.springframework.beans.factory.annotation.Autowired;
25 -import org.springframework.http.HttpStatus;  
26 import org.springframework.http.ResponseEntity; 24 import org.springframework.http.ResponseEntity;
27 import org.springframework.util.ObjectUtils; 25 import org.springframework.util.ObjectUtils;
28 -import org.springframework.util.StringUtils;  
29 import org.springframework.web.bind.annotation.*; 26 import org.springframework.web.bind.annotation.*;
30 import org.springframework.web.context.request.async.DeferredResult; 27 import org.springframework.web.context.request.async.DeferredResult;
31 28
@@ -130,15 +127,14 @@ public class DeviceControl { @@ -130,15 +127,14 @@ public class DeviceControl {
130 */ 127 */
131 @Operation(summary = "布防/撤防命令") 128 @Operation(summary = "布防/撤防命令")
132 @Parameter(name = "deviceId", description = "设备国标编号", required = true) 129 @Parameter(name = "deviceId", description = "设备国标编号", required = true)
133 - @Parameter(name = "channelId", description = "通道国标编号", required = true)  
134 @Parameter(name = "guardCmdStr", description = "命令, 可选值:SetGuard(布防),ResetGuard(撤防)", required = true) 130 @Parameter(name = "guardCmdStr", description = "命令, 可选值:SetGuard(布防),ResetGuard(撤防)", required = true)
135 @GetMapping("/guard/{deviceId}/{guardCmdStr}") 131 @GetMapping("/guard/{deviceId}/{guardCmdStr}")
136 - public DeferredResult<String> guardApi(@PathVariable String deviceId, String channelId, @PathVariable String guardCmdStr) { 132 + public DeferredResult<String> guardApi(@PathVariable String deviceId, @PathVariable String guardCmdStr) {
137 if (logger.isDebugEnabled()) { 133 if (logger.isDebugEnabled()) {
138 logger.debug("布防/撤防API调用"); 134 logger.debug("布防/撤防API调用");
139 } 135 }
140 Device device = storager.queryVideoDevice(deviceId); 136 Device device = storager.queryVideoDevice(deviceId);
141 - String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId + channelId; 137 + String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId + deviceId;
142 String uuid =UUID.randomUUID().toString(); 138 String uuid =UUID.randomUUID().toString();
143 try { 139 try {
144 cmder.guardCmd(device, guardCmdStr, event -> { 140 cmder.guardCmd(device, guardCmdStr, event -> {
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
@@ -99,7 +99,7 @@ public class DeviceQuery { @@ -99,7 +99,7 @@ public class DeviceQuery {
99 @GetMapping("/devices") 99 @GetMapping("/devices")
100 public PageInfo<Device> devices(int page, int count){ 100 public PageInfo<Device> devices(int page, int count){
101 101
102 - return storager.queryVideoDeviceList(page, count); 102 + return storager.queryVideoDeviceList(page, count,null);
103 } 103 }
104 104
105 /** 105 /**
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java
@@ -5,11 +5,11 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException; @@ -5,11 +5,11 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException;
5 import com.genersoft.iot.vmp.conf.security.SecurityUtils; 5 import com.genersoft.iot.vmp.conf.security.SecurityUtils;
6 import com.genersoft.iot.vmp.conf.security.dto.LoginUser; 6 import com.genersoft.iot.vmp.conf.security.dto.LoginUser;
7 import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; 7 import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
8 -import com.genersoft.iot.vmp.service.IStreamProxyService;  
9 import com.genersoft.iot.vmp.service.IMediaService; 8 import com.genersoft.iot.vmp.service.IMediaService;
  9 +import com.genersoft.iot.vmp.service.IStreamProxyService;
10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
11 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; 11 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
12 -import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 12 +import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
13 import io.swagger.v3.oas.annotations.Operation; 13 import io.swagger.v3.oas.annotations.Operation;
14 import io.swagger.v3.oas.annotations.Parameter; 14 import io.swagger.v3.oas.annotations.Parameter;
15 import io.swagger.v3.oas.annotations.tags.Tag; 15 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -53,11 +53,11 @@ public class MediaController { @@ -53,11 +53,11 @@ public class MediaController {
53 @Parameter(name = "useSourceIpAsStreamIp", description = "是否使用请求IP作为返回的地址IP") 53 @Parameter(name = "useSourceIpAsStreamIp", description = "是否使用请求IP作为返回的地址IP")
54 @GetMapping(value = "/stream_info_by_app_and_stream") 54 @GetMapping(value = "/stream_info_by_app_and_stream")
55 @ResponseBody 55 @ResponseBody
56 - public StreamInfo getStreamInfoByAppAndStream(HttpServletRequest request, @RequestParam String app,  
57 - @RequestParam String stream,  
58 - @RequestParam(required = false) String mediaServerId,  
59 - @RequestParam(required = false) String callId,  
60 - @RequestParam(required = false) Boolean useSourceIpAsStreamIp){ 56 + public StreamContent getStreamInfoByAppAndStream(HttpServletRequest request, @RequestParam String app,
  57 + @RequestParam String stream,
  58 + @RequestParam(required = false) String mediaServerId,
  59 + @RequestParam(required = false) String callId,
  60 + @RequestParam(required = false) Boolean useSourceIpAsStreamIp){
61 boolean authority = false; 61 boolean authority = false;
62 if (callId != null) { 62 if (callId != null) {
63 // 权限校验 63 // 权限校验
@@ -88,9 +88,8 @@ public class MediaController { @@ -88,9 +88,8 @@ public class MediaController {
88 streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority); 88 streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority);
89 } 89 }
90 90
91 - WVPResult<StreamInfo> result = new WVPResult<>();  
92 if (streamInfo != null){ 91 if (streamInfo != null){
93 - return streamInfo; 92 + return new StreamContent(streamInfo);
94 }else { 93 }else {
95 //获取流失败,重启拉流后重试一次 94 //获取流失败,重启拉流后重试一次
96 streamProxyService.stop(app,stream); 95 streamProxyService.stop(app,stream);
@@ -109,7 +108,7 @@ public class MediaController { @@ -109,7 +108,7 @@ public class MediaController {
109 streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority); 108 streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority);
110 } 109 }
111 if (streamInfo != null){ 110 if (streamInfo != null){
112 - return streamInfo; 111 + return new StreamContent(streamInfo);
113 }else { 112 }else {
114 throw new ControllerException(ErrorCode.ERROR100); 113 throw new ControllerException(ErrorCode.ERROR100);
115 } 114 }
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
@@ -22,6 +22,7 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorage; @@ -22,6 +22,7 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
22 import com.genersoft.iot.vmp.vmanager.bean.DeferredResultEx; 22 import com.genersoft.iot.vmp.vmanager.bean.DeferredResultEx;
23 import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult; 23 import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
24 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; 24 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  25 +import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
25 import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 26 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
26 import io.swagger.v3.oas.annotations.Operation; 27 import io.swagger.v3.oas.annotations.Operation;
27 import io.swagger.v3.oas.annotations.Parameter; 28 import io.swagger.v3.oas.annotations.Parameter;
@@ -85,8 +86,8 @@ public class PlayController { @@ -85,8 +86,8 @@ public class PlayController {
85 @Parameter(name = "deviceId", description = "设备国标编号", required = true) 86 @Parameter(name = "deviceId", description = "设备国标编号", required = true)
86 @Parameter(name = "channelId", description = "通道国标编号", required = true) 87 @Parameter(name = "channelId", description = "通道国标编号", required = true)
87 @GetMapping("/start/{deviceId}/{channelId}") 88 @GetMapping("/start/{deviceId}/{channelId}")
88 - public DeferredResult<WVPResult<StreamInfo>> play(HttpServletRequest request, @PathVariable String deviceId,  
89 - @PathVariable String channelId) { 89 + public DeferredResult<WVPResult<StreamContent>> play(HttpServletRequest request, @PathVariable String deviceId,
  90 + @PathVariable String channelId) {
90 91
91 // 获取可用的zlm 92 // 获取可用的zlm
92 Device device = storager.queryVideoDevice(deviceId); 93 Device device = storager.queryVideoDevice(deviceId);
@@ -98,8 +99,8 @@ public class PlayController { @@ -98,8 +99,8 @@ public class PlayController {
98 msg.setKey(key); 99 msg.setKey(key);
99 String uuid = UUID.randomUUID().toString(); 100 String uuid = UUID.randomUUID().toString();
100 msg.setId(uuid); 101 msg.setId(uuid);
101 - DeferredResult<WVPResult<StreamInfo>> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());  
102 - DeferredResultEx<WVPResult<StreamInfo>> deferredResultEx = new DeferredResultEx<>(result); 102 + DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
  103 + DeferredResultEx<WVPResult<StreamContent>> deferredResultEx = new DeferredResultEx<>(result);
103 104
104 result.onTimeout(()->{ 105 result.onTimeout(()->{
105 logger.info("点播接口等待超时"); 106 logger.info("点播接口等待超时");
@@ -110,25 +111,22 @@ public class PlayController { @@ -110,25 +111,22 @@ public class PlayController {
110 msg.setData(wvpResult); 111 msg.setData(wvpResult);
111 resultHolder.invokeResult(msg); 112 resultHolder.invokeResult(msg);
112 }); 113 });
113 -  
114 - if (userSetting.getUseSourceIpAsStreamIp()) {  
115 - // TODO 在点播未成功的情况下在此调用接口点播会导致返回的流地址ip错误  
116 - deferredResultEx.setFilter(result1 -> {  
117 - WVPResult<StreamInfo> wvpResult1 = (WVPResult<StreamInfo>)result1;  
118 - WVPResult<StreamInfo> clone = null;  
119 - try {  
120 - clone = (WVPResult<StreamInfo>)wvpResult1.clone();  
121 - } catch (CloneNotSupportedException e) {  
122 - throw new RuntimeException(e);  
123 - }  
124 - if (clone.getCode() == ErrorCode.SUCCESS.getCode()) {  
125 - StreamInfo data = clone.getData().clone(); 114 + // TODO 在点播未成功的情况下在此调用接口点播会导致返回的流地址ip错误
  115 + deferredResultEx.setFilter(result1 -> {
  116 + WVPResult<StreamInfo> wvpResult1 = (WVPResult<StreamInfo>)result1;
  117 + WVPResult<StreamContent> resultStream = new WVPResult<>();
  118 + resultStream.setCode(wvpResult1.getCode());
  119 + resultStream.setMsg(wvpResult1.getMsg());
  120 + if (wvpResult1.getCode() == ErrorCode.SUCCESS.getCode()) {
  121 + StreamInfo data = wvpResult1.getData().clone();
  122 + if (userSetting.getUseSourceIpAsStreamIp()) {
126 data.channgeStreamIp(request.getLocalName()); 123 data.channgeStreamIp(request.getLocalName());
127 - clone.setData(data);  
128 } 124 }
129 - return clone;  
130 - });  
131 - } 125 + resultStream.setData(new StreamContent(wvpResult1.getData()));
  126 + }
  127 + return resultStream;
  128 + });
  129 +
132 130
133 // 录像查询以channelId作为deviceId查询 131 // 录像查询以channelId作为deviceId查询
134 resultHolder.put(key, uuid, deferredResultEx); 132 resultHolder.put(key, uuid, deferredResultEx);
@@ -273,7 +271,7 @@ public class PlayController { @@ -273,7 +271,7 @@ public class PlayController {
273 271
274 @GetMapping("/1111") 272 @GetMapping("/1111")
275 public void broadcastApi1() { 273 public void broadcastApi1() {
276 - MediaServerItem defaultMediaServer = mediaServerService.getMediaServerForMinimumLoad(); 274 + MediaServerItem defaultMediaServer = mediaServerService.getMediaServerForMinimumLoad(null);
277 Device device = storager.queryVideoDevice("34020000001320090001"); 275 Device device = storager.queryVideoDevice("34020000001320090001");
278 playService.talk(defaultMediaServer, device, "34020000001370000001", null, null, null); 276 playService.talk(defaultMediaServer, device, "34020000001370000001", null, null, null);
279 277
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java
@@ -10,6 +10,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; @@ -10,6 +10,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
11 import com.genersoft.iot.vmp.service.IPlayService; 11 import com.genersoft.iot.vmp.service.IPlayService;
12 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; 12 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  13 +import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
13 import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 14 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
14 import io.swagger.v3.oas.annotations.Operation; 15 import io.swagger.v3.oas.annotations.Operation;
15 import io.swagger.v3.oas.annotations.Parameter; 16 import io.swagger.v3.oas.annotations.Parameter;
@@ -32,6 +33,7 @@ import org.springframework.web.context.request.async.DeferredResult; @@ -32,6 +33,7 @@ import org.springframework.web.context.request.async.DeferredResult;
32 import javax.sip.InvalidArgumentException; 33 import javax.sip.InvalidArgumentException;
33 import javax.sip.SipException; 34 import javax.sip.SipException;
34 import java.text.ParseException; 35 import java.text.ParseException;
  36 +import java.util.UUID;
35 37
36 /** 38 /**
37 * @author lin 39 * @author lin
@@ -68,24 +70,37 @@ public class PlaybackController { @@ -68,24 +70,37 @@ public class PlaybackController {
68 @Parameter(name = "startTime", description = "开始时间", required = true) 70 @Parameter(name = "startTime", description = "开始时间", required = true)
69 @Parameter(name = "endTime", description = "结束时间", required = true) 71 @Parameter(name = "endTime", description = "结束时间", required = true)
70 @GetMapping("/start/{deviceId}/{channelId}") 72 @GetMapping("/start/{deviceId}/{channelId}")
71 - public DeferredResult<WVPResult<StreamInfo>> play(@PathVariable String deviceId, @PathVariable String channelId,  
72 - String startTime, String endTime) { 73 + public DeferredResult<WVPResult<StreamContent>> play(@PathVariable String deviceId, @PathVariable String channelId,
  74 + String startTime, String endTime) {
73 75
74 if (logger.isDebugEnabled()) { 76 if (logger.isDebugEnabled()) {
75 logger.debug(String.format("设备回放 API调用,deviceId:%s ,channelId:%s", deviceId, channelId)); 77 logger.debug(String.format("设备回放 API调用,deviceId:%s ,channelId:%s", deviceId, channelId));
76 } 78 }
77 79
  80 + String uuid = UUID.randomUUID().toString();
  81 + String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId;
  82 + DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(30000L);
  83 + resultHolder.put(key, uuid, result);
78 84
79 - return playService.playBack(deviceId, channelId, startTime, endTime, null, 85 + WVPResult<StreamContent> wvpResult = new WVPResult<>();
  86 +
  87 + RequestMessage msg = new RequestMessage();
  88 + msg.setKey(key);
  89 + msg.setId(uuid);
  90 +
  91 + playService.playBack(deviceId, channelId, startTime, endTime, null,
80 playBackResult->{ 92 playBackResult->{
81 - if (playBackResult.getCode() != ErrorCode.SUCCESS.getCode()) {  
82 - RequestMessage data = playBackResult.getData();  
83 - data.setData(WVPResult.fail(playBackResult.getCode(), playBackResult.getMsg()));  
84 - resultHolder.invokeResult(data);  
85 - }else {  
86 - resultHolder.invokeResult(playBackResult.getData()); 93 + wvpResult.setCode(playBackResult.getCode());
  94 + wvpResult.setMsg(playBackResult.getMsg());
  95 + if (playBackResult.getCode() == ErrorCode.SUCCESS.getCode()) {
  96 + StreamInfo streamInfo = (StreamInfo)playBackResult.getData();
  97 + wvpResult.setData(new StreamContent(streamInfo));
87 } 98 }
  99 + msg.setData(wvpResult);
  100 + resultHolder.invokeResult(msg);
88 }); 101 });
  102 +
  103 + return result;
89 } 104 }
90 105
91 106
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/record/GBRecordController.java
@@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.service.IDeviceService; @@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.service.IDeviceService;
8 import com.genersoft.iot.vmp.service.IPlayService; 8 import com.genersoft.iot.vmp.service.IPlayService;
9 import com.genersoft.iot.vmp.utils.DateUtil; 9 import com.genersoft.iot.vmp.utils.DateUtil;
10 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; 10 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  11 +import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
11 import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 12 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
12 13
13 import io.swagger.v3.oas.annotations.Operation; 14 import io.swagger.v3.oas.annotations.Operation;
@@ -121,15 +122,33 @@ public class GBRecordController { @@ -121,15 +122,33 @@ public class GBRecordController {
121 @Parameter(name = "endTime", description = "结束时间", required = true) 122 @Parameter(name = "endTime", description = "结束时间", required = true)
122 @Parameter(name = "downloadSpeed", description = "下载倍速", required = true) 123 @Parameter(name = "downloadSpeed", description = "下载倍速", required = true)
123 @GetMapping("/download/start/{deviceId}/{channelId}") 124 @GetMapping("/download/start/{deviceId}/{channelId}")
124 - public DeferredResult<WVPResult<StreamInfo>> download(@PathVariable String deviceId, @PathVariable String channelId, 125 + public DeferredResult<WVPResult<StreamContent>> download(@PathVariable String deviceId, @PathVariable String channelId,
125 String startTime, String endTime, String downloadSpeed) { 126 String startTime, String endTime, String downloadSpeed) {
126 127
127 if (logger.isDebugEnabled()) { 128 if (logger.isDebugEnabled()) {
128 logger.debug(String.format("历史媒体下载 API调用,deviceId:%s,channelId:%s,downloadSpeed:%s", deviceId, channelId, downloadSpeed)); 129 logger.debug(String.format("历史媒体下载 API调用,deviceId:%s,channelId:%s,downloadSpeed:%s", deviceId, channelId, downloadSpeed));
129 } 130 }
130 131
131 - DeferredResult<WVPResult<StreamInfo>> result = playService.download(deviceId, channelId, startTime, endTime, Integer.parseInt(downloadSpeed), null, hookCallBack->{  
132 - resultHolder.invokeResult(hookCallBack.getData()); 132 + String uuid = UUID.randomUUID().toString();
  133 + String key = DeferredResultHolder.CALLBACK_CMD_DOWNLOAD + deviceId + channelId;
  134 + DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(30000L);
  135 + resultHolder.put(key, uuid, result);
  136 + RequestMessage msg = new RequestMessage();
  137 + msg.setId(uuid);
  138 + msg.setKey(key);
  139 +
  140 + WVPResult<StreamContent> wvpResult = new WVPResult<>();
  141 +
  142 + playService.download(deviceId, channelId, startTime, endTime, Integer.parseInt(downloadSpeed), null, playBackResult->{
  143 +
  144 + wvpResult.setCode(playBackResult.getCode());
  145 + wvpResult.setMsg(playBackResult.getMsg());
  146 + if (playBackResult.getCode() == ErrorCode.SUCCESS.getCode()) {
  147 + StreamInfo streamInfo = (StreamInfo)playBackResult.getData();
  148 + wvpResult.setData(new StreamContent(streamInfo));
  149 + }
  150 + msg.setData(wvpResult);
  151 + resultHolder.invokeResult(msg);
133 }); 152 });
134 153
135 return result; 154 return result;
@@ -168,7 +187,11 @@ public class GBRecordController { @@ -168,7 +187,11 @@ public class GBRecordController {
168 @Parameter(name = "channelId", description = "通道国标编号", required = true) 187 @Parameter(name = "channelId", description = "通道国标编号", required = true)
169 @Parameter(name = "stream", description = "流ID", required = true) 188 @Parameter(name = "stream", description = "流ID", required = true)
170 @GetMapping("/download/progress/{deviceId}/{channelId}/{stream}") 189 @GetMapping("/download/progress/{deviceId}/{channelId}/{stream}")
171 - public StreamInfo getProgress(@PathVariable String deviceId, @PathVariable String channelId, @PathVariable String stream) {  
172 - return playService.getDownLoadInfo(deviceId, channelId, stream); 190 + public StreamContent getProgress(@PathVariable String deviceId, @PathVariable String channelId, @PathVariable String stream) {
  191 + StreamInfo downLoadInfo = playService.getDownLoadInfo(deviceId, channelId, stream);
  192 + if (downLoadInfo == null) {
  193 + throw new ControllerException(ErrorCode.ERROR404);
  194 + }
  195 + return new StreamContent(downLoadInfo);
173 } 196 }
174 } 197 }
src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java
1 package com.genersoft.iot.vmp.vmanager.streamProxy; 1 package com.genersoft.iot.vmp.vmanager.streamProxy;
2 2
3 import com.alibaba.fastjson2.JSONObject; 3 import com.alibaba.fastjson2.JSONObject;
4 -import com.genersoft.iot.vmp.common.StreamInfo;  
5 import com.genersoft.iot.vmp.conf.exception.ControllerException; 4 import com.genersoft.iot.vmp.conf.exception.ControllerException;
6 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 5 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
7 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; 6 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
8 import com.genersoft.iot.vmp.service.IMediaServerService; 7 import com.genersoft.iot.vmp.service.IMediaServerService;
9 import com.genersoft.iot.vmp.service.IStreamProxyService; 8 import com.genersoft.iot.vmp.service.IStreamProxyService;
10 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; 9 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  10 +import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
11 import com.github.pagehelper.PageInfo; 11 import com.github.pagehelper.PageInfo;
12 import io.swagger.v3.oas.annotations.Operation; 12 import io.swagger.v3.oas.annotations.Operation;
13 import io.swagger.v3.oas.annotations.Parameter; 13 import io.swagger.v3.oas.annotations.Parameter;
@@ -58,7 +58,7 @@ public class StreamProxyController { @@ -58,7 +58,7 @@ public class StreamProxyController {
58 }) 58 })
59 @PostMapping(value = "/save") 59 @PostMapping(value = "/save")
60 @ResponseBody 60 @ResponseBody
61 - public StreamInfo save(@RequestBody StreamProxyItem param){ 61 + public StreamContent save(@RequestBody StreamProxyItem param){
62 logger.info("添加代理: " + JSONObject.toJSONString(param)); 62 logger.info("添加代理: " + JSONObject.toJSONString(param));
63 if (ObjectUtils.isEmpty(param.getMediaServerId())) { 63 if (ObjectUtils.isEmpty(param.getMediaServerId())) {
64 param.setMediaServerId("auto"); 64 param.setMediaServerId("auto");
@@ -69,7 +69,7 @@ public class StreamProxyController { @@ -69,7 +69,7 @@ public class StreamProxyController {
69 if (ObjectUtils.isEmpty(param.getGbId())) { 69 if (ObjectUtils.isEmpty(param.getGbId())) {
70 param.setGbId(null); 70 param.setGbId(null);
71 } 71 }
72 - return streamProxyService.save(param); 72 + return new StreamContent(streamProxyService.save(param));
73 } 73 }
74 74
75 @GetMapping(value = "/ffmpeg_cmd/list") 75 @GetMapping(value = "/ffmpeg_cmd/list")
src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java
@@ -11,22 +11,16 @@ import com.genersoft.iot.vmp.conf.security.dto.LoginUser; @@ -11,22 +11,16 @@ import com.genersoft.iot.vmp.conf.security.dto.LoginUser;
11 import com.genersoft.iot.vmp.gb28181.bean.GbStream; 11 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
12 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; 12 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
13 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; 13 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
14 -import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;  
15 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 14 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
16 import com.genersoft.iot.vmp.service.IMediaServerService; 15 import com.genersoft.iot.vmp.service.IMediaServerService;
17 import com.genersoft.iot.vmp.service.IMediaService; 16 import com.genersoft.iot.vmp.service.IMediaService;
18 import com.genersoft.iot.vmp.service.IStreamPushService; 17 import com.genersoft.iot.vmp.service.IStreamPushService;
19 import com.genersoft.iot.vmp.service.impl.StreamPushUploadFileHandler; 18 import com.genersoft.iot.vmp.service.impl.StreamPushUploadFileHandler;
20 -import com.genersoft.iot.vmp.vmanager.bean.BatchGBStreamParam;  
21 -import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;  
22 -import com.genersoft.iot.vmp.vmanager.bean.StreamPushExcelDto;  
23 -import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 19 +import com.genersoft.iot.vmp.vmanager.bean.*;
24 import com.github.pagehelper.PageInfo; 20 import com.github.pagehelper.PageInfo;
25 -  
26 import io.swagger.v3.oas.annotations.Operation; 21 import io.swagger.v3.oas.annotations.Operation;
27 import io.swagger.v3.oas.annotations.Parameter; 22 import io.swagger.v3.oas.annotations.Parameter;
28 import io.swagger.v3.oas.annotations.tags.Tag; 23 import io.swagger.v3.oas.annotations.tags.Tag;
29 -import org.apache.poi.sl.usermodel.Sheet;  
30 import org.slf4j.Logger; 24 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory; 25 import org.slf4j.LoggerFactory;
32 import org.springframework.beans.factory.annotation.Autowired; 26 import org.springframework.beans.factory.annotation.Autowired;
@@ -34,12 +28,10 @@ import org.springframework.http.HttpStatus; @@ -34,12 +28,10 @@ import org.springframework.http.HttpStatus;
34 import org.springframework.http.ResponseEntity; 28 import org.springframework.http.ResponseEntity;
35 import org.springframework.stereotype.Controller; 29 import org.springframework.stereotype.Controller;
36 import org.springframework.util.ObjectUtils; 30 import org.springframework.util.ObjectUtils;
37 -import org.springframework.util.StringUtils;  
38 import org.springframework.web.bind.annotation.*; 31 import org.springframework.web.bind.annotation.*;
39 import org.springframework.web.context.request.async.DeferredResult; 32 import org.springframework.web.context.request.async.DeferredResult;
40 import org.springframework.web.multipart.MultipartFile; 33 import org.springframework.web.multipart.MultipartFile;
41 34
42 -import javax.servlet.http.HttpServletRequest;  
43 import java.io.IOException; 35 import java.io.IOException;
44 import java.io.InputStream; 36 import java.io.InputStream;
45 import java.util.HashMap; 37 import java.util.HashMap;
@@ -243,8 +235,8 @@ public class StreamPushController { @@ -243,8 +235,8 @@ public class StreamPushController {
243 @Parameter(name = "app", description = "应用名", required = true) 235 @Parameter(name = "app", description = "应用名", required = true)
244 @Parameter(name = "stream", description = "流id", required = true) 236 @Parameter(name = "stream", description = "流id", required = true)
245 @Parameter(name = "mediaServerId", description = "媒体服务器id") 237 @Parameter(name = "mediaServerId", description = "媒体服务器id")
246 - public StreamInfo getPlayUrl(@RequestParam String app,@RequestParam String stream,  
247 - @RequestParam(required = false) String mediaServerId){ 238 + public StreamContent getPlayUrl(@RequestParam String app, @RequestParam String stream,
  239 + @RequestParam(required = false) String mediaServerId){
248 boolean authority = false; 240 boolean authority = false;
249 // 是否登陆用户, 登陆用户返回完整信息 241 // 是否登陆用户, 登陆用户返回完整信息
250 LoginUser userInfo = SecurityUtils.getUserInfo(); 242 LoginUser userInfo = SecurityUtils.getUserInfo();
@@ -259,7 +251,7 @@ public class StreamPushController { @@ -259,7 +251,7 @@ public class StreamPushController {
259 if (streamInfo == null){ 251 if (streamInfo == null){
260 throw new ControllerException(ErrorCode.ERROR100.getCode(), "获取播放地址失败"); 252 throw new ControllerException(ErrorCode.ERROR100.getCode(), "获取播放地址失败");
261 } 253 }
262 - return streamInfo; 254 + return new StreamContent(streamInfo);
263 } 255 }
264 256
265 /** 257 /**
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiDeviceController.java
@@ -10,8 +10,10 @@ import com.github.pagehelper.PageInfo; @@ -10,8 +10,10 @@ import com.github.pagehelper.PageInfo;
10 import org.slf4j.Logger; 10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory; 11 import org.slf4j.LoggerFactory;
12 import org.springframework.beans.factory.annotation.Autowired; 12 import org.springframework.beans.factory.annotation.Autowired;
  13 +import org.springframework.util.StringUtils;
13 import org.springframework.web.bind.annotation.*; 14 import org.springframework.web.bind.annotation.*;
14 15
  16 +import java.util.Arrays;
15 import java.util.List; 17 import java.util.List;
16 18
17 /** 19 /**
@@ -59,10 +61,10 @@ public class ApiDeviceController { @@ -59,10 +61,10 @@ public class ApiDeviceController {
59 JSONObject result = new JSONObject(); 61 JSONObject result = new JSONObject();
60 List<Device> devices; 62 List<Device> devices;
61 if (start == null || limit ==null) { 63 if (start == null || limit ==null) {
62 - devices = storager.queryVideoDeviceList(); 64 + devices = storager.queryVideoDeviceList(online);
63 result.put("DeviceCount", devices.size()); 65 result.put("DeviceCount", devices.size());
64 }else { 66 }else {
65 - PageInfo<Device> deviceList = storager.queryVideoDeviceList(start/limit, limit); 67 + PageInfo<Device> deviceList = storager.queryVideoDeviceList(start/limit, limit,online);
66 result.put("DeviceCount", deviceList.getTotal()); 68 result.put("DeviceCount", deviceList.getTotal());
67 devices = deviceList.getList(); 69 devices = deviceList.getList();
68 } 70 }
@@ -94,6 +96,7 @@ public class ApiDeviceController { @@ -94,6 +96,7 @@ public class ApiDeviceController {
94 96
95 @RequestMapping(value = "/channellist") 97 @RequestMapping(value = "/channellist")
96 public JSONObject channellist( String serial, 98 public JSONObject channellist( String serial,
  99 + @RequestParam(required = false)String code,
97 @RequestParam(required = false)String channel_type, 100 @RequestParam(required = false)String channel_type,
98 @RequestParam(required = false)String dir_serial , 101 @RequestParam(required = false)String dir_serial ,
99 @RequestParam(required = false)Integer start, 102 @RequestParam(required = false)Integer start,
@@ -113,12 +116,17 @@ public class ApiDeviceController { @@ -113,12 +116,17 @@ public class ApiDeviceController {
113 return result; 116 return result;
114 } 117 }
115 List<DeviceChannel> deviceChannels; 118 List<DeviceChannel> deviceChannels;
116 - List<DeviceChannel> allDeviceChannelList = storager.queryChannelsByDeviceId(serial); 119 + List<String> channelIds = null;
  120 + if (!StringUtils.isEmpty(code)) {
  121 + String[] split = code.trim().split(",");
  122 + channelIds = Arrays.asList(split);
  123 + }
  124 + List<DeviceChannel> allDeviceChannelList = storager.queryChannelsByDeviceId(serial,online,channelIds);
117 if (start == null || limit ==null) { 125 if (start == null || limit ==null) {
118 deviceChannels = allDeviceChannelList; 126 deviceChannels = allDeviceChannelList;
119 result.put("ChannelCount", deviceChannels.size()); 127 result.put("ChannelCount", deviceChannels.size());
120 }else { 128 }else {
121 - deviceChannels = storager.queryChannelsByDeviceIdWithStartAndLimit(serial, null, null, null,start, limit); 129 + deviceChannels = storager.queryChannelsByDeviceIdWithStartAndLimit(serial, null, null, online,start, limit,channelIds);
122 int total = allDeviceChannelList.size(); 130 int total = allDeviceChannelList.size();
123 result.put("ChannelCount", total); 131 result.put("ChannelCount", total);
124 } 132 }
@@ -148,9 +156,9 @@ public class ApiDeviceController { @@ -148,9 +156,9 @@ public class ApiDeviceController {
148 // 1-IETF RFC3261, 156 // 1-IETF RFC3261,
149 // 2-基于口令的双向认证, 157 // 2-基于口令的双向认证,
150 // 3-基于数字证书的双向认证 158 // 3-基于数字证书的双向认证
151 - deviceJOSNChannel.put("Status", deviceChannel.getStatus());  
152 - deviceJOSNChannel.put("Longitude", deviceChannel.getLongitudeWgs84());  
153 - deviceJOSNChannel.put("Latitude", deviceChannel.getLatitudeWgs84()); 159 + deviceJOSNChannel.put("Status", deviceChannel.getStatus() == 1 ? "ON":"OFF");
  160 + deviceJOSNChannel.put("Longitude", deviceChannel.getLongitude());
  161 + deviceJOSNChannel.put("Latitude", deviceChannel.getLatitude());
154 deviceJOSNChannel.put("PTZType ", deviceChannel.getPTZType()); // 云台类型, 0 - 未知, 1 - 球机, 2 - 半球, 162 deviceJOSNChannel.put("PTZType ", deviceChannel.getPTZType()); // 云台类型, 0 - 未知, 1 - 球机, 2 - 半球,
155 // 3 - 固定枪机, 4 - 遥控枪机 163 // 3 - 固定枪机, 4 - 遥控枪机
156 deviceJOSNChannel.put("CustomPTZType", ""); 164 deviceJOSNChannel.put("CustomPTZType", "");
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java
@@ -12,7 +12,6 @@ import com.genersoft.iot.vmp.service.IDeviceService; @@ -12,7 +12,6 @@ import com.genersoft.iot.vmp.service.IDeviceService;
12 import com.genersoft.iot.vmp.service.IPlayService; 12 import com.genersoft.iot.vmp.service.IPlayService;
13 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 13 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
14 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 14 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
15 -import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;  
16 import org.slf4j.Logger; 15 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory; 16 import org.slf4j.LoggerFactory;
18 import org.springframework.beans.factory.annotation.Autowired; 17 import org.springframework.beans.factory.annotation.Autowired;
@@ -120,12 +119,12 @@ public class ApiStreamController { @@ -120,12 +119,12 @@ public class ApiStreamController {
120 result.put("ChannelID", code); 119 result.put("ChannelID", code);
121 result.put("ChannelName", deviceChannel.getName()); 120 result.put("ChannelName", deviceChannel.getName());
122 result.put("ChannelCustomName", ""); 121 result.put("ChannelCustomName", "");
123 - result.put("FLV", streamInfo.getFlv());  
124 - result.put("WS_FLV", streamInfo.getWs_flv());  
125 - result.put("RTMP", streamInfo.getRtmp());  
126 - result.put("HLS", streamInfo.getHls());  
127 - result.put("RTSP", streamInfo.getRtsp());  
128 - result.put("WEBRTC", streamInfo.getRtc()); 122 + result.put("FLV", streamInfo.getFlv().getUrl());
  123 + result.put("WS_FLV", streamInfo.getWs_flv().getUrl());
  124 + result.put("RTMP", streamInfo.getRtmp().getUrl());
  125 + result.put("HLS", streamInfo.getHls().getUrl());
  126 + result.put("RTSP", streamInfo.getRtsp().getUrl());
  127 + result.put("WEBRTC", streamInfo.getRtc().getUrl());
129 result.put("CDN", ""); 128 result.put("CDN", "");
130 result.put("SnapURL", ""); 129 result.put("SnapURL", "");
131 result.put("Transport", device.getTransport()); 130 result.put("Transport", device.getTransport());
src/main/resources/all-application.yml
@@ -186,7 +186,7 @@ user-settings: @@ -186,7 +186,7 @@ user-settings:
186 use-pushing-as-status: true 186 use-pushing-as-status: true
187 # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 187 # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启
188 use-source-ip-as-stream-ip: true 188 use-source-ip-as-stream-ip: true
189 - # 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 189 + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放
190 stream-on-demand: true 190 stream-on-demand: true
191 # 推流鉴权, 默认开启 191 # 推流鉴权, 默认开启
192 push-authority: true 192 push-authority: true
@@ -197,6 +197,10 @@ user-settings: @@ -197,6 +197,10 @@ user-settings:
197 sync-channel-on-device-online: false 197 sync-channel-on-device-online: false
198 # 国标级联语音喊话发流模式 * UDP:udp传输 TCP-ACTIVE:tcp主动模式 TCP-PASSIVE:tcp被动模式 198 # 国标级联语音喊话发流模式 * UDP:udp传输 TCP-ACTIVE:tcp主动模式 TCP-PASSIVE:tcp被动模式
199 broadcast-for-platform: UDP 199 broadcast-for-platform: UDP
  200 + # 是否使用设备来源Ip作为回复IP, 不设置则为 false
  201 + sip-use-source-ip-as-remote-address: false
  202 + # 是否开启sip日志
  203 + sip-log: true
200 # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 204 # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流
201 push-stream-after-ack: false 205 push-stream-after-ack: false
202 206
web_src/src/components/CloudRecordDetail.vue
@@ -30,7 +30,7 @@ @@ -30,7 +30,7 @@
30 </el-aside> 30 </el-aside>
31 <el-main style="padding: 22px"> 31 <el-main style="padding: 22px">
32 <div class="playBox" :style="playerStyle"> 32 <div class="playBox" :style="playerStyle">
33 - <player ref="recordVideoPlayer" :videoUrl="videoUrl" fluent autoplay :height="true" ></player> 33 + <player ref="recordVideoPlayer" :videoUrl="videoUrl" :height="true" style="width: 100%" ></player>
34 </div> 34 </div>
35 <div class="player-option-box" > 35 <div class="player-option-box" >
36 <el-slider 36 <el-slider
@@ -310,7 +310,20 @@ @@ -310,7 +310,20 @@
310 let h = parseInt(val/3600); 310 let h = parseInt(val/3600);
311 let m = parseInt((val - h*3600)/60); 311 let m = parseInt((val - h*3600)/60);
312 let s = parseInt(val - h*3600 - m*60); 312 let s = parseInt(val - h*3600 - m*60);
313 - return h + ":" + m + ":" + s 313 +
  314 + let hStr = h;
  315 + let mStr = m;
  316 + let sStr = s;
  317 + if (h < 10) {
  318 + hStr = "0" + hStr;
  319 + }
  320 + if (m < 10) {
  321 + mStr = "0" + mStr;s
  322 + }
  323 + if (s < 10) {
  324 + sStr = "0" + sStr;
  325 + }
  326 + return hStr + ":" + mStr + ":" + sStr
314 }, 327 },
315 deleteRecord(){ 328 deleteRecord(){
316 // TODO 329 // TODO
web_src/src/components/GBRecordDetail.vue 0 → 100644
  1 +<template>
  2 + <div style="width: 100%">
  3 + <div class="page-header" >
  4 + <div class="page-title">
  5 + <el-page-header @back="goBack" content="国标录像"></el-page-header>
  6 + </div>
  7 + </div>
  8 + <el-container>
  9 + <el-aside width="300px">
  10 + <div class="record-list-box-box">
  11 + <el-date-picker size="mini" v-model="chooseDate" type="date" value-format="yyyy-MM-dd" placeholder="日期" @change="dateChange()"></el-date-picker>
  12 + <div class="record-list-box" v-loading="recordsLoading" :style="recordListStyle">
  13 + <ul v-if="detailFiles.length >0" class="infinite-list record-list" >
  14 + <li v-for="item in detailFiles" class="infinite-list-item record-list-item" >
  15 +
  16 + <el-tag v-if="chooseFile != item" @click="checkedFile(item)">
  17 + <i class="el-icon-video-camera" ></i>
  18 + {{ moment(item.startTime).format('HH:mm:ss')}}-{{ moment(item.endTime).format('HH:mm:ss')}}
  19 + </el-tag>
  20 + <el-tag v-if="chooseFile == item" type="danger" >
  21 + <i class="el-icon-video-camera" ></i>
  22 + {{ moment(item.startTime).format('HH:mm:ss')}}-{{ moment(item.endTime).format('HH:mm:ss')}}
  23 + </el-tag>
  24 + <i style="color: #409EFF;margin-left: 5px;" class="el-icon-download" @click="downloadRecord(item)" ></i>
  25 + </li>
  26 + </ul>
  27 + </div>
  28 + <div size="mini" v-if="detailFiles.length ==0" class="record-list-no-val" >暂无数据</div>
  29 + </div>
  30 +
  31 + </el-aside>
  32 + <el-main style="padding-bottom: 10px;">
  33 + <div class="playBox" :style="playerStyle">
  34 + <player ref="recordVideoPlayer"
  35 + :videoUrl="videoUrl"
  36 + :error="videoError"
  37 + :message="videoError"
  38 + :hasAudio="hasAudio"
  39 + style="max-height: 100%"
  40 + fluent autoplay live ></player>
  41 + </div>
  42 + <div class="player-option-box">
  43 + <div>
  44 + <el-button-group >
  45 + <el-time-picker
  46 + size="mini"
  47 + is-range
  48 + align="left"
  49 + v-model="timeRange"
  50 + value-format="yyyy-MM-dd HH:mm:ss"
  51 + range-separator="至"
  52 + start-placeholder="开始时间"
  53 + end-placeholder="结束时间"
  54 + @change="timePickerChange"
  55 + placeholder="选择时间范围">
  56 + </el-time-picker>
  57 + </el-button-group>
  58 +
  59 + <el-button-group >
  60 + <el-button size="mini" class="iconfont icon-zanting" title="开始" @click="gbPause()"></el-button>
  61 + <el-button size="mini" class="iconfont icon-kaishi" title="暂停" @click="gbPlay()"></el-button>
  62 + <el-dropdown size="mini" title="播放倍速" @command="gbScale">
  63 + <el-button size="mini">
  64 + 倍速 <i class="el-icon-arrow-down el-icon--right"></i>
  65 + </el-button>
  66 + <el-dropdown-menu slot="dropdown">
  67 + <el-dropdown-item command="0.25">0.25倍速</el-dropdown-item>
  68 + <el-dropdown-item command="0.5">0.5倍速</el-dropdown-item>
  69 + <el-dropdown-item command="1.0">1倍速</el-dropdown-item>
  70 + <el-dropdown-item command="2.0">2倍速</el-dropdown-item>
  71 + <el-dropdown-item command="4.0">4倍速</el-dropdown-item>
  72 + </el-dropdown-menu>
  73 + </el-dropdown>
  74 + <el-button size="mini" class="iconfont icon-xiazai1" title="下载选定录像" @click="downloadRecord()"></el-button>
  75 + <el-button v-if="sliderMIn === 0 && sliderMax === 86400" size="mini" class="iconfont icon-slider" title="放大滑块" @click="setSliderFit()"></el-button>
  76 + <el-button v-if="sliderMIn !== 0 || sliderMax !== 86400" size="mini" class="iconfont icon-slider-right" title="恢复滑块" @click="setSliderFit()"></el-button>
  77 + </el-button-group>
  78 + </div>
  79 + <el-slider
  80 + class="playtime-slider"
  81 + v-model="playTime"
  82 + id="playtimeSlider"
  83 + :disabled="detailFiles.length === 0"
  84 + :min="sliderMIn"
  85 + :max="sliderMax"
  86 + :range="true"
  87 + :format-tooltip="playTimeFormat"
  88 + @change="playTimeChange"
  89 + :marks="playTimeSliderMarks">
  90 + </el-slider>
  91 + <div class="slider-val-box">
  92 + <div class="slider-val" v-for="item of detailFiles" :style="'width:' + getDataWidth(item) + '%; left:' + getDataLeft(item) + '%'"></div>
  93 + </div>
  94 + </div>
  95 +
  96 + </el-main>
  97 + </el-container>
  98 + <recordDownload ref="recordDownload"></recordDownload>
  99 + </div>
  100 +</template>
  101 +
  102 +
  103 +<script>
  104 + import uiHeader from '../layout/UiHeader.vue'
  105 + import player from './common/jessibuca.vue'
  106 + import moment from 'moment'
  107 + import recordDownload from './dialog/recordDownload.vue'
  108 + export default {
  109 + name: 'app',
  110 + components: {
  111 + uiHeader, player,recordDownload
  112 + },
  113 + data() {
  114 + return {
  115 + deviceId: this.$route.params.deviceId,
  116 + channelId: this.$route.params.channelId,
  117 + recordsLoading: false,
  118 + streamId: "",
  119 + hasAudio: false,
  120 + detailFiles: [],
  121 + chooseDate: null,
  122 + videoUrl: null,
  123 + chooseFile: null,
  124 + streamInfo: null,
  125 + app: null,
  126 + mediaServerId: null,
  127 + ssrc: null,
  128 +
  129 + sliderMIn: 0,
  130 + sliderMax: 86400,
  131 + autoPlay: true,
  132 + taskUpdate: null,
  133 + tabVal: "running",
  134 + recordListStyle: {
  135 + height: this.winHeight + "px",
  136 + overflow: "auto",
  137 + margin: "10px auto 10px auto"
  138 + },
  139 + playerStyle: {
  140 + "margin": "0 auto 20px auto",
  141 + "height": this.winHeight + "px",
  142 + },
  143 + winHeight: window.innerHeight - 240,
  144 + playTime: null,
  145 + timeRange: null,
  146 + startTime: null,
  147 + endTime: null,
  148 + playTimeSliderMarks: {
  149 + 0: "00:00",
  150 + 3600: "01:00",
  151 + 7200: "02:00",
  152 + 10800: "03:00",
  153 + 14400: "04:00",
  154 + 18000: "05:00",
  155 + 21600: "06:00",
  156 + 25200: "07:00",
  157 + 28800: "08:00",
  158 + 32400: "09:00",
  159 + 36000: "10:00",
  160 + 39600: "11:00",
  161 + 43200: "12:00",
  162 + 46800: "13:00",
  163 + 50400: "14:00",
  164 + 54000: "15:00",
  165 + 57600: "16:00",
  166 + 61200: "17:00",
  167 + 64800: "18:00",
  168 + 68400: "19:00",
  169 + 72000: "20:00",
  170 + 75600: "21:00",
  171 + 79200: "22:00",
  172 + 82800: "23:00",
  173 + 86400: "24:00",
  174 + },
  175 + };
  176 + },
  177 + computed: {
  178 +
  179 + },
  180 + mounted() {
  181 + this.recordListStyle.height = this.winHeight + "px";
  182 + this.playerStyle["height"] = this.winHeight + "px";
  183 + this.chooseDate = moment().format('YYYY-MM-DD')
  184 + this.dateChange();
  185 + },
  186 + destroyed() {
  187 + this.$destroy('recordVideoPlayer');
  188 + },
  189 + methods: {
  190 + dateChange(){
  191 + if (!this.chooseDate) {
  192 + return;
  193 + }
  194 +
  195 + this.setTime(this.chooseDate + " 00:00:00", this.chooseDate + " 23:59:59");
  196 + this.recordsLoading = true;
  197 + this.detailFiles = [];
  198 + this.$axios({
  199 + method: 'get',
  200 + url: '/api/gb_record/query/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.startTime + '&endTime=' + this.endTime
  201 + }).then((res)=>{
  202 + this.recordsLoading = false;
  203 + if(res.data.code === 0) {
  204 + // 处理时间信息
  205 + this.detailFiles = res.data.data.recordList;
  206 +
  207 + }else {
  208 + this.$message({
  209 + showClose: true,
  210 + message: res.data.msg,
  211 + type: "error",
  212 + });
  213 + }
  214 +
  215 + }).catch((e)=> {
  216 + this.recordsLoading = false;
  217 + // that.videoHistory.searchHistoryResult = falsificationData.recordData;
  218 + });
  219 + },
  220 + moment: function (v) {
  221 + return moment(v)
  222 + },
  223 + setTime: function (startTime, endTime){
  224 + this.startTime = startTime;
  225 + this.endTime = endTime;
  226 + let start = (new Date(this.startTime).getTime() - new Date(this.chooseDate + " 00:00:00").getTime())/1000;
  227 + let end = (new Date(this.endTime).getTime() - new Date(this.chooseDate + " 00:00:00").getTime())/1000;
  228 + console.log(start)
  229 + console.log(end)
  230 + this.playTime = [start, end];
  231 + this.timeRange = [startTime, endTime];
  232 + },
  233 + videoError: function (e) {
  234 + console.log("播放器错误:" + JSON.stringify(e));
  235 + },
  236 + checkedFile(file){
  237 + this.chooseFile = file;
  238 + this.setTime(file.startTime, file.endTime);
  239 + // 开始回放
  240 + this.playRecord()
  241 + },
  242 + playRecord: function () {
  243 +
  244 + if (this.streamId !== "") {
  245 + this.stopPlayRecord(()=> {
  246 + this.streamId = "";
  247 + this.playRecord();
  248 + })
  249 + } else {
  250 + this.$axios({
  251 + method: 'get',
  252 + url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.startTime + '&endTime=' +
  253 + this.endTime
  254 + }).then((res)=> {
  255 + if (res.data.code === 0) {
  256 + this.streamInfo = res.data.data;
  257 + this.app = this.streamInfo.app;
  258 + this.streamId = this.streamInfo.stream;
  259 + this.mediaServerId = this.streamInfo.mediaServerId;
  260 + this.ssrc = this.streamInfo.ssrc;
  261 + this.videoUrl = this.getUrlByStreamInfo();
  262 + }else {
  263 + this.$message({
  264 + showClose: true,
  265 + message: res.data.msg,
  266 + type: "error",
  267 + });
  268 + }
  269 + });
  270 + }
  271 + },
  272 + gbPlay(){
  273 + console.log('前端控制:播放');
  274 + this.$axios({
  275 + method: 'get',
  276 + url: '/api/playback/resume/' + this.streamId
  277 + }).then((res)=> {
  278 + this.$refs["recordVideoPlayer"].play(this.videoUrl)
  279 + });
  280 + },
  281 + gbPause(){
  282 + console.log('前端控制:暂停');
  283 + this.$axios({
  284 + method: 'get',
  285 + url: '/api/playback/pause/' + this.streamId
  286 + }).then(function (res) {});
  287 + },
  288 + gbScale(command){
  289 + console.log('前端控制:倍速 ' + command);
  290 + this.$axios({
  291 + method: 'get',
  292 + url: `/api/playback/speed/${this.streamId }/${command}`
  293 + }).then(function (res) {});
  294 + },
  295 + downloadRecord: function (row) {
  296 + if (!row) {
  297 + let startTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + this.playTime[0]*1000).format("YYYY-MM-DD HH:mm:ss");
  298 + let endTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + this.playTime[1]*1000).format("YYYY-MM-DD HH:mm:ss");
  299 + console.log(startTimeStr);
  300 + console.log(endTimeStr);
  301 + row = {
  302 + startTime: startTimeStr,
  303 + endTime: endTimeStr
  304 + }
  305 + }
  306 + if (this.streamId !== "") {
  307 + this.stopPlayRecord(()=> {
  308 + this.streamId = "";
  309 + this.downloadRecord(row);
  310 + })
  311 + }else {
  312 + this.$axios({
  313 + method: 'get',
  314 + url: '/api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +
  315 + row.endTime + '&downloadSpeed=4'
  316 + }).then( (res)=> {
  317 + if (res.data.code === 0) {
  318 + let streamInfo = res.data.data;
  319 + this.$refs.recordDownload.openDialog(this.deviceId, this.channelId, streamInfo.app, streamInfo.stream, streamInfo.mediaServerId);
  320 + }else {
  321 + this.$message({
  322 + showClose: true,
  323 + message: res.data.msg,
  324 + type: "error",
  325 + });
  326 + }
  327 + });
  328 + }
  329 + },
  330 + stopDownloadRecord: function (callback) {
  331 + this.$refs["recordVideoPlayer"].pause();
  332 + this.videoUrl = '';
  333 + this.$axios({
  334 + method: 'get',
  335 + url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId
  336 + }).then((res)=> {
  337 + if (callback) callback(res)
  338 + });
  339 + },
  340 + stopPlayRecord: function (callback) {
  341 + this.$refs["recordVideoPlayer"].pause();
  342 + this.videoUrl = '';
  343 + this.$axios({
  344 + method: 'get',
  345 + url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId
  346 + }).then(function (res) {
  347 + if (callback) callback()
  348 + });
  349 + },
  350 + getDataWidth(item){
  351 + let timeForFile = this.getTimeForFile(item);
  352 + let result = (timeForFile[2])/((this.sliderMax - this.sliderMIn)*1000)
  353 + return result*100
  354 + },
  355 + getDataLeft(item){
  356 + let timeForFile = this.getTimeForFile(item);
  357 + let differenceTime = timeForFile[0].getTime() - new Date(this.chooseDate + " 00:00:00").getTime()
  358 + return parseFloat((differenceTime - this.sliderMIn * 1000)/((this.sliderMax - this.sliderMIn)*1000))*100 ;
  359 + },
  360 + getUrlByStreamInfo(){
  361 + if (location.protocol === "https:") {
  362 + this.videoUrl = this.streamInfo["wss_flv"]
  363 + }else {
  364 + this.videoUrl = this.streamInfo["ws_flv"]
  365 + }
  366 + return this.videoUrl;
  367 +
  368 + },
  369 + timePickerChange: function (val){
  370 + this.setTime(val[0], val[1])
  371 + },
  372 + playTimeChange(val){
  373 + console.log(val)
  374 +
  375 + let startTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + val[0]*1000).format("YYYY-MM-DD HH:mm:ss");
  376 + let endTimeStr = moment(new Date(this.chooseDate + " 00:00:00").getTime() + val[1]*1000).format("YYYY-MM-DD HH:mm:ss");
  377 +
  378 + this.setTime(startTimeStr, endTimeStr)
  379 +
  380 + this.playRecord();
  381 + },
  382 + setSliderFit() {
  383 + if (this.sliderMIn === 0 && this.sliderMax === 86400) {
  384 + if (this.detailFiles.length > 0){
  385 + let timeForFile = this.getTimeForFile(this.detailFiles[0]);
  386 + let lastTimeForFile = this.getTimeForFile(this.detailFiles[this.detailFiles.length - 1]);
  387 + let timeNum = timeForFile[0].getTime() - new Date(this.chooseDate + " " + "00:00:00").getTime()
  388 + let lastTimeNum = lastTimeForFile[1].getTime() - new Date(this.chooseDate + " " + "00:00:00").getTime()
  389 +
  390 + this.playTime = parseInt(timeNum/1000)
  391 + this.sliderMIn = parseInt(timeNum/1000 - timeNum/1000%(60*60))
  392 + this.sliderMax = parseInt(lastTimeNum/1000 - lastTimeNum/1000%(60*60)) + 60*60
  393 +
  394 + this.playTime = [this.sliderMIn, this.sliderMax];
  395 + }
  396 + }else {
  397 + this.sliderMIn = 0;
  398 + this.sliderMax = 86400;
  399 + }
  400 + },
  401 + getTimeForFile(file){
  402 + let startTime = new Date(file.startTime);
  403 + let endTime = new Date(file.endTime);
  404 + return [startTime, endTime, endTime.getTime() - startTime.getTime()];
  405 + },
  406 + playTimeFormat(val){
  407 + let h = parseInt(val/3600);
  408 + let m = parseInt((val - h*3600)/60);
  409 + let s = parseInt(val - h*3600 - m*60);
  410 +
  411 + let hStr = h;
  412 + let mStr = m;
  413 + let sStr = s;
  414 + if (h < 10) {
  415 + hStr = "0" + hStr;
  416 + }
  417 + if (m < 10) {
  418 + mStr = "0" + mStr;s
  419 + }
  420 + if (s < 10) {
  421 + sStr = "0" + sStr;
  422 + }
  423 + return hStr + ":" + mStr + ":" + sStr
  424 + },
  425 + goBack(){
  426 + window.history.go(-1);
  427 + }
  428 + }
  429 + };
  430 +</script>
  431 +
  432 +<style>
  433 + .el-slider__runway {
  434 + background-color:rgba(206, 206, 206, 0.47) !important;
  435 + }
  436 + .el-slider__bar {
  437 + background-color: rgba(153, 153, 153, 0) !important;
  438 + }
  439 + .playtime-slider {
  440 + position: relative;
  441 + z-index: 100;
  442 + }
  443 + .data-picker-true{
  444 +
  445 + }
  446 + .data-picker-true:after{
  447 + content: "";
  448 + position: absolute;
  449 + width: 4px;
  450 + height: 4px;
  451 + background-color: #606060;
  452 + border-radius: 4px;
  453 + left: 45%;
  454 + top: 74%;
  455 +
  456 + }
  457 + .data-picker-false{
  458 +
  459 + }
  460 + .slider-val-box{
  461 + height: 6px;
  462 + position: relative;
  463 + top: -22px;
  464 + }
  465 + .slider-val{
  466 + height: 6px;
  467 + background-color: #007CFF;
  468 + position: absolute;
  469 + }
  470 + .record-list-box-box{
  471 + width: 250px;
  472 + float: left;
  473 + }
  474 + .record-list-box{
  475 + overflow: auto;
  476 + width: 220px;
  477 + list-style: none;
  478 + padding: 0;
  479 + margin: 0;
  480 + margin-top: 0px;
  481 + padding: 1rem 0;
  482 + background-color: #FFF;
  483 + margin-top: 10px;
  484 + }
  485 + .record-list{
  486 + list-style: none;
  487 + padding: 0;
  488 + margin: 0;
  489 + background-color: #FFF;
  490 +
  491 + }
  492 + .record-list-no-val {
  493 + position: absolute;
  494 + color: #9f9f9f;
  495 + top: 50%;
  496 + left: 110px;
  497 + }
  498 + .record-list-item{
  499 + padding: 0;
  500 + margin: 0;
  501 + margin: 0.5rem 0;
  502 + cursor: pointer;
  503 + }
  504 + .record-list-option {
  505 + width: 10px;
  506 + float: left;
  507 + margin-top: 39px;
  508 +
  509 + }
  510 + .player-option-box{
  511 + padding: 0 20px;
  512 + }
  513 +</style>
web_src/src/components/channelList.vue
@@ -269,10 +269,10 @@ export default { @@ -269,10 +269,10 @@ export default {
269 }); 269 });
270 }, 270 },
271 queryRecords: function (itemData) { 271 queryRecords: function (itemData) {
272 - var format = moment().format("yyyy-MM-DD");  
273 let deviceId = this.deviceId; 272 let deviceId = this.deviceId;
274 let channelId = itemData.channelId; 273 let channelId = itemData.channelId;
275 - this.$refs.devicePlayer.openDialog("record", deviceId, channelId, {date: format}) 274 +
  275 + this.$router.push(`/gbRecordDetail/${deviceId}/${channelId}`)
276 }, 276 },
277 stopDevicePush: function (itemData) { 277 stopDevicePush: function (itemData) {
278 var that = this; 278 var that = this;
web_src/src/components/console.vue
@@ -101,11 +101,14 @@ export default { @@ -101,11 +101,14 @@ export default {
101 window.clearTimeout(this.timer); 101 window.clearTimeout(this.timer);
102 } 102 }
103 this.timer = setTimeout(()=>{ 103 this.timer = setTimeout(()=>{
104 - this.getSystemInfo();  
105 - this.getLoad();  
106 - this.timer = null;  
107 - this.loopForSystemInfo()  
108 - this.getResourceInfo() 104 + if (this.$route.path === "/console") {
  105 + this.getSystemInfo();
  106 + this.getLoad();
  107 + this.timer = null;
  108 + this.loopForSystemInfo()
  109 + this.getResourceInfo()
  110 + }
  111 +
109 }, 2000) 112 }, 2000)
110 }, 113 },
111 getSystemInfo: function (){ 114 getSystemInfo: function (){
web_src/src/components/console/ConsoleResource.vue
1 <template > 1 <template >
2 <div id="consoleResource" style="width: 100%; height: 100%; background: #FFFFFF; text-align: center"> 2 <div id="consoleResource" style="width: 100%; height: 100%; background: #FFFFFF; text-align: center">
3 <div style="width: 50%;height: 50%; float:left; "> 3 <div style="width: 50%;height: 50%; float:left; ">
4 - <el-progress :width="100" :stroke-width="8" type="circle" :percentage="Math.floor(deviceInfo.online/deviceInfo.total*100)" style="margin-top: 20px; font-size: 18px"></el-progress> 4 + <el-progress v-if="deviceInfo.total > 0" :width="100" :stroke-width="8" type="circle" :percentage="Math.floor(deviceInfo.online/deviceInfo.total*100)" style="margin-top: 20px; font-size: 18px"></el-progress>
  5 + <el-progress v-if="deviceInfo.total === 0" :width="100" :stroke-width="8" type="circle" :percentage="0" style="margin-top: 20px; font-size: 18px"></el-progress>
5 <div class="resourceInfo"> 6 <div class="resourceInfo">
6 设备总数:{{deviceInfo.total}}<br/> 7 设备总数:{{deviceInfo.total}}<br/>
7 在线数:{{deviceInfo.online}} 8 在线数:{{deviceInfo.online}}
8 </div> 9 </div>
9 </div> 10 </div>
10 <div style="width: 50%;height: 50%; float:left; "> 11 <div style="width: 50%;height: 50%; float:left; ">
11 - <el-progress :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(channelInfo.online/channelInfo.total*100)" style="margin-top: 20px"></el-progress> 12 + <el-progress v-if="channelInfo.total > 0" :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(channelInfo.online/channelInfo.total*100)" style="margin-top: 20px"></el-progress>
  13 + <el-progress v-if="channelInfo.total === 0" :width="100" :stroke-width="10" type="circle" :percentage="0" style="margin-top: 20px"></el-progress>
12 <div class="resourceInfo"> 14 <div class="resourceInfo">
13 通道总数:{{channelInfo.total}}<br/> 15 通道总数:{{channelInfo.total}}<br/>
14 在线数:{{channelInfo.online}} 16 在线数:{{channelInfo.online}}
15 </div> 17 </div>
16 </div> 18 </div>
17 <div style="width: 50%;height: 50%; float:left; "> 19 <div style="width: 50%;height: 50%; float:left; ">
18 - <el-progress :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(pushInfo.online/pushInfo.total*100)" style="margin-top: 20px"></el-progress> 20 + <el-progress v-if="pushInfo.total > 0" :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(pushInfo.online/pushInfo.total*100)" style="margin-top: 20px"></el-progress>
  21 + <el-progress v-if="pushInfo.total === 0" :width="100" :stroke-width="10" type="circle" :percentage="0" style="margin-top: 20px"></el-progress>
19 <div class="resourceInfo"> 22 <div class="resourceInfo">
20 推流总数:{{pushInfo.total}}<br/> 23 推流总数:{{pushInfo.total}}<br/>
21 在线数:{{pushInfo.online}} 24 在线数:{{pushInfo.online}}
22 </div> 25 </div>
23 </div> 26 </div>
24 <div style="width: 50%;height: 50%; float:left; "> 27 <div style="width: 50%;height: 50%; float:left; ">
25 - <el-progress :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(proxyInfo.online/proxyInfo.total*100)" style="margin-top: 20px"></el-progress> 28 + <el-progress v-if="proxyInfo.total > 0" :width="100" :stroke-width="10" type="circle" :percentage="Math.floor(proxyInfo.online/proxyInfo.total*100)" style="margin-top: 20px"></el-progress>
  29 + <el-progress v-if="proxyInfo.total === 0" :width="100" :stroke-width="10" type="circle" :percentage="0" style="margin-top: 20px"></el-progress>
26 <div class="resourceInfo"> 30 <div class="resourceInfo">
27 拉流代理总数:{{proxyInfo.total}}<br/> 31 拉流代理总数:{{proxyInfo.total}}<br/>
28 在线数:{{proxyInfo.online}} 32 在线数:{{proxyInfo.online}}
web_src/src/components/dialog/devicePlayer.vue
1 <template> 1 <template>
2 -<div id="devicePlayer" v-loading="isLoging"> 2 + <div id="devicePlayer" v-loading="isLoging">
3 3
4 <el-dialog title="视频播放" top="0" :close-on-click-modal="false" :visible.sync="showVideoDialog" @close="close()"> 4 <el-dialog title="视频播放" top="0" :close-on-click-modal="false" :visible.sync="showVideoDialog" @close="close()">
5 <div style="width: 100%; height: 100%"> 5 <div style="width: 100%; height: 100%">
6 - <el-tabs type="card" :stretch="true" v-model="activePlayer" @tab-click="changePlayer" v-if="Object.keys(this.player).length > 1"> 6 + <el-tabs type="card" :stretch="true" v-model="activePlayer" @tab-click="changePlayer"
  7 + v-if="Object.keys(this.player).length > 1">
7 <el-tab-pane label="Jessibuca" name="jessibuca"> 8 <el-tab-pane label="Jessibuca" name="jessibuca">
8 - <jessibucaPlayer v-if="activePlayer === 'jessibuca'" ref="jessibuca" :visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px" :hasAudio="hasAudio" fluent autoplay live ></jessibucaPlayer> 9 + <jessibucaPlayer v-if="activePlayer === 'jessibuca'" ref="jessibuca" :visible.sync="showVideoDialog"
  10 + :videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px"
  11 + :hasAudio="hasAudio" fluent autoplay live></jessibucaPlayer>
9 </el-tab-pane> 12 </el-tab-pane>
10 <el-tab-pane label="WebRTC" name="webRTC"> 13 <el-tab-pane label="WebRTC" name="webRTC">
11 - <rtc-player v-if="activePlayer === 'webRTC'" ref="webRTC" :visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px" :hasAudio="hasAudio" fluent autoplay live ></rtc-player> 14 + <rtc-player v-if="activePlayer === 'webRTC'" ref="webRTC" :visible.sync="showVideoDialog"
  15 + :videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px"
  16 + :hasAudio="hasAudio" fluent autoplay live></rtc-player>
12 </el-tab-pane> 17 </el-tab-pane>
13 <el-tab-pane label="h265web">h265web敬请期待</el-tab-pane> 18 <el-tab-pane label="h265web">h265web敬请期待</el-tab-pane>
14 <el-tab-pane label="wsPlayer">wsPlayer 敬请期待</el-tab-pane> 19 <el-tab-pane label="wsPlayer">wsPlayer 敬请期待</el-tab-pane>
15 </el-tabs> 20 </el-tabs>
16 - <jessibucaPlayer v-if="Object.keys(this.player).length == 1 && this.player.jessibuca" ref="jessibuca" :visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px" :hasAudio="hasAudio" fluent autoplay live ></jessibucaPlayer>  
17 - <rtc-player v-if="Object.keys(this.player).length == 1 && this.player.webRTC" ref="jessibuca" :visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px" :hasAudio="hasAudio" fluent autoplay live ></rtc-player> 21 + <jessibucaPlayer v-if="Object.keys(this.player).length == 1 && this.player.jessibuca" ref="jessibuca"
  22 + :visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError"
  23 + height="100px" :hasAudio="hasAudio" fluent autoplay live></jessibucaPlayer>
  24 + <rtc-player v-if="Object.keys(this.player).length == 1 && this.player.webRTC" ref="jessibuca"
  25 + :visible.sync="showVideoDialog" :videoUrl="videoUrl" :error="videoError" :message="videoError"
  26 + height="100px" :hasAudio="hasAudio" fluent autoplay live></rtc-player>
18 27
19 </div> 28 </div>
20 - <div id="shared" style="text-align: right; margin-top: 1rem;">  
21 - <el-tabs v-model="tabActiveName" @tab-click="tabHandleClick" >  
22 - <el-tab-pane label="实时视频" name="media">  
23 - <div style="margin-bottom: 0.5rem;">  
24 - <!-- <el-button type="primary" size="small" @click="playRecord(true, '')">播放</el-button>-->  
25 - <!-- <el-button type="primary" size="small" @click="startRecord()">录制</el-button>-->  
26 - <!-- <el-button type="primary" size="small" @click="stopRecord()">停止录制</el-button>-->  
27 - </div>  
28 - <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">  
29 - <span style="width: 5rem; line-height: 2.5rem; text-align: right;">播放地址:</span>  
30 - <el-input v-model="getPlayerShared.sharedUrl" :disabled="true" >  
31 - <template slot="append">  
32 - <i class="cpoy-btn el-icon-document-copy" title="点击拷贝" v-clipboard="getPlayerShared.sharedUrl" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></i>  
33 - </template>  
34 - </el-input>  
35 - </div>  
36 - <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">  
37 - <span style="width: 5rem; line-height: 2.5rem; text-align: right;">iframe:</span>  
38 - <el-input v-model="getPlayerShared.sharedIframe" :disabled="true" >  
39 - <template slot="append">  
40 - <i class="cpoy-btn el-icon-document-copy" title="点击拷贝" v-clipboard="getPlayerShared.sharedIframe" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></i>  
41 - </template>  
42 - </el-input>  
43 - </div>  
44 - <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">  
45 - <span style="width: 5rem; line-height: 2.5rem; text-align: right;">资源地址:</span>  
46 - <el-input v-model="getPlayerShared.sharedRtmp" :disabled="true" >  
47 - <el-button slot="append" icon="el-icon-document-copy" title="点击拷贝" v-clipboard="getPlayerShared.sharedRtmp" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></el-button>  
48 - <el-dropdown slot="prepend" v-if="streamInfo" trigger="click" @command="copyUrl">  
49 - <el-button >  
50 - 更多地址<i class="el-icon-arrow-down el-icon--right"></i>  
51 - </el-button>  
52 - <el-dropdown-menu slot="dropdown" >  
53 - <el-dropdown-item v-if="streamInfo.flv" :command="streamInfo.flv.url">  
54 - <el-tag >FLV:</el-tag>  
55 - <span>{{ streamInfo.flv.url }}</span>  
56 - </el-dropdown-item>  
57 - <el-dropdown-item v-if="streamInfo.https_flv" :command="streamInfo.https_flv.url">  
58 - <el-tag >FLV(https):</el-tag>  
59 - <span>{{ streamInfo.https_flv.url }}</span>  
60 - </el-dropdown-item>  
61 - <el-dropdown-item v-if="streamInfo.ws_flv" :command="streamInfo.ws_flv.url">  
62 - <el-tag >FLV(ws):</el-tag>  
63 - <span >{{ streamInfo.ws_flv.url }}</span>  
64 - </el-dropdown-item>  
65 - <el-dropdown-item v-if="streamInfo.wss_flv" :command="streamInfo.wss_flv.url">  
66 - <el-tag >FLV(wss):</el-tag>  
67 - <span>{{ streamInfo.wss_flv.url }}</span>  
68 - </el-dropdown-item>  
69 - <el-dropdown-item v-if="streamInfo.fmp4" :command="streamInfo.fmp4.url">  
70 - <el-tag >FMP4:</el-tag>  
71 - <span>{{ streamInfo.fmp4.url }}</span>  
72 - </el-dropdown-item>  
73 - <el-dropdown-item v-if="streamInfo.https_fmp4" :command="streamInfo.https_fmp4.url">  
74 - <el-tag >FMP4(https):</el-tag>  
75 - <span>{{ streamInfo.https_fmp4.url }}</span>  
76 - </el-dropdown-item>  
77 - <el-dropdown-item v-if="streamInfo.ws_fmp4" :command="streamInfo.ws_fmp4.url">  
78 - <el-tag >FMP4(ws):</el-tag>  
79 - <span>{{ streamInfo.ws_fmp4.url }}</span>  
80 - </el-dropdown-item>  
81 - <el-dropdown-item v-if="streamInfo.wss_fmp4" :command="streamInfo.wss_fmp4.url">  
82 - <el-tag >FMP4(wss):</el-tag>  
83 - <span>{{ streamInfo.wss_fmp4.url }}</span>  
84 - </el-dropdown-item>  
85 - <el-dropdown-item v-if="streamInfo.hls" :command="streamInfo.hls.url">  
86 - <el-tag>HLS:</el-tag>  
87 - <span>{{ streamInfo.hls.url }}</span>  
88 - </el-dropdown-item>  
89 - <el-dropdown-item v-if="streamInfo.https_hls" :command="streamInfo.https_hls.url">  
90 - <el-tag >HLS(https):</el-tag>  
91 - <span>{{ streamInfo.https_hls.url }}</span>  
92 - </el-dropdown-item>  
93 - <el-dropdown-item v-if="streamInfo.ws_hls" :command="streamInfo.ws_hls.url">  
94 - <el-tag >HLS(ws):</el-tag>  
95 - <span>{{ streamInfo.ws_hls.url }}</span>  
96 - </el-dropdown-item>  
97 - <el-dropdown-item v-if="streamInfo.wss_hls" :command="streamInfo.wss_hls.url">  
98 - <el-tag >HLS(wss):</el-tag>  
99 - <span>{{ streamInfo.wss_hls.url }}</span>  
100 - </el-dropdown-item>  
101 - <el-dropdown-item v-if="streamInfo.ts" :command="streamInfo.ts.url">  
102 - <el-tag>TS:</el-tag>  
103 - <span>{{ streamInfo.ts.url }}</span>  
104 - </el-dropdown-item>  
105 - <el-dropdown-item v-if="streamInfo.https_ts" :command="streamInfo.https_ts.url">  
106 - <el-tag>TS(https):</el-tag>  
107 - <span>{{ streamInfo.https_ts.url }}</span>  
108 - </el-dropdown-item>  
109 - <el-dropdown-item v-if="streamInfo.ws_ts" :command="streamInfo.ws_ts.url">  
110 - <el-tag>TS(ws):</el-tag>  
111 - <span>{{ streamInfo.ws_ts.url }}</span>  
112 - </el-dropdown-item>  
113 - <el-dropdown-item v-if="streamInfo.wss_ts" :command="streamInfo.wss_ts.url">  
114 - <el-tag>TS(wss):</el-tag>  
115 - <span>{{ streamInfo.wss_ts.url }}</span>  
116 - </el-dropdown-item>  
117 - <el-dropdown-item v-if="streamInfo.rtc" :command="streamInfo.rtc.url">  
118 - <el-tag >RTC:</el-tag>  
119 - <span>{{ streamInfo.rtc.url }}</span>  
120 - </el-dropdown-item>  
121 - <el-dropdown-item v-if="streamInfo.rtcs" :command="streamInfo.rtcs.url">  
122 - <el-tag >RTCS:</el-tag>  
123 - <span>{{ streamInfo.rtcs }}</span>  
124 - </el-dropdown-item>  
125 - <el-dropdown-item v-if="streamInfo.rtmp" :command="streamInfo.rtmp.url">  
126 - <el-tag >RTMP:</el-tag>  
127 - <span>{{ streamInfo.rtmp.url }}</span>  
128 - </el-dropdown-item>  
129 - <el-dropdown-item v-if="streamInfo.rtmps" :command="streamInfo.rtmps.url">  
130 - <el-tag >RTMPS:</el-tag>  
131 - <span>{{ streamInfo.rtmps.url }}</span>  
132 - </el-dropdown-item>  
133 - <el-dropdown-item v-if="streamInfo.rtsp" :command="streamInfo.rtsp.url">  
134 - <el-tag >RTSP:</el-tag>  
135 - <span>{{ streamInfo.rtsp.url }}</span>  
136 - </el-dropdown-item>  
137 - <el-dropdown-item v-if="streamInfo.rtsps" :command="streamInfo.rtsps.url">  
138 - <el-tag >RTSPS:</el-tag>  
139 - <span>{{ streamInfo.rtsps.url }}</span>  
140 - </el-dropdown-item>  
141 - </el-dropdown-menu>  
142 - </el-dropdown>  
143 - </el-input>  
144 -  
145 - </div>  
146 - </el-tab-pane>  
147 - <!--{"code":0,"data":{"paths":["22-29-30.mp4"],"rootPath":"/home/kkkkk/Documents/ZLMediaKit/release/linux/Debug/www/record/hls/kkkkk/2020-05-11/"}}-->  
148 - <el-tab-pane label="录像查询" name="record" v-if="showRrecord">  
149 - <div style="width: 100%;">  
150 - <div style="width: 100%; text-align: left">  
151 - <span>录像控制</span>  
152 - <el-button-group style="margin-left: 1rem;">  
153 - <el-button size="mini" class="iconfont icon-zanting" title="开始" @click="gbPause()"></el-button>  
154 - <el-button size="mini" class="iconfont icon-kaishi" title="暂停" @click="gbPlay()"></el-button>  
155 - <el-dropdown size="mini" title="播放倍速" style="margin-left: 1px;" @command="gbScale">  
156 - <el-button size="mini">  
157 - 倍速 <i class="el-icon-arrow-down el-icon--right"></i>  
158 - </el-button>  
159 - <el-dropdown-menu slot="dropdown">  
160 - <el-dropdown-item command="0.25">0.25倍速</el-dropdown-item>  
161 - <el-dropdown-item command="0.5">0.5倍速</el-dropdown-item>  
162 - <el-dropdown-item command="1.0">1倍速</el-dropdown-item>  
163 - <el-dropdown-item command="2.0">2倍速</el-dropdown-item>  
164 - <el-dropdown-item command="4.0">4倍速</el-dropdown-item>  
165 - </el-dropdown-menu>  
166 - </el-dropdown>  
167 - </el-button-group>  
168 - <el-date-picker style="float: right;" size="mini" v-model="videoHistory.date" type="date" value-format="yyyy-MM-dd" placeholder="日期" @change="queryRecords()"></el-date-picker>  
169 - </div>  
170 - <div style="width: 100%; text-align: left">  
171 - <span class="demonstration" style="padding: 12px 36px 12px 0;float: left;">{{showTimeText}}</span>  
172 - <el-slider style="width: 80%; float:left;" v-model="sliderTime" @change="gbSeek" :show-tooltip="false"></el-slider>  
173 - </div>  
174 - </div>  
175 -  
176 -  
177 - <el-table :data="videoHistory.searchHistoryResult" height="150" v-loading="recordsLoading">  
178 - <el-table-column label="名称" prop="name"></el-table-column>  
179 - <el-table-column label="文件" prop="filePath"></el-table-column>  
180 - <el-table-column label="开始时间" prop="startTime" :formatter="timeFormatter"></el-table-column>  
181 - <el-table-column label="结束时间" prop="endTime" :formatter="timeFormatter"></el-table-column>  
182 -  
183 - <el-table-column label="操作">  
184 - <template slot-scope="scope">  
185 - <el-button-group>  
186 - <el-button icon="el-icon-video-play" size="mini" @click="playRecord(scope.row)">播放</el-button>  
187 - <el-button icon="el-icon-download" size="mini" @click="downloadRecord(scope.row)">下载</el-button>  
188 - </el-button-group>  
189 - </template>  
190 - </el-table-column>  
191 - </el-table>  
192 - </el-tab-pane>  
193 - <!--遥控界面-->  
194 - <el-tab-pane label="云台控制" name="control" v-if="showPtz">  
195 - <div style="display: flex; justify-content: left;">  
196 - <div class="control-wrapper">  
197 - <div class="control-btn control-top" @mousedown="ptzCamera('up')" @mouseup="ptzCamera('stop')">  
198 - <i class="el-icon-caret-top"></i>  
199 - <div class="control-inner-btn control-inner"></div>  
200 - </div>  
201 - <div class="control-btn control-left" @mousedown="ptzCamera('left')" @mouseup="ptzCamera('stop')">  
202 - <i class="el-icon-caret-left"></i>  
203 - <div class="control-inner-btn control-inner"></div>  
204 - </div>  
205 - <div class="control-btn control-bottom" @mousedown="ptzCamera('down')" @mouseup="ptzCamera('stop')">  
206 - <i class="el-icon-caret-bottom"></i>  
207 - <div class="control-inner-btn control-inner"></div>  
208 - </div>  
209 - <div class="control-btn control-right" @mousedown="ptzCamera('right')" @mouseup="ptzCamera('stop')">  
210 - <i class="el-icon-caret-right"></i>  
211 - <div class="control-inner-btn control-inner"></div>  
212 - </div>  
213 - <div class="control-round">  
214 - <div class="control-round-inner"><i class="fa fa-pause-circle"></i></div>  
215 - </div>  
216 - <div style="position: absolute; left: 7.25rem; top: 1.25rem" @mousedown="ptzCamera('zoomin')" @mouseup="ptzCamera('stop')"><i class="el-icon-zoom-in control-zoom-btn" style="font-size: 1.875rem;"></i></div>  
217 - <div style="position: absolute; left: 7.25rem; top: 3.25rem; font-size: 1.875rem;" @mousedown="ptzCamera('zoomout')" @mouseup="ptzCamera('stop')"><i class="el-icon-zoom-out control-zoom-btn"></i></div>  
218 - <div class="contro-speed" style="position: absolute; left: 4px; top: 7rem; width: 9rem;">  
219 - <el-slider v-model="controSpeed" :max="255"></el-slider>  
220 - </div>  
221 - </div>  
222 -  
223 - <div class="control-panel">  
224 - <el-button-group>  
225 - <el-tag style="position :absolute; left: 0rem; top: 0rem; width: 5rem; text-align: center" size="medium">预置位编号</el-tag>  
226 - <el-input-number style="position: absolute; left: 5rem; top: 0rem; width: 6rem" size="mini" v-model="presetPos" controls-position="right" :precision="0" :step="1" :min="1" :max="255"></el-input-number>  
227 - <el-button style="position: absolute; left: 11rem; top: 0rem; width: 5rem" size="mini" icon="el-icon-add-location" @click="presetPosition(129, presetPos)">设置</el-button>  
228 - <el-button style="position: absolute; left: 27rem; top: 0rem; width: 5rem" size="mini" type="primary" icon="el-icon-place" @click="presetPosition(130, presetPos)">调用</el-button>  
229 - <el-button style="position: absolute; left: 16rem; top: 0rem; width: 5rem" size="mini" icon="el-icon-delete-location" @click="presetPosition(131, presetPos)">删除</el-button>  
230 - <el-tag style="position :absolute; left: 0rem; top: 2.5rem; width: 5rem; text-align: center" size="medium">巡航速度</el-tag>  
231 - <el-input-number style="position: absolute; left: 5rem; top: 2.5rem; width: 6rem" size="mini" v-model="cruisingSpeed" controls-position="right" :precision="0" :min="1" :max="4095"></el-input-number>  
232 - <el-button style="position: absolute; left: 11rem; top: 2.5rem; width: 5rem" size="mini" icon="el-icon-loading" @click="setSpeedOrTime(134, cruisingGroup, cruisingSpeed)">设置</el-button>  
233 - <el-tag style="position :absolute; left: 16rem; top: 2.5rem; width: 5rem; text-align: center" size="medium">停留时间</el-tag>  
234 - <el-input-number style="position: absolute; left: 21rem; top: 2.5rem; width: 6rem" size="mini" v-model="cruisingTime" controls-position="right" :precision="0" :min="1" :max="4095"></el-input-number>  
235 - <el-button style="position: absolute; left: 27rem; top: 2.5rem; width: 5rem" size="mini" icon="el-icon-timer" @click="setSpeedOrTime(135, cruisingGroup, cruisingTime)">设置</el-button>  
236 - <el-tag style="position :absolute; left: 0rem; top: 4.5rem; width: 5rem; text-align: center" size="medium">巡航组编号</el-tag>  
237 - <el-input-number style="position: absolute; left: 5rem; top: 4.5rem; width: 6rem" size="mini" v-model="cruisingGroup" controls-position="right" :precision="0" :min="0" :max="255"></el-input-number>  
238 - <el-button style="position: absolute; left: 11rem; top: 4.5rem; width: 5rem" size="mini" icon="el-icon-add-location" @click="setCommand(132, cruisingGroup, presetPos)">添加点</el-button>  
239 - <el-button style="position: absolute; left: 16rem; top: 4.5rem; width: 5rem" size="mini" icon="el-icon-delete-location" @click="setCommand(133, cruisingGroup, presetPos)">删除点</el-button>  
240 - <el-button style="position: absolute; left: 21rem; top: 4.5rem; width: 5rem" size="mini" icon="el-icon-delete" @click="setCommand(133, cruisingGroup, 0)">删除组</el-button>  
241 - <el-button style="position: absolute; left: 27rem; top: 5rem; width: 5rem" size="mini" type="primary" icon="el-icon-video-camera-solid" @click="setCommand(136, cruisingGroup, 0)">巡航</el-button>  
242 - <el-tag style="position :absolute; left: 0rem; top: 7rem; width: 5rem; text-align: center" size="medium">扫描速度</el-tag>  
243 - <el-input-number style="position: absolute; left: 5rem; top: 7rem; width: 6rem" size="mini" v-model="scanSpeed" controls-position="right" :precision="0" :min="1" :max="4095"></el-input-number>  
244 - <el-button style="position: absolute; left: 11rem; top: 7rem; width: 5rem" size="mini" icon="el-icon-loading" @click="setSpeedOrTime(138, scanGroup, scanSpeed)">设置</el-button>  
245 - <el-tag style="position :absolute; left: 0rem; top: 9rem; width: 5rem; text-align: center" size="medium">扫描组编号</el-tag>  
246 - <el-input-number style="position: absolute; left: 5rem; top: 9rem; width: 6rem" size="mini" v-model="scanGroup" controls-position="right" :precision="0" :step="1" :min="0" :max="255"></el-input-number>  
247 - <el-button style="position: absolute; left: 11rem; top: 9rem; width: 5rem" size="mini" icon="el-icon-d-arrow-left" @click="setCommand(137, scanGroup, 1)">左边界</el-button>  
248 - <el-button style="position: absolute; left: 16rem; top: 9rem; width: 5rem" size="mini" icon="el-icon-d-arrow-right" @click="setCommand(137, scanGroup, 2)">右边界</el-button>  
249 - <el-button style="position: absolute; left: 27rem; top: 7rem; width: 5rem" size="mini" type="primary" icon="el-icon-video-camera-solid" @click="setCommand(137, scanGroup, 0)">扫描</el-button>  
250 - <el-button style="position: absolute; left: 27rem; top: 9rem; width: 5rem" size="mini" type="danger" icon="el-icon-switch-button" @click="ptzCamera('stop')">停止</el-button>  
251 - </el-button-group>  
252 - </div>  
253 - </div>  
254 - </el-tab-pane>  
255 - <el-tab-pane label="编码信息" name="codec" v-loading="tracksLoading">  
256 - <p>  
257 - 无法播放或者没有声音?&nbsp&nbsp&nbsp试一试&nbsp  
258 - <el-button size="mini" type="primary" v-if="!coverPlaying" @click="coverPlay">转码播放</el-button>  
259 - <el-button size="mini" type="danger" v-if="coverPlaying" @click="convertStopClick">停止转码</el-button>  
260 - </p>  
261 - <div class="trank" >  
262 - <p v-if="tracksNotLoaded" style="text-align: center;padding-top: 3rem;">暂无数据</p>  
263 - <div v-for="(item, index) in tracks" style="width: 50%; float: left" loading>  
264 - <span >流 {{index}}</span>  
265 - <div class="trankInfo" v-if="item.codec_type == 0">  
266 - <p>格式: {{item.codec_id_name}}</p>  
267 - <p>类型: 视频</p>  
268 - <p>分辨率: {{item.width}} x {{item.height}}</p>  
269 - <p>帧率: {{item.fps}}</p>  
270 - </div>  
271 - <div class="trankInfo" v-if="item.codec_type == 1">  
272 - <p>格式: {{item.codec_id_name}}</p>  
273 - <p>类型: 音频</p>  
274 - <p>采样位数: {{item.sample_bit}}</p>  
275 - <p>采样率: {{item.sample_rate}}</p>  
276 - </div>  
277 - </div>  
278 -  
279 - </div> 29 + <div id="shared" style="text-align: right; margin-top: 1rem;">
  30 + <el-tabs v-model="tabActiveName" @tab-click="tabHandleClick">
  31 + <el-tab-pane label="实时视频" name="media">
  32 + <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
  33 + <span style="width: 5rem; line-height: 2.5rem; text-align: right;">播放地址:</span>
  34 + <el-input v-model="getPlayerShared.sharedUrl" :disabled="true">
  35 + <template slot="append">
  36 + <i class="cpoy-btn el-icon-document-copy" title="点击拷贝" v-clipboard="getPlayerShared.sharedUrl"
  37 + @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></i>
  38 + </template>
  39 + </el-input>
  40 + </div>
  41 + <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
  42 + <span style="width: 5rem; line-height: 2.5rem; text-align: right;">iframe:</span>
  43 + <el-input v-model="getPlayerShared.sharedIframe" :disabled="true">
  44 + <template slot="append">
  45 + <i class="cpoy-btn el-icon-document-copy" title="点击拷贝" v-clipboard="getPlayerShared.sharedIframe"
  46 + @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></i>
  47 + </template>
  48 + </el-input>
  49 + </div>
  50 + <div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
  51 + <span style="width: 5rem; line-height: 2.5rem; text-align: right;">资源地址:</span>
  52 + <el-input v-model="getPlayerShared.sharedRtmp" :disabled="true">
  53 + <el-button slot="append" icon="el-icon-document-copy" title="点击拷贝"
  54 + v-clipboard="getPlayerShared.sharedRtmp"
  55 + @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></el-button>
  56 + <el-dropdown slot="prepend" v-if="streamInfo" trigger="click" @command="copyUrl">
  57 + <el-button>
  58 + 更多地址<i class="el-icon-arrow-down el-icon--right"></i>
  59 + </el-button>
  60 + <el-dropdown-menu slot="dropdown">
  61 + <el-dropdown-item v-if="streamInfo.flv" :command="streamInfo.flv">
  62 + <el-tag>FLV:</el-tag>
  63 + <span>{{ streamInfo.flv }}</span>
  64 + </el-dropdown-item>
  65 + <el-dropdown-item v-if="streamInfo.https_flv" :command="streamInfo.https_flv">
  66 + <el-tag>FLV(https):</el-tag>
  67 + <span>{{ streamInfo.https_flv }}</span>
  68 + </el-dropdown-item>
  69 + <el-dropdown-item v-if="streamInfo.ws_flv" :command="streamInfo.ws_flv">
  70 + <el-tag>FLV(ws):</el-tag>
  71 + <span>{{ streamInfo.ws_flv }}</span>
  72 + </el-dropdown-item>
  73 + <el-dropdown-item v-if="streamInfo.wss_flv" :command="streamInfo.wss_flv">
  74 + <el-tag>FLV(wss):</el-tag>
  75 + <span>{{ streamInfo.wss_flv }}</span>
  76 + </el-dropdown-item>
  77 + <el-dropdown-item v-if="streamInfo.fmp4" :command="streamInfo.fmp4">
  78 + <el-tag>FMP4:</el-tag>
  79 + <span>{{ streamInfo.fmp4 }}</span>
  80 + </el-dropdown-item>
  81 + <el-dropdown-item v-if="streamInfo.https_fmp4" :command="streamInfo.https_fmp4">
  82 + <el-tag>FMP4(https):</el-tag>
  83 + <span>{{ streamInfo.https_fmp4 }}</span>
  84 + </el-dropdown-item>
  85 + <el-dropdown-item v-if="streamInfo.ws_fmp4" :command="streamInfo.ws_fmp4">
  86 + <el-tag>FMP4(ws):</el-tag>
  87 + <span>{{ streamInfo.ws_fmp4 }}</span>
  88 + </el-dropdown-item>
  89 + <el-dropdown-item v-if="streamInfo.wss_fmp4" :command="streamInfo.wss_fmp4">
  90 + <el-tag>FMP4(wss):</el-tag>
  91 + <span>{{ streamInfo.wss_fmp4 }}</span>
  92 + </el-dropdown-item>
  93 + <el-dropdown-item v-if="streamInfo.hls" :command="streamInfo.hls">
  94 + <el-tag>HLS:</el-tag>
  95 + <span>{{ streamInfo.hls }}</span>
  96 + </el-dropdown-item>
  97 + <el-dropdown-item v-if="streamInfo.https_hls" :command="streamInfo.https_hls">
  98 + <el-tag>HLS(https):</el-tag>
  99 + <span>{{ streamInfo.https_hls }}</span>
  100 + </el-dropdown-item>
  101 + <el-dropdown-item v-if="streamInfo.ws_hls" :command="streamInfo.ws_hls">
  102 + <el-tag>HLS(ws):</el-tag>
  103 + <span>{{ streamInfo.ws_hls }}</span>
  104 + </el-dropdown-item>
  105 + <el-dropdown-item v-if="streamInfo.wss_hls" :command="streamInfo.wss_hls">
  106 + <el-tag>HLS(wss):</el-tag>
  107 + <span>{{ streamInfo.wss_hls }}</span>
  108 + </el-dropdown-item>
  109 + <el-dropdown-item v-if="streamInfo.ts" :command="streamInfo.ts">
  110 + <el-tag>TS:</el-tag>
  111 + <span>{{ streamInfo.ts }}</span>
  112 + </el-dropdown-item>
  113 + <el-dropdown-item v-if="streamInfo.https_ts" :command="streamInfo.https_ts">
  114 + <el-tag>TS(https):</el-tag>
  115 + <span>{{ streamInfo.https_ts }}</span>
  116 + </el-dropdown-item>
  117 + <el-dropdown-item v-if="streamInfo.ws_ts" :command="streamInfo.ws_ts">
  118 + <el-tag>TS(ws):</el-tag>
  119 + <span>{{ streamInfo.ws_ts }}</span>
  120 + </el-dropdown-item>
  121 + <el-dropdown-item v-if="streamInfo.wss_ts" :command="streamInfo.wss_ts">
  122 + <el-tag>TS(wss):</el-tag>
  123 + <span>{{ streamInfo.wss_ts }}</span>
  124 + </el-dropdown-item>
  125 + <el-dropdown-item v-if="streamInfo.rtc" :command="streamInfo.rtc">
  126 + <el-tag>RTC:</el-tag>
  127 + <span>{{ streamInfo.rtc }}</span>
  128 + </el-dropdown-item>
  129 + <el-dropdown-item v-if="streamInfo.rtcs" :command="streamInfo.rtcs">
  130 + <el-tag>RTCS:</el-tag>
  131 + <span>{{ streamInfo.rtcs }}</span>
  132 + </el-dropdown-item>
  133 + <el-dropdown-item v-if="streamInfo.rtmp" :command="streamInfo.rtmp">
  134 + <el-tag>RTMP:</el-tag>
  135 + <span>{{ streamInfo.rtmp }}</span>
  136 + </el-dropdown-item>
  137 + <el-dropdown-item v-if="streamInfo.rtmps" :command="streamInfo.rtmps">
  138 + <el-tag>RTMPS:</el-tag>
  139 + <span>{{ streamInfo.rtmps }}</span>
  140 + </el-dropdown-item>
  141 + <el-dropdown-item v-if="streamInfo.rtsp" :command="streamInfo.rtsp">
  142 + <el-tag>RTSP:</el-tag>
  143 + <span>{{ streamInfo.rtsp }}</span>
  144 + </el-dropdown-item>
  145 + <el-dropdown-item v-if="streamInfo.rtsps" :command="streamInfo.rtsps">
  146 + <el-tag>RTSPS:</el-tag>
  147 + <span>{{ streamInfo.rtsps }}</span>
  148 + </el-dropdown-item>
  149 + </el-dropdown-menu>
  150 + </el-dropdown>
  151 + </el-input>
  152 +
  153 + </div>
  154 + </el-tab-pane>
  155 + <!--{"code":0,"data":{"paths":["22-29-30.mp4"],"rootPath":"/home/kkkkk/Documents/ZLMediaKit/release/linux/Debug/www/record/hls/kkkkk/2020-05-11/"}}-->
  156 + <!--遥控界面-->
  157 + <el-tab-pane label="云台控制" name="control" v-if="showPtz">
  158 + <div style="display: flex; justify-content: left;">
  159 + <div class="control-wrapper">
  160 + <div class="control-btn control-top" @mousedown="ptzCamera('up')" @mouseup="ptzCamera('stop')">
  161 + <i class="el-icon-caret-top"></i>
  162 + <div class="control-inner-btn control-inner"></div>
  163 + </div>
  164 + <div class="control-btn control-left" @mousedown="ptzCamera('left')" @mouseup="ptzCamera('stop')">
  165 + <i class="el-icon-caret-left"></i>
  166 + <div class="control-inner-btn control-inner"></div>
  167 + </div>
  168 + <div class="control-btn control-bottom" @mousedown="ptzCamera('down')" @mouseup="ptzCamera('stop')">
  169 + <i class="el-icon-caret-bottom"></i>
  170 + <div class="control-inner-btn control-inner"></div>
  171 + </div>
  172 + <div class="control-btn control-right" @mousedown="ptzCamera('right')" @mouseup="ptzCamera('stop')">
  173 + <i class="el-icon-caret-right"></i>
  174 + <div class="control-inner-btn control-inner"></div>
  175 + </div>
  176 + <div class="control-round">
  177 + <div class="control-round-inner"><i class="fa fa-pause-circle"></i></div>
  178 + </div>
  179 + <div style="position: absolute; left: 7.25rem; top: 1.25rem" @mousedown="ptzCamera('zoomin')"
  180 + @mouseup="ptzCamera('stop')"><i class="el-icon-zoom-in control-zoom-btn"
  181 + style="font-size: 1.875rem;"></i></div>
  182 + <div style="position: absolute; left: 7.25rem; top: 3.25rem; font-size: 1.875rem;"
  183 + @mousedown="ptzCamera('zoomout')" @mouseup="ptzCamera('stop')"><i
  184 + class="el-icon-zoom-out control-zoom-btn"></i></div>
  185 + <div class="contro-speed" style="position: absolute; left: 4px; top: 7rem; width: 9rem;">
  186 + <el-slider v-model="controSpeed" :max="255"></el-slider>
  187 + </div>
  188 + </div>
  189 +
  190 + <div class="control-panel">
  191 + <el-button-group>
  192 + <el-tag style="position :absolute; left: 0rem; top: 0rem; width: 5rem; text-align: center"
  193 + size="medium">预置位编号
  194 + </el-tag>
  195 + <el-input-number style="position: absolute; left: 5rem; top: 0rem; width: 6rem" size="mini"
  196 + v-model="presetPos" controls-position="right" :precision="0" :step="1" :min="1"
  197 + :max="255"></el-input-number>
  198 + <el-button style="position: absolute; left: 11rem; top: 0rem; width: 5rem" size="mini"
  199 + icon="el-icon-add-location" @click="presetPosition(129, presetPos)">设置
  200 + </el-button>
  201 + <el-button style="position: absolute; left: 27rem; top: 0rem; width: 5rem" size="mini" type="primary"
  202 + icon="el-icon-place" @click="presetPosition(130, presetPos)">调用
  203 + </el-button>
  204 + <el-button style="position: absolute; left: 16rem; top: 0rem; width: 5rem" size="mini"
  205 + icon="el-icon-delete-location" @click="presetPosition(131, presetPos)">删除
  206 + </el-button>
  207 + <el-tag style="position :absolute; left: 0rem; top: 2.5rem; width: 5rem; text-align: center"
  208 + size="medium">巡航速度
  209 + </el-tag>
  210 + <el-input-number style="position: absolute; left: 5rem; top: 2.5rem; width: 6rem" size="mini"
  211 + v-model="cruisingSpeed" controls-position="right" :precision="0" :min="1"
  212 + :max="4095"></el-input-number>
  213 + <el-button style="position: absolute; left: 11rem; top: 2.5rem; width: 5rem" size="mini"
  214 + icon="el-icon-loading" @click="setSpeedOrTime(134, cruisingGroup, cruisingSpeed)">设置
  215 + </el-button>
  216 + <el-tag style="position :absolute; left: 16rem; top: 2.5rem; width: 5rem; text-align: center"
  217 + size="medium">停留时间
  218 + </el-tag>
  219 + <el-input-number style="position: absolute; left: 21rem; top: 2.5rem; width: 6rem" size="mini"
  220 + v-model="cruisingTime" controls-position="right" :precision="0" :min="1"
  221 + :max="4095"></el-input-number>
  222 + <el-button style="position: absolute; left: 27rem; top: 2.5rem; width: 5rem" size="mini"
  223 + icon="el-icon-timer" @click="setSpeedOrTime(135, cruisingGroup, cruisingTime)">设置
  224 + </el-button>
  225 + <el-tag style="position :absolute; left: 0rem; top: 4.5rem; width: 5rem; text-align: center"
  226 + size="medium">巡航组编号
  227 + </el-tag>
  228 + <el-input-number style="position: absolute; left: 5rem; top: 4.5rem; width: 6rem" size="mini"
  229 + v-model="cruisingGroup" controls-position="right" :precision="0" :min="0"
  230 + :max="255"></el-input-number>
  231 + <el-button style="position: absolute; left: 11rem; top: 4.5rem; width: 5rem" size="mini"
  232 + icon="el-icon-add-location" @click="setCommand(132, cruisingGroup, presetPos)">添加点
  233 + </el-button>
  234 + <el-button style="position: absolute; left: 16rem; top: 4.5rem; width: 5rem" size="mini"
  235 + icon="el-icon-delete-location" @click="setCommand(133, cruisingGroup, presetPos)">删除点
  236 + </el-button>
  237 + <el-button style="position: absolute; left: 21rem; top: 4.5rem; width: 5rem" size="mini"
  238 + icon="el-icon-delete" @click="setCommand(133, cruisingGroup, 0)">删除组
  239 + </el-button>
  240 + <el-button style="position: absolute; left: 27rem; top: 5rem; width: 5rem" size="mini" type="primary"
  241 + icon="el-icon-video-camera-solid" @click="setCommand(136, cruisingGroup, 0)">巡航
  242 + </el-button>
  243 + <el-tag style="position :absolute; left: 0rem; top: 7rem; width: 5rem; text-align: center"
  244 + size="medium">扫描速度
  245 + </el-tag>
  246 + <el-input-number style="position: absolute; left: 5rem; top: 7rem; width: 6rem" size="mini"
  247 + v-model="scanSpeed" controls-position="right" :precision="0" :min="1"
  248 + :max="4095"></el-input-number>
  249 + <el-button style="position: absolute; left: 11rem; top: 7rem; width: 5rem" size="mini"
  250 + icon="el-icon-loading" @click="setSpeedOrTime(138, scanGroup, scanSpeed)">设置
  251 + </el-button>
  252 + <el-tag style="position :absolute; left: 0rem; top: 9rem; width: 5rem; text-align: center"
  253 + size="medium">扫描组编号
  254 + </el-tag>
  255 + <el-input-number style="position: absolute; left: 5rem; top: 9rem; width: 6rem" size="mini"
  256 + v-model="scanGroup" controls-position="right" :precision="0" :step="1" :min="0"
  257 + :max="255"></el-input-number>
  258 + <el-button style="position: absolute; left: 11rem; top: 9rem; width: 5rem" size="mini"
  259 + icon="el-icon-d-arrow-left" @click="setCommand(137, scanGroup, 1)">左边界
  260 + </el-button>
  261 + <el-button style="position: absolute; left: 16rem; top: 9rem; width: 5rem" size="mini"
  262 + icon="el-icon-d-arrow-right" @click="setCommand(137, scanGroup, 2)">右边界
  263 + </el-button>
  264 + <el-button style="position: absolute; left: 27rem; top: 7rem; width: 5rem" size="mini" type="primary"
  265 + icon="el-icon-video-camera-solid" @click="setCommand(137, scanGroup, 0)">扫描
  266 + </el-button>
  267 + <el-button style="position: absolute; left: 27rem; top: 9rem; width: 5rem" size="mini" type="danger"
  268 + icon="el-icon-switch-button" @click="ptzCamera('stop')">停止
  269 + </el-button>
  270 + </el-button-group>
  271 + </div>
  272 + </div>
  273 + </el-tab-pane>
  274 + <el-tab-pane label="编码信息" name="codec" v-loading="tracksLoading">
  275 + <p>
  276 + 无法播放或者没有声音?&nbsp&nbsp&nbsp试一试&nbsp
  277 + <el-button size="mini" type="primary" v-if="!coverPlaying" @click="coverPlay">转码播放</el-button>
  278 + <el-button size="mini" type="danger" v-if="coverPlaying" @click="convertStopClick">停止转码</el-button>
  279 + </p>
  280 + <div class="trank">
  281 + <p v-if="tracksNotLoaded" style="text-align: center;padding-top: 3rem;">暂无数据</p>
  282 + <div v-for="(item, index) in tracks" style="width: 50%; float: left" loading>
  283 + <span>流 {{ index }}</span>
  284 + <div class="trankInfo" v-if="item.codec_type == 0">
  285 + <p>格式: {{ item.codec_id_name }}</p>
  286 + <p>类型: 视频</p>
  287 + <p>分辨率: {{ item.width }} x {{ item.height }}</p>
  288 + <p>帧率: {{ item.fps }}</p>
  289 + </div>
  290 + <div class="trankInfo" v-if="item.codec_type == 1">
  291 + <p>格式: {{ item.codec_id_name }}</p>
  292 + <p>类型: 音频</p>
  293 + <p>采样位数: {{ item.sample_bit }}</p>
  294 + <p>采样率: {{ item.sample_rate }}</p>
  295 + </div>
  296 + </div>
280 297
281 - </el-tab-pane>  
282 - <el-tab-pane label="语音喊话" name="broadcast" >  
283 - <div class="trank" style="text-align: center;">  
284 - <el-button @click="broadcastStatusClick()" :type="getBroadcastStatus()" :disabled="broadcastStatus === -2" circle icon="el-icon-microphone" style="font-size: 32px; padding: 24px;margin-top: 24px;"/>  
285 - <p>  
286 - <span v-if="broadcastStatus === -2">正在释放资源</span>  
287 - <span v-if="broadcastStatus === -1">点击开始对讲</span>  
288 - <span v-if="broadcastStatus === 0">等待接通中...</span>  
289 - <span v-if="broadcastStatus === 1">请说话</span>  
290 - </p> 298 + </div>
291 299
292 - </div>  
293 - </el-tab-pane> 300 + </el-tab-pane>
  301 + <el-tab-pane label="语音对讲" name="broadcast">
  302 + <div class="trank" style="text-align: center;">
  303 + <el-button @click="broadcastStatusClick()" :type="getBroadcastStatus()" :disabled="broadcastStatus === -2"
  304 + circle icon="el-icon-microphone" style="font-size: 32px; padding: 24px;margin-top: 24px;"/>
  305 + <p>
  306 + <span v-if="broadcastStatus === -2">正在释放资源</span>
  307 + <span v-if="broadcastStatus === -1">点击开始对讲</span>
  308 + <span v-if="broadcastStatus === 0">等待接通中...</span>
  309 + <span v-if="broadcastStatus === 1">请说话</span>
  310 + </p>
  311 +
  312 + </div>
  313 + </el-tab-pane>
294 314
295 - </el-tabs>  
296 - </div> 315 + </el-tabs>
  316 + </div>
297 </el-dialog> 317 </el-dialog>
298 - <recordDownload ref="recordDownload"></recordDownload>  
299 -</div> 318 + </div>
300 </template> 319 </template>
301 320
302 <script> 321 <script>
303 import rtcPlayer from '../dialog/rtcPlayer.vue' 322 import rtcPlayer from '../dialog/rtcPlayer.vue'
  323 +import LivePlayer from '@liveqing/liveplayer'
304 import crypto from 'crypto' 324 import crypto from 'crypto'
305 import jessibucaPlayer from '../common/jessibuca.vue' 325 import jessibucaPlayer from '../common/jessibuca.vue'
306 -import recordDownload from '../dialog/recordDownload.vue' 326 +
307 export default { 327 export default {
308 - name: 'devicePlayer',  
309 - props: {},  
310 - components: {  
311 - jessibucaPlayer, rtcPlayer, recordDownload, 328 + name: 'devicePlayer',
  329 + props: {},
  330 + components: {
  331 + LivePlayer, jessibucaPlayer, rtcPlayer,
  332 + },
  333 + computed: {
  334 + getPlayerShared: function () {
  335 + return {
  336 + sharedUrl: window.location.origin + '/#/play/wasm/' + encodeURIComponent(this.videoUrl),
  337 + sharedIframe: '<iframe src="' + window.location.origin + '/#/play/wasm/' + encodeURIComponent(this.videoUrl) + '"></iframe>',
  338 + sharedRtmp: this.videoUrl
  339 + };
  340 + }
  341 + },
  342 + created() {
  343 + console.log("created")
  344 + console.log(this.player)
  345 + this.broadcastStatus = -1;
  346 + if (Object.keys(this.player).length === 1) {
  347 + this.activePlayer = Object.keys(this.player)[0]
  348 + }
  349 + },
  350 + data() {
  351 + return {
  352 + video: 'http://lndxyj.iqilu.com/public/upload/2019/10/14/8c001ea0c09cdc59a57829dabc8010fa.mp4',
  353 + videoUrl: '',
  354 + activePlayer: "jessibuca",
  355 + // 如何你只是用一种播放器,直接注释掉不用的部分即可
  356 + player: {
  357 + jessibuca: ["ws_flv", "wss_flv"],
  358 + webRTC: ["rtc", "rtcs"],
  359 + },
  360 + showVideoDialog: false,
  361 + streamId: '',
  362 + app: '',
  363 + mediaServerId: '',
  364 + convertKey: '',
  365 + deviceId: '',
  366 + channelId: '',
  367 + tabActiveName: 'media',
  368 + hasAudio: false,
  369 + loadingRecords: false,
  370 + recordsLoading: false,
  371 + isLoging: false,
  372 + controSpeed: 30,
  373 + timeVal: 0,
  374 + timeMin: 0,
  375 + timeMax: 1440,
  376 + presetPos: 1,
  377 + cruisingSpeed: 100,
  378 + cruisingTime: 5,
  379 + cruisingGroup: 0,
  380 + scanSpeed: 100,
  381 + scanGroup: 0,
  382 + tracks: [],
  383 + coverPlaying: false,
  384 + tracksLoading: false,
  385 + showPtz: true,
  386 + showRrecord: true,
  387 + tracksNotLoaded: false,
  388 + sliderTime: 0,
  389 + seekTime: 0,
  390 + recordStartTime: 0,
  391 + showTimeText: "00:00:00",
  392 + streamInfo: null,
  393 + broadcastRtc: null,
  394 + broadcastStatus: -1, // -2 正在释放资源 -1 默认状态 0 等待接通 1 接通成功
  395 + };
  396 + },
  397 + methods: {
  398 + tabHandleClick: function (tab, event) {
  399 + console.log(tab)
  400 + var that = this;
  401 + that.tracks = [];
  402 + that.tracksLoading = true;
  403 + that.tracksNotLoaded = false;
  404 + if (tab.name === "codec") {
  405 + this.$axios({
  406 + method: 'get',
  407 + url: '/zlm/' + this.mediaServerId + '/index/api/getMediaInfo?vhost=__defaultVhost__&schema=rtsp&app=' + this.app + '&stream=' + this.streamId
  408 + }).then(function (res) {
  409 + that.tracksLoading = false;
  410 + if (res.data.code == 0 && res.data.tracks) {
  411 + that.tracks = res.data.tracks;
  412 + } else {
  413 + that.tracksNotLoaded = true;
  414 + that.$message({
  415 + showClose: true,
  416 + message: '获取编码信息失败,',
  417 + type: 'warning'
  418 + });
  419 + }
  420 + }).catch(function (e) {
  421 + });
  422 + }
312 }, 423 },
313 - computed: {  
314 - getPlayerShared: function () {  
315 - return {  
316 - sharedUrl: window.location.origin + '/#/play/wasm/' + encodeURIComponent(this.videoUrl),  
317 - sharedIframe: '<iframe src="' + window.location.origin + '/#/play/wasm/' + encodeURIComponent(this.videoUrl) + '"></iframe>',  
318 - sharedRtmp: this.videoUrl  
319 - };  
320 - } 424 + changePlayer: function (tab) {
  425 + console.log(this.player[tab.name][0])
  426 + this.activePlayer = tab.name;
  427 + this.videoUrl = this.getUrlByStreamInfo()
  428 + console.log(this.videoUrl)
321 }, 429 },
322 - created() {  
323 - console.log("created")  
324 - console.log(this.player)  
325 - this.broadcastStatus = -1;  
326 - if (Object.keys(this.player).length === 1) {  
327 - this.activePlayer = Object.keys(this.player)[0] 430 + openDialog: function (tab, deviceId, channelId, param) {
  431 + if (this.showVideoDialog) {
  432 + return;
  433 + }
  434 + this.tabActiveName = tab;
  435 + this.channelId = channelId;
  436 + this.deviceId = deviceId;
  437 + this.streamId = "";
  438 + this.mediaServerId = "";
  439 + this.app = "";
  440 + this.videoUrl = ""
  441 + if (!!this.$refs[this.activePlayer]) {
  442 + this.$refs[this.activePlayer].pause();
  443 + }
  444 + switch (tab) {
  445 + case "media":
  446 + this.play(param.streamInfo, param.hasAudio)
  447 + break;
  448 + case "streamPlay":
  449 + this.tabActiveName = "media";
  450 + this.showRrecord = false;
  451 + this.showPtz = false;
  452 + this.play(param.streamInfo, param.hasAudio)
  453 + break;
  454 + case "control":
  455 + break;
328 } 456 }
329 }, 457 },
330 - data() {  
331 - return {  
332 - video: 'http://lndxyj.iqilu.com/public/upload/2019/10/14/8c001ea0c09cdc59a57829dabc8010fa.mp4',  
333 - videoUrl: '',  
334 - activePlayer: "jessibuca",  
335 - // 如何你只是用一种播放器,直接注释掉不用的部分即可  
336 - player: {  
337 - jessibuca : ["ws_flv", "wss_flv"],  
338 - webRTC: ["rtc", "rtcs"],  
339 - },  
340 - videoHistory: {  
341 - date: '',  
342 - searchHistoryResult: [] //媒体流历史记录搜索结果  
343 - },  
344 - showVideoDialog: false,  
345 - streamId: '',  
346 - app : '',  
347 - mediaServerId : '',  
348 - convertKey: '',  
349 - deviceId: '',  
350 - channelId: '',  
351 - tabActiveName: 'media',  
352 - hasAudio: false,  
353 - loadingRecords: false,  
354 - recordsLoading: false,  
355 - isLoging: false,  
356 - controSpeed: 30,  
357 - timeVal: 0,  
358 - timeMin: 0,  
359 - timeMax: 1440,  
360 - presetPos: 1,  
361 - cruisingSpeed: 100,  
362 - cruisingTime: 5,  
363 - cruisingGroup: 0,  
364 - scanSpeed: 100,  
365 - scanGroup: 0,  
366 - tracks: [],  
367 - coverPlaying:false,  
368 - tracksLoading: false,  
369 - recordPlay: "",  
370 - showPtz: true,  
371 - showRrecord: true,  
372 - tracksNotLoaded: false,  
373 - sliderTime: 0,  
374 - seekTime: 0,  
375 - recordStartTime: 0,  
376 - showTimeText: "00:00:00",  
377 - streamInfo: null,  
378 - broadcastRtc: null,  
379 - broadcastStatus: -1, // -2 正在释放资源 -1 默认状态 0 等待接通 1 接通成功  
380 - }; 458 + play: function (streamInfo, hasAudio) {
  459 + this.streamInfo = streamInfo;
  460 + this.hasAudio = hasAudio;
  461 + this.isLoging = false;
  462 + // this.videoUrl = streamInfo.rtc;
  463 + this.videoUrl = this.getUrlByStreamInfo();
  464 + this.streamId = streamInfo.stream;
  465 + this.app = streamInfo.app;
  466 + this.mediaServerId = streamInfo.mediaServerId;
  467 + this.playFromStreamInfo(false, streamInfo)
381 }, 468 },
382 - methods: {  
383 - tabHandleClick: function(tab, event) {  
384 - console.log(tab)  
385 - var that = this;  
386 - that.tracks = [];  
387 - that.tracksLoading = true;  
388 - that.tracksNotLoaded = false;  
389 - if (tab.name === "codec") {  
390 - this.$axios({  
391 - method: 'get',  
392 - url: '/zlm/' +this.mediaServerId+ '/index/api/getMediaInfo?vhost=__defaultVhost__&schema=rtsp&app='+ this.app +'&stream='+ this.streamId  
393 - }).then(function (res) {  
394 - that.tracksLoading = false;  
395 - if (res.data.code == 0 && res.data.tracks) {  
396 - that.tracks = res.data.tracks;  
397 - }else{  
398 - that.tracksNotLoaded = true;  
399 - that.$message({  
400 - showClose: true,  
401 - message: '获取编码信息失败,',  
402 - type: 'warning'  
403 - });  
404 - }  
405 - }).catch(function (e) {});  
406 - }  
407 - },  
408 - changePlayer: function (tab) {  
409 - console.log(this.player[tab.name][0])  
410 - this.activePlayer = tab.name;  
411 - this.videoUrl = this.getUrlByStreamInfo()  
412 - console.log(this.videoUrl)  
413 - },  
414 - openDialog: function (tab, deviceId, channelId, param) {  
415 - if (this.showVideoDialog) {  
416 - return;  
417 - }  
418 - this.tabActiveName = tab;  
419 - this.channelId = channelId;  
420 - this.deviceId = deviceId;  
421 - this.streamId = "";  
422 - this.mediaServerId = "";  
423 - this.app = "";  
424 - this.videoUrl = ""  
425 - if (!!this.$refs[this.activePlayer]) {  
426 - this.$refs[this.activePlayer].pause();  
427 - }  
428 - switch (tab) {  
429 - case "media":  
430 - this.play(param.streamInfo, param.hasAudio)  
431 - break;  
432 - case "record":  
433 - this.showVideoDialog = true;  
434 - this.videoHistory.date = param.date;  
435 - this.queryRecords()  
436 - break;  
437 - case "streamPlay":  
438 - this.tabActiveName = "media";  
439 - this.showRrecord = false;  
440 - this.showPtz = false;  
441 - this.play(param.streamInfo, param.hasAudio)  
442 - break;  
443 - case "control":  
444 - break;  
445 - }  
446 - },  
447 - timeAxisSelTime: function (val) {  
448 - console.log(val)  
449 - },  
450 - play: function (streamInfo, hasAudio) {  
451 - this.streamInfo = streamInfo;  
452 - this.hasAudio = hasAudio;  
453 - this.isLoging = false;  
454 - // this.videoUrl = streamInfo.rtc;  
455 - this.videoUrl = this.getUrlByStreamInfo();  
456 - this.streamId = streamInfo.stream;  
457 - this.app = streamInfo.app;  
458 - this.mediaServerId = streamInfo.mediaServerId;  
459 - this.playFromStreamInfo(false, streamInfo)  
460 - },  
461 - getUrlByStreamInfo(){  
462 - console.log(this.streamInfo)  
463 - if (location.protocol === "https:") {  
464 - this.videoUrl = this.streamInfo[this.player[this.activePlayer][1]].url  
465 - }else {  
466 - this.videoUrl = this.streamInfo[this.player[this.activePlayer][0]].url  
467 - }  
468 - return this.videoUrl;  
469 -  
470 - },  
471 - coverPlay: function () {  
472 - var that = this;  
473 - this.coverPlaying = true;  
474 - this.$refs[this.activePlayer].pause()  
475 - that.$axios({  
476 - method: 'post',  
477 - url: '/api/play/convert/' + that.streamId  
478 - }).then(function (res) {  
479 - if (res.data.code === 0) {  
480 - that.convertKey = res.data.key;  
481 - setTimeout(()=>{  
482 - that.isLoging = false;  
483 - that.playFromStreamInfo(false, res.data.data);  
484 - }, 2000)  
485 - } else {  
486 - that.isLoging = false;  
487 - that.coverPlaying = false;  
488 - that.$message({  
489 - showClose: true,  
490 - message: '转码失败',  
491 - type: 'error'  
492 - });  
493 - }  
494 - }).catch(function (e) {  
495 - console.log(e)  
496 - that.coverPlaying = false;  
497 - that.$message({  
498 - showClose: true,  
499 - message: '播放错误',  
500 - type: 'error'  
501 - });  
502 - });  
503 - },  
504 - convertStopClick: function() {  
505 - this.convertStop(()=>{  
506 - this.$refs[this.activePlayer].play(this.videoUrl)  
507 - });  
508 - },  
509 - convertStop: function(callback) {  
510 - var that = this;  
511 - that.$refs.videoPlayer.pause()  
512 - this.$axios({  
513 - method: 'post',  
514 - url: '/api/play/convertStop/' + this.convertKey  
515 - }).then(function (res) {  
516 - if (res.data.code == 0) {  
517 - console.log(res.data.msg)  
518 - }else {  
519 - console.error(res.data.msg)  
520 - }  
521 - if (callback )callback();  
522 - }).catch(function (e) {});  
523 - that.coverPlaying = false;  
524 - that.convertKey = "";  
525 - // if (callback )callback();  
526 - },  
527 -  
528 - playFromStreamInfo: function (realHasAudio, streamInfo) {  
529 - this.showVideoDialog = true;  
530 - this.hasaudio = realHasAudio && this.hasaudio;  
531 - this.$refs[this.activePlayer].play(this.getUrlByStreamInfo(streamInfo))  
532 - },  
533 - close: function () {  
534 - console.log('关闭视频');  
535 - if (!!this.$refs[this.activePlayer]){  
536 - this.$refs[this.activePlayer].pause();  
537 - }  
538 - this.videoUrl = '';  
539 - this.coverPlaying = false;  
540 - this.showVideoDialog = false;  
541 - if (this.convertKey != '') {  
542 - this.convertStop();  
543 - }  
544 - this.convertKey = ''  
545 - if (this.recordPlay != '') {  
546 - this.stopPlayRecord();  
547 - }  
548 - this.recordPlay = ''  
549 - this.stopBroadcast()  
550 - },  
551 -  
552 - copySharedInfo: function (data) {  
553 - console.log('复制内容:' + data);  
554 - this.coverPlaying = false;  
555 - this.tracks = []  
556 - let _this = this;  
557 - this.$copyText(data).then(  
558 - function (e) {  
559 - _this.$message({  
560 - showClose: true,  
561 - message: '复制成功',  
562 - type: 'success'  
563 - });  
564 - },  
565 - function (e) {  
566 - _this.$message({  
567 - showClose: true,  
568 - message: '复制失败,请手动复制',  
569 - type: 'error'  
570 - });  
571 - }  
572 - );  
573 - },  
574 -  
575 - queryRecords: function () {  
576 - if (!this.videoHistory.date) {  
577 - return;  
578 - }  
579 - this.recordsLoading = true;  
580 - this.videoHistory.searchHistoryResult = [];  
581 - let that = this;  
582 - var startTime = this.videoHistory.date + " 00:00:00";  
583 - var endTime = this.videoHistory.date + " 23:59:59";  
584 - this.$axios({  
585 - method: 'get',  
586 - url: '/api/gb_record/query/' + this.deviceId + '/' + this.channelId + '?startTime=' + startTime + '&endTime=' + endTime  
587 - }).then(function (res) {  
588 - console.log(res)  
589 - that.recordsLoading = false;  
590 - if(res.data.code === 0) {  
591 - // 处理时间信息  
592 - that.videoHistory.searchHistoryResult = res.data.data.recordList;  
593 - }else {  
594 - this.$message({  
595 - showClose: true,  
596 - message: res.data.msg,  
597 - type: "error",  
598 - });  
599 - }  
600 -  
601 - }).catch(function (e) {  
602 - console.log(e.message);  
603 - // that.videoHistory.searchHistoryResult = falsificationData.recordData;  
604 - });  
605 -  
606 - },  
607 - onTimeChange: function (video) {  
608 - // this.queryRecords()  
609 - },  
610 - playRecord: function (row) {  
611 - let that = this; 469 + getUrlByStreamInfo() {
  470 + console.log(this.streamInfo)
  471 + if (location.protocol === "https:") {
  472 + this.videoUrl = this.streamInfo[this.player[this.activePlayer][1]]
  473 + } else {
  474 + this.videoUrl = this.streamInfo[this.player[this.activePlayer][0]]
  475 + }
  476 + return this.videoUrl;
612 477
613 - let startTime = row.startTime  
614 - this.recordStartTime = row.startTime  
615 - this.showTimeText = row.startTime.split(" ")[1]  
616 - let endtime = row.endTime  
617 - this.sliderTime = 0;  
618 - this.seekTime = new Date(endtime).getTime() - new Date(startTime).getTime();  
619 - console.log(this.seekTime)  
620 - if (that.streamId != "") {  
621 - that.stopPlayRecord(function () {  
622 - that.streamId = "";  
623 - that.playRecord(row);  
624 - })  
625 - } else {  
626 - this.$axios({  
627 - method: 'get',  
628 - url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +  
629 - row.endTime  
630 - }).then(function (res) {  
631 - if (res.data.code === 0) {  
632 - that.streamInfo = res.data.data;  
633 - that.app = that.streamInfo.app;  
634 - that.streamId = that.streamInfo.stream;  
635 - that.mediaServerId = that.streamInfo.mediaServerId;  
636 - that.ssrc = that.streamInfo.ssrc;  
637 - that.videoUrl = that.getUrlByStreamInfo();  
638 - }else {  
639 - that.$message({  
640 - showClose: true,  
641 - message: res.data.msg,  
642 - type: "error",  
643 - });  
644 - }  
645 - that.recordPlay = true;  
646 - });  
647 - }  
648 - },  
649 - stopPlayRecord: function (callback) {  
650 - this.$refs[this.activePlayer].pause();  
651 - this.videoUrl = '';  
652 - this.$axios({  
653 - method: 'get',  
654 - url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId  
655 - }).then(function (res) {  
656 - if (callback) callback()  
657 - });  
658 - },  
659 - downloadRecord: function (row) {  
660 - let that = this;  
661 - if (that.streamId != "") {  
662 - that.stopDownloadRecord(function (res) {  
663 - if (res.code == 0) {  
664 - that.streamId = "";  
665 - that.downloadRecord(row);  
666 - }else {  
667 - this.$message({  
668 - showClose: true,  
669 - message: res.data.msg,  
670 - type: "error",  
671 - });  
672 - } 478 + },
  479 + coverPlay: function () {
  480 + var that = this;
  481 + this.coverPlaying = true;
  482 + this.$refs[this.activePlayer].pause()
  483 + that.$axios({
  484 + method: 'post',
  485 + url: '/api/play/convert/' + that.streamId
  486 + }).then(function (res) {
  487 + if (res.data.code === 0) {
  488 + that.convertKey = res.data.key;
  489 + setTimeout(() => {
  490 + that.isLoging = false;
  491 + that.playFromStreamInfo(false, res.data.data);
  492 + }, 2000)
  493 + } else {
  494 + that.isLoging = false;
  495 + that.coverPlaying = false;
  496 + that.$message({
  497 + showClose: true,
  498 + message: '转码失败',
  499 + type: 'error'
  500 + });
  501 + }
  502 + }).catch(function (e) {
  503 + console.log(e)
  504 + that.coverPlaying = false;
  505 + that.$message({
  506 + showClose: true,
  507 + message: '播放错误',
  508 + type: 'error'
  509 + });
  510 + });
  511 + },
  512 + convertStopClick: function () {
  513 + this.convertStop(() => {
  514 + this.$refs[this.activePlayer].play(this.videoUrl)
  515 + });
  516 + },
  517 + convertStop: function (callback) {
  518 + var that = this;
  519 + that.$refs.videoPlayer.pause()
  520 + this.$axios({
  521 + method: 'post',
  522 + url: '/api/play/convertStop/' + this.convertKey
  523 + }).then(function (res) {
  524 + if (res.data.code == 0) {
  525 + console.log(res.data.msg)
  526 + } else {
  527 + console.error(res.data.msg)
  528 + }
  529 + if (callback) callback();
  530 + }).catch(function (e) {
  531 + });
  532 + that.coverPlaying = false;
  533 + that.convertKey = "";
  534 + // if (callback )callback();
  535 + },
673 536
674 - })  
675 - } else {  
676 - this.$axios({  
677 - method: 'get',  
678 - url: '/api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +  
679 - row.endTime + '&downloadSpeed=4'  
680 - }).then(function (res) {  
681 - if (res.data.code == 0) {  
682 - let streamInfo = res.data.data;  
683 - that.recordPlay = false;  
684 - that.$refs.recordDownload.openDialog(that.deviceId, that.channelId, streamInfo.app, streamInfo.stream, streamInfo.mediaServerId);  
685 - }else {  
686 - that.$message({  
687 - showClose: true,  
688 - message: res.data.msg,  
689 - type: "error",  
690 - });  
691 - }  
692 - });  
693 - }  
694 - },  
695 - stopDownloadRecord: function (callback) {  
696 - this.$refs[this.activePlayer].pause();  
697 - this.videoUrl = '';  
698 - this.$axios({  
699 - method: 'get',  
700 - url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId  
701 - }).then((res)=> {  
702 - if (callback) callback(res)  
703 - });  
704 - },  
705 - ptzCamera: function (command) {  
706 - console.log('云台控制:' + command);  
707 - let that = this;  
708 - this.$axios({  
709 - method: 'post',  
710 - url: '/api/ptz/control/' + this.deviceId + '/' + this.channelId + '?command=' + command + '&horizonSpeed=' + this.controSpeed + '&verticalSpeed=' + this.controSpeed + '&zoomSpeed=' + this.controSpeed  
711 - }).then(function (res) {});  
712 - },  
713 - //////////////////////播放器事件处理//////////////////////////  
714 - videoError: function (e) {  
715 - console.log("播放器错误:" + JSON.stringify(e));  
716 - },  
717 - presetPosition: function (cmdCode, presetPos) {  
718 - console.log('预置位控制:' + this.presetPos + ' : 0x' + cmdCode.toString(16));  
719 - let that = this;  
720 - this.$axios({  
721 - method: 'post',  
722 - url: '/api/ptz/front_end_command/' + this.deviceId + '/' + this.channelId + '?cmdCode=' + cmdCode + '&parameter1=0&parameter2=' + presetPos + '&combindCode2=0'  
723 - }).then(function (res) {});  
724 - },  
725 - setSpeedOrTime: function (cmdCode, groupNum, parameter) {  
726 - let that = this;  
727 - let parameter2 = parameter % 256;  
728 - let combindCode2 = Math.floor(parameter / 256) * 16;  
729 - console.log('前端控制:0x' + cmdCode.toString(16) + ' 0x' + groupNum.toString(16) + ' 0x' + parameter2.toString(16) + ' 0x' + combindCode2.toString(16));  
730 - this.$axios({  
731 - method: 'post',  
732 - url: '/api/ptz/front_end_command/' + this.deviceId + '/' + this.channelId + '?cmdCode=' + cmdCode + '&parameter1=' + groupNum + '&parameter2=' + parameter2 + '&combindCode2=' + combindCode2  
733 - }).then(function (res) {});  
734 - },  
735 - setCommand: function (cmdCode, groupNum, parameter) {  
736 - let that = this;  
737 - console.log('前端控制:0x' + cmdCode.toString(16) + ' 0x' + groupNum.toString(16) + ' 0x' + parameter.toString(16) + ' 0x0');  
738 - this.$axios({  
739 - method: 'post',  
740 - url: '/api/ptz/front_end_command/' + this.deviceId + '/' + this.channelId + '?cmdCode=' + cmdCode + '&parameter1=' + groupNum + '&parameter2=' + parameter + '&combindCode2=0'  
741 - }).then(function (res) {});  
742 - },  
743 - formatTooltip: function (val) {  
744 - var h = parseInt(val / 60);  
745 - var hStr = h < 10 ? ("0" + h) : h;  
746 - var s = val % 60;  
747 - var sStr = s < 10 ? ("0" + s) : s;  
748 - return h + ":" + sStr;  
749 - },  
750 - timeFormatter: function (row, column, cellValue, index) {  
751 - return cellValue.split(" ")[1];  
752 - },  
753 - mergeTime: function (timeArray) {  
754 - var resultArray = [];  
755 - for (let i = 0; i < timeArray.length; i++) {  
756 - var startTime = new Date(timeArray[i].startTime);  
757 - var endTime = new Date(timeArray[i].endTime);  
758 - if (i == 0) {  
759 - resultArray[0] = {  
760 - startTime: startTime,  
761 - endTime: endTime  
762 - }  
763 - }  
764 - for (let j = 0; j < resultArray.length; j++) {  
765 - if (startTime > resultArray[j].endTime) { // 合并  
766 - if (startTime - resultArray[j].endTime <= 1000) {  
767 - resultArray[j].endTime = endTime;  
768 - } else {  
769 - resultArray[resultArray.length] = {  
770 - startTime: startTime,  
771 - endTime: endTime  
772 - }  
773 - }  
774 - } else if (resultArray[j].startTime > endTime) { // 合并  
775 - if (resultArray[j].startTime - endTime <= 1000) {  
776 - resultArray[j].startTime = startTime;  
777 - } else {  
778 - resultArray[resultArray.length] = {  
779 - startTime: startTime,  
780 - endTime: endTime  
781 - }  
782 - }  
783 - }  
784 - }  
785 - }  
786 - console.log(resultArray)  
787 - return resultArray;  
788 - },  
789 - copyUrl: function (dropdownItem){  
790 - console.log(dropdownItem)  
791 - this.$copyText(dropdownItem).then((e)=> {  
792 - this.$message.success("成功拷贝到粘贴板");  
793 - }, (e)=> { 537 + playFromStreamInfo: function (realHasAudio, streamInfo) {
  538 + this.showVideoDialog = true;
  539 + this.hasaudio = realHasAudio && this.hasaudio;
  540 + this.$refs[this.activePlayer].play(this.getUrlByStreamInfo(streamInfo))
  541 + },
  542 + close: function () {
  543 + console.log('关闭视频');
  544 + if (!!this.$refs[this.activePlayer]) {
  545 + this.$refs[this.activePlayer].pause();
  546 + }
  547 + this.videoUrl = '';
  548 + this.coverPlaying = false;
  549 + this.showVideoDialog = false;
  550 + if (this.convertKey != '') {
  551 + this.convertStop();
  552 + }
  553 + this.convertKey = ''
  554 + this.stopBroadcast()
  555 + },
794 556
795 - })  
796 - },  
797 - gbPlay(){  
798 - console.log('前端控制:播放');  
799 - this.$axios({  
800 - method: 'get',  
801 - url: '/api/playback/resume/' + this.streamId  
802 - }).then((res)=> {  
803 - this.$refs[this.activePlayer].play(this.videoUrl) 557 + copySharedInfo: function (data) {
  558 + console.log('复制内容:' + data);
  559 + this.coverPlaying = false;
  560 + this.tracks = []
  561 + let _this = this;
  562 + this.$copyText(data).then(
  563 + function (e) {
  564 + _this.$message({
  565 + showClose: true,
  566 + message: '复制成功',
  567 + type: 'success'
804 }); 568 });
805 }, 569 },
806 - gbPause(){  
807 - console.log('前端控制:暂停');  
808 - this.$axios({  
809 - method: 'get',  
810 - url: '/api/playback/pause/' + this.streamId  
811 - }).then(function (res) {});  
812 - },  
813 - gbScale(command){  
814 - console.log('前端控制:倍速 ' + command);  
815 - this.$axios({  
816 - method: 'get',  
817 - url: `/api/playback/speed/${this.streamId }/${command}`  
818 - }).then(function (res) {});  
819 - },  
820 - gbSeek(val){  
821 - console.log('前端控制:seek ');  
822 - console.log(this.seekTime);  
823 - console.log(this.sliderTime);  
824 - let showTime = new Date(new Date(this.recordStartTime).getTime() + this.seekTime * val / 100)  
825 - let hour = showTime.getHours();  
826 - let minutes = showTime.getMinutes();  
827 - let seconds = showTime.getSeconds();  
828 - this.showTimeText = (hour < 10?("0" + hour):hour) + ":" + (minutes<10?("0" + minutes):minutes) + ":" + (seconds<10?("0" + seconds):seconds)  
829 - this.$axios({  
830 - method: 'get',  
831 - url: `/api/playback/seek/${this.streamId }/` + Math.floor(this.seekTime * val / 100000)  
832 - }).then( (res)=> {  
833 - setTimeout(()=>{  
834 - this.$refs[this.activePlayer].play(this.videoUrl)  
835 - }, 600) 570 + function (e) {
  571 + _this.$message({
  572 + showClose: true,
  573 + message: '复制失败,请手动复制',
  574 + type: 'error'
836 }); 575 });
837 - },  
838 - getBroadcastStatus() {  
839 - if (this.broadcastStatus == -2) {  
840 - return "primary"  
841 - }  
842 - if (this.broadcastStatus == -1) {  
843 - return "primary"  
844 - }  
845 - if (this.broadcastStatus == 0) {  
846 - return "warning"  
847 - }  
848 - if (this.broadcastStatus == 1) {  
849 - return "danger"  
850 - } 576 + }
  577 + );
  578 + },
  579 + ptzCamera: function (command) {
  580 + console.log('云台控制:' + command);
  581 + let that = this;
  582 + this.$axios({
  583 + method: 'post',
  584 + url: '/api/ptz/control/' + this.deviceId + '/' + this.channelId + '?command=' + command + '&horizonSpeed=' + this.controSpeed + '&verticalSpeed=' + this.controSpeed + '&zoomSpeed=' + this.controSpeed
  585 + }).then(function (res) {
  586 + });
  587 + },
  588 + //////////////////////播放器事件处理//////////////////////////
  589 + videoError: function (e) {
  590 + console.log("播放器错误:" + JSON.stringify(e));
  591 + },
  592 + presetPosition: function (cmdCode, presetPos) {
  593 + console.log('预置位控制:' + this.presetPos + ' : 0x' + cmdCode.toString(16));
  594 + let that = this;
  595 + this.$axios({
  596 + method: 'post',
  597 + url: '/api/ptz/front_end_command/' + this.deviceId + '/' + this.channelId + '?cmdCode=' + cmdCode + '&parameter1=0&parameter2=' + presetPos + '&combindCode2=0'
  598 + }).then(function (res) {
  599 + });
  600 + },
  601 + setSpeedOrTime: function (cmdCode, groupNum, parameter) {
  602 + let that = this;
  603 + let parameter2 = parameter % 256;
  604 + let combindCode2 = Math.floor(parameter / 256) * 16;
  605 + console.log('前端控制:0x' + cmdCode.toString(16) + ' 0x' + groupNum.toString(16) + ' 0x' + parameter2.toString(16) + ' 0x' + combindCode2.toString(16));
  606 + this.$axios({
  607 + method: 'post',
  608 + url: '/api/ptz/front_end_command/' + this.deviceId + '/' + this.channelId + '?cmdCode=' + cmdCode + '&parameter1=' + groupNum + '&parameter2=' + parameter2 + '&combindCode2=' + combindCode2
  609 + }).then(function (res) {
  610 + });
  611 + },
  612 + setCommand: function (cmdCode, groupNum, parameter) {
  613 + let that = this;
  614 + console.log('前端控制:0x' + cmdCode.toString(16) + ' 0x' + groupNum.toString(16) + ' 0x' + parameter.toString(16) + ' 0x0');
  615 + this.$axios({
  616 + method: 'post',
  617 + url: '/api/ptz/front_end_command/' + this.deviceId + '/' + this.channelId + '?cmdCode=' + cmdCode + '&parameter1=' + groupNum + '&parameter2=' + parameter + '&combindCode2=0'
  618 + }).then(function (res) {
  619 + });
  620 + },
  621 + copyUrl: function (dropdownItem) {
  622 + console.log(dropdownItem)
  623 + this.$copyText(dropdownItem).then((e) => {
  624 + this.$message.success("成功拷贝到粘贴板");
  625 + }, (e) => {
  626 +
  627 + })
  628 + },
  629 + getBroadcastStatus() {
  630 + if (this.broadcastStatus == -2) {
  631 + return "primary"
  632 + }
  633 + if (this.broadcastStatus == -1) {
  634 + return "primary"
  635 + }
  636 + if (this.broadcastStatus == 0) {
  637 + return "warning"
  638 + }
  639 + if (this.broadcastStatus == 1) {
  640 + return "danger"
  641 + }
851 642
852 }, 643 },
853 broadcastStatusClick() { 644 broadcastStatusClick() {
@@ -908,16 +699,16 @@ export default { @@ -908,16 +699,16 @@ export default {
908 recvOnly: false, 699 recvOnly: false,
909 }) 700 })
910 701
911 - // webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS,(e)=>{//获取到了远端流,可以播放  
912 - // console.error('播放成功',e.streams)  
913 - // this.broadcastStatus = 1;  
914 - // });  
915 - //  
916 - // webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM,(s)=>{// 获取到了本地流  
917 - // this.broadcastStatus = 1;  
918 - // // document.getElementById('selfVideo').srcObject=s;  
919 - // // this.eventcallbacK("LOCAL STREAM", "获取到了本地流")  
920 - // }); 702 + // webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS,(e)=>{//获取到了远端流,可以播放
  703 + // console.error('播放成功',e.streams)
  704 + // this.broadcastStatus = 1;
  705 + // });
  706 + //
  707 + // webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM,(s)=>{// 获取到了本地流
  708 + // this.broadcastStatus = 1;
  709 + // // document.getElementById('selfVideo').srcObject=s;
  710 + // // this.eventcallbacK("LOCAL STREAM", "获取到了本地流")
  711 + // });
921 712
922 this.broadcastRtc.on(ZLMRTCClient.Events.WEBRTC_NOT_SUPPORT,(e)=>{// 获取到了本地流 713 this.broadcastRtc.on(ZLMRTCClient.Events.WEBRTC_NOT_SUPPORT,(e)=>{// 获取到了本地流
923 console.error('不支持webrtc',e) 714 console.error('不支持webrtc',e)
@@ -929,263 +720,268 @@ export default { @@ -929,263 +720,268 @@ export default {
929 this.broadcastStatus = -1; 720 this.broadcastStatus = -1;
930 }); 721 });
931 722
932 - this.broadcastRtc.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR,(e)=>{// ICE 协商出错  
933 - console.error('ICE 协商出错')  
934 - this.$message({  
935 - showClose: true,  
936 - message: 'ICE 协商出错',  
937 - type: 'error'  
938 - });  
939 - this.broadcastStatus = -1;  
940 - }); 723 + this.broadcastRtc.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR, (e) => {// ICE 协商出错
  724 + console.error('ICE 协商出错')
  725 + this.$message({
  726 + showClose: true,
  727 + message: 'ICE 协商出错',
  728 + type: 'error'
  729 + });
  730 + this.broadcastStatus = -1;
  731 + });
941 732
942 - this.broadcastRtc.on(ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED,(e)=>{// offer anwser 交换失败  
943 - console.error('offer anwser 交换失败',e)  
944 - this.$message({  
945 - showClose: true,  
946 - message: 'offer anwser 交换失败' + e,  
947 - type: 'error'  
948 - });  
949 - this.broadcastStatus = -1;  
950 - });  
951 - this.broadcastRtc.on(ZLMRTCClient.Events.WEBRTC_ON_CONNECTION_STATE_CHANGE,(e)=>{// offer anwser 交换失败  
952 - console.log('状态改变',e)  
953 - if (e === "connecting") {  
954 - this.broadcastStatus = 0;  
955 - }else if (e === "connected") {  
956 - this.broadcastStatus = 1;  
957 - }else if (e === "disconnected") {  
958 - this.broadcastStatus = -1;  
959 - }  
960 - });  
961 - this.broadcastRtc.on(ZLMRTCClient.Events.CAPTURE_STREAM_FAILED,(e)=>{// offer anwser 交换失败  
962 - console.log('捕获流失败',e)  
963 - this.$message({  
964 - showClose: true,  
965 - message: '捕获流失败' + e,  
966 - type: 'error'  
967 - });  
968 - this.broadcastStatus = -1;  
969 - }); 733 + this.broadcastRtc.on(ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED, (e) => {// offer anwser 交换失败
  734 + console.error('offer anwser 交换失败', e)
  735 + this.$message({
  736 + showClose: true,
  737 + message: 'offer anwser 交换失败' + e,
  738 + type: 'error'
  739 + });
  740 + this.broadcastStatus = -1;
  741 + });
  742 + this.broadcastRtc.on(ZLMRTCClient.Events.WEBRTC_ON_CONNECTION_STATE_CHANGE, (e) => {// offer anwser 交换失败
  743 + console.log('状态改变', e)
  744 + if (e === "connecting") {
  745 + this.broadcastStatus = 0;
  746 + } else if (e === "connected") {
  747 + this.broadcastStatus = 1;
  748 + } else if (e === "disconnected") {
  749 + this.broadcastStatus = -1;
970 } 750 }
971 - }).catch((e) => { 751 + });
  752 + this.broadcastRtc.on(ZLMRTCClient.Events.CAPTURE_STREAM_FAILED, (e) => {// offer anwser 交换失败
  753 + console.log('捕获流失败', e)
972 this.$message({ 754 this.$message({
973 showClose: true, 755 showClose: true,
974 - message: e, 756 + message: '捕获流失败' + e,
975 type: 'error' 757 type: 'error'
976 }); 758 });
977 this.broadcastStatus = -1; 759 this.broadcastStatus = -1;
978 }); 760 });
  761 + }
  762 + }).catch((e) => {
  763 + this.$message({
  764 + showClose: true,
  765 + message: e,
  766 + type: 'error'
  767 + });
  768 + this.broadcastStatus = -1;
  769 + });
979 770
980 771
981 - },  
982 - stopBroadcast(){  
983 - this.broadcastRtc.close();  
984 - this.broadcastStatus = -1;  
985 - this.$axios({  
986 - method: 'get',  
987 - url: '/api/play/broadcast/stop/' + this.deviceId + '/' + this.channelId  
988 - }).then( (res)=> {  
989 - if (res.data.code == 0) {  
990 - // this.broadcastStatus = -1;  
991 - // this.broadcastRtc.close()  
992 - }else {  
993 - this.$message({  
994 - showClose: true,  
995 - message: res.data.msg,  
996 - type: "error",  
997 - });  
998 - } 772 + },
  773 + stopBroadcast() {
  774 + this.broadcastRtc.close();
  775 + this.broadcastStatus = -1;
  776 + this.$axios({
  777 + method: 'get',
  778 + url: '/api/play/broadcast/stop/' + this.deviceId + '/' + this.channelId
  779 + }).then((res) => {
  780 + if (res.data.code == 0) {
  781 + // this.broadcastStatus = -1;
  782 + // this.broadcastRtc.close()
  783 + } else {
  784 + this.$message({
  785 + showClose: true,
  786 + message: res.data.msg,
  787 + type: "error",
999 }); 788 });
1000 } 789 }
  790 + });
1001 } 791 }
  792 + }
1002 }; 793 };
1003 </script> 794 </script>
1004 795
1005 <style> 796 <style>
1006 .control-wrapper { 797 .control-wrapper {
1007 - position: relative;  
1008 - width: 6.25rem;  
1009 - height: 6.25rem;  
1010 - max-width: 6.25rem;  
1011 - max-height: 6.25rem;  
1012 - border-radius: 100%;  
1013 - margin-top: 1.5rem;  
1014 - margin-left: 0.5rem;  
1015 - float: left; 798 + position: relative;
  799 + width: 6.25rem;
  800 + height: 6.25rem;
  801 + max-width: 6.25rem;
  802 + max-height: 6.25rem;
  803 + border-radius: 100%;
  804 + margin-top: 1.5rem;
  805 + margin-left: 0.5rem;
  806 + float: left;
1016 } 807 }
1017 808
1018 .control-panel { 809 .control-panel {
1019 - position: relative;  
1020 - top: 0;  
1021 - left: 5rem;  
1022 - height: 11rem;  
1023 - max-height: 11rem; 810 + position: relative;
  811 + top: 0;
  812 + left: 5rem;
  813 + height: 11rem;
  814 + max-height: 11rem;
1024 } 815 }
1025 816
1026 .control-btn { 817 .control-btn {
1027 - display: flex;  
1028 - justify-content: center;  
1029 - position: absolute;  
1030 - width: 44%;  
1031 - height: 44%;  
1032 - border-radius: 5px;  
1033 - border: 1px solid #78aee4;  
1034 - box-sizing: border-box;  
1035 - transition: all 0.3s linear; 818 + display: flex;
  819 + justify-content: center;
  820 + position: absolute;
  821 + width: 44%;
  822 + height: 44%;
  823 + border-radius: 5px;
  824 + border: 1px solid #78aee4;
  825 + box-sizing: border-box;
  826 + transition: all 0.3s linear;
1036 } 827 }
  828 +
1037 .control-btn:hover { 829 .control-btn:hover {
1038 - cursor:pointer 830 + cursor: pointer
1039 } 831 }
1040 832
1041 .control-btn i { 833 .control-btn i {
1042 - font-size: 20px;  
1043 - color: #78aee4;  
1044 - display: flex;  
1045 - justify-content: center;  
1046 - align-items: center; 834 + font-size: 20px;
  835 + color: #78aee4;
  836 + display: flex;
  837 + justify-content: center;
  838 + align-items: center;
1047 } 839 }
  840 +
1048 .control-btn i:hover { 841 .control-btn i:hover {
1049 - cursor:pointer 842 + cursor: pointer
1050 } 843 }
  844 +
1051 .control-zoom-btn:hover { 845 .control-zoom-btn:hover {
1052 - cursor:pointer 846 + cursor: pointer
1053 } 847 }
1054 848
1055 .control-round { 849 .control-round {
1056 - position: absolute;  
1057 - top: 21%;  
1058 - left: 21%;  
1059 - width: 58%;  
1060 - height: 58%;  
1061 - background: #fff;  
1062 - border-radius: 100%; 850 + position: absolute;
  851 + top: 21%;
  852 + left: 21%;
  853 + width: 58%;
  854 + height: 58%;
  855 + background: #fff;
  856 + border-radius: 100%;
1063 } 857 }
1064 858
1065 .control-round-inner { 859 .control-round-inner {
1066 - position: absolute;  
1067 - left: 13%;  
1068 - top: 13%;  
1069 - display: flex;  
1070 - justify-content: center;  
1071 - align-items: center;  
1072 - width: 70%;  
1073 - height: 70%;  
1074 - font-size: 40px;  
1075 - color: #78aee4;  
1076 - border: 1px solid #78aee4;  
1077 - border-radius: 100%;  
1078 - transition: all 0.3s linear; 860 + position: absolute;
  861 + left: 13%;
  862 + top: 13%;
  863 + display: flex;
  864 + justify-content: center;
  865 + align-items: center;
  866 + width: 70%;
  867 + height: 70%;
  868 + font-size: 40px;
  869 + color: #78aee4;
  870 + border: 1px solid #78aee4;
  871 + border-radius: 100%;
  872 + transition: all 0.3s linear;
1079 } 873 }
1080 874
1081 .control-inner-btn { 875 .control-inner-btn {
1082 - position: absolute;  
1083 - width: 60%;  
1084 - height: 60%;  
1085 - background: #fafafa; 876 + position: absolute;
  877 + width: 60%;
  878 + height: 60%;
  879 + background: #fafafa;
1086 } 880 }
1087 881
1088 .control-top { 882 .control-top {
1089 - top: -8%;  
1090 - left: 27%;  
1091 - transform: rotate(-45deg);  
1092 - border-radius: 5px 100% 5px 0; 883 + top: -8%;
  884 + left: 27%;
  885 + transform: rotate(-45deg);
  886 + border-radius: 5px 100% 5px 0;
1093 } 887 }
1094 888
1095 .control-top i { 889 .control-top i {
1096 - transform: rotate(45deg);  
1097 - border-radius: 5px 100% 5px 0; 890 + transform: rotate(45deg);
  891 + border-radius: 5px 100% 5px 0;
1098 } 892 }
1099 893
1100 .control-top .control-inner { 894 .control-top .control-inner {
1101 - left: -1px;  
1102 - bottom: 0;  
1103 - border-top: 1px solid #78aee4;  
1104 - border-right: 1px solid #78aee4;  
1105 - border-radius: 0 100% 0 0; 895 + left: -1px;
  896 + bottom: 0;
  897 + border-top: 1px solid #78aee4;
  898 + border-right: 1px solid #78aee4;
  899 + border-radius: 0 100% 0 0;
1106 } 900 }
1107 901
1108 .control-top .fa { 902 .control-top .fa {
1109 - transform: rotate(45deg) translateY(-7px); 903 + transform: rotate(45deg) translateY(-7px);
1110 } 904 }
1111 905
1112 .control-left { 906 .control-left {
1113 - top: 27%;  
1114 - left: -8%;  
1115 - transform: rotate(45deg);  
1116 - border-radius: 5px 0 5px 100%; 907 + top: 27%;
  908 + left: -8%;
  909 + transform: rotate(45deg);
  910 + border-radius: 5px 0 5px 100%;
1117 } 911 }
1118 912
1119 .control-left i { 913 .control-left i {
1120 - transform: rotate(-45deg); 914 + transform: rotate(-45deg);
1121 } 915 }
1122 916
1123 .control-left .control-inner { 917 .control-left .control-inner {
1124 - right: -1px;  
1125 - top: -1px;  
1126 - border-bottom: 1px solid #78aee4;  
1127 - border-left: 1px solid #78aee4;  
1128 - border-radius: 0 0 0 100%; 918 + right: -1px;
  919 + top: -1px;
  920 + border-bottom: 1px solid #78aee4;
  921 + border-left: 1px solid #78aee4;
  922 + border-radius: 0 0 0 100%;
1129 } 923 }
1130 924
1131 .control-left .fa { 925 .control-left .fa {
1132 - transform: rotate(-45deg) translateX(-7px); 926 + transform: rotate(-45deg) translateX(-7px);
1133 } 927 }
1134 928
1135 .control-right { 929 .control-right {
1136 - top: 27%;  
1137 - right: -8%;  
1138 - transform: rotate(45deg);  
1139 - border-radius: 5px 100% 5px 0; 930 + top: 27%;
  931 + right: -8%;
  932 + transform: rotate(45deg);
  933 + border-radius: 5px 100% 5px 0;
1140 } 934 }
1141 935
1142 .control-right i { 936 .control-right i {
1143 - transform: rotate(-45deg); 937 + transform: rotate(-45deg);
1144 } 938 }
1145 939
1146 .control-right .control-inner { 940 .control-right .control-inner {
1147 - left: -1px;  
1148 - bottom: -1px;  
1149 - border-top: 1px solid #78aee4;  
1150 - border-right: 1px solid #78aee4;  
1151 - border-radius: 0 100% 0 0; 941 + left: -1px;
  942 + bottom: -1px;
  943 + border-top: 1px solid #78aee4;
  944 + border-right: 1px solid #78aee4;
  945 + border-radius: 0 100% 0 0;
1152 } 946 }
1153 947
1154 .control-right .fa { 948 .control-right .fa {
1155 - transform: rotate(-45deg) translateX(7px); 949 + transform: rotate(-45deg) translateX(7px);
1156 } 950 }
1157 951
1158 .control-bottom { 952 .control-bottom {
1159 - left: 27%;  
1160 - bottom: -8%;  
1161 - transform: rotate(45deg);  
1162 - border-radius: 0 5px 100% 5px; 953 + left: 27%;
  954 + bottom: -8%;
  955 + transform: rotate(45deg);
  956 + border-radius: 0 5px 100% 5px;
1163 } 957 }
1164 958
1165 .control-bottom i { 959 .control-bottom i {
1166 - transform: rotate(-45deg); 960 + transform: rotate(-45deg);
1167 } 961 }
1168 962
1169 .control-bottom .control-inner { 963 .control-bottom .control-inner {
1170 - top: -1px;  
1171 - left: -1px;  
1172 - border-bottom: 1px solid #78aee4;  
1173 - border-right: 1px solid #78aee4;  
1174 - border-radius: 0 0 100% 0; 964 + top: -1px;
  965 + left: -1px;
  966 + border-bottom: 1px solid #78aee4;
  967 + border-right: 1px solid #78aee4;
  968 + border-radius: 0 0 100% 0;
1175 } 969 }
1176 970
1177 .control-bottom .fa { 971 .control-bottom .fa {
1178 - transform: rotate(-45deg) translateY(7px); 972 + transform: rotate(-45deg) translateY(7px);
1179 } 973 }
  974 +
1180 .trank { 975 .trank {
1181 - width: 80%;  
1182 - height: 180px;  
1183 - text-align: left;  
1184 - padding: 0 10%;  
1185 - overflow: auto; 976 + width: 80%;
  977 + height: 180px;
  978 + text-align: left;
  979 + padding: 0 10%;
  980 + overflow: auto;
1186 } 981 }
  982 +
1187 .trankInfo { 983 .trankInfo {
1188 - width: 80%;  
1189 - padding: 0 10%; 984 + width: 80%;
  985 + padding: 0 10%;
1190 } 986 }
1191 </style> 987 </style>
web_src/src/components/dialog/recordDownload.vue
@@ -6,18 +6,6 @@ @@ -6,18 +6,6 @@
6 <el-progress :percentage="percentage"></el-progress> 6 <el-progress :percentage="percentage"></el-progress>
7 </el-col> 7 </el-col>
8 <el-col :span="6" > 8 <el-col :span="6" >
9 -<!-- <el-dropdown size="mini" title="播放倍速" style="margin-left: 1px;" @command="gbScale">-->  
10 -<!-- <el-button-group>-->  
11 -<!-- <el-button size="mini" style="width: 100%">-->  
12 -<!-- {{scale}}倍速 <i class="el-icon-arrow-down el-icon&#45;&#45;right"></i>-->  
13 -<!-- </el-button>-->  
14 -<!-- </el-button-group>-->  
15 -<!-- <el-dropdown-menu slot="dropdown">-->  
16 -<!-- <el-dropdown-item command="1">1倍速</el-dropdown-item>-->  
17 -<!-- <el-dropdown-item command="2">2倍速</el-dropdown-item>-->  
18 -<!-- <el-dropdown-item command="4">4倍速</el-dropdown-item>-->  
19 -<!-- </el-dropdown-menu>-->  
20 -<!-- </el-dropdown>-->  
21 <el-button icon="el-icon-download" v-if="percentage < 100" size="mini" title="点击下载可将以缓存部分下载到本地" @click="download()">停止缓存并下载</el-button> 9 <el-button icon="el-icon-download" v-if="percentage < 100" size="mini" title="点击下载可将以缓存部分下载到本地" @click="download()">停止缓存并下载</el-button>
22 </el-col> 10 </el-col>
23 </el-row> 11 </el-row>
@@ -51,6 +39,7 @@ export default { @@ -51,6 +39,7 @@ export default {
51 taskId: null, 39 taskId: null,
52 getProgressRun: false, 40 getProgressRun: false,
53 getProgressForFileRun: false, 41 getProgressForFileRun: false,
  42 + timer: null
54 43
55 }; 44 };
56 }, 45 },
@@ -66,7 +55,7 @@ export default { @@ -66,7 +55,7 @@ export default {
66 this.percentage = 0.0; 55 this.percentage = 0.0;
67 this.getProgressTimer() 56 this.getProgressTimer()
68 }, 57 },
69 - getProgressTimer(){ 58 + getProgressTimer: function (){
70 if (!this.getProgressRun) { 59 if (!this.getProgressRun) {
71 return; 60 return;
72 } 61 }
@@ -93,15 +82,24 @@ export default { @@ -93,15 +82,24 @@ export default {
93 this.percentage = (parseFloat(res.data.data.progress)*100).toFixed(1); 82 this.percentage = (parseFloat(res.data.data.progress)*100).toFixed(1);
94 } 83 }
95 if (callback)callback(); 84 if (callback)callback();
  85 + }else {
  86 + this.$message({
  87 + showClose: true,
  88 + message: res.data.msg,
  89 + type: "error",
  90 + });
  91 + this.close();
96 } 92 }
97 93
98 }).catch((e) =>{ 94 }).catch((e) =>{
99 - 95 + console.log(e)
100 }); 96 });
101 }, 97 },
102 close: function (){ 98 close: function (){
103 - if (this.streamInfo.progress < 100) {  
104 - this.stopDownloadRecord(); 99 + this.stopDownloadRecord();
  100 + if (this.timer !== null) {
  101 + window.clearTimeout(this.timer);
  102 + this.timer = null;
105 } 103 }
106 this.showDialog=false; 104 this.showDialog=false;
107 this.getProgressRun = false; 105 this.getProgressRun = false;
web_src/src/components/live.vue
@@ -140,9 +140,9 @@ export default { @@ -140,9 +140,9 @@ export default {
140 if (res.data.code === 0 && res.data.data) { 140 if (res.data.code === 0 && res.data.data) {
141 let videoUrl; 141 let videoUrl;
142 if (location.protocol === "https:") { 142 if (location.protocol === "https:") {
143 - videoUrl = res.data.data.wss_flv.url; 143 + videoUrl = res.data.data.wss_flv;
144 } else { 144 } else {
145 - videoUrl = res.data.data.ws_flv.url; 145 + videoUrl = res.data.data.ws_flv;
146 } 146 }
147 itemData.playUrl = videoUrl; 147 itemData.playUrl = videoUrl;
148 that.setPlayUrl(videoUrl, idxTmp); 148 that.setPlayUrl(videoUrl, idxTmp);
web_src/src/router/index.js
@@ -5,6 +5,7 @@ import Layout from &quot;../layout/index.vue&quot; @@ -5,6 +5,7 @@ import Layout from &quot;../layout/index.vue&quot;
5 import console from '../components/console.vue' 5 import console from '../components/console.vue'
6 import deviceList from '../components/DeviceList.vue' 6 import deviceList from '../components/DeviceList.vue'
7 import channelList from '../components/channelList.vue' 7 import channelList from '../components/channelList.vue'
  8 +import gbRecordDetail from '../components/GBRecordDetail.vue'
8 import pushVideoList from '../components/PushVideoList.vue' 9 import pushVideoList from '../components/PushVideoList.vue'
9 import streamProxyList from '../components/StreamProxyList.vue' 10 import streamProxyList from '../components/StreamProxyList.vue'
10 import map from '../components/map.vue' 11 import map from '../components/map.vue'
@@ -65,6 +66,11 @@ export default new VueRouter({ @@ -65,6 +66,11 @@ export default new VueRouter({
65 component: channelList, 66 component: channelList,
66 }, 67 },
67 { 68 {
  69 + path: '/gbRecordDetail/:deviceId/:channelId/',
  70 + name: 'gbRecordDetail',
  71 + component: gbRecordDetail,
  72 + },
  73 + {
68 path: '/parentPlatformList/:count/:page', 74 path: '/parentPlatformList/:count/:page',
69 name: 'parentPlatformList', 75 name: 'parentPlatformList',
70 component: parentPlatformList, 76 component: parentPlatformList,
web_src/static/css/iconfont.css
1 @font-face { 1 @font-face {
2 font-family: "iconfont"; /* Project id 1291092 */ 2 font-family: "iconfont"; /* Project id 1291092 */
3 - src: url('iconfont.woff2?t=1655453611360') format('woff2'),  
4 - url('iconfont.woff?t=1655453611360') format('woff'),  
5 - url('iconfont.ttf?t=1655453611360') format('truetype'); 3 + src: url('iconfont.woff2?t=1673251105600') format('woff2'),
  4 + url('iconfont.woff?t=1673251105600') format('woff'),
  5 + url('iconfont.ttf?t=1673251105600') format('truetype');
6 } 6 }
7 7
8 .iconfont { 8 .iconfont {
@@ -13,6 +13,14 @@ @@ -13,6 +13,14 @@
13 -moz-osx-font-smoothing: grayscale; 13 -moz-osx-font-smoothing: grayscale;
14 } 14 }
15 15
  16 +.icon-slider:before {
  17 + content: "\e7e0";
  18 +}
  19 +
  20 +.icon-slider-right:before {
  21 + content: "\ea19";
  22 +}
  23 +
16 .icon-list:before { 24 .icon-list:before {
17 content: "\e7de"; 25 content: "\e7de";
18 } 26 }
web_src/static/css/iconfont.woff2
No preview for this file type