Commit 7d1116c8928770cd7703c83955d77f1e6a430ce3
Committed by
GitHub
Merge branch '648540858:wvp-28181-2.0' into wvp-28181-2.0
Showing
49 changed files
with
3070 additions
and
2665 deletions
README.md
| ... | ... | @@ -134,10 +134,10 @@ QQ遘∽ソ。荳闊ャ荳榊屓, 邊セ蜉帶怏髯.谺「霑主、ァ螳カ蝨ィ鄒、驥瑚ョィ隶コ.隗牙セ鈴。ケ逶ョ蟇ケ菴 |
| 134 | 134 | 諢溯ー「菴懆dexter langhuihui](https://github.com/langhuihui) 蠑貅占ソ吩ケ亥・ス逕ィ逧ЦEB謦ュ謾セ蝎ィ縲 |
| 135 | 135 | 諢溯ー「菴懆Kyle](https://gitee.com/kkkkk5G) 蠑貅蝉コ・ス逕ィ逧燕遶ッ鬘オ髱「 |
| 136 | 136 | 諢溯ー「蜷ス榊、ァ菴ャ逧オ槫勧莉・蜿雁ッケ鬘ケ逶ョ逧欠豁」荳主クョ蜉ゥ縲ょ桁諡ャ菴ク埼剞莠惹サ」遐∬エ。迪ョ縲琉鬚伜渚鬥医∬オ謐占オ遲牙推遘肴婿蠑冗噪謾ッ謖シ∽サ・荳区賜蜷堺ク榊蜈亥錘 |
| 137 | -[lawrencehj](https://github.com/lawrencehj) @髯クー-蛻帛・ァ第橿 [swwhaha](https://github.com/swwheihei) | |
| 137 | +[lawrencehj](https://github.com/lawrencehj) [Smallwhitepig](https://github.com/Smallwhitepig) [swwhaha](https://github.com/swwheihei) | |
| 138 | 138 | [hotcoffie](https://github.com/hotcoffie) [xiaomu](https://github.com/nikmu) [TristingChen](https://github.com/TristingChen) |
| 139 | 139 | [chenparty](https://github.com/chenparty) [Hotleave](https://github.com/hotleave) [ydwxb](https://github.com/ydwxb) |
| 140 | -[ydpd](https://github.com/ydpd) [szy833](https://github.com/szy833) [ydwxb](https://github.com/ydwxb) | |
| 140 | +[ydpd](https://github.com/ydpd) [szy833](https://github.com/szy833) [ydwxb](https://github.com/ydwxb) [Albertzhu666](https://github.com/Albertzhu666) | |
| 141 | 141 | |
| 142 | 142 | ps: 蛻壼「槫刈莠ソ吩クェ蜷榊黒瑚け螳夐@貍丈コク莠帛、ァ菴ャ梧ャ「霑主、ァ菴ャ閨皮ウサ謌第キサ蜉縲 |
| 143 | 143 | ... | ... |
pom.xml
sql/clean.sql
0 → 100644
| 1 | +delete from device; | |
| 2 | +delete from device_alarm; | |
| 3 | +delete from device_channel; | |
| 4 | +delete from device_mobile_position; | |
| 5 | +delete from gb_stream; | |
| 6 | +delete from log; | |
| 7 | +delete from media_server; | |
| 8 | +delete from parent_platform; | |
| 9 | +delete from platform_catalog; | |
| 10 | +delete from platform_gb_channel; | |
| 11 | +delete from platform_gb_stream; | |
| 12 | +delete from stream_proxy; | |
| 13 | +delete from stream_push; | |
| 0 | 14 | \ No newline at end of file | ... | ... |
sql/mysql.sql
| 1 | --- MySQL dump 10.13 Distrib 8.0.28, for Linux (x86_64) | |
| 1 | +-- MariaDB dump 10.19 Distrib 10.7.3-MariaDB, for Linux (x86_64) | |
| 2 | 2 | -- |
| 3 | --- Host: 127.0.0.1 Database: wvp | |
| 3 | +-- Host: 127.0.0.1 Database: wvp3 | |
| 4 | 4 | -- ------------------------------------------------------ |
| 5 | --- Server version 8.0.28-0ubuntu0.20.04.3 | |
| 5 | +-- Server version 8.0.0-dmr | |
| 6 | 6 | |
| 7 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; |
| 8 | 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; |
| 9 | 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; |
| 10 | -/*!50503 SET NAMES utf8mb4 */; | |
| 10 | +/*!40101 SET NAMES utf8mb4 */; | |
| 11 | 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; |
| 12 | 12 | /*!40103 SET TIME_ZONE='+00:00' */; |
| 13 | 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; |
| ... | ... | @@ -21,33 +21,34 @@ |
| 21 | 21 | |
| 22 | 22 | DROP TABLE IF EXISTS `device`; |
| 23 | 23 | /*!40101 SET @saved_cs_client = @@character_set_client */; |
| 24 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 24 | +/*!40101 SET character_set_client = utf8 */; | |
| 25 | 25 | CREATE TABLE `device` ( |
| 26 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 27 | - `deviceId` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, | |
| 28 | - `name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 29 | - `manufacturer` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 30 | - `model` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 31 | - `firmware` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 32 | - `transport` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 33 | - `streamMode` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 34 | - `online` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 35 | - `registerTime` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 36 | - `keepaliveTime` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 37 | - `ip` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, | |
| 38 | - `createTime` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, | |
| 39 | - `updateTime` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, | |
| 40 | - `port` int NOT NULL, | |
| 41 | - `expires` int NOT NULL, | |
| 42 | - `subscribeCycleForCatalog` int NOT NULL, | |
| 43 | - `subscribeCycleForMobilePosition` int NOT NULL, | |
| 44 | - `mobilePositionSubmissionInterval` int DEFAULT 5 NOT NULL, | |
| 45 | - `subscribeCycleForAlarm` int NOT NULL, | |
| 46 | - `hostAddress` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, | |
| 47 | - `charset` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, | |
| 26 | + `id` int(11) NOT NULL AUTO_INCREMENT, | |
| 27 | + `deviceId` varchar(50) NOT NULL, | |
| 28 | + `name` varchar(255) DEFAULT NULL, | |
| 29 | + `manufacturer` varchar(255) DEFAULT NULL, | |
| 30 | + `model` varchar(255) DEFAULT NULL, | |
| 31 | + `firmware` varchar(255) DEFAULT NULL, | |
| 32 | + `transport` varchar(50) DEFAULT NULL, | |
| 33 | + `streamMode` varchar(50) DEFAULT NULL, | |
| 34 | + `online` varchar(50) DEFAULT NULL, | |
| 35 | + `registerTime` varchar(50) DEFAULT NULL, | |
| 36 | + `keepaliveTime` varchar(50) DEFAULT NULL, | |
| 37 | + `ip` varchar(50) NOT NULL, | |
| 38 | + `createTime` varchar(50) NOT NULL, | |
| 39 | + `updateTime` varchar(50) NOT NULL, | |
| 40 | + `port` int(11) NOT NULL, | |
| 41 | + `expires` int(11) NOT NULL, | |
| 42 | + `subscribeCycleForCatalog` int(11) NOT NULL, | |
| 43 | + `subscribeCycleForMobilePosition` int(11) NOT NULL, | |
| 44 | + `mobilePositionSubmissionInterval` int(11) NOT NULL DEFAULT '5', | |
| 45 | + `subscribeCycleForAlarm` int(11) NOT NULL, | |
| 46 | + `hostAddress` varchar(50) NOT NULL, | |
| 47 | + `charset` varchar(50) NOT NULL, | |
| 48 | + `ssrcCheck` int(11) DEFAULT '0', | |
| 48 | 49 | PRIMARY KEY (`id`), |
| 49 | 50 | UNIQUE KEY `device_deviceId_uindex` (`deviceId`) |
| 50 | -) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; | |
| 51 | +) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8mb4; | |
| 51 | 52 | /*!40101 SET character_set_client = @saved_cs_client */; |
| 52 | 53 | |
| 53 | 54 | -- |
| ... | ... | @@ -65,20 +66,20 @@ UNLOCK TABLES; |
| 65 | 66 | |
| 66 | 67 | DROP TABLE IF EXISTS `device_alarm`; |
| 67 | 68 | /*!40101 SET @saved_cs_client = @@character_set_client */; |
| 68 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 69 | +/*!40101 SET character_set_client = utf8 */; | |
| 69 | 70 | CREATE TABLE `device_alarm` ( |
| 70 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 71 | - `deviceId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 72 | - `channelId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 73 | - `alarmPriority` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 74 | - `alarmMethod` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 75 | - `alarmTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 76 | - `alarmDescription` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 71 | + `id` int(11) NOT NULL AUTO_INCREMENT, | |
| 72 | + `deviceId` varchar(50) NOT NULL, | |
| 73 | + `channelId` varchar(50) NOT NULL, | |
| 74 | + `alarmPriority` varchar(50) NOT NULL, | |
| 75 | + `alarmMethod` varchar(50) DEFAULT NULL, | |
| 76 | + `alarmTime` varchar(50) NOT NULL, | |
| 77 | + `alarmDescription` varchar(255) DEFAULT NULL, | |
| 77 | 78 | `longitude` double DEFAULT NULL, |
| 78 | 79 | `latitude` double DEFAULT NULL, |
| 79 | - `alarmType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 80 | + `alarmType` varchar(50) DEFAULT NULL, | |
| 80 | 81 | PRIMARY KEY (`id`) USING BTREE |
| 81 | -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 82 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; | |
| 82 | 83 | /*!40101 SET character_set_client = @saved_cs_client */; |
| 83 | 84 | |
| 84 | 85 | -- |
| ... | ... | @@ -96,43 +97,43 @@ UNLOCK TABLES; |
| 96 | 97 | |
| 97 | 98 | DROP TABLE IF EXISTS `device_channel`; |
| 98 | 99 | /*!40101 SET @saved_cs_client = @@character_set_client */; |
| 99 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 100 | +/*!40101 SET character_set_client = utf8 */; | |
| 100 | 101 | CREATE TABLE `device_channel` ( |
| 101 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 102 | - `channelId` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, | |
| 103 | - `name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 104 | - `manufacture` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 105 | - `model` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 106 | - `owner` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 107 | - `civilCode` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 108 | - `block` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 109 | - `address` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 110 | - `parentId` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 111 | - `safetyWay` int DEFAULT NULL, | |
| 112 | - `registerWay` int DEFAULT NULL, | |
| 113 | - `certNum` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 114 | - `certifiable` int DEFAULT NULL, | |
| 115 | - `errCode` int DEFAULT NULL, | |
| 116 | - `endTime` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 117 | - `secrecy` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 118 | - `ipAddress` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 119 | - `port` int DEFAULT NULL, | |
| 120 | - `password` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 121 | - `PTZType` int DEFAULT NULL, | |
| 122 | - `status` int DEFAULT NULL, | |
| 102 | + `id` int(11) NOT NULL AUTO_INCREMENT, | |
| 103 | + `channelId` varchar(50) NOT NULL, | |
| 104 | + `name` varchar(255) DEFAULT NULL, | |
| 105 | + `manufacture` varchar(50) DEFAULT NULL, | |
| 106 | + `model` varchar(50) DEFAULT NULL, | |
| 107 | + `owner` varchar(50) DEFAULT NULL, | |
| 108 | + `civilCode` varchar(50) DEFAULT NULL, | |
| 109 | + `block` varchar(50) DEFAULT NULL, | |
| 110 | + `address` varchar(50) DEFAULT NULL, | |
| 111 | + `parentId` varchar(50) DEFAULT NULL, | |
| 112 | + `safetyWay` int(11) DEFAULT NULL, | |
| 113 | + `registerWay` int(11) DEFAULT NULL, | |
| 114 | + `certNum` varchar(50) DEFAULT NULL, | |
| 115 | + `certifiable` int(11) DEFAULT NULL, | |
| 116 | + `errCode` int(11) DEFAULT NULL, | |
| 117 | + `endTime` varchar(50) DEFAULT NULL, | |
| 118 | + `secrecy` varchar(50) DEFAULT NULL, | |
| 119 | + `ipAddress` varchar(50) DEFAULT NULL, | |
| 120 | + `port` int(11) DEFAULT NULL, | |
| 121 | + `password` varchar(255) DEFAULT NULL, | |
| 122 | + `PTZType` int(11) DEFAULT NULL, | |
| 123 | + `status` int(11) DEFAULT NULL, | |
| 123 | 124 | `longitude` double DEFAULT NULL, |
| 124 | 125 | `latitude` double DEFAULT NULL, |
| 125 | - `streamId` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 126 | - `deviceId` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, | |
| 127 | - `parental` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 126 | + `streamId` varchar(50) DEFAULT NULL, | |
| 127 | + `deviceId` varchar(50) NOT NULL, | |
| 128 | + `parental` varchar(50) DEFAULT NULL, | |
| 128 | 129 | `hasAudio` bit(1) DEFAULT NULL, |
| 129 | - `createTime` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, | |
| 130 | - `updateTime` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, | |
| 131 | - `subCount` int DEFAULT '0', | |
| 130 | + `createTime` varchar(50) NOT NULL, | |
| 131 | + `updateTime` varchar(50) NOT NULL, | |
| 132 | + `subCount` int(11) DEFAULT '0', | |
| 132 | 133 | PRIMARY KEY (`id`), |
| 133 | 134 | UNIQUE KEY `device_channel_id_uindex` (`id`), |
| 134 | 135 | UNIQUE KEY `device_channel_pk` (`channelId`,`deviceId`) |
| 135 | -) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; | |
| 136 | +) ENGINE=InnoDB AUTO_INCREMENT=81657 DEFAULT CHARSET=utf8mb4; | |
| 136 | 137 | /*!40101 SET character_set_client = @saved_cs_client */; |
| 137 | 138 | |
| 138 | 139 | -- |
| ... | ... | @@ -150,24 +151,24 @@ UNLOCK TABLES; |
| 150 | 151 | |
| 151 | 152 | DROP TABLE IF EXISTS `device_mobile_position`; |
| 152 | 153 | /*!40101 SET @saved_cs_client = @@character_set_client */; |
| 153 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 154 | +/*!40101 SET character_set_client = utf8 */; | |
| 154 | 155 | CREATE TABLE `device_mobile_position` ( |
| 155 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 156 | - `deviceId` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, | |
| 157 | - `channelId` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, | |
| 158 | - `deviceName` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 159 | - `time` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, | |
| 156 | + `id` int(11) NOT NULL AUTO_INCREMENT, | |
| 157 | + `deviceId` varchar(50) NOT NULL, | |
| 158 | + `channelId` varchar(50) NOT NULL, | |
| 159 | + `deviceName` varchar(255) DEFAULT NULL, | |
| 160 | + `time` varchar(50) NOT NULL, | |
| 160 | 161 | `longitude` double NOT NULL, |
| 161 | 162 | `latitude` double NOT NULL, |
| 162 | 163 | `altitude` double DEFAULT NULL, |
| 163 | 164 | `speed` double DEFAULT NULL, |
| 164 | 165 | `direction` double DEFAULT NULL, |
| 165 | - `reportSource` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 166 | - `geodeticSystem` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 167 | - `cnLng` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 168 | - `cnLat` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 166 | + `reportSource` varchar(50) DEFAULT NULL, | |
| 167 | + `geodeticSystem` varchar(50) DEFAULT NULL, | |
| 168 | + `cnLng` varchar(50) DEFAULT NULL, | |
| 169 | + `cnLat` varchar(50) DEFAULT NULL, | |
| 169 | 170 | PRIMARY KEY (`id`) |
| 170 | -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; | |
| 171 | +) ENGINE=InnoDB AUTO_INCREMENT=6108 DEFAULT CHARSET=utf8mb4; | |
| 171 | 172 | /*!40101 SET character_set_client = @saved_cs_client */; |
| 172 | 173 | |
| 173 | 174 | -- |
| ... | ... | @@ -185,23 +186,23 @@ UNLOCK TABLES; |
| 185 | 186 | |
| 186 | 187 | DROP TABLE IF EXISTS `gb_stream`; |
| 187 | 188 | /*!40101 SET @saved_cs_client = @@character_set_client */; |
| 188 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 189 | +/*!40101 SET character_set_client = utf8 */; | |
| 189 | 190 | CREATE TABLE `gb_stream` ( |
| 190 | - `gbStreamId` int NOT NULL AUTO_INCREMENT, | |
| 191 | - `app` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 192 | - `stream` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 193 | - `gbId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 194 | - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 191 | + `gbStreamId` int(11) NOT NULL AUTO_INCREMENT, | |
| 192 | + `app` varchar(255) NOT NULL, | |
| 193 | + `stream` varchar(255) NOT NULL, | |
| 194 | + `gbId` varchar(50) NOT NULL, | |
| 195 | + `name` varchar(255) DEFAULT NULL, | |
| 195 | 196 | `longitude` double DEFAULT NULL, |
| 196 | 197 | `latitude` double DEFAULT NULL, |
| 197 | - `streamType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 198 | - `mediaServerId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 199 | - `status` int DEFAULT NULL, | |
| 200 | - `createStamp` bigint DEFAULT NULL, | |
| 198 | + `streamType` varchar(50) DEFAULT NULL, | |
| 199 | + `mediaServerId` varchar(50) DEFAULT NULL, | |
| 200 | + `status` int(11) DEFAULT NULL, | |
| 201 | + `createStamp` bigint(20) DEFAULT NULL, | |
| 201 | 202 | PRIMARY KEY (`gbStreamId`) USING BTREE, |
| 202 | 203 | UNIQUE KEY `app` (`app`,`stream`) USING BTREE, |
| 203 | 204 | UNIQUE KEY `gbId` (`gbId`) USING BTREE |
| 204 | -) ENGINE=InnoDB AUTO_INCREMENT=300766 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 205 | +) ENGINE=InnoDB AUTO_INCREMENT=300769 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; | |
| 205 | 206 | /*!40101 SET character_set_client = @saved_cs_client */; |
| 206 | 207 | |
| 207 | 208 | -- |
| ... | ... | @@ -219,19 +220,19 @@ UNLOCK TABLES; |
| 219 | 220 | |
| 220 | 221 | DROP TABLE IF EXISTS `log`; |
| 221 | 222 | /*!40101 SET @saved_cs_client = @@character_set_client */; |
| 222 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 223 | +/*!40101 SET character_set_client = utf8 */; | |
| 223 | 224 | CREATE TABLE `log` ( |
| 224 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 225 | - `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 226 | - `type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 227 | - `uri` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 228 | - `address` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 229 | - `result` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 230 | - `timing` bigint NOT NULL, | |
| 231 | - `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 232 | - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 225 | + `id` int(11) NOT NULL AUTO_INCREMENT, | |
| 226 | + `name` varchar(50) NOT NULL, | |
| 227 | + `type` varchar(50) NOT NULL, | |
| 228 | + `uri` varchar(200) NOT NULL, | |
| 229 | + `address` varchar(50) NOT NULL, | |
| 230 | + `result` varchar(50) NOT NULL, | |
| 231 | + `timing` bigint(20) NOT NULL, | |
| 232 | + `username` varchar(50) NOT NULL, | |
| 233 | + `createTime` varchar(50) NOT NULL, | |
| 233 | 234 | PRIMARY KEY (`id`) USING BTREE |
| 234 | -) ENGINE=InnoDB AUTO_INCREMENT=962 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 235 | +) ENGINE=InnoDB AUTO_INCREMENT=1552 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; | |
| 235 | 236 | /*!40101 SET character_set_client = @saved_cs_client */; |
| 236 | 237 | |
| 237 | 238 | -- |
| ... | ... | @@ -249,34 +250,34 @@ UNLOCK TABLES; |
| 249 | 250 | |
| 250 | 251 | DROP TABLE IF EXISTS `media_server`; |
| 251 | 252 | /*!40101 SET @saved_cs_client = @@character_set_client */; |
| 252 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 253 | +/*!40101 SET character_set_client = utf8 */; | |
| 253 | 254 | CREATE TABLE `media_server` ( |
| 254 | - `id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 255 | - `ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 256 | - `hookIp` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 257 | - `sdpIp` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 258 | - `streamIp` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 259 | - `httpPort` int NOT NULL, | |
| 260 | - `httpSSlPort` int NOT NULL, | |
| 261 | - `rtmpPort` int NOT NULL, | |
| 262 | - `rtmpSSlPort` int NOT NULL, | |
| 263 | - `rtpProxyPort` int NOT NULL, | |
| 264 | - `rtspPort` int NOT NULL, | |
| 265 | - `rtspSSLPort` int NOT NULL, | |
| 266 | - `autoConfig` int NOT NULL, | |
| 267 | - `secret` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 268 | - `streamNoneReaderDelayMS` int NOT NULL, | |
| 269 | - `rtpEnable` int NOT NULL, | |
| 270 | - `rtpPortRange` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 271 | - `sendRtpPortRange` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 272 | - `recordAssistPort` int NOT NULL, | |
| 273 | - `defaultServer` int NOT NULL, | |
| 274 | - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 275 | - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 276 | - `hookAliveInterval` int NOT NULL, | |
| 255 | + `id` varchar(255) NOT NULL, | |
| 256 | + `ip` varchar(50) NOT NULL, | |
| 257 | + `hookIp` varchar(50) NOT NULL, | |
| 258 | + `sdpIp` varchar(50) NOT NULL, | |
| 259 | + `streamIp` varchar(50) NOT NULL, | |
| 260 | + `httpPort` int(11) NOT NULL, | |
| 261 | + `httpSSlPort` int(11) NOT NULL, | |
| 262 | + `rtmpPort` int(11) NOT NULL, | |
| 263 | + `rtmpSSlPort` int(11) NOT NULL, | |
| 264 | + `rtpProxyPort` int(11) NOT NULL, | |
| 265 | + `rtspPort` int(11) NOT NULL, | |
| 266 | + `rtspSSLPort` int(11) NOT NULL, | |
| 267 | + `autoConfig` int(11) NOT NULL, | |
| 268 | + `secret` varchar(50) NOT NULL, | |
| 269 | + `streamNoneReaderDelayMS` int(11) NOT NULL, | |
| 270 | + `rtpEnable` int(11) NOT NULL, | |
| 271 | + `rtpPortRange` varchar(50) NOT NULL, | |
| 272 | + `sendRtpPortRange` varchar(50) NOT NULL, | |
| 273 | + `recordAssistPort` int(11) NOT NULL, | |
| 274 | + `defaultServer` int(11) NOT NULL, | |
| 275 | + `createTime` varchar(50) NOT NULL, | |
| 276 | + `updateTime` varchar(50) NOT NULL, | |
| 277 | + `hookAliveInterval` int(11) NOT NULL, | |
| 277 | 278 | PRIMARY KEY (`id`) USING BTREE, |
| 278 | 279 | UNIQUE KEY `media_server_i` (`ip`,`httpPort`) USING BTREE |
| 279 | -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 280 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; | |
| 280 | 281 | /*!40101 SET character_set_client = @saved_cs_client */; |
| 281 | 282 | |
| 282 | 283 | -- |
| ... | ... | @@ -294,33 +295,36 @@ UNLOCK TABLES; |
| 294 | 295 | |
| 295 | 296 | DROP TABLE IF EXISTS `parent_platform`; |
| 296 | 297 | /*!40101 SET @saved_cs_client = @@character_set_client */; |
| 297 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 298 | +/*!40101 SET character_set_client = utf8 */; | |
| 298 | 299 | CREATE TABLE `parent_platform` ( |
| 299 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 300 | - `enable` int DEFAULT NULL, | |
| 301 | - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 302 | - `serverGBId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 303 | - `serverGBDomain` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 304 | - `serverIP` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 305 | - `serverPort` int DEFAULT NULL, | |
| 306 | - `deviceGBId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 307 | - `deviceIp` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 308 | - `devicePort` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 309 | - `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 310 | - `password` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 311 | - `expires` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 312 | - `keepTimeout` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 313 | - `transport` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 314 | - `characterSet` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 315 | - `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 316 | - `ptz` int DEFAULT NULL, | |
| 317 | - `rtcp` int DEFAULT NULL, | |
| 300 | + `id` int(11) NOT NULL AUTO_INCREMENT, | |
| 301 | + `enable` int(11) DEFAULT NULL, | |
| 302 | + `name` varchar(255) DEFAULT NULL, | |
| 303 | + `serverGBId` varchar(50) NOT NULL, | |
| 304 | + `serverGBDomain` varchar(50) DEFAULT NULL, | |
| 305 | + `serverIP` varchar(50) DEFAULT NULL, | |
| 306 | + `serverPort` int(11) DEFAULT NULL, | |
| 307 | + `deviceGBId` varchar(50) NOT NULL, | |
| 308 | + `deviceIp` varchar(50) DEFAULT NULL, | |
| 309 | + `devicePort` varchar(50) DEFAULT NULL, | |
| 310 | + `username` varchar(255) DEFAULT NULL, | |
| 311 | + `password` varchar(50) DEFAULT NULL, | |
| 312 | + `expires` varchar(50) DEFAULT NULL, | |
| 313 | + `keepTimeout` varchar(50) DEFAULT NULL, | |
| 314 | + `transport` varchar(50) DEFAULT NULL, | |
| 315 | + `characterSet` varchar(50) DEFAULT NULL, | |
| 316 | + `catalogId` varchar(50) NOT NULL, | |
| 317 | + `ptz` int(11) DEFAULT NULL, | |
| 318 | + `rtcp` int(11) DEFAULT NULL, | |
| 318 | 319 | `status` bit(1) DEFAULT NULL, |
| 319 | - `shareAllLiveStream` int DEFAULT NULL, | |
| 320 | + `shareAllLiveStream` int(11) DEFAULT NULL, | |
| 321 | + `startOfflinePush` int(11) DEFAULT '0', | |
| 322 | + `administrativeDivision` varchar(50) NOT NULL, | |
| 323 | + `catalogGroup` int(11) DEFAULT '1', | |
| 320 | 324 | PRIMARY KEY (`id`), |
| 321 | 325 | UNIQUE KEY `parent_platform_id_uindex` (`id`), |
| 322 | 326 | UNIQUE KEY `parent_platform_pk` (`serverGBId`) |
| 323 | -) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 327 | +) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; | |
| 324 | 328 | /*!40101 SET character_set_client = @saved_cs_client */; |
| 325 | 329 | |
| 326 | 330 | -- |
| ... | ... | @@ -338,14 +342,14 @@ UNLOCK TABLES; |
| 338 | 342 | |
| 339 | 343 | DROP TABLE IF EXISTS `platform_catalog`; |
| 340 | 344 | /*!40101 SET @saved_cs_client = @@character_set_client */; |
| 341 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 345 | +/*!40101 SET character_set_client = utf8 */; | |
| 342 | 346 | CREATE TABLE `platform_catalog` ( |
| 343 | - `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 344 | - `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 345 | - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 346 | - `parentId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 347 | + `id` varchar(50) NOT NULL, | |
| 348 | + `platformId` varchar(50) NOT NULL, | |
| 349 | + `name` varchar(255) NOT NULL, | |
| 350 | + `parentId` varchar(50) DEFAULT NULL, | |
| 347 | 351 | PRIMARY KEY (`id`) USING BTREE |
| 348 | -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 352 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; | |
| 349 | 353 | /*!40101 SET character_set_client = @saved_cs_client */; |
| 350 | 354 | |
| 351 | 355 | -- |
| ... | ... | @@ -363,14 +367,14 @@ UNLOCK TABLES; |
| 363 | 367 | |
| 364 | 368 | DROP TABLE IF EXISTS `platform_gb_channel`; |
| 365 | 369 | /*!40101 SET @saved_cs_client = @@character_set_client */; |
| 366 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 370 | +/*!40101 SET character_set_client = utf8 */; | |
| 367 | 371 | CREATE TABLE `platform_gb_channel` ( |
| 368 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 369 | - `platformId` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, | |
| 370 | - `catalogId` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, | |
| 371 | - `deviceChannelId` int NOT NULL, | |
| 372 | + `id` int(11) NOT NULL AUTO_INCREMENT, | |
| 373 | + `platformId` varchar(50) NOT NULL, | |
| 374 | + `catalogId` varchar(50) NOT NULL, | |
| 375 | + `deviceChannelId` int(11) NOT NULL, | |
| 372 | 376 | PRIMARY KEY (`id`) |
| 373 | -) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; | |
| 377 | +) ENGINE=InnoDB AUTO_INCREMENT=250 DEFAULT CHARSET=utf8mb4; | |
| 374 | 378 | /*!40101 SET character_set_client = @saved_cs_client */; |
| 375 | 379 | |
| 376 | 380 | -- |
| ... | ... | @@ -388,15 +392,15 @@ UNLOCK TABLES; |
| 388 | 392 | |
| 389 | 393 | DROP TABLE IF EXISTS `platform_gb_stream`; |
| 390 | 394 | /*!40101 SET @saved_cs_client = @@character_set_client */; |
| 391 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 395 | +/*!40101 SET character_set_client = utf8 */; | |
| 392 | 396 | CREATE TABLE `platform_gb_stream` ( |
| 393 | - `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 394 | - `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 395 | - `gbStreamId` int NOT NULL, | |
| 396 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 397 | + `platformId` varchar(50) NOT NULL, | |
| 398 | + `catalogId` varchar(50) NOT NULL, | |
| 399 | + `gbStreamId` int(11) NOT NULL, | |
| 400 | + `id` int(11) NOT NULL AUTO_INCREMENT, | |
| 397 | 401 | PRIMARY KEY (`id`), |
| 398 | 402 | UNIQUE KEY `platform_gb_stream_pk` (`platformId`,`catalogId`,`gbStreamId`) |
| 399 | -) ENGINE=InnoDB AUTO_INCREMENT=301207 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 403 | +) ENGINE=InnoDB AUTO_INCREMENT=301210 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; | |
| 400 | 404 | /*!40101 SET character_set_client = @saved_cs_client */; |
| 401 | 405 | |
| 402 | 406 | -- |
| ... | ... | @@ -414,29 +418,29 @@ UNLOCK TABLES; |
| 414 | 418 | |
| 415 | 419 | DROP TABLE IF EXISTS `stream_proxy`; |
| 416 | 420 | /*!40101 SET @saved_cs_client = @@character_set_client */; |
| 417 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 421 | +/*!40101 SET character_set_client = utf8 */; | |
| 418 | 422 | CREATE TABLE `stream_proxy` ( |
| 419 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 420 | - `type` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, | |
| 421 | - `app` varchar(255) COLLATE utf8mb4_general_ci NOT NULL, | |
| 422 | - `stream` varchar(255) COLLATE utf8mb4_general_ci NOT NULL, | |
| 423 | - `url` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 424 | - `src_url` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 425 | - `dst_url` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 426 | - `timeout_ms` int DEFAULT NULL, | |
| 427 | - `ffmpeg_cmd_key` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 428 | - `rtp_type` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 429 | - `mediaServerId` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 423 | + `id` int(11) NOT NULL AUTO_INCREMENT, | |
| 424 | + `type` varchar(50) NOT NULL, | |
| 425 | + `app` varchar(255) NOT NULL, | |
| 426 | + `stream` varchar(255) NOT NULL, | |
| 427 | + `url` varchar(255) DEFAULT NULL, | |
| 428 | + `src_url` varchar(255) DEFAULT NULL, | |
| 429 | + `dst_url` varchar(255) DEFAULT NULL, | |
| 430 | + `timeout_ms` int(11) DEFAULT NULL, | |
| 431 | + `ffmpeg_cmd_key` varchar(255) DEFAULT NULL, | |
| 432 | + `rtp_type` varchar(50) DEFAULT NULL, | |
| 433 | + `mediaServerId` varchar(50) DEFAULT NULL, | |
| 430 | 434 | `enable_hls` bit(1) DEFAULT NULL, |
| 431 | 435 | `enable_mp4` bit(1) DEFAULT NULL, |
| 432 | 436 | `enable` bit(1) NOT NULL, |
| 433 | 437 | `status` bit(1) NOT NULL, |
| 434 | 438 | `enable_remove_none_reader` bit(1) NOT NULL, |
| 435 | - `createTime` varchar(50) COLLATE utf8mb4_general_ci NOT NULL, | |
| 436 | - `name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 439 | + `createTime` varchar(50) NOT NULL, | |
| 440 | + `name` varchar(255) DEFAULT NULL, | |
| 437 | 441 | PRIMARY KEY (`id`), |
| 438 | 442 | UNIQUE KEY `stream_proxy_pk` (`app`,`stream`) |
| 439 | -) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; | |
| 443 | +) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4; | |
| 440 | 444 | /*!40101 SET character_set_client = @saved_cs_client */; |
| 441 | 445 | |
| 442 | 446 | -- |
| ... | ... | @@ -454,20 +458,20 @@ UNLOCK TABLES; |
| 454 | 458 | |
| 455 | 459 | DROP TABLE IF EXISTS `stream_push`; |
| 456 | 460 | /*!40101 SET @saved_cs_client = @@character_set_client */; |
| 457 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 461 | +/*!40101 SET character_set_client = utf8 */; | |
| 458 | 462 | CREATE TABLE `stream_push` ( |
| 459 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 460 | - `app` varchar(255) COLLATE utf8mb4_general_ci NOT NULL, | |
| 461 | - `stream` varchar(255) COLLATE utf8mb4_general_ci NOT NULL, | |
| 462 | - `totalReaderCount` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 463 | - `originType` int DEFAULT NULL, | |
| 464 | - `originTypeStr` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 465 | - `createStamp` bigint DEFAULT NULL, | |
| 466 | - `aliveSecond` int DEFAULT NULL, | |
| 467 | - `mediaServerId` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 463 | + `id` int(11) NOT NULL AUTO_INCREMENT, | |
| 464 | + `app` varchar(255) NOT NULL, | |
| 465 | + `stream` varchar(255) NOT NULL, | |
| 466 | + `totalReaderCount` varchar(50) DEFAULT NULL, | |
| 467 | + `originType` int(11) DEFAULT NULL, | |
| 468 | + `originTypeStr` varchar(50) DEFAULT NULL, | |
| 469 | + `createStamp` bigint(20) DEFAULT NULL, | |
| 470 | + `aliveSecond` int(11) DEFAULT NULL, | |
| 471 | + `mediaServerId` varchar(50) DEFAULT NULL, | |
| 468 | 472 | PRIMARY KEY (`id`), |
| 469 | 473 | UNIQUE KEY `stream_push_pk` (`app`,`stream`) |
| 470 | -) ENGINE=InnoDB AUTO_INCREMENT=300799 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; | |
| 474 | +) ENGINE=InnoDB AUTO_INCREMENT=300838 DEFAULT CHARSET=utf8mb4; | |
| 471 | 475 | /*!40101 SET character_set_client = @saved_cs_client */; |
| 472 | 476 | |
| 473 | 477 | -- |
| ... | ... | @@ -485,17 +489,17 @@ UNLOCK TABLES; |
| 485 | 489 | |
| 486 | 490 | DROP TABLE IF EXISTS `user`; |
| 487 | 491 | /*!40101 SET @saved_cs_client = @@character_set_client */; |
| 488 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 492 | +/*!40101 SET character_set_client = utf8 */; | |
| 489 | 493 | CREATE TABLE `user` ( |
| 490 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 491 | - `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 492 | - `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 493 | - `roleId` int NOT NULL, | |
| 494 | - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 495 | - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 494 | + `id` int(11) NOT NULL AUTO_INCREMENT, | |
| 495 | + `username` varchar(255) NOT NULL, | |
| 496 | + `password` varchar(255) NOT NULL, | |
| 497 | + `roleId` int(11) NOT NULL, | |
| 498 | + `createTime` varchar(50) NOT NULL, | |
| 499 | + `updateTime` varchar(50) NOT NULL, | |
| 496 | 500 | PRIMARY KEY (`id`) USING BTREE, |
| 497 | 501 | UNIQUE KEY `user_username_uindex` (`username`) USING BTREE |
| 498 | -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 502 | +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; | |
| 499 | 503 | /*!40101 SET character_set_client = @saved_cs_client */; |
| 500 | 504 | |
| 501 | 505 | -- |
| ... | ... | @@ -504,7 +508,8 @@ CREATE TABLE `user` ( |
| 504 | 508 | |
| 505 | 509 | LOCK TABLES `user` WRITE; |
| 506 | 510 | /*!40000 ALTER TABLE `user` DISABLE KEYS */; |
| 507 | -INSERT INTO `user` VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021 - 04 - 13 14:14:57','2021 - 04 - 13 14:14:57'); | |
| 511 | +INSERT INTO `user` VALUES | |
| 512 | + (1,'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021 - 04 - 13 14:14:57','2021 - 04 - 13 14:14:57'); | |
| 508 | 513 | /*!40000 ALTER TABLE `user` ENABLE KEYS */; |
| 509 | 514 | UNLOCK TABLES; |
| 510 | 515 | |
| ... | ... | @@ -514,15 +519,15 @@ UNLOCK TABLES; |
| 514 | 519 | |
| 515 | 520 | DROP TABLE IF EXISTS `user_role`; |
| 516 | 521 | /*!40101 SET @saved_cs_client = @@character_set_client */; |
| 517 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 522 | +/*!40101 SET character_set_client = utf8 */; | |
| 518 | 523 | CREATE TABLE `user_role` ( |
| 519 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 520 | - `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 521 | - `authority` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 522 | - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 523 | - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 524 | + `id` int(11) NOT NULL AUTO_INCREMENT, | |
| 525 | + `name` varchar(50) NOT NULL, | |
| 526 | + `authority` varchar(50) NOT NULL, | |
| 527 | + `createTime` varchar(50) NOT NULL, | |
| 528 | + `updateTime` varchar(50) NOT NULL, | |
| 524 | 529 | PRIMARY KEY (`id`) USING BTREE |
| 525 | -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 530 | +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; | |
| 526 | 531 | /*!40101 SET character_set_client = @saved_cs_client */; |
| 527 | 532 | |
| 528 | 533 | -- |
| ... | ... | @@ -531,7 +536,8 @@ CREATE TABLE `user_role` ( |
| 531 | 536 | |
| 532 | 537 | LOCK TABLES `user_role` WRITE; |
| 533 | 538 | /*!40000 ALTER TABLE `user_role` DISABLE KEYS */; |
| 534 | -INSERT INTO `user_role` VALUES (1,'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57'); | |
| 539 | +INSERT INTO `user_role` VALUES | |
| 540 | + (1,'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57'); | |
| 535 | 541 | /*!40000 ALTER TABLE `user_role` ENABLE KEYS */; |
| 536 | 542 | UNLOCK TABLES; |
| 537 | 543 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; |
| ... | ... | @@ -544,4 +550,4 @@ UNLOCK TABLES; |
| 544 | 550 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; |
| 545 | 551 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; |
| 546 | 552 | |
| 547 | --- Dump completed on 2022-03-07 8:26:30 | |
| 553 | +-- Dump completed on 2022-04-18 10:50:27 | ... | ... |
sql/update.sql
| 1 | -alter table device | |
| 2 | - add subscribeCycleForMobilePosition int null; | |
| 1 | +alter table parent_platform | |
| 2 | + add startOfflinePush int default 0 null; | |
| 3 | 3 | |
| 4 | -alter table device | |
| 5 | - add mobilePositionSubmissionInterval int default 5 null; | |
| 4 | +alter table parent_platform | |
| 5 | + add administrativeDivision varchar(50) not null; | |
| 6 | + | |
| 7 | +alter table parent_platform | |
| 8 | + add catalogGroup int default 1 null; | |
| 6 | 9 | |
| 7 | 10 | alter table device |
| 8 | - add subscribeCycleForAlarm int null; | |
| 9 | 11 | \ No newline at end of file |
| 12 | + add ssrcCheck int default 0 null; | |
| 13 | + | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
| ... | ... | @@ -129,6 +129,11 @@ public class Device { |
| 129 | 129 | */ |
| 130 | 130 | private int subscribeCycleForAlarm; |
| 131 | 131 | |
| 132 | + /** | |
| 133 | + * 是否开启ssrc校验,默认关闭,开启可以防止串流 | |
| 134 | + */ | |
| 135 | + private boolean ssrcCheck; | |
| 136 | + | |
| 132 | 137 | |
| 133 | 138 | public String getDeviceId() { |
| 134 | 139 | return deviceId; |
| ... | ... | @@ -321,4 +326,12 @@ public class Device { |
| 321 | 326 | public void setSubscribeCycleForAlarm(int subscribeCycleForAlarm) { |
| 322 | 327 | this.subscribeCycleForAlarm = subscribeCycleForAlarm; |
| 323 | 328 | } |
| 329 | + | |
| 330 | + public boolean isSsrcCheck() { | |
| 331 | + return ssrcCheck; | |
| 332 | + } | |
| 333 | + | |
| 334 | + public void setSsrcCheck(boolean ssrcCheck) { | |
| 335 | + this.ssrcCheck = ssrcCheck; | |
| 336 | + } | |
| 324 | 337 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java
| ... | ... | @@ -169,6 +169,11 @@ public class DeviceChannel { |
| 169 | 169 | */ |
| 170 | 170 | private boolean hasAudio; |
| 171 | 171 | |
| 172 | + /** | |
| 173 | + * 标记通道的类型,0->国标通道 1->直播流通道 2->业务分组/虚拟组织/行政区划 | |
| 174 | + */ | |
| 175 | + private int channelType; | |
| 176 | + | |
| 172 | 177 | public int getId() { |
| 173 | 178 | return id; |
| 174 | 179 | } |
| ... | ... | @@ -441,4 +446,12 @@ public class DeviceChannel { |
| 441 | 446 | public void setUpdateTime(String updateTime) { |
| 442 | 447 | this.updateTime = updateTime; |
| 443 | 448 | } |
| 449 | + | |
| 450 | + public int getChannelType() { | |
| 451 | + return channelType; | |
| 452 | + } | |
| 453 | + | |
| 454 | + public void setChannelType(int channelType) { | |
| 455 | + this.channelType = channelType; | |
| 456 | + } | |
| 444 | 457 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java
| ... | ... | @@ -129,6 +129,21 @@ public class ParentPlatform { |
| 129 | 129 | */ |
| 130 | 130 | private boolean mobilePositionSubscribe; |
| 131 | 131 | |
| 132 | + /** | |
| 133 | + * 点播未推流的设备时是否使用redis通知拉起 | |
| 134 | + */ | |
| 135 | + private boolean startOfflinePush; | |
| 136 | + | |
| 137 | + /** | |
| 138 | + * 目录分组-每次向上级发送通道信息时单个包携带的通道数量,取值1,2,4,8 | |
| 139 | + */ | |
| 140 | + private int catalogGroup; | |
| 141 | + | |
| 142 | + /** | |
| 143 | + * 行政区划 | |
| 144 | + */ | |
| 145 | + private String administrativeDivision; | |
| 146 | + | |
| 132 | 147 | public Integer getId() { |
| 133 | 148 | return id; |
| 134 | 149 | } |
| ... | ... | @@ -329,4 +344,28 @@ public class ParentPlatform { |
| 329 | 344 | public void setMobilePositionSubscribe(boolean mobilePositionSubscribe) { |
| 330 | 345 | this.mobilePositionSubscribe = mobilePositionSubscribe; |
| 331 | 346 | } |
| 347 | + | |
| 348 | + public boolean isStartOfflinePush() { | |
| 349 | + return startOfflinePush; | |
| 350 | + } | |
| 351 | + | |
| 352 | + public void setStartOfflinePush(boolean startOfflinePush) { | |
| 353 | + this.startOfflinePush = startOfflinePush; | |
| 354 | + } | |
| 355 | + | |
| 356 | + public int getCatalogGroup() { | |
| 357 | + return catalogGroup; | |
| 358 | + } | |
| 359 | + | |
| 360 | + public void setCatalogGroup(int catalogGroup) { | |
| 361 | + this.catalogGroup = catalogGroup; | |
| 362 | + } | |
| 363 | + | |
| 364 | + public String getAdministrativeDivision() { | |
| 365 | + return administrativeDivision; | |
| 366 | + } | |
| 367 | + | |
| 368 | + public void setAdministrativeDivision(String administrativeDivision) { | |
| 369 | + this.administrativeDivision = administrativeDivision; | |
| 370 | + } | |
| 332 | 371 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/session/CatalogDataCatch.java
| ... | ... | @@ -85,6 +85,12 @@ public class CatalogDataCatch { |
| 85 | 85 | return syncStatus; |
| 86 | 86 | } |
| 87 | 87 | |
| 88 | + public boolean isSyncRunning(String deviceId) { | |
| 89 | + CatalogData catalogData = data.get(deviceId); | |
| 90 | + if (catalogData == null) return false; | |
| 91 | + return !catalogData.getStatus().equals(CatalogData.CatalogDataStatus.end); | |
| 92 | + } | |
| 93 | + | |
| 88 | 94 | @Scheduled(fixedRate = 5 * 1000) //每5秒执行一次, 发现数据5秒未更新则移除数据并认为数据接收超时 |
| 89 | 95 | private void timerTask(){ |
| 90 | 96 | Set<String> keys = data.keySet(); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/CatalogSubscribeTask.java
| ... | ... | @@ -10,6 +10,8 @@ import org.springframework.scheduling.annotation.Async; |
| 10 | 10 | import javax.sip.Dialog; |
| 11 | 11 | import javax.sip.DialogState; |
| 12 | 12 | import javax.sip.ResponseEvent; |
| 13 | +import java.util.Timer; | |
| 14 | +import java.util.TimerTask; | |
| 13 | 15 | |
| 14 | 16 | /** |
| 15 | 17 | * 目录订阅任务 |
| ... | ... | @@ -20,6 +22,8 @@ public class CatalogSubscribeTask implements ISubscribeTask { |
| 20 | 22 | private final ISIPCommander sipCommander; |
| 21 | 23 | private Dialog dialog; |
| 22 | 24 | |
| 25 | + private Timer timer ; | |
| 26 | + | |
| 23 | 27 | public CatalogSubscribeTask(Device device, ISIPCommander sipCommander) { |
| 24 | 28 | this.device = device; |
| 25 | 29 | this.sipCommander = sipCommander; |
| ... | ... | @@ -27,6 +31,10 @@ public class CatalogSubscribeTask implements ISubscribeTask { |
| 27 | 31 | |
| 28 | 32 | @Override |
| 29 | 33 | public void run() { |
| 34 | + if (timer != null ) { | |
| 35 | + timer.cancel(); | |
| 36 | + timer = null; | |
| 37 | + } | |
| 30 | 38 | sipCommander.catalogSubscribe(device, dialog, eventResult -> { |
| 31 | 39 | if (eventResult.dialog != null || eventResult.dialog.getState().equals(DialogState.CONFIRMED)) { |
| 32 | 40 | dialog = eventResult.dialog; |
| ... | ... | @@ -43,6 +51,13 @@ public class CatalogSubscribeTask implements ISubscribeTask { |
| 43 | 51 | dialog = null; |
| 44 | 52 | // 失败 |
| 45 | 53 | logger.warn("[目录订阅]失败,信令发送失败: {}-{} ", device.getDeviceId(), eventResult.msg); |
| 54 | + timer = new Timer(); | |
| 55 | + timer.schedule(new TimerTask() { | |
| 56 | + @Override | |
| 57 | + public void run() { | |
| 58 | + CatalogSubscribeTask.this.run(); | |
| 59 | + } | |
| 60 | + }, 2000); | |
| 46 | 61 | }); |
| 47 | 62 | } |
| 48 | 63 | |
| ... | ... | @@ -56,9 +71,13 @@ public class CatalogSubscribeTask implements ISubscribeTask { |
| 56 | 71 | * TERMINATED-> Terminated Dialog状态-终止 |
| 57 | 72 | */ |
| 58 | 73 | logger.info("取消目录订阅时dialog状态为{}", DialogState.CONFIRMED); |
| 74 | + if (timer != null ) { | |
| 75 | + timer.cancel(); | |
| 76 | + timer = null; | |
| 77 | + } | |
| 59 | 78 | if (dialog != null && dialog.getState().equals(DialogState.CONFIRMED)) { |
| 60 | 79 | device.setSubscribeCycleForCatalog(0); |
| 61 | - sipCommander.mobilePositionSubscribe(device, dialog, eventResult -> { | |
| 80 | + sipCommander.catalogSubscribe(device, dialog, eventResult -> { | |
| 62 | 81 | ResponseEvent event = (ResponseEvent) eventResult.event; |
| 63 | 82 | if (event.getResponse().getRawContent() != null) { |
| 64 | 83 | // 成功 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/task/impl/MobilePositionSubscribeHandlerTask.java
| ... | ... | @@ -29,7 +29,6 @@ public class MobilePositionSubscribeHandlerTask implements ISubscribeTask { |
| 29 | 29 | private String key; |
| 30 | 30 | |
| 31 | 31 | public MobilePositionSubscribeHandlerTask(IRedisCatchStorage redisCatchStorage, ISIPCommanderForPlatform sipCommanderForPlatform, IVideoManagerStorage storager, String platformId, String sn, String key, SubscribeHolder subscribeInfo) { |
| 32 | - System.out.println("MobilePositionSubscribeHandlerTask 初始化"); | |
| 33 | 32 | this.redisCatchStorage = redisCatchStorage; |
| 34 | 33 | this.storager = storager; |
| 35 | 34 | this.platform = storager.queryParentPlatByServerGBId(platformId); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
| ... | ... | @@ -32,6 +32,7 @@ import javax.sip.header.*; |
| 32 | 32 | import javax.sip.message.Request; |
| 33 | 33 | import java.lang.reflect.Field; |
| 34 | 34 | import java.text.ParseException; |
| 35 | +import java.util.ArrayList; | |
| 35 | 36 | import java.util.HashSet; |
| 36 | 37 | import java.util.List; |
| 37 | 38 | import java.util.UUID; |
| ... | ... | @@ -215,7 +216,11 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 215 | 216 | return false; |
| 216 | 217 | } |
| 217 | 218 | try { |
| 218 | - String catalogXml = getCatalogXml(channel, sn, parentPlatform, size); | |
| 219 | + List<DeviceChannel> channels = new ArrayList<>(); | |
| 220 | + if (channel != null) { | |
| 221 | + channels.add(channel); | |
| 222 | + } | |
| 223 | + String catalogXml = getCatalogXml(channels, sn, parentPlatform, size); | |
| 219 | 224 | |
| 220 | 225 | // callid |
| 221 | 226 | CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() |
| ... | ... | @@ -239,7 +244,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 239 | 244 | sendCatalogResponse(channels, parentPlatform, sn, fromTag, 0); |
| 240 | 245 | return true; |
| 241 | 246 | } |
| 242 | - private String getCatalogXml(DeviceChannel channel, String sn, ParentPlatform parentPlatform, int size) { | |
| 247 | + private String getCatalogXml(List<DeviceChannel> channels, String sn, ParentPlatform parentPlatform, int size) { | |
| 243 | 248 | String characterSet = parentPlatform.getCharacterSet(); |
| 244 | 249 | StringBuffer catalogXml = new StringBuffer(600); |
| 245 | 250 | catalogXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet +"\"?>\r\n"); |
| ... | ... | @@ -248,34 +253,38 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 248 | 253 | catalogXml.append("<SN>" +sn + "</SN>\r\n"); |
| 249 | 254 | catalogXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n"); |
| 250 | 255 | catalogXml.append("<SumNum>" + size + "</SumNum>\r\n"); |
| 251 | - catalogXml.append("<DeviceList Num=\"1\">\r\n"); | |
| 252 | - catalogXml.append("<Item>\r\n"); | |
| 253 | - if (channel != null) { | |
| 254 | - catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n"); | |
| 255 | - catalogXml.append("<Name>" + channel.getName() + "</Name>\r\n"); | |
| 256 | - catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n"); | |
| 257 | - catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n"); | |
| 258 | - catalogXml.append("<Owner>" + channel.getOwner() + "</Owner>\r\n"); | |
| 259 | - catalogXml.append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n"); | |
| 260 | - catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n"); | |
| 261 | - catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n"); | |
| 262 | - if (channel.getParentId() != null) { | |
| 263 | - catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n"); | |
| 256 | + catalogXml.append("<DeviceList Num=\"" + channels.size() +"\">\r\n"); | |
| 257 | + if (channels.size() > 0) { | |
| 258 | + for (DeviceChannel channel : channels) { | |
| 259 | + catalogXml.append("<Item>\r\n"); | |
| 260 | + catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n"); | |
| 261 | + catalogXml.append("<Name>" + channel.getName() + "</Name>\r\n"); | |
| 262 | + catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n"); | |
| 263 | + catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n"); | |
| 264 | + if (channel.getParentId() != null) { | |
| 265 | + catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n"); | |
| 266 | + } | |
| 267 | + catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n"); | |
| 268 | + catalogXml.append("<Status>" + (channel.getStatus() == 0?"OFF":"ON") + "</Status>\r\n"); | |
| 269 | + catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n"); | |
| 270 | + if (channel.getChannelType() != 2) { // 业务分组/虚拟组织/行政区划 不设置以下字段 | |
| 271 | + catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n"); | |
| 272 | + catalogXml.append("<Owner>" + channel.getOwner() + "</Owner>\r\n"); | |
| 273 | + catalogXml.append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n"); | |
| 274 | + catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n"); | |
| 275 | + catalogXml.append("<Longitude>" + channel.getLongitude() + "</Longitude>\r\n"); | |
| 276 | + catalogXml.append("<Latitude>" + channel.getLatitude() + "</Latitude>\r\n"); | |
| 277 | + catalogXml.append("<IPAddress>" + channel.getIpAddress() + "</IPAddress>\r\n"); | |
| 278 | + catalogXml.append("<Port>" + channel.getPort() + "</Port>\r\n"); | |
| 279 | + catalogXml.append("<Info>\r\n"); | |
| 280 | + catalogXml.append("<PTZType>" + channel.getPTZType() + "</PTZType>\r\n"); | |
| 281 | + catalogXml.append("</Info>\r\n"); | |
| 282 | + } | |
| 283 | + | |
| 284 | + catalogXml.append("</Item>\r\n"); | |
| 264 | 285 | } |
| 265 | - catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n"); | |
| 266 | - catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n"); | |
| 267 | - catalogXml.append("<Status>" + (channel.getStatus() == 0?"OFF":"ON") + "</Status>\r\n"); | |
| 268 | - catalogXml.append("<Longitude>" + channel.getLongitude() + "</Longitude>\r\n"); | |
| 269 | - catalogXml.append("<Latitude>" + channel.getLatitude() + "</Latitude>\r\n"); | |
| 270 | - catalogXml.append("<IPAddress>" + channel.getIpAddress() + "</IPAddress>\r\n"); | |
| 271 | - catalogXml.append("<Port>" + channel.getPort() + "</Port>\r\n"); | |
| 272 | - catalogXml.append("<Info>\r\n"); | |
| 273 | - catalogXml.append("<PTZType>" + channel.getPTZType() + "</PTZType>\r\n"); | |
| 274 | - catalogXml.append("</Info>\r\n"); | |
| 275 | 286 | } |
| 276 | 287 | |
| 277 | - | |
| 278 | - catalogXml.append("</Item>\r\n"); | |
| 279 | 288 | catalogXml.append("</DeviceList>\r\n"); |
| 280 | 289 | catalogXml.append("</Response>\r\n"); |
| 281 | 290 | return catalogXml.toString(); |
| ... | ... | @@ -286,15 +295,20 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 286 | 295 | return; |
| 287 | 296 | } |
| 288 | 297 | try { |
| 289 | - DeviceChannel deviceChannel = channels.get(index); | |
| 290 | - String catalogXml = getCatalogXml(deviceChannel, sn, parentPlatform, channels.size()); | |
| 298 | + List<DeviceChannel> deviceChannels; | |
| 299 | + if (index + parentPlatform.getCatalogGroup() < channels.size()) { | |
| 300 | + deviceChannels = channels.subList(index, index + parentPlatform.getCatalogGroup()); | |
| 301 | + }else { | |
| 302 | + deviceChannels = channels.subList(index, channels.size()); | |
| 303 | + } | |
| 304 | + String catalogXml = getCatalogXml(deviceChannels, sn, parentPlatform, channels.size()); | |
| 291 | 305 | // callid |
| 292 | 306 | CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() |
| 293 | 307 | : udpSipProvider.getNewCallId(); |
| 294 | 308 | |
| 295 | 309 | Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, catalogXml, fromTag, callIdHeader); |
| 296 | 310 | transmitRequest(parentPlatform, request, null, eventResult -> { |
| 297 | - int indexNext = index + 1; | |
| 311 | + int indexNext = index + parentPlatform.getCatalogGroup(); | |
| 298 | 312 | sendCatalogResponse(channels, parentPlatform, sn, fromTag, indexNext); |
| 299 | 313 | }); |
| 300 | 314 | } catch (SipException | ParseException | InvalidArgumentException e) { |
| ... | ... | @@ -432,13 +446,21 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 432 | 446 | if (index >= deviceChannels.size()) { |
| 433 | 447 | return true; |
| 434 | 448 | } |
| 449 | + List<DeviceChannel> channels; | |
| 450 | + if (index + parentPlatform.getCatalogGroup() < deviceChannels.size()) { | |
| 451 | + channels = deviceChannels.subList(index, index + parentPlatform.getCatalogGroup()); | |
| 452 | + }else { | |
| 453 | + channels = deviceChannels.subList(index, deviceChannels.size()); | |
| 454 | + } | |
| 435 | 455 | try { |
| 436 | 456 | Integer finalIndex = index; |
| 437 | - String catalogXmlContent = getCatalogXmlContentForCatalogAddOrUpdate(parentPlatform, deviceChannels.get(index ), deviceChannels.size(), type, subscribeInfo); | |
| 457 | + String catalogXmlContent = getCatalogXmlContentForCatalogAddOrUpdate(parentPlatform, channels, | |
| 458 | + deviceChannels.size(), type, subscribeInfo); | |
| 438 | 459 | sendNotify(parentPlatform, catalogXmlContent, subscribeInfo, eventResult -> { |
| 439 | 460 | logger.error("发送NOTIFY通知消息失败。错误:{} {}", eventResult.statusCode, eventResult.msg); |
| 440 | 461 | }, (eventResult -> { |
| 441 | - sendNotifyForCatalogAddOrUpdate(type, parentPlatform, deviceChannels, subscribeInfo, finalIndex + 1); | |
| 462 | + sendNotifyForCatalogAddOrUpdate(type, parentPlatform, deviceChannels, subscribeInfo, | |
| 463 | + finalIndex + parentPlatform.getCatalogGroup()); | |
| 442 | 464 | })); |
| 443 | 465 | } catch (SipException | ParseException e) { |
| 444 | 466 | e.printStackTrace(); |
| ... | ... | @@ -500,11 +522,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 500 | 522 | |
| 501 | 523 | } |
| 502 | 524 | |
| 503 | - private String getCatalogXmlContentForCatalogAddOrUpdate(ParentPlatform parentPlatform, DeviceChannel channel, int sumNum, String type, SubscribeInfo subscribeInfo) { | |
| 525 | + private String getCatalogXmlContentForCatalogAddOrUpdate(ParentPlatform parentPlatform, List<DeviceChannel> channels, int sumNum, String type, SubscribeInfo subscribeInfo) { | |
| 504 | 526 | StringBuffer catalogXml = new StringBuffer(600); |
| 505 | - if (parentPlatform.getServerGBId().equals(channel.getParentId())) { | |
| 506 | - channel.setParentId(parentPlatform.getDeviceGBId()); | |
| 507 | - } | |
| 527 | + | |
| 508 | 528 | String characterSet = parentPlatform.getCharacterSet(); |
| 509 | 529 | catalogXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n"); |
| 510 | 530 | catalogXml.append("<Notify>\r\n"); |
| ... | ... | @@ -512,26 +532,35 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 512 | 532 | catalogXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n"); |
| 513 | 533 | catalogXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n"); |
| 514 | 534 | catalogXml.append("<SumNum>1</SumNum>\r\n"); |
| 515 | - catalogXml.append("<DeviceList Num=\"1\">\r\n"); | |
| 516 | - catalogXml.append("<Item>\r\n"); | |
| 517 | - catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n"); | |
| 518 | - catalogXml.append("<Name>" + channel.getName() + "</Name>\r\n"); | |
| 519 | - catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n"); | |
| 520 | - catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n"); | |
| 521 | - catalogXml.append("<Owner>0</Owner>\r\n"); | |
| 522 | - catalogXml.append("<CivilCode>CivilCode</CivilCode>\r\n"); | |
| 523 | - catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n"); | |
| 524 | - catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n"); | |
| 525 | - if (channel.getParentId() != null) { | |
| 526 | - catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n"); | |
| 527 | - } | |
| 528 | - catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n"); | |
| 529 | - catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n"); | |
| 530 | - catalogXml.append("<Status>" + (channel.getStatus() == 0 ? "OFF" : "ON") + "</Status>\r\n"); | |
| 531 | - if (!"presence".equals(subscribeInfo.getEventType())) { | |
| 532 | - catalogXml.append("<Event>" + type + "</Event>\r\n"); | |
| 533 | - } | |
| 534 | - catalogXml.append("</Item>\r\n"); | |
| 535 | + catalogXml.append("<DeviceList Num=\"" + channels.size() + "\">\r\n"); | |
| 536 | + if (channels.size() > 0) { | |
| 537 | + for (DeviceChannel channel : channels) { | |
| 538 | + if (parentPlatform.getServerGBId().equals(channel.getParentId())) { | |
| 539 | + channel.setParentId(parentPlatform.getDeviceGBId()); | |
| 540 | + } | |
| 541 | + catalogXml.append("<Item>\r\n"); | |
| 542 | + catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n"); | |
| 543 | + catalogXml.append("<Name>" + channel.getName() + "</Name>\r\n"); | |
| 544 | + catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n"); | |
| 545 | + catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n"); | |
| 546 | + if (channel.getParentId() != null) { | |
| 547 | + catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n"); | |
| 548 | + } | |
| 549 | + catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n"); | |
| 550 | + catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n"); | |
| 551 | + catalogXml.append("<Status>" + (channel.getStatus() == 0 ? "OFF" : "ON") + "</Status>\r\n"); | |
| 552 | + if (channel.getChannelType() == 2) { // 业务分组/虚拟组织/行政区划 不设置以下属性 | |
| 553 | + catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n"); | |
| 554 | + catalogXml.append("<Owner>0</Owner>\r\n"); | |
| 555 | + catalogXml.append("<CivilCode>CivilCode</CivilCode>\r\n"); | |
| 556 | + catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n"); | |
| 557 | + } | |
| 558 | + if (!"presence".equals(subscribeInfo.getEventType())) { | |
| 559 | + catalogXml.append("<Event>" + type + "</Event>\r\n"); | |
| 560 | + } | |
| 561 | + catalogXml.append("</Item>\r\n"); | |
| 562 | + } | |
| 563 | + } | |
| 535 | 564 | catalogXml.append("</DeviceList>\r\n"); |
| 536 | 565 | catalogXml.append("</Notify>\r\n"); |
| 537 | 566 | return catalogXml.toString(); |
| ... | ... | @@ -553,13 +582,20 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 553 | 582 | if (index >= deviceChannels.size()) { |
| 554 | 583 | return true; |
| 555 | 584 | } |
| 585 | + List<DeviceChannel> channels; | |
| 586 | + if (index + parentPlatform.getCatalogGroup() < deviceChannels.size()) { | |
| 587 | + channels = deviceChannels.subList(index, index + parentPlatform.getCatalogGroup()); | |
| 588 | + }else { | |
| 589 | + channels = deviceChannels.subList(index, deviceChannels.size()); | |
| 590 | + } | |
| 556 | 591 | try { |
| 557 | 592 | Integer finalIndex = index; |
| 558 | - String catalogXmlContent = getCatalogXmlContentForCatalogOther(parentPlatform, deviceChannels.get(index), type); | |
| 593 | + String catalogXmlContent = getCatalogXmlContentForCatalogOther(parentPlatform, channels, type); | |
| 559 | 594 | sendNotify(parentPlatform, catalogXmlContent, subscribeInfo, eventResult -> { |
| 560 | 595 | logger.error("发送NOTIFY通知消息失败。错误:{} {}", eventResult.statusCode, eventResult.msg); |
| 561 | 596 | }, (eventResult -> { |
| 562 | - sendNotifyForCatalogOther(type, parentPlatform, deviceChannels, subscribeInfo, finalIndex + 1); | |
| 597 | + sendNotifyForCatalogOther(type, parentPlatform, deviceChannels, subscribeInfo, | |
| 598 | + finalIndex + parentPlatform.getCatalogGroup()); | |
| 563 | 599 | })); |
| 564 | 600 | } catch (SipException e) { |
| 565 | 601 | e.printStackTrace(); |
| ... | ... | @@ -574,10 +610,8 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 574 | 610 | return true; |
| 575 | 611 | } |
| 576 | 612 | |
| 577 | - private String getCatalogXmlContentForCatalogOther(ParentPlatform parentPlatform, DeviceChannel channel, String type) { | |
| 578 | - if (parentPlatform.getServerGBId().equals(channel.getParentId())) { | |
| 579 | - channel.setParentId(parentPlatform.getDeviceGBId()); | |
| 580 | - } | |
| 613 | + private String getCatalogXmlContentForCatalogOther(ParentPlatform parentPlatform, List<DeviceChannel> channels, String type) { | |
| 614 | + | |
| 581 | 615 | String characterSet = parentPlatform.getCharacterSet(); |
| 582 | 616 | StringBuffer catalogXml = new StringBuffer(600); |
| 583 | 617 | catalogXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n"); |
| ... | ... | @@ -586,11 +620,18 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 586 | 620 | catalogXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n"); |
| 587 | 621 | catalogXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n"); |
| 588 | 622 | catalogXml.append("<SumNum>1</SumNum>\r\n"); |
| 589 | - catalogXml.append("<DeviceList Num=\"1\">\r\n"); | |
| 590 | - catalogXml.append("<Item>\r\n"); | |
| 591 | - catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n"); | |
| 592 | - catalogXml.append("<Event>" + type + "</Event>\r\n"); | |
| 593 | - catalogXml.append("</Item>\r\n"); | |
| 623 | + catalogXml.append("<DeviceList Num=\" " + channels.size() + " \">\r\n"); | |
| 624 | + if (channels.size() > 0) { | |
| 625 | + for (DeviceChannel channel : channels) { | |
| 626 | + if (parentPlatform.getServerGBId().equals(channel.getParentId())) { | |
| 627 | + channel.setParentId(parentPlatform.getDeviceGBId()); | |
| 628 | + } | |
| 629 | + catalogXml.append("<Item>\r\n"); | |
| 630 | + catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n"); | |
| 631 | + catalogXml.append("<Event>" + type + "</Event>\r\n"); | |
| 632 | + catalogXml.append("</Item>\r\n"); | |
| 633 | + } | |
| 634 | + } | |
| 594 | 635 | catalogXml.append("</DeviceList>\r\n"); |
| 595 | 636 | catalogXml.append("</Notify>\r\n"); |
| 596 | 637 | return catalogXml.toString(); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
| ... | ... | @@ -397,6 +397,10 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 397 | 397 | logger.info("[ app={}, stream={} ]通道离线,启用流后开始推流",gbStream.getApp(), gbStream.getStream()); |
| 398 | 398 | responseAck(evt, Response.BAD_REQUEST, "channel [" + gbStream.getGbId() + "] offline"); |
| 399 | 399 | }else if ("push".equals(gbStream.getStreamType())) { |
| 400 | + if (!platform.isStartOfflinePush()) { | |
| 401 | + responseAck(evt, Response.TEMPORARILY_UNAVAILABLE, "channel unavailable"); | |
| 402 | + return; | |
| 403 | + } | |
| 400 | 404 | // 发送redis消息以使设备上线 |
| 401 | 405 | logger.info("[ app={}, stream={} ]通道离线,发送redis信息控制设备开始推流",gbStream.getApp(), gbStream.getStream()); |
| 402 | 406 | MessageForPushChannel messageForPushChannel = new MessageForPushChannel(); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java
| ... | ... | @@ -3,7 +3,6 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; |
| 3 | 3 | import com.genersoft.iot.vmp.common.VideoManagerConstants; |
| 4 | 4 | import com.genersoft.iot.vmp.conf.SipConfig; |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper; |
| 6 | -import com.genersoft.iot.vmp.gb28181.auth.RegisterLogicHandler; | |
| 7 | 6 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 8 | 7 | import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate; |
| 9 | 8 | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| ... | ... | @@ -42,166 +41,157 @@ import java.util.Locale; |
| 42 | 41 | @Component |
| 43 | 42 | public class RegisterRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor { |
| 44 | 43 | |
| 45 | - private Logger logger = LoggerFactory.getLogger(RegisterRequestProcessor.class); | |
| 46 | - | |
| 47 | - public String method = "REGISTER"; | |
| 48 | - | |
| 49 | - @Autowired | |
| 50 | - private SipConfig sipConfig; | |
| 51 | - | |
| 52 | - @Autowired | |
| 53 | - private RegisterLogicHandler handler; | |
| 54 | - | |
| 55 | - @Autowired | |
| 56 | - private IRedisCatchStorage redisCatchStorage; | |
| 57 | - | |
| 58 | - @Autowired | |
| 59 | - private IVideoManagerStorage storager; | |
| 60 | - | |
| 61 | - @Autowired | |
| 62 | - private EventPublisher publisher; | |
| 63 | - | |
| 64 | - @Autowired | |
| 65 | - private SIPProcessorObserver sipProcessorObserver; | |
| 66 | - | |
| 67 | - @Override | |
| 68 | - public void afterPropertiesSet() throws Exception { | |
| 69 | - // 添加消息处理的订阅 | |
| 70 | - sipProcessorObserver.addRequestProcessor(method, this); | |
| 71 | - } | |
| 72 | - | |
| 73 | - /** | |
| 74 | - * 收到注册请求 处理 | |
| 75 | - * @param evt | |
| 76 | - */ | |
| 77 | - @Override | |
| 78 | - public void process(RequestEvent evt) { | |
| 79 | - try { | |
| 80 | - RequestEventExt evtExt = (RequestEventExt)evt; | |
| 81 | - String requestAddress = evtExt.getRemoteIpAddress() + ":" + evtExt.getRemotePort(); | |
| 82 | - logger.info("[{}] 收到注册请求,开始处理", requestAddress); | |
| 83 | - Request request = evt.getRequest(); | |
| 84 | - ExpiresHeader expiresHeader = (ExpiresHeader) request.getHeader(Expires.NAME); | |
| 85 | - Response response = null; | |
| 86 | - boolean passwordCorrect = false; | |
| 87 | - // 注册标志 0:未携带授权头或者密码错误 1:注册成功 2:注销成功 | |
| 88 | - int registerFlag = 0; | |
| 89 | - FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); | |
| 90 | - AddressImpl address = (AddressImpl) fromHeader.getAddress(); | |
| 91 | - SipUri uri = (SipUri) address.getURI(); | |
| 92 | - String deviceId = uri.getUser(); | |
| 93 | - Device deviceInRedis = redisCatchStorage.getDevice(deviceId); | |
| 94 | - Device device = storager.queryVideoDevice(deviceId); | |
| 95 | - if (deviceInRedis != null && device == null) { | |
| 96 | - // redis 存在脏数据 | |
| 97 | - redisCatchStorage.clearCatchByDeviceId(deviceId); | |
| 98 | - } | |
| 99 | - AuthorizationHeader authorhead = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); | |
| 100 | - // 校验密码是否正确 | |
| 101 | - if (authorhead != null) { | |
| 102 | - passwordCorrect = new DigestServerAuthenticationHelper().doAuthenticatePlainTextPassword(request, | |
| 103 | - sipConfig.getPassword()); | |
| 104 | - } | |
| 105 | - if (StringUtils.isEmpty(sipConfig.getPassword())){ | |
| 106 | - passwordCorrect = true; | |
| 107 | - } | |
| 108 | - | |
| 109 | - // 未携带授权头或者密码错误 回复401 | |
| 110 | - if (authorhead == null ) { | |
| 111 | - | |
| 112 | - logger.info("[{}] 未携带授权头 回复401", requestAddress); | |
| 113 | - response = getMessageFactory().createResponse(Response.UNAUTHORIZED, request); | |
| 114 | - new DigestServerAuthenticationHelper().generateChallenge(getHeaderFactory(), response, sipConfig.getDomain()); | |
| 115 | - }else { | |
| 116 | - if (!passwordCorrect){ | |
| 117 | - // 注册失败 | |
| 118 | - response = getMessageFactory().createResponse(Response.FORBIDDEN, request); | |
| 119 | - response.setReasonPhrase("wrong password"); | |
| 120 | - logger.info("[{}] 密码/SIP服务器ID错误, 回复403", requestAddress); | |
| 121 | - }else { | |
| 122 | - // 携带授权头并且密码正确 | |
| 123 | - response = getMessageFactory().createResponse(Response.OK, request); | |
| 124 | - // 添加date头 | |
| 125 | - SIPDateHeader dateHeader = new SIPDateHeader(); | |
| 126 | - // 使用自己修改的 | |
| 127 | - WvpSipDate wvpSipDate = new WvpSipDate(Calendar.getInstance(Locale.ENGLISH).getTimeInMillis()); | |
| 128 | - dateHeader.setDate(wvpSipDate); | |
| 129 | - response.addHeader(dateHeader); | |
| 130 | - | |
| 131 | - | |
| 132 | - if (expiresHeader == null) { | |
| 133 | - response = getMessageFactory().createResponse(Response.BAD_REQUEST, request); | |
| 134 | - ServerTransaction serverTransaction = getServerTransaction(evt); | |
| 135 | - serverTransaction.sendResponse(response); | |
| 136 | - if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete(); | |
| 137 | - return; | |
| 138 | - } | |
| 139 | - // 添加Contact头 | |
| 140 | - response.addHeader(request.getHeader(ContactHeader.NAME)); | |
| 141 | - // 添加Expires头 | |
| 142 | - response.addHeader(request.getExpires()); | |
| 143 | - | |
| 144 | - // 获取到通信地址等信息 | |
| 145 | - ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); | |
| 146 | - String received = viaHeader.getReceived(); | |
| 147 | - int rPort = viaHeader.getRPort(); | |
| 148 | - // 解析本地地址替代 | |
| 149 | - if (StringUtils.isEmpty(received) || rPort == -1) { | |
| 150 | - received = viaHeader.getHost(); | |
| 151 | - rPort = viaHeader.getPort(); | |
| 152 | - } | |
| 153 | - // | |
| 154 | - | |
| 155 | - if (device == null) { | |
| 156 | - device = new Device(); | |
| 157 | - device.setStreamMode("UDP"); | |
| 158 | - device.setCharset("GB2312"); | |
| 159 | - device.setDeviceId(deviceId); | |
| 160 | - device.setFirsRegister(true); | |
| 161 | - }else { | |
| 162 | - if (device.getOnline() == 0) { | |
| 163 | - device.setFirsRegister(true); | |
| 164 | - } | |
| 165 | - } | |
| 166 | - device.setIp(received); | |
| 167 | - device.setPort(rPort); | |
| 168 | - device.setHostAddress(received.concat(":").concat(String.valueOf(rPort))); | |
| 169 | - // 注销成功 | |
| 170 | - if (expiresHeader.getExpires() == 0) { | |
| 171 | - registerFlag = 2; | |
| 172 | - } | |
| 173 | - // 注册成功 | |
| 174 | - else { | |
| 175 | - device.setExpires(expiresHeader.getExpires()); | |
| 176 | - registerFlag = 1; | |
| 177 | - // 判断TCP还是UDP | |
| 178 | - boolean isTcp = false; | |
| 179 | - ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); | |
| 180 | - String transport = reqViaHeader.getTransport(); | |
| 181 | - if (transport.equals("TCP")) { | |
| 182 | - isTcp = true; | |
| 183 | - } | |
| 184 | - device.setTransport(isTcp ? "TCP" : "UDP"); | |
| 185 | - } | |
| 186 | - } | |
| 187 | - } | |
| 188 | - | |
| 189 | - ServerTransaction serverTransaction = getServerTransaction(evt); | |
| 190 | - serverTransaction.sendResponse(response); | |
| 191 | - if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete(); | |
| 192 | - // 注册成功 | |
| 193 | - // 保存到redis | |
| 194 | - if (registerFlag == 1 ) { | |
| 195 | - logger.info("[{}] 注册成功! deviceId:" + device.getDeviceId(), requestAddress); | |
| 196 | - publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_REGISTER, expiresHeader.getExpires()); | |
| 197 | - } else if (registerFlag == 2) { | |
| 198 | - logger.info("[{}] 注销成功! deviceId:" + device.getDeviceId(), requestAddress); | |
| 199 | - publisher.outlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_OUTLINE_UNREGISTER); | |
| 200 | - } | |
| 201 | - } catch (SipException | InvalidArgumentException | NoSuchAlgorithmException | ParseException e) { | |
| 202 | - e.printStackTrace(); | |
| 203 | - } | |
| 204 | - | |
| 205 | - } | |
| 44 | + private final Logger logger = LoggerFactory.getLogger(RegisterRequestProcessor.class); | |
| 45 | + | |
| 46 | + public String method = "REGISTER"; | |
| 47 | + | |
| 48 | + @Autowired | |
| 49 | + private SipConfig sipConfig; | |
| 50 | + | |
| 51 | + @Autowired | |
| 52 | + private IRedisCatchStorage redisCatchStorage; | |
| 53 | + | |
| 54 | + @Autowired | |
| 55 | + private IVideoManagerStorage storager; | |
| 56 | + | |
| 57 | + @Autowired | |
| 58 | + private EventPublisher publisher; | |
| 59 | + | |
| 60 | + @Autowired | |
| 61 | + private SIPProcessorObserver sipProcessorObserver; | |
| 62 | + | |
| 63 | + @Override | |
| 64 | + public void afterPropertiesSet() throws Exception { | |
| 65 | + // 添加消息处理的订阅 | |
| 66 | + sipProcessorObserver.addRequestProcessor(method, this); | |
| 67 | + } | |
| 68 | + | |
| 69 | + /** | |
| 70 | + * 收到注册请求 处理 | |
| 71 | + * | |
| 72 | + * @param evt | |
| 73 | + */ | |
| 74 | + @Override | |
| 75 | + public void process(RequestEvent evt) { | |
| 76 | + try { | |
| 77 | + RequestEventExt evtExt = (RequestEventExt) evt; | |
| 78 | + String requestAddress = evtExt.getRemoteIpAddress() + ":" + evtExt.getRemotePort(); | |
| 79 | + logger.info("[{}] 收到注册请求,开始处理", requestAddress); | |
| 80 | + Request request = evt.getRequest(); | |
| 81 | + ExpiresHeader expiresHeader = (ExpiresHeader) request.getHeader(Expires.NAME); | |
| 82 | + Response response = null; | |
| 83 | + boolean passwordCorrect = false; | |
| 84 | + // 注册标志 0:未携带授权头或者密码错误 1:注册成功 2:注销成功 | |
| 85 | + int registerFlag = 0; | |
| 86 | + FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); | |
| 87 | + AddressImpl address = (AddressImpl) fromHeader.getAddress(); | |
| 88 | + SipUri uri = (SipUri) address.getURI(); | |
| 89 | + String deviceId = uri.getUser(); | |
| 90 | + | |
| 91 | + AuthorizationHeader authHead = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); | |
| 92 | + if (authHead == null) { | |
| 93 | + logger.info("[{}] 未携带授权头 回复401", requestAddress); | |
| 94 | + response = getMessageFactory().createResponse(Response.UNAUTHORIZED, request); | |
| 95 | + new DigestServerAuthenticationHelper().generateChallenge(getHeaderFactory(), response, sipConfig.getDomain()); | |
| 96 | + sendResponse(evt, response); | |
| 97 | + return; | |
| 98 | + } | |
| 99 | + | |
| 100 | + // 校验密码是否正确 | |
| 101 | + passwordCorrect = StringUtils.isEmpty(sipConfig.getPassword()) || | |
| 102 | + new DigestServerAuthenticationHelper().doAuthenticatePlainTextPassword(request, sipConfig.getPassword()); | |
| 103 | + // 未携带授权头或者密码错误 回复401 | |
| 104 | + | |
| 105 | + if (!passwordCorrect) { | |
| 106 | + // 注册失败 | |
| 107 | + response = getMessageFactory().createResponse(Response.FORBIDDEN, request); | |
| 108 | + response.setReasonPhrase("wrong password"); | |
| 109 | + logger.info("[{}] 密码/SIP服务器ID错误, 回复403", requestAddress); | |
| 110 | + sendResponse(evt, response); | |
| 111 | + return; | |
| 112 | + } | |
| 113 | + | |
| 114 | + Device deviceInRedis = redisCatchStorage.getDevice(deviceId); | |
| 115 | + Device device = storager.queryVideoDevice(deviceId); | |
| 116 | + if (deviceInRedis != null && device == null) { | |
| 117 | + // redis 存在脏数据 | |
| 118 | + redisCatchStorage.clearCatchByDeviceId(deviceId); | |
| 119 | + } | |
| 120 | + // 携带授权头并且密码正确 | |
| 121 | + response = getMessageFactory().createResponse(Response.OK, request); | |
| 122 | + // 添加date头 | |
| 123 | + SIPDateHeader dateHeader = new SIPDateHeader(); | |
| 124 | + // 使用自己修改的 | |
| 125 | + WvpSipDate wvpSipDate = new WvpSipDate(Calendar.getInstance(Locale.ENGLISH).getTimeInMillis()); | |
| 126 | + dateHeader.setDate(wvpSipDate); | |
| 127 | + response.addHeader(dateHeader); | |
| 128 | + | |
| 129 | + if (expiresHeader == null) { | |
| 130 | + response = getMessageFactory().createResponse(Response.BAD_REQUEST, request); | |
| 131 | + ServerTransaction serverTransaction = getServerTransaction(evt); | |
| 132 | + serverTransaction.sendResponse(response); | |
| 133 | + if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete(); | |
| 134 | + return; | |
| 135 | + } | |
| 136 | + // 添加Contact头 | |
| 137 | + response.addHeader(request.getHeader(ContactHeader.NAME)); | |
| 138 | + // 添加Expires头 | |
| 139 | + response.addHeader(request.getExpires()); | |
| 140 | + | |
| 141 | + // 获取到通信地址等信息 | |
| 142 | + ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); | |
| 143 | + String received = viaHeader.getReceived(); | |
| 144 | + int rPort = viaHeader.getRPort(); | |
| 145 | + // 解析本地地址替代 | |
| 146 | + if (StringUtils.isEmpty(received) || rPort == -1) { | |
| 147 | + received = viaHeader.getHost(); | |
| 148 | + rPort = viaHeader.getPort(); | |
| 149 | + } | |
| 150 | + if (device == null) { | |
| 151 | + device = new Device(); | |
| 152 | + device.setStreamMode("UDP"); | |
| 153 | + device.setCharset("GB2312"); | |
| 154 | + device.setDeviceId(deviceId); | |
| 155 | + device.setFirsRegister(true); | |
| 156 | + } else { | |
| 157 | + device.setFirsRegister(device.getOnline() == 0); | |
| 158 | + } | |
| 159 | + device.setIp(received); | |
| 160 | + device.setPort(rPort); | |
| 161 | + device.setHostAddress(received.concat(":").concat(String.valueOf(rPort))); | |
| 162 | + if (expiresHeader.getExpires() == 0) { | |
| 163 | + // 注销成功 | |
| 164 | + registerFlag = 2; | |
| 165 | + } else { | |
| 166 | + // 注册成功 | |
| 167 | + device.setExpires(expiresHeader.getExpires()); | |
| 168 | + registerFlag = 1; | |
| 169 | + // 判断TCP还是UDP | |
| 170 | + ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); | |
| 171 | + String transport = reqViaHeader.getTransport(); | |
| 172 | + device.setTransport("TCP".equals(transport) ? "TCP" : "UDP"); | |
| 173 | + } | |
| 174 | + | |
| 175 | + sendResponse(evt, response); | |
| 176 | + // 注册成功 | |
| 177 | + // 保存到redis | |
| 178 | + if (registerFlag == 1) { | |
| 179 | + logger.info("[{}] 注册成功! deviceId:" + deviceId, requestAddress); | |
| 180 | + publisher.onlineEventPublish(device, VideoManagerConstants.EVENT_ONLINE_REGISTER, expiresHeader.getExpires()); | |
| 181 | + } else if (registerFlag == 2) { | |
| 182 | + logger.info("[{}] 注销成功! deviceId:" + deviceId, requestAddress); | |
| 183 | + publisher.outlineEventPublish(deviceId, VideoManagerConstants.EVENT_OUTLINE_UNREGISTER); | |
| 184 | + } | |
| 185 | + } catch (SipException | InvalidArgumentException | NoSuchAlgorithmException | ParseException e) { | |
| 186 | + e.printStackTrace(); | |
| 187 | + } | |
| 188 | + | |
| 189 | + } | |
| 190 | + | |
| 191 | + private void sendResponse(RequestEvent evt, Response response) throws InvalidArgumentException, SipException { | |
| 192 | + ServerTransaction serverTransaction = getServerTransaction(evt); | |
| 193 | + serverTransaction.sendResponse(response); | |
| 194 | + if (serverTransaction.getDialog() != null) serverTransaction.getDialog().delete(); | |
| 195 | + } | |
| 206 | 196 | |
| 207 | 197 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/CatalogNotifyMessageHandler.java
| ... | ... | @@ -79,7 +79,7 @@ public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent imple |
| 79 | 79 | deviceChannel.setParental(1); |
| 80 | 80 | deviceChannel.setParentId(catalog.getParentId()); |
| 81 | 81 | deviceChannel.setRegisterWay(1); |
| 82 | - deviceChannel.setCivilCode(parentPlatform.getDeviceGBId().substring(0,6)); | |
| 82 | + deviceChannel.setCivilCode(parentPlatform.getAdministrativeDivision()); | |
| 83 | 83 | deviceChannel.setModel("live"); |
| 84 | 84 | deviceChannel.setOwner("wvp-pro"); |
| 85 | 85 | deviceChannel.setSecrecy("0"); |
| ... | ... | @@ -116,7 +116,7 @@ public class CatalogNotifyMessageHandler extends SIPRequestProcessorParent imple |
| 116 | 116 | deviceChannel.setStatus(1); |
| 117 | 117 | deviceChannel.setParentId(gbStream.getCatalogId()); |
| 118 | 118 | deviceChannel.setRegisterWay(1); |
| 119 | - deviceChannel.setCivilCode(parentPlatform.getDeviceGBId().substring(0,6)); | |
| 119 | + deviceChannel.setCivilCode(parentPlatform.getAdministrativeDivision()); | |
| 120 | 120 | deviceChannel.setModel("live"); |
| 121 | 121 | deviceChannel.setOwner("wvp-pro"); |
| 122 | 122 | deviceChannel.setParental(0); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/CatalogQueryMessageHandler.java
| ... | ... | @@ -83,20 +83,17 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem |
| 83 | 83 | catalog.setParentId(parentPlatform.getDeviceGBId()); |
| 84 | 84 | } |
| 85 | 85 | DeviceChannel deviceChannel = new DeviceChannel(); |
| 86 | + // 通道的类型,0->国标通道 1->直播流通道 2->业务分组/虚拟组织/行政区划 | |
| 87 | + deviceChannel.setChannelType(2); | |
| 86 | 88 | deviceChannel.setChannelId(catalog.getId()); |
| 87 | 89 | deviceChannel.setName(catalog.getName()); |
| 88 | - deviceChannel.setLongitude(0.0); | |
| 89 | - deviceChannel.setLatitude(0.0); | |
| 90 | 90 | deviceChannel.setDeviceId(parentPlatform.getDeviceGBId()); |
| 91 | 91 | deviceChannel.setManufacture("wvp-pro"); |
| 92 | 92 | deviceChannel.setStatus(1); |
| 93 | 93 | deviceChannel.setParental(1); |
| 94 | 94 | deviceChannel.setParentId(catalog.getParentId()); |
| 95 | 95 | deviceChannel.setRegisterWay(1); |
| 96 | - deviceChannel.setCivilCode(parentPlatform.getDeviceGBId().substring(0,6)); | |
| 97 | - deviceChannel.setModel("live"); | |
| 98 | - deviceChannel.setOwner("wvp-pro"); | |
| 99 | - deviceChannel.setSecrecy("0"); | |
| 96 | + deviceChannel.setCivilCode(parentPlatform.getAdministrativeDivision()); | |
| 100 | 97 | allChannels.add(deviceChannel); |
| 101 | 98 | } |
| 102 | 99 | } |
| ... | ... | @@ -107,6 +104,8 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem |
| 107 | 104 | channel.setCatalogId(parentPlatform.getDeviceGBId()); |
| 108 | 105 | } |
| 109 | 106 | DeviceChannel deviceChannel = storage.queryChannel(channel.getDeviceId(), channel.getChannelId()); |
| 107 | + // 通道的类型,0->国标通道 1->直播流通道 2->业务分组/虚拟组织/行政区划 | |
| 108 | + deviceChannel.setChannelType(0); | |
| 110 | 109 | deviceChannel.setParental(0); |
| 111 | 110 | deviceChannel.setParentId(channel.getCatalogId()); |
| 112 | 111 | deviceChannel.setCivilCode(parentPlatform.getDeviceGBId().substring(0, 6)); |
| ... | ... | @@ -120,6 +119,8 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem |
| 120 | 119 | gbStream.setCatalogId(null); |
| 121 | 120 | } |
| 122 | 121 | DeviceChannel deviceChannel = new DeviceChannel(); |
| 122 | + // 通道的类型,0->国标通道 1->直播流通道 2->业务分组/虚拟组织/行政区划 | |
| 123 | + deviceChannel.setChannelType(1); | |
| 123 | 124 | deviceChannel.setChannelId(gbStream.getGbId()); |
| 124 | 125 | deviceChannel.setName(gbStream.getName()); |
| 125 | 126 | deviceChannel.setLongitude(gbStream.getLongitude()); |
| ... | ... | @@ -130,7 +131,7 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem |
| 130 | 131 | deviceChannel.setStatus(1); |
| 131 | 132 | deviceChannel.setParentId(gbStream.getCatalogId()); |
| 132 | 133 | deviceChannel.setRegisterWay(1); |
| 133 | - deviceChannel.setCivilCode(parentPlatform.getDeviceGBId().substring(0,6)); | |
| 134 | + deviceChannel.setCivilCode(parentPlatform.getAdministrativeDivision()); | |
| 134 | 135 | deviceChannel.setModel("live"); |
| 135 | 136 | deviceChannel.setOwner("wvp-pro"); |
| 136 | 137 | deviceChannel.setParental(0); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java
| ... | ... | @@ -118,8 +118,8 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp |
| 118 | 118 | channelList.add(deviceChannel); |
| 119 | 119 | } |
| 120 | 120 | int sn = Integer.parseInt(snElement.getText()); |
| 121 | - logger.info("收到来自设备【{}】的通道: {}个,{}/{}", device.getDeviceId(), channelList.size(), catalogDataCatch.get(key) == null ? 0 :catalogDataCatch.get(key).size(), sumNum); | |
| 122 | 121 | catalogDataCatch.put(device.getDeviceId(), sn, sumNum, device, channelList); |
| 122 | + logger.info("收到来自设备【{}】的通道: {}个,{}/{}", device.getDeviceId(), channelList.size(), catalogDataCatch.get(device.getDeviceId()) == null ? 0 :catalogDataCatch.get(device.getDeviceId()).size(), sumNum); | |
| 123 | 123 | if (catalogDataCatch.get(device.getDeviceId()).size() == sumNum) { |
| 124 | 124 | // 数据已经完整接收 |
| 125 | 125 | boolean resetChannelsResult = storager.resetChannels(device.getDeviceId(), catalogDataCatch.get(device.getDeviceId())); |
| ... | ... | @@ -223,6 +223,14 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp |
| 223 | 223 | } |
| 224 | 224 | } |
| 225 | 225 | |
| 226 | + public boolean isSyncRunning(String deviceId) { | |
| 227 | + if (catalogDataCatch.get(deviceId) == null) { | |
| 228 | + return false; | |
| 229 | + }else { | |
| 230 | + return catalogDataCatch.isSyncRunning(deviceId); | |
| 231 | + } | |
| 232 | + } | |
| 233 | + | |
| 226 | 234 | public void setChannelSyncReady(Device device, int sn) { |
| 227 | 235 | catalogDataCatch.addReady(device, sn); |
| 228 | 236 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
| ... | ... | @@ -20,8 +20,8 @@ import java.util.*; |
| 20 | 20 | |
| 21 | 21 | /** |
| 22 | 22 | * 基于dom4j的工具包 |
| 23 | - * | |
| 24 | - * | |
| 23 | + * | |
| 24 | + * | |
| 25 | 25 | */ |
| 26 | 26 | public class XmlUtil { |
| 27 | 27 | /** |
| ... | ... | @@ -31,9 +31,9 @@ public class XmlUtil { |
| 31 | 31 | |
| 32 | 32 | /** |
| 33 | 33 | * 解析XML为Document对象 |
| 34 | - * | |
| 34 | + * | |
| 35 | 35 | * @param xml 被解析的XMl |
| 36 | - * | |
| 36 | + * | |
| 37 | 37 | * @return Document |
| 38 | 38 | */ |
| 39 | 39 | public static Element parseXml(String xml) { |
| ... | ... | @@ -51,7 +51,7 @@ public class XmlUtil { |
| 51 | 51 | |
| 52 | 52 | /** |
| 53 | 53 | * 获取element对象的text的值 |
| 54 | - * | |
| 54 | + * | |
| 55 | 55 | * @param em 节点的对象 |
| 56 | 56 | * @param tag 节点的tag |
| 57 | 57 | * @return 节点 |
| ... | ... | @@ -62,12 +62,12 @@ public class XmlUtil { |
| 62 | 62 | } |
| 63 | 63 | Element e = em.element(tag); |
| 64 | 64 | // |
| 65 | - return null == e ? null : e.getText(); | |
| 65 | + return null == e ? null : e.getText().trim(); | |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | 68 | /** |
| 69 | 69 | * 递归解析xml节点,适用于 多节点数据 |
| 70 | - * | |
| 70 | + * | |
| 71 | 71 | * @param node node |
| 72 | 72 | * @param nodeName nodeName |
| 73 | 73 | * @return List<Map<String, Object>> |
| ... | ... | @@ -106,7 +106,7 @@ public class XmlUtil { |
| 106 | 106 | |
| 107 | 107 | /** |
| 108 | 108 | * xml转json |
| 109 | - * | |
| 109 | + * | |
| 110 | 110 | * @param element |
| 111 | 111 | * @param json |
| 112 | 112 | */ | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
| ... | ... | @@ -81,7 +81,7 @@ public class ZLMRTPServerFactory { |
| 81 | 81 | return result; |
| 82 | 82 | } |
| 83 | 83 | |
| 84 | - public int createRTPServer(MediaServerItem mediaServerItem, String streamId) { | |
| 84 | + public int createRTPServer(MediaServerItem mediaServerItem, String streamId, int ssrc) { | |
| 85 | 85 | int result = -1; |
| 86 | 86 | // 查询此rtp server 是否已经存在 |
| 87 | 87 | JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaServerItem, streamId); |
| ... | ... | @@ -94,6 +94,7 @@ public class ZLMRTPServerFactory { |
| 94 | 94 | param.put("enable_tcp", 1); |
| 95 | 95 | param.put("stream_id", streamId); |
| 96 | 96 | param.put("port", 0); |
| 97 | + param.put("ssrc", ssrc); | |
| 97 | 98 | JSONObject openRtpServerResultJson = zlmresTfulUtils.openRtpServer(mediaServerItem, param); |
| 98 | 99 | |
| 99 | 100 | if (openRtpServerResultJson != null) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/IDeviceService.java
| ... | ... | @@ -44,6 +44,13 @@ public interface IDeviceService { |
| 44 | 44 | SyncStatus getChannelSyncStatus(String deviceId); |
| 45 | 45 | |
| 46 | 46 | /** |
| 47 | + * 查看是否仍在同步 | |
| 48 | + * @param deviceId 设备ID | |
| 49 | + * @return | |
| 50 | + */ | |
| 51 | + Boolean isSyncRunning(String deviceId); | |
| 52 | + | |
| 53 | + /** | |
| 47 | 54 | * 通道同步 |
| 48 | 55 | * @param device |
| 49 | 56 | */ | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
| ... | ... | @@ -44,9 +44,9 @@ public interface IMediaServerService { |
| 44 | 44 | |
| 45 | 45 | void updateVmServer(List<MediaServerItem> mediaServerItemList); |
| 46 | 46 | |
| 47 | - SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId); | |
| 47 | + SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, boolean ssrcCheck); | |
| 48 | 48 | |
| 49 | - SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, boolean isPlayback); | |
| 49 | + SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, boolean ssrcCheck, boolean isPlayback); | |
| 50 | 50 | |
| 51 | 51 | void closeRTPServer(String deviceId, String channelId, String ssrc); |
| 52 | 52 | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
| ... | ... | @@ -41,10 +41,6 @@ public class DeviceServiceImpl implements IDeviceService { |
| 41 | 41 | if (device == null || device.getSubscribeCycleForCatalog() < 0) { |
| 42 | 42 | return false; |
| 43 | 43 | } |
| 44 | - CatalogSubscribeTask task = (CatalogSubscribeTask)dynamicTask.get(device.getDeviceId() + "catalog"); | |
| 45 | - if (task != null && task.getDialogState() != null && task.getDialogState().equals(DialogState.CONFIRMED)) { // 已存在不需要再次添加 | |
| 46 | - return true; | |
| 47 | - } | |
| 48 | 44 | logger.info("[添加目录订阅] 设备{}", device.getDeviceId()); |
| 49 | 45 | // 添加目录订阅 |
| 50 | 46 | CatalogSubscribeTask catalogSubscribeTask = new CatalogSubscribeTask(device, sipCommander); |
| ... | ... | @@ -71,10 +67,6 @@ public class DeviceServiceImpl implements IDeviceService { |
| 71 | 67 | return false; |
| 72 | 68 | } |
| 73 | 69 | logger.info("[添加移动位置订阅] 设备{}", device.getDeviceId()); |
| 74 | - MobilePositionSubscribeTask task = (MobilePositionSubscribeTask)dynamicTask.get(device.getDeviceId() + "mobile_position"); | |
| 75 | - if (task != null && task.getDialogState() != null && task.getDialogState().equals(DialogState.CONFIRMED)) { // 已存在不需要再次添加 | |
| 76 | - return true; | |
| 77 | - } | |
| 78 | 70 | // 添加目录订阅 |
| 79 | 71 | MobilePositionSubscribeTask mobilePositionSubscribeTask = new MobilePositionSubscribeTask(device, sipCommander); |
| 80 | 72 | // 提前开始刷新订阅 |
| ... | ... | @@ -100,8 +92,13 @@ public class DeviceServiceImpl implements IDeviceService { |
| 100 | 92 | } |
| 101 | 93 | |
| 102 | 94 | @Override |
| 95 | + public Boolean isSyncRunning(String deviceId) { | |
| 96 | + return catalogResponseMessageHandler.isSyncRunning(deviceId); | |
| 97 | + } | |
| 98 | + | |
| 99 | + @Override | |
| 103 | 100 | public void sync(Device device) { |
| 104 | - if (catalogResponseMessageHandler.getChannelSyncProgress(device.getDeviceId()) != null) { | |
| 101 | + if (catalogResponseMessageHandler.isSyncRunning(device.getDeviceId())) { | |
| 105 | 102 | logger.info("开启同步时发现同步已经存在"); |
| 106 | 103 | return; |
| 107 | 104 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
| ... | ... | @@ -117,12 +117,12 @@ public class MediaServerServiceImpl implements IMediaServerService { |
| 117 | 117 | } |
| 118 | 118 | |
| 119 | 119 | @Override |
| 120 | - public SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId) { | |
| 121 | - return openRTPServer(mediaServerItem, streamId, false); | |
| 120 | + public SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, boolean ssrcCheck) { | |
| 121 | + return openRTPServer(mediaServerItem, streamId, ssrcCheck,false); | |
| 122 | 122 | } |
| 123 | 123 | |
| 124 | 124 | @Override |
| 125 | - public SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, boolean isPlayback) { | |
| 125 | + public SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, boolean ssrcCheck, boolean isPlayback) { | |
| 126 | 126 | if (mediaServerItem == null || mediaServerItem.getId() == null) { |
| 127 | 127 | return null; |
| 128 | 128 | } |
| ... | ... | @@ -146,7 +146,7 @@ public class MediaServerServiceImpl implements IMediaServerService { |
| 146 | 146 | } |
| 147 | 147 | int rtpServerPort = mediaServerItem.getRtpProxyPort(); |
| 148 | 148 | if (mediaServerItem.isRtpEnable()) { |
| 149 | - rtpServerPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId); | |
| 149 | + rtpServerPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId, ssrcCheck?Integer.parseInt(ssrc):0); | |
| 150 | 150 | } |
| 151 | 151 | redisUtil.set(key, mediaServerItem); |
| 152 | 152 | return new SSRCInfo(rtpServerPort, ssrc, streamId); | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
| ... | ... | @@ -188,7 +188,7 @@ public class PlayServiceImpl implements IPlayService { |
| 188 | 188 | if (mediaServerItem.isRtpEnable()) { |
| 189 | 189 | streamId = String.format("%s_%s", device.getDeviceId(), channelId); |
| 190 | 190 | } |
| 191 | - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId); | |
| 191 | + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, device.isSsrcCheck()); | |
| 192 | 192 | play(mediaServerItem, ssrcInfo, device, channelId, (mediaServerItemInUse, response)->{ |
| 193 | 193 | if (hookEvent != null) { |
| 194 | 194 | hookEvent.response(mediaServerItem, response); |
| ... | ... | @@ -232,7 +232,7 @@ public class PlayServiceImpl implements IPlayService { |
| 232 | 232 | streamId = String.format("%s_%s", device.getDeviceId(), channelId); |
| 233 | 233 | } |
| 234 | 234 | if (ssrcInfo == null) { |
| 235 | - ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId); | |
| 235 | + ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, device.isSsrcCheck()); | |
| 236 | 236 | } |
| 237 | 237 | |
| 238 | 238 | // 超时处理 | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
| ... | ... | @@ -420,9 +420,6 @@ public class StreamPushServiceImpl implements IStreamPushService { |
| 420 | 420 | continue; |
| 421 | 421 | } |
| 422 | 422 | streamPushItemForPlatform.setPlatformId(platFormInfoArray[0]); |
| 423 | - if (platFormInfoArray[0].equals("34020000002110000001")) { | |
| 424 | - System.out.println(111); | |
| 425 | - } | |
| 426 | 423 | List<GbStream> gbStreamList = platformForEvent.get(platFormInfoArray[0]); |
| 427 | 424 | if (gbStreamList == null) { |
| 428 | 425 | gbStreamList = new ArrayList<>(); | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
| ... | ... | @@ -37,6 +37,7 @@ public interface DeviceMapper { |
| 37 | 37 | "subscribeCycleForMobilePosition," + |
| 38 | 38 | "mobilePositionSubmissionInterval," + |
| 39 | 39 | "subscribeCycleForAlarm," + |
| 40 | + "ssrcCheck," + | |
| 40 | 41 | "online" + |
| 41 | 42 | ") VALUES (" + |
| 42 | 43 | "#{deviceId}," + |
| ... | ... | @@ -59,6 +60,7 @@ public interface DeviceMapper { |
| 59 | 60 | "#{subscribeCycleForMobilePosition}," + |
| 60 | 61 | "#{mobilePositionSubmissionInterval}," + |
| 61 | 62 | "#{subscribeCycleForAlarm}," + |
| 63 | + "#{ssrcCheck}," + | |
| 62 | 64 | "#{online}" + |
| 63 | 65 | ")") |
| 64 | 66 | int add(Device device); |
| ... | ... | @@ -84,6 +86,7 @@ public interface DeviceMapper { |
| 84 | 86 | "<if test=\"subscribeCycleForMobilePosition != null\">, subscribeCycleForMobilePosition=${subscribeCycleForMobilePosition}</if>" + |
| 85 | 87 | "<if test=\"mobilePositionSubmissionInterval != null\">, mobilePositionSubmissionInterval=${mobilePositionSubmissionInterval}</if>" + |
| 86 | 88 | "<if test=\"subscribeCycleForAlarm != null\">, subscribeCycleForAlarm=${subscribeCycleForAlarm}</if>" + |
| 89 | + "<if test=\"ssrcCheck != null\">, ssrcCheck=${ssrcCheck}</if>" + | |
| 87 | 90 | "WHERE deviceId='${deviceId}'"+ |
| 88 | 91 | " </script>"}) |
| 89 | 92 | int update(Device device); | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java
| ... | ... | @@ -16,10 +16,10 @@ public interface ParentPlatformMapper { |
| 16 | 16 | |
| 17 | 17 | @Insert("INSERT INTO parent_platform (enable, name, serverGBId, serverGBDomain, serverIP, serverPort, deviceGBId, deviceIp, " + |
| 18 | 18 | " devicePort, username, password, expires, keepTimeout, transport, characterSet, ptz, rtcp, " + |
| 19 | - " status, shareAllLiveStream, catalogId) " + | |
| 19 | + " status, shareAllLiveStream, startOfflinePush, catalogId, administrativeDivision, catalogGroup) " + | |
| 20 | 20 | " VALUES (${enable}, '${name}', '${serverGBId}', '${serverGBDomain}', '${serverIP}', ${serverPort}, '${deviceGBId}', '${deviceIp}', " + |
| 21 | 21 | " '${devicePort}', '${username}', '${password}', '${expires}', '${keepTimeout}', '${transport}', '${characterSet}', ${ptz}, ${rtcp}, " + |
| 22 | - " ${status}, ${shareAllLiveStream}, #{catalogId})") | |
| 22 | + " ${status}, ${shareAllLiveStream}, ${startOfflinePush}, #{catalogId}, #{administrativeDivision}, #{catalogGroup})") | |
| 23 | 23 | int addParentPlatform(ParentPlatform parentPlatform); |
| 24 | 24 | |
| 25 | 25 | @Update("UPDATE parent_platform " + |
| ... | ... | @@ -42,6 +42,9 @@ public interface ParentPlatformMapper { |
| 42 | 42 | "rtcp=#{rtcp}, " + |
| 43 | 43 | "status=#{status}, " + |
| 44 | 44 | "shareAllLiveStream=#{shareAllLiveStream}, " + |
| 45 | + "startOfflinePush=${startOfflinePush}, " + | |
| 46 | + "catalogGroup=#{catalogGroup}, " + | |
| 47 | + "administrativeDivision=#{administrativeDivision}, " + | |
| 45 | 48 | "catalogId=#{catalogId} " + |
| 46 | 49 | "WHERE id=#{id}") |
| 47 | 50 | int updateParentPlatform(ParentPlatform parentPlatform); | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java
| ... | ... | @@ -520,6 +520,12 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { |
| 520 | 520 | @Override |
| 521 | 521 | public boolean updateParentPlatform(ParentPlatform parentPlatform) { |
| 522 | 522 | int result = 0; |
| 523 | + if (parentPlatform.getCatalogGroup() == 0) { | |
| 524 | + parentPlatform.setCatalogGroup(1); | |
| 525 | + } | |
| 526 | + if (parentPlatform.getAdministrativeDivision() == null) { | |
| 527 | + parentPlatform.setAdministrativeDivision(parentPlatform.getAdministrativeDivision()); | |
| 528 | + } | |
| 523 | 529 | ParentPlatformCatch parentPlatformCatch = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId()); // .getDeviceGBId()); |
| 524 | 530 | if (parentPlatform.getId() == null ) { |
| 525 | 531 | if (parentPlatform.getCatalogId() == null) { |
| ... | ... | @@ -539,6 +545,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { |
| 539 | 545 | parentPlatformCatch.setId(parentPlatform.getServerGBId()); |
| 540 | 546 | redisCatchStorage.delPlatformCatchInfo(parentPlatById.getServerGBId()); |
| 541 | 547 | } |
| 548 | + | |
| 542 | 549 | result = platformMapper.updateParentPlatform(parentPlatform); |
| 543 | 550 | } |
| 544 | 551 | // 更新缓存 |
| ... | ... | @@ -1074,7 +1081,7 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { |
| 1074 | 1081 | deviceChannel.setParentId(catalog.getParentId()); |
| 1075 | 1082 | deviceChannel.setRegisterWay(1); |
| 1076 | 1083 | // 行政区划应该是Domain的前八位 |
| 1077 | - deviceChannel.setCivilCode(parentPlatByServerGBId.getDeviceGBId().substring(0,6)); | |
| 1084 | + deviceChannel.setCivilCode(parentPlatByServerGBId.getAdministrativeDivision()); | |
| 1078 | 1085 | deviceChannel.setModel("live"); |
| 1079 | 1086 | deviceChannel.setOwner("wvp-pro"); |
| 1080 | 1087 | deviceChannel.setSecrecy("0"); | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
| ... | ... | @@ -164,12 +164,13 @@ public class DeviceQuery { |
| 164 | 164 | logger.debug("设备通道信息同步API调用,deviceId:" + deviceId); |
| 165 | 165 | } |
| 166 | 166 | Device device = storager.queryVideoDevice(deviceId); |
| 167 | - SyncStatus syncStatus = deviceService.getChannelSyncStatus(deviceId); | |
| 167 | + boolean status = deviceService.isSyncRunning(deviceId); | |
| 168 | 168 | // 已存在则返回进度 |
| 169 | - if (syncStatus != null && syncStatus.getErrorMsg() == null) { | |
| 169 | + if (status) { | |
| 170 | 170 | WVPResult<SyncStatus> wvpResult = new WVPResult<>(); |
| 171 | 171 | wvpResult.setCode(0); |
| 172 | - wvpResult.setData(syncStatus); | |
| 172 | + SyncStatus channelSyncStatus = deviceService.getChannelSyncStatus(deviceId); | |
| 173 | + wvpResult.setData(channelSyncStatus); | |
| 173 | 174 | return wvpResult; |
| 174 | 175 | } |
| 175 | 176 | deviceService.sync(device); | ... | ... |
web_src/src/components/CloudRecord.vue
| 1 | 1 | <template> |
| 2 | - <div id="app"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | |
| 9 | - <span v-if="!recordDetail" >云端录像</span> | |
| 10 | - <el-page-header v-if="recordDetail" @back="backToList" content="云端录像"> | |
| 11 | - </el-page-header> | |
| 12 | - <div style="position: absolute; right: 5rem; top: 0.3rem;"> | |
| 13 | - 节点选择: | |
| 14 | - <el-select size="mini" @change="chooseMediaChange" style="width: 16rem; margin-right: 1rem;" v-model="mediaServerId" placeholder="请选择" :disabled="recordDetail"> | |
| 15 | - <el-option | |
| 16 | - v-for="item in mediaServerList" | |
| 17 | - :key="item.id" | |
| 18 | - :label="item.id" | |
| 19 | - :value="item.id"> | |
| 20 | - </el-option> | |
| 21 | - </el-select> | |
| 22 | - </div> | |
| 23 | - <div style="position: absolute; right: 1rem; top: 0.3rem;"> | |
| 24 | - <el-button v-if="!recordDetail" icon="el-icon-refresh-right" circle size="mini" :loading="loading" @click="getRecordList()"></el-button> | |
| 25 | - </div> | |
| 26 | - </div> | |
| 27 | - <div v-if="!recordDetail"> | |
| 2 | + <div id="app" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title">云端录像</div> | |
| 5 | + <div class="page-header-btn"> | |
| 6 | + 节点选择: | |
| 7 | + <el-select size="mini" @change="chooseMediaChange" style="width: 16rem; margin-right: 1rem;" v-model="mediaServerId" placeholder="请选择" :disabled="recordDetail"> | |
| 8 | + <el-option | |
| 9 | + v-for="item in mediaServerList" | |
| 10 | + :key="item.id" | |
| 11 | + :label="item.id" | |
| 12 | + :value="item.id"> | |
| 13 | + </el-option> | |
| 14 | + </el-select> | |
| 15 | + <el-button v-if="!recordDetail" icon="el-icon-refresh-right" circle size="mini" :loading="loading" @click="getRecordList()"></el-button> | |
| 16 | + </div> | |
| 17 | + </div> | |
| 18 | + <div v-if="!recordDetail"> | |
| 28 | 19 | |
| 29 | - <!--设备列表--> | |
| 30 | - <el-table :data="recordList" border style="width: 100%" :height="winHeight"> | |
| 31 | - <el-table-column prop="app" label="应用名" align="center"> | |
| 32 | - </el-table-column> | |
| 33 | - <el-table-column prop="stream" label="流ID" align="center"> | |
| 34 | - </el-table-column> | |
| 35 | - <el-table-column prop="time" label="时间" align="center"> | |
| 36 | - </el-table-column> | |
| 37 | - <el-table-column label="操作" width="360" align="center" fixed="right"> | |
| 38 | - <template slot-scope="scope"> | |
| 39 | - <el-button-group> | |
| 40 | - <el-button size="mini" icon="el-icon-video-camera-solid" type="primary" @click="showRecordDetail(scope.row)">查看</el-button> | |
| 41 | -<!-- <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteRecord(scope.row)">删除</el-button>--> | |
| 42 | - </el-button-group> | |
| 43 | - </template> | |
| 44 | - </el-table-column> | |
| 45 | - </el-table> | |
| 46 | - <el-pagination | |
| 47 | - style="float: right" | |
| 48 | - @size-change="handleSizeChange" | |
| 49 | - @current-change="currentChange" | |
| 50 | - :current-page="currentPage" | |
| 51 | - :page-size="count" | |
| 52 | - :page-sizes="[15, 25, 35, 50]" | |
| 53 | - layout="total, sizes, prev, pager, next" | |
| 54 | - :total="total"> | |
| 55 | - </el-pagination> | |
| 56 | - </div> | |
| 57 | - <cloud-record-detail ref="cloudRecordDetail" v-if="recordDetail" :recordFile="chooseRecord" :mediaServerId="mediaServerId" :mediaServerPath="mediaServerPath" ></cloud-record-detail> | |
| 58 | - </el-main> | |
| 59 | - </el-container> | |
| 60 | - </div> | |
| 20 | + <!--设备列表--> | |
| 21 | + <el-table :data="recordList" border style="width: 100%" :height="winHeight"> | |
| 22 | + <el-table-column prop="app" label="应用名" align="center"> | |
| 23 | + </el-table-column> | |
| 24 | + <el-table-column prop="stream" label="流ID" align="center"> | |
| 25 | + </el-table-column> | |
| 26 | + <el-table-column prop="time" label="时间" align="center"> | |
| 27 | + </el-table-column> | |
| 28 | + <el-table-column label="操作" width="360" align="center" fixed="right"> | |
| 29 | + <template slot-scope="scope"> | |
| 30 | + <el-button-group> | |
| 31 | + <el-button size="mini" icon="el-icon-video-camera-solid" type="primary" @click="showRecordDetail(scope.row)">查看</el-button> | |
| 32 | + <!-- <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteRecord(scope.row)">删除</el-button>--> | |
| 33 | + </el-button-group> | |
| 34 | + </template> | |
| 35 | + </el-table-column> | |
| 36 | + </el-table> | |
| 37 | + <el-pagination | |
| 38 | + style="float: right" | |
| 39 | + @size-change="handleSizeChange" | |
| 40 | + @current-change="currentChange" | |
| 41 | + :current-page="currentPage" | |
| 42 | + :page-size="count" | |
| 43 | + :page-sizes="[15, 25, 35, 50]" | |
| 44 | + layout="total, sizes, prev, pager, next" | |
| 45 | + :total="total"> | |
| 46 | + </el-pagination> | |
| 47 | + </div> | |
| 48 | + <cloud-record-detail ref="cloudRecordDetail" v-if="recordDetail" :recordFile="chooseRecord" :mediaServerId="mediaServerId" :mediaServerPath="mediaServerPath" ></cloud-record-detail> | |
| 49 | + | |
| 50 | + </div> | |
| 61 | 51 | </template> |
| 62 | 52 | |
| 63 | 53 | <script> |
| 64 | - import uiHeader from './UiHeader.vue' | |
| 54 | + import uiHeader from '../layout/UiHeader.vue' | |
| 65 | 55 | import cloudRecordDetail from './CloudRecordDetail.vue' |
| 66 | 56 | import MediaServer from './service/MediaServer' |
| 67 | 57 | export default { | ... | ... |
web_src/src/components/CloudRecordDetail.vue
| ... | ... | @@ -104,7 +104,7 @@ |
| 104 | 104 | |
| 105 | 105 | <script> |
| 106 | 106 | // TODO 根据查询的时间列表设置滑轨的最大值与最小值, |
| 107 | - import uiHeader from './UiHeader.vue' | |
| 107 | + import uiHeader from '../layout/UiHeader.vue' | |
| 108 | 108 | import player from './dialog/easyPlayer.vue' |
| 109 | 109 | import moment from 'moment' |
| 110 | 110 | export default { | ... | ... |
web_src/src/components/DeviceList.vue
| 1 | 1 | <template> |
| 2 | - <div id="app"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: bold;">设备列表</span> | |
| 10 | - <div style="position: absolute; right: 1rem; top: 0.3rem;"> | |
| 11 | - <el-button icon="el-icon-refresh-right" circle size="mini" :loading="getDeviceListLoading" @click="getDeviceList()"></el-button> | |
| 12 | - </div> | |
| 13 | - </div> | |
| 14 | - <!-- <devicePlayer ref="devicePlayer"></devicePlayer> --> | |
| 15 | - <!--设备列表--> | |
| 16 | - <el-table :data="deviceList" border style="width: 100%;font-size: 12px;" :height="winHeight"> | |
| 17 | - <el-table-column prop="name" label="名称" align="center"> | |
| 18 | - </el-table-column> | |
| 19 | - <el-table-column prop="deviceId" label="设备编号" width="180" align="center"> | |
| 20 | - </el-table-column> | |
| 21 | - <el-table-column label="地址" width="180" align="center"> | |
| 22 | - <template slot-scope="scope"> | |
| 23 | - <div slot="reference" class="name-wrapper"> | |
| 24 | - <el-tag size="medium">{{ scope.row.hostAddress }}</el-tag> | |
| 25 | - </div> | |
| 26 | - </template> | |
| 27 | - </el-table-column> | |
| 28 | - <el-table-column prop="manufacturer" label="厂家" align="center"> | |
| 29 | - </el-table-column> | |
| 30 | - <el-table-column label="流传输模式" align="center" width="120"> | |
| 31 | - <template slot-scope="scope"> | |
| 32 | - <el-select size="mini" @change="transportChange(scope.row)" v-model="scope.row.streamMode" placeholder="请选择"> | |
| 33 | - <el-option key="UDP" label="UDP" value="UDP"></el-option> | |
| 34 | - <el-option key="TCP-ACTIVE" label="TCP主动模式" :disabled="true" value="TCP-ACTIVE"></el-option> | |
| 35 | - <el-option key="TCP-PASSIVE" label="TCP被动模式" value="TCP-PASSIVE"></el-option> | |
| 36 | - </el-select> | |
| 37 | - </template> | |
| 38 | - </el-table-column> | |
| 39 | - <el-table-column prop="channelCount" label="通道数" align="center"> | |
| 40 | - </el-table-column> | |
| 41 | - <el-table-column label="状态" width="120" align="center"> | |
| 42 | - <template slot-scope="scope"> | |
| 43 | - <div slot="reference" class="name-wrapper"> | |
| 44 | - <el-tag size="medium" v-if="scope.row.online == 1">在线</el-tag> | |
| 45 | - <el-tag size="medium" type="info" v-if="scope.row.online == 0">离线</el-tag> | |
| 46 | - </div> | |
| 47 | - </template> | |
| 48 | - </el-table-column> | |
| 49 | - <el-table-column prop="keepaliveTime" label="最近心跳" align="center" width="140"> | |
| 50 | - </el-table-column> | |
| 51 | - <el-table-column prop="registerTime" label="最近注册" align="center" width="140"> | |
| 52 | - </el-table-column> | |
| 53 | - <el-table-column prop="updateTime" label="更新时间" align="center" width="140"> | |
| 54 | - </el-table-column> | |
| 55 | - <el-table-column prop="createTime" label="创建时间" align="center" width="140"> | |
| 56 | - </el-table-column> | |
| 2 | + <div id="app" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title">设备列表</div> | |
| 5 | + <div class="page-header-btn"> | |
| 6 | + <el-button icon="el-icon-refresh-right" circle size="mini" :loading="getDeviceListLoading" | |
| 7 | + @click="getDeviceList()"></el-button> | |
| 8 | + </div> | |
| 9 | + </div> | |
| 10 | + <!-- <devicePlayer ref="devicePlayer"></devicePlayer> --> | |
| 11 | + <!--设备列表--> | |
| 12 | + <el-table :data="deviceList" border style="width: 100%;font-size: 12px;" :height="winHeight"> | |
| 13 | + <el-table-column prop="name" label="名称" align="center"> | |
| 14 | + </el-table-column> | |
| 15 | + <el-table-column prop="deviceId" label="设备编号" width="180" align="center"> | |
| 16 | + </el-table-column> | |
| 17 | + <el-table-column label="地址" width="180" align="center"> | |
| 18 | + <template slot-scope="scope"> | |
| 19 | + <div slot="reference" class="name-wrapper"> | |
| 20 | + <el-tag size="medium">{{ scope.row.hostAddress }}</el-tag> | |
| 21 | + </div> | |
| 22 | + </template> | |
| 23 | + </el-table-column> | |
| 24 | + <el-table-column prop="manufacturer" label="厂家" align="center"> | |
| 25 | + </el-table-column> | |
| 26 | + <el-table-column label="流传输模式" align="center" width="120"> | |
| 27 | + <template slot-scope="scope"> | |
| 28 | + <el-select size="mini" @change="transportChange(scope.row)" v-model="scope.row.streamMode" placeholder="请选择"> | |
| 29 | + <el-option key="UDP" label="UDP" value="UDP"></el-option> | |
| 30 | + <el-option key="TCP-ACTIVE" label="TCP主动模式" :disabled="true" value="TCP-ACTIVE"></el-option> | |
| 31 | + <el-option key="TCP-PASSIVE" label="TCP被动模式" value="TCP-PASSIVE"></el-option> | |
| 32 | + </el-select> | |
| 33 | + </template> | |
| 34 | + </el-table-column> | |
| 35 | + <el-table-column prop="channelCount" label="通道数" align="center"> | |
| 36 | + </el-table-column> | |
| 37 | + <el-table-column label="状态" width="120" align="center"> | |
| 38 | + <template slot-scope="scope"> | |
| 39 | + <div slot="reference" class="name-wrapper"> | |
| 40 | + <el-tag size="medium" v-if="scope.row.online == 1">在线</el-tag> | |
| 41 | + <el-tag size="medium" type="info" v-if="scope.row.online == 0">离线</el-tag> | |
| 42 | + </div> | |
| 43 | + </template> | |
| 44 | + </el-table-column> | |
| 45 | + <el-table-column prop="keepaliveTime" label="最近心跳" align="center" width="140"> | |
| 46 | + </el-table-column> | |
| 47 | + <el-table-column prop="registerTime" label="最近注册" align="center" width="140"> | |
| 48 | + </el-table-column> | |
| 49 | + <el-table-column prop="updateTime" label="更新时间" align="center" width="140"> | |
| 50 | + </el-table-column> | |
| 51 | + <el-table-column prop="createTime" label="创建时间" align="center" width="140"> | |
| 52 | + </el-table-column> | |
| 57 | 53 | |
| 58 | - <el-table-column label="操作" width="450" align="center" fixed="right"> | |
| 59 | - <template slot-scope="scope"> | |
| 60 | - <el-button size="mini" v-if="scope.row.online!=0" icon="el-icon-refresh" @click="refDevice(scope.row)" @mouseover="getTooltipContent(scope.row.deviceId)">刷新</el-button> | |
| 61 | - <el-button-group> | |
| 62 | - <el-button size="mini" icon="el-icon-video-camera-solid" v-bind:disabled="scope.row.online==0" type="primary" @click="showChannelList(scope.row)">通道</el-button> | |
| 63 | - <el-button size="mini" icon="el-icon-location" v-bind:disabled="scope.row.online==0" type="primary" @click="showDevicePosition(scope.row)">定位</el-button> | |
| 64 | - <el-button size="mini" icon="el-icon-edit" type="primary" @click="edit(scope.row)">编辑</el-button> | |
| 65 | - <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteDevice(scope.row)">删除</el-button> | |
| 66 | - </el-button-group> | |
| 67 | - </template> | |
| 68 | - </el-table-column> | |
| 69 | - </el-table> | |
| 70 | - <el-pagination | |
| 71 | - style="float: right" | |
| 72 | - @size-change="handleSizeChange" | |
| 73 | - @current-change="currentChange" | |
| 74 | - :current-page="currentPage" | |
| 75 | - :page-size="count" | |
| 76 | - :page-sizes="[15, 25, 35, 50]" | |
| 77 | - layout="total, sizes, prev, pager, next" | |
| 78 | - :total="total"> | |
| 79 | - </el-pagination> | |
| 80 | - <deviceEdit ref="deviceEdit" ></deviceEdit> | |
| 81 | - <syncChannelProgress ref="syncChannelProgress" ></syncChannelProgress> | |
| 82 | - </el-main> | |
| 83 | - </el-container> | |
| 84 | - </div> | |
| 54 | + <el-table-column label="操作" width="450" align="center" fixed="right"> | |
| 55 | + <template slot-scope="scope"> | |
| 56 | + <el-button size="mini" v-if="scope.row.online!=0" icon="el-icon-refresh" @click="refDevice(scope.row)" | |
| 57 | + @mouseover="getTooltipContent(scope.row.deviceId)">刷新 | |
| 58 | + </el-button> | |
| 59 | + <el-button-group> | |
| 60 | + <el-button size="mini" icon="el-icon-video-camera-solid" v-bind:disabled="scope.row.online==0" | |
| 61 | + type="primary" @click="showChannelList(scope.row)">通道 | |
| 62 | + </el-button> | |
| 63 | + <el-button size="mini" icon="el-icon-location" v-bind:disabled="scope.row.online==0" type="primary" | |
| 64 | + @click="showDevicePosition(scope.row)">定位 | |
| 65 | + </el-button> | |
| 66 | + <el-button size="mini" icon="el-icon-edit" type="primary" @click="edit(scope.row)">编辑</el-button> | |
| 67 | + <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteDevice(scope.row)">删除</el-button> | |
| 68 | + </el-button-group> | |
| 69 | + </template> | |
| 70 | + </el-table-column> | |
| 71 | + </el-table> | |
| 72 | + <el-pagination | |
| 73 | + style="float: right" | |
| 74 | + @size-change="handleSizeChange" | |
| 75 | + @current-change="currentChange" | |
| 76 | + :current-page="currentPage" | |
| 77 | + :page-size="count" | |
| 78 | + :page-sizes="[15, 25, 35, 50]" | |
| 79 | + layout="total, sizes, prev, pager, next" | |
| 80 | + :total="total"> | |
| 81 | + </el-pagination> | |
| 82 | + <deviceEdit ref="deviceEdit"></deviceEdit> | |
| 83 | + <syncChannelProgress ref="syncChannelProgress"></syncChannelProgress> | |
| 84 | + </div> | |
| 85 | 85 | </template> |
| 86 | 86 | |
| 87 | 87 | <script> |
| 88 | - import uiHeader from './UiHeader.vue' | |
| 89 | - import deviceEdit from './dialog/deviceEdit.vue' | |
| 90 | - import syncChannelProgress from './dialog/SyncChannelProgress.vue' | |
| 91 | - export default { | |
| 92 | - name: 'app', | |
| 93 | - components: { | |
| 94 | - uiHeader, | |
| 95 | - deviceEdit, | |
| 96 | - syncChannelProgress, | |
| 97 | - }, | |
| 98 | - data() { | |
| 99 | - return { | |
| 100 | - deviceList: [], //设备列表 | |
| 101 | - currentDevice: {}, //当前操作设备对象 | |
| 88 | +import uiHeader from '../layout/UiHeader.vue' | |
| 89 | +import deviceEdit from './dialog/deviceEdit.vue' | |
| 90 | +import syncChannelProgress from './dialog/SyncChannelProgress.vue' | |
| 102 | 91 | |
| 103 | - videoComponentList: [], | |
| 104 | - updateLooper: 0, //数据刷新轮训标志 | |
| 105 | - currentDeviceChannelsLenth:0, | |
| 106 | - winHeight: window.innerHeight - 200, | |
| 107 | - currentPage:1, | |
| 108 | - count:15, | |
| 109 | - total:0, | |
| 110 | - getDeviceListLoading: false, | |
| 111 | - }; | |
| 112 | - }, | |
| 113 | - computed: { | |
| 114 | - getcurrentDeviceChannels: function() { | |
| 115 | - let data = this.currentDevice['channelMap']; | |
| 116 | - let channels = null; | |
| 117 | - if (data) { | |
| 118 | - channels = Object.keys(data).map(key => { | |
| 119 | - return data[key]; | |
| 120 | - }); | |
| 121 | - this.currentDeviceChannelsLenth = channels.length; | |
| 122 | - } | |
| 123 | - return channels; | |
| 124 | - } | |
| 125 | - }, | |
| 126 | - mounted() { | |
| 127 | - this.initData(); | |
| 128 | - this.updateLooper = setInterval(this.initData, 10000); | |
| 129 | - }, | |
| 130 | - destroyed() { | |
| 131 | - this.$destroy('videojs'); | |
| 132 | - clearTimeout(this.updateLooper); | |
| 133 | - }, | |
| 134 | - methods: { | |
| 135 | - initData: function() { | |
| 136 | - this.getDeviceList(); | |
| 137 | - }, | |
| 138 | - currentChange: function(val){ | |
| 139 | - this.currentPage = val; | |
| 140 | - this.getDeviceList(); | |
| 141 | - }, | |
| 142 | - handleSizeChange: function(val){ | |
| 143 | - this.count = val; | |
| 144 | - this.getDeviceList(); | |
| 145 | - }, | |
| 146 | - getDeviceList: function() { | |
| 147 | - let that = this; | |
| 148 | - this.getDeviceListLoading = true; | |
| 149 | - this.$axios({ | |
| 150 | - method: 'get', | |
| 151 | - url:`/api/device/query/devices`, | |
| 152 | - params: { | |
| 153 | - page: that.currentPage, | |
| 154 | - count: that.count | |
| 155 | - } | |
| 156 | - }).then(function (res) { | |
| 157 | - that.total = res.data.total; | |
| 158 | - that.deviceList = res.data.list; | |
| 159 | - that.getDeviceListLoading = false; | |
| 160 | - }).catch(function (error) { | |
| 161 | - console.error(error); | |
| 162 | - that.getDeviceListLoading = false; | |
| 163 | - }); | |
| 92 | +export default { | |
| 93 | + name: 'app', | |
| 94 | + components: { | |
| 95 | + uiHeader, | |
| 96 | + deviceEdit, | |
| 97 | + syncChannelProgress, | |
| 98 | + }, | |
| 99 | + data() { | |
| 100 | + return { | |
| 101 | + deviceList: [], //设备列表 | |
| 102 | + currentDevice: {}, //当前操作设备对象 | |
| 164 | 103 | |
| 165 | - }, | |
| 166 | - deleteDevice: function(row) { | |
| 167 | - let msg = "确定删除此设备?" | |
| 168 | - if (row.online !== 0) { | |
| 169 | - msg = "在线设备删除后仍可通过注册再次上线。<br/>如需彻底删除请先将设备离线。<br/><strong>确定删除此设备?</strong>" | |
| 104 | + videoComponentList: [], | |
| 105 | + updateLooper: 0, //数据刷新轮训标志 | |
| 106 | + currentDeviceChannelsLenth: 0, | |
| 107 | + winHeight: window.innerHeight - 200, | |
| 108 | + currentPage: 1, | |
| 109 | + count: 15, | |
| 110 | + total: 0, | |
| 111 | + getDeviceListLoading: false, | |
| 112 | + }; | |
| 113 | + }, | |
| 114 | + computed: { | |
| 115 | + getcurrentDeviceChannels: function () { | |
| 116 | + let data = this.currentDevice['channelMap']; | |
| 117 | + let channels = null; | |
| 118 | + if (data) { | |
| 119 | + channels = Object.keys(data).map(key => { | |
| 120 | + return data[key]; | |
| 121 | + }); | |
| 122 | + this.currentDeviceChannelsLenth = channels.length; | |
| 123 | + } | |
| 124 | + return channels; | |
| 125 | + } | |
| 126 | + }, | |
| 127 | + mounted() { | |
| 128 | + this.initData(); | |
| 129 | + this.updateLooper = setInterval(this.initData, 10000); | |
| 130 | + }, | |
| 131 | + destroyed() { | |
| 132 | + this.$destroy('videojs'); | |
| 133 | + clearTimeout(this.updateLooper); | |
| 134 | + }, | |
| 135 | + methods: { | |
| 136 | + initData: function () { | |
| 137 | + this.getDeviceList(); | |
| 138 | + }, | |
| 139 | + currentChange: function (val) { | |
| 140 | + this.currentPage = val; | |
| 141 | + this.getDeviceList(); | |
| 142 | + }, | |
| 143 | + handleSizeChange: function (val) { | |
| 144 | + this.count = val; | |
| 145 | + this.getDeviceList(); | |
| 146 | + }, | |
| 147 | + getDeviceList: function () { | |
| 148 | + let that = this; | |
| 149 | + this.getDeviceListLoading = true; | |
| 150 | + this.$axios({ | |
| 151 | + method: 'get', | |
| 152 | + url: `/api/device/query/devices`, | |
| 153 | + params: { | |
| 154 | + page: that.currentPage, | |
| 155 | + count: that.count | |
| 170 | 156 | } |
| 171 | - this.$confirm(msg, '提示', { | |
| 172 | - dangerouslyUseHTMLString : true, | |
| 173 | - confirmButtonText: '确定', | |
| 174 | - cancelButtonText: '取消', | |
| 175 | - center: true, | |
| 176 | - type: 'warning' | |
| 177 | - }).then(() => { | |
| 178 | - this.$axios({ | |
| 179 | - method: 'delete', | |
| 180 | - url:`/api/device/query/devices/${row.deviceId}/delete` | |
| 181 | - }).then((res)=>{ | |
| 182 | - this.getDeviceList(); | |
| 183 | - }).catch((error) =>{ | |
| 184 | - console.error(error); | |
| 185 | - }); | |
| 186 | - }).catch(() => { | |
| 157 | + }).then(function (res) { | |
| 158 | + that.total = res.data.total; | |
| 159 | + that.deviceList = res.data.list; | |
| 160 | + that.getDeviceListLoading = false; | |
| 161 | + }).catch(function (error) { | |
| 162 | + console.error(error); | |
| 163 | + that.getDeviceListLoading = false; | |
| 164 | + }); | |
| 187 | 165 | |
| 166 | + }, | |
| 167 | + deleteDevice: function (row) { | |
| 168 | + let msg = "确定删除此设备?" | |
| 169 | + if (row.online !== 0) { | |
| 170 | + msg = "在线设备删除后仍可通过注册再次上线。<br/>如需彻底删除请先将设备离线。<br/><strong>确定删除此设备?</strong>" | |
| 171 | + } | |
| 172 | + this.$confirm(msg, '提示', { | |
| 173 | + dangerouslyUseHTMLString: true, | |
| 174 | + confirmButtonText: '确定', | |
| 175 | + cancelButtonText: '取消', | |
| 176 | + center: true, | |
| 177 | + type: 'warning' | |
| 178 | + }).then(() => { | |
| 179 | + this.$axios({ | |
| 180 | + method: 'delete', | |
| 181 | + url: `/api/device/query/devices/${row.deviceId}/delete` | |
| 182 | + }).then((res) => { | |
| 183 | + this.getDeviceList(); | |
| 184 | + }).catch((error) => { | |
| 185 | + console.error(error); | |
| 188 | 186 | }); |
| 187 | + }).catch(() => { | |
| 188 | + | |
| 189 | + }); | |
| 189 | 190 | |
| 190 | 191 | |
| 191 | - }, | |
| 192 | - showChannelList: function(row) { | |
| 193 | - this.$router.push(`/channelList/${row.deviceId}/0/15/1`); | |
| 194 | - }, | |
| 195 | - showDevicePosition: function(row) { | |
| 196 | - this.$router.push(`/devicePosition/${row.deviceId}/0/15/1`); | |
| 197 | - }, | |
| 192 | + }, | |
| 193 | + showChannelList: function (row) { | |
| 194 | + this.$router.push(`/channelList/${row.deviceId}/0/15/1`); | |
| 195 | + }, | |
| 196 | + showDevicePosition: function (row) { | |
| 197 | + this.$router.push(`/devicePosition/${row.deviceId}/0/15/1`); | |
| 198 | + }, | |
| 198 | 199 | |
| 199 | - //gb28181平台对接 | |
| 200 | - //刷新设备信息 | |
| 201 | - refDevice: function(itemData) { | |
| 202 | - console.log("刷新对应设备:" + itemData.deviceId); | |
| 203 | - let that = this; | |
| 204 | - this.$axios({ | |
| 205 | - method: 'post', | |
| 206 | - url: '/api/device/query/devices/' + itemData.deviceId + '/sync' | |
| 207 | - }).then((res) => { | |
| 208 | - console.log("刷新设备结果:"+JSON.stringify(res)); | |
| 209 | - if (res.data.code !==0) { | |
| 210 | - that.$message({ | |
| 211 | - showClose: true, | |
| 212 | - message: res.data.msg, | |
| 213 | - type: 'error' | |
| 214 | - }); | |
| 215 | - }else{ | |
| 216 | - // that.$message({ | |
| 217 | - // showClose: true, | |
| 218 | - // message: res.data.msg, | |
| 219 | - // type: 'success' | |
| 220 | - // }); | |
| 221 | - this.$refs.syncChannelProgress.openDialog(itemData.deviceId) | |
| 222 | - } | |
| 223 | - that.initData() | |
| 224 | - }).catch((e) => { | |
| 225 | - console.error(e) | |
| 200 | + //gb28181平台对接 | |
| 201 | + //刷新设备信息 | |
| 202 | + refDevice: function (itemData) { | |
| 203 | + console.log("刷新对应设备:" + itemData.deviceId); | |
| 204 | + let that = this; | |
| 205 | + this.$axios({ | |
| 206 | + method: 'post', | |
| 207 | + url: '/api/device/query/devices/' + itemData.deviceId + '/sync' | |
| 208 | + }).then((res) => { | |
| 209 | + console.log("刷新设备结果:" + JSON.stringify(res)); | |
| 210 | + if (res.data.code !== 0) { | |
| 226 | 211 | that.$message({ |
| 227 | 212 | showClose: true, |
| 228 | - message: e, | |
| 213 | + message: res.data.msg, | |
| 229 | 214 | type: 'error' |
| 230 | 215 | }); |
| 231 | - }); | |
| 216 | + } else { | |
| 217 | + // that.$message({ | |
| 218 | + // showClose: true, | |
| 219 | + // message: res.data.msg, | |
| 220 | + // type: 'success' | |
| 221 | + // }); | |
| 222 | + this.$refs.syncChannelProgress.openDialog(itemData.deviceId) | |
| 223 | + } | |
| 224 | + that.initData() | |
| 225 | + }).catch((e) => { | |
| 226 | + console.error(e) | |
| 227 | + that.$message({ | |
| 228 | + showClose: true, | |
| 229 | + message: e, | |
| 230 | + type: 'error' | |
| 231 | + }); | |
| 232 | + }); | |
| 232 | 233 | |
| 233 | - }, | |
| 234 | + }, | |
| 234 | 235 | |
| 235 | - getTooltipContent: async function (deviceId){ | |
| 236 | - let result = ""; | |
| 237 | - await this.$axios({ | |
| 238 | - method: 'get', | |
| 239 | - async: false, | |
| 240 | - url:`/api/device/query/${deviceId}/sync_status/`, | |
| 241 | - }).then((res) => { | |
| 242 | - if (res.data.code == 0) { | |
| 243 | - if (res.data.data.errorMsg !== null) { | |
| 244 | - result = res.data.data.errorMsg | |
| 245 | - } else if (res.data.msg !== null) { | |
| 246 | - result = res.data.msg | |
| 247 | - } else { | |
| 248 | - result = `同步中...[${res.data.data.current}/${res.data.data.total}]`; | |
| 249 | - } | |
| 250 | - } | |
| 251 | - }) | |
| 252 | - return result; | |
| 253 | - }, | |
| 254 | - //通知设备上传媒体流 | |
| 255 | - sendDevicePush: function(itemData) { | |
| 256 | - // let deviceId = this.currentDevice.deviceId; | |
| 257 | - // let channelId = itemData.channelId; | |
| 258 | - // console.log("通知设备推流1:" + deviceId + " : " + channelId); | |
| 259 | - // let that = this; | |
| 260 | - // this.$axios({ | |
| 261 | - // method: 'get', | |
| 262 | - // url: '/api/play/' + deviceId + '/' + channelId | |
| 263 | - // }).then(function(res) { | |
| 264 | - // let ssrc = res.data.ssrc; | |
| 265 | - // that.$refs.devicePlayer.play(ssrc,deviceId,channelId); | |
| 266 | - // }).catch(function(e) { | |
| 267 | - // }); | |
| 268 | - }, | |
| 269 | - transportChange: function (row) { | |
| 270 | - console.log(`修改传输方式为 ${row.streamMode}:${row.deviceId} `); | |
| 271 | - let that = this; | |
| 272 | - this.$axios({ | |
| 273 | - method: 'post', | |
| 274 | - url: '/api/device/query/transport/' + row.deviceId + '/' + row.streamMode | |
| 275 | - }).then(function(res) { | |
| 236 | + getTooltipContent: async function (deviceId) { | |
| 237 | + let result = ""; | |
| 238 | + await this.$axios({ | |
| 239 | + method: 'get', | |
| 240 | + async: false, | |
| 241 | + url: `/api/device/query/${deviceId}/sync_status/`, | |
| 242 | + }).then((res) => { | |
| 243 | + if (res.data.code == 0) { | |
| 244 | + if (res.data.data.errorMsg !== null) { | |
| 245 | + result = res.data.data.errorMsg | |
| 246 | + } else if (res.data.msg !== null) { | |
| 247 | + result = res.data.msg | |
| 248 | + } else { | |
| 249 | + result = `同步中...[${res.data.data.current}/${res.data.data.total}]`; | |
| 250 | + } | |
| 251 | + } | |
| 252 | + }) | |
| 253 | + return result; | |
| 254 | + }, | |
| 255 | + //通知设备上传媒体流 | |
| 256 | + sendDevicePush: function (itemData) { | |
| 257 | + // let deviceId = this.currentDevice.deviceId; | |
| 258 | + // let channelId = itemData.channelId; | |
| 259 | + // console.log("通知设备推流1:" + deviceId + " : " + channelId); | |
| 260 | + // let that = this; | |
| 261 | + // this.$axios({ | |
| 262 | + // method: 'get', | |
| 263 | + // url: '/api/play/' + deviceId + '/' + channelId | |
| 264 | + // }).then(function(res) { | |
| 265 | + // let ssrc = res.data.ssrc; | |
| 266 | + // that.$refs.devicePlayer.play(ssrc,deviceId,channelId); | |
| 267 | + // }).catch(function(e) { | |
| 268 | + // }); | |
| 269 | + }, | |
| 270 | + transportChange: function (row) { | |
| 271 | + console.log(`修改传输方式为 ${row.streamMode}:${row.deviceId} `); | |
| 272 | + let that = this; | |
| 273 | + this.$axios({ | |
| 274 | + method: 'post', | |
| 275 | + url: '/api/device/query/transport/' + row.deviceId + '/' + row.streamMode | |
| 276 | + }).then(function (res) { | |
| 276 | 277 | |
| 277 | - }).catch(function(e) { | |
| 278 | + }).catch(function (e) { | |
| 279 | + }); | |
| 280 | + }, | |
| 281 | + edit: function (row) { | |
| 282 | + this.$refs.deviceEdit.openDialog(row, () => { | |
| 283 | + this.$refs.deviceEdit.close(); | |
| 284 | + this.$message({ | |
| 285 | + showClose: true, | |
| 286 | + message: "设备修改成功,通道字符集将在下次更新生效", | |
| 287 | + type: "success", | |
| 278 | 288 | }); |
| 279 | - }, | |
| 280 | - edit: function (row) { | |
| 281 | - this.$refs.deviceEdit.openDialog(row, ()=>{ | |
| 282 | - this.$refs.deviceEdit.close(); | |
| 283 | - this.$message({ | |
| 284 | - showClose: true, | |
| 285 | - message: "设备修改成功,通道字符集将在下次更新生效", | |
| 286 | - type: "success", | |
| 287 | - }); | |
| 288 | - setTimeout(this.getDeviceList, 200) | |
| 289 | + setTimeout(this.getDeviceList, 200) | |
| 289 | 290 | |
| 290 | - }) | |
| 291 | - } | |
| 291 | + }) | |
| 292 | + } | |
| 292 | 293 | |
| 293 | - } | |
| 294 | - }; | |
| 294 | + } | |
| 295 | +}; | |
| 295 | 296 | </script> |
| 296 | 297 | |
| 297 | 298 | <style> |
| 298 | - .videoList { | |
| 299 | - display: flex; | |
| 300 | - flex-wrap: wrap; | |
| 301 | - align-content: flex-start; | |
| 302 | - } | |
| 299 | +.videoList { | |
| 300 | + display: flex; | |
| 301 | + flex-wrap: wrap; | |
| 302 | + align-content: flex-start; | |
| 303 | +} | |
| 303 | 304 | |
| 304 | - .video-item { | |
| 305 | - position: relative; | |
| 306 | - width: 15rem; | |
| 307 | - height: 10rem; | |
| 308 | - margin-right: 1rem; | |
| 309 | - background-color: #000000; | |
| 310 | - } | |
| 305 | +.video-item { | |
| 306 | + position: relative; | |
| 307 | + width: 15rem; | |
| 308 | + height: 10rem; | |
| 309 | + margin-right: 1rem; | |
| 310 | + background-color: #000000; | |
| 311 | +} | |
| 311 | 312 | |
| 312 | - .video-item-img { | |
| 313 | - position: absolute; | |
| 314 | - top: 0; | |
| 315 | - bottom: 0; | |
| 316 | - left: 0; | |
| 317 | - right: 0; | |
| 318 | - margin: auto; | |
| 319 | - width: 100%; | |
| 320 | - height: 100%; | |
| 321 | - } | |
| 313 | +.video-item-img { | |
| 314 | + position: absolute; | |
| 315 | + top: 0; | |
| 316 | + bottom: 0; | |
| 317 | + left: 0; | |
| 318 | + right: 0; | |
| 319 | + margin: auto; | |
| 320 | + width: 100%; | |
| 321 | + height: 100%; | |
| 322 | +} | |
| 322 | 323 | |
| 323 | - .video-item-img:after { | |
| 324 | - content: ""; | |
| 325 | - display: inline-block; | |
| 326 | - position: absolute; | |
| 327 | - z-index: 2; | |
| 328 | - top: 0; | |
| 329 | - bottom: 0; | |
| 330 | - left: 0; | |
| 331 | - right: 0; | |
| 332 | - margin: auto; | |
| 333 | - width: 3rem; | |
| 334 | - height: 3rem; | |
| 335 | - background-image: url("../assets/loading.png"); | |
| 336 | - background-size: cover; | |
| 337 | - background-color: #000000; | |
| 338 | - } | |
| 324 | +.video-item-img:after { | |
| 325 | + content: ""; | |
| 326 | + display: inline-block; | |
| 327 | + position: absolute; | |
| 328 | + z-index: 2; | |
| 329 | + top: 0; | |
| 330 | + bottom: 0; | |
| 331 | + left: 0; | |
| 332 | + right: 0; | |
| 333 | + margin: auto; | |
| 334 | + width: 3rem; | |
| 335 | + height: 3rem; | |
| 336 | + background-image: url("../assets/loading.png"); | |
| 337 | + background-size: cover; | |
| 338 | + background-color: #000000; | |
| 339 | +} | |
| 339 | 340 | |
| 340 | - .video-item-title { | |
| 341 | - position: absolute; | |
| 342 | - bottom: 0; | |
| 343 | - color: #000000; | |
| 344 | - background-color: #ffffff; | |
| 345 | - line-height: 1.5rem; | |
| 346 | - padding: 0.3rem; | |
| 347 | - width: 14.4rem; | |
| 348 | - } | |
| 341 | +.video-item-title { | |
| 342 | + position: absolute; | |
| 343 | + bottom: 0; | |
| 344 | + color: #000000; | |
| 345 | + background-color: #ffffff; | |
| 346 | + line-height: 1.5rem; | |
| 347 | + padding: 0.3rem; | |
| 348 | + width: 14.4rem; | |
| 349 | +} | |
| 349 | 350 | </style> | ... | ... |
web_src/src/components/MediaServerManger.vue
| 1 | 1 | <template> |
| 2 | - <div id="mediaServerManger"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main id="msMain"> | |
| 8 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: bold;">节点列表</span> | |
| 10 | - </div> | |
| 11 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> | |
| 12 | - <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="add">添加节点</el-button> | |
| 13 | - </div> | |
| 2 | + <div id="mediaServerManger" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title">节点列表</div> | |
| 5 | + <div class="page-header-btn"> | |
| 6 | + <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="add">添加节点</el-button> | |
| 7 | + </div> | |
| 8 | + </div> | |
| 14 | 9 | |
| 15 | - <el-row :gutter="12"> | |
| 16 | - <el-col :span="num" v-for="item in mediaServerList" :key="item.id"> | |
| 17 | - <el-card shadow="hover" :body-style="{ padding: '0px'}" class="server-card"> | |
| 18 | - <div class="card-img-zlm"></div> | |
| 19 | - <div style="padding: 14px;text-align: left"> | |
| 20 | - <span style="font-size: 16px">{{item.id}}</span> | |
| 21 | - <el-button v-if="!item.defaultServer" icon="el-icon-edit" style="padding: 0;float: right;" type="text" @click="edit(item)">编辑</el-button> | |
| 22 | - <el-button v-if="item.defaultServer" icon="el-icon-edit" style="padding: 0;float: right;" type="text" @click="edit(item)">查看</el-button> | |
| 23 | - <el-button icon="el-icon-delete" style="margin-right: 10px;padding: 0;float: right;" type="text" @click="del(item)">移除</el-button> | |
| 24 | - <div style="margin-top: 13px; line-height: 12px; "> | |
| 25 | - <span style="font-size: 14px; color: #999; margin-top: 5px; ">{{item.ip}}</span> | |
| 26 | - <span style="font-size: 14px; color: #999; margin-top: 5px; float: right;">{{item.createTime}}</span> | |
| 27 | - </div> | |
| 28 | - </div> | |
| 29 | - <i v-if="item.status" class="iconfont icon-online server-card-status-online" title="在线"></i> | |
| 30 | - <i v-if="!item.status" class="iconfont icon-online server-card-status-offline" title="离线"></i> | |
| 31 | - <i v-if="item.defaultServer" class="server-card-default" >默认</i> | |
| 32 | - </el-card> | |
| 33 | - </el-col> | |
| 34 | - </el-row> | |
| 35 | - <mediaServerEdit ref="mediaServerEdit" ></mediaServerEdit> | |
| 36 | - </el-main> | |
| 37 | - </el-container> | |
| 10 | + <el-row :gutter="12"> | |
| 11 | + <el-col :span="num" v-for="item in mediaServerList" :key="item.id"> | |
| 12 | + <el-card shadow="hover" :body-style="{ padding: '0px'}" class="server-card"> | |
| 13 | + <div class="card-img-zlm"></div> | |
| 14 | + <div style="padding: 14px;text-align: left"> | |
| 15 | + <span style="font-size: 16px">{{item.id}}</span> | |
| 16 | + <el-button v-if="!item.defaultServer" icon="el-icon-edit" style="padding: 0;float: right;" type="text" @click="edit(item)">编辑</el-button> | |
| 17 | + <el-button v-if="item.defaultServer" icon="el-icon-edit" style="padding: 0;float: right;" type="text" @click="edit(item)">查看</el-button> | |
| 18 | + <el-button icon="el-icon-delete" style="margin-right: 10px;padding: 0;float: right;" type="text" @click="del(item)">移除</el-button> | |
| 19 | + <div style="margin-top: 13px; line-height: 12px; "> | |
| 20 | + <span style="font-size: 14px; color: #999; margin-top: 5px; ">{{item.ip}}</span> | |
| 21 | + <span style="font-size: 14px; color: #999; margin-top: 5px; float: right;">{{item.createTime}}</span> | |
| 22 | + </div> | |
| 23 | + </div> | |
| 24 | + <i v-if="item.status" class="iconfont icon-online server-card-status-online" title="在线"></i> | |
| 25 | + <i v-if="!item.status" class="iconfont icon-online server-card-status-offline" title="离线"></i> | |
| 26 | + <i v-if="item.defaultServer" class="server-card-default" >默认</i> | |
| 27 | + </el-card> | |
| 28 | + </el-col> | |
| 29 | + </el-row> | |
| 30 | + <mediaServerEdit ref="mediaServerEdit" ></mediaServerEdit> | |
| 38 | 31 | </div> |
| 39 | 32 | </template> |
| 40 | 33 | |
| 41 | 34 | <script> |
| 42 | - import uiHeader from './UiHeader.vue' | |
| 35 | + import uiHeader from '../layout/UiHeader.vue' | |
| 43 | 36 | import MediaServer from './service/MediaServer' |
| 44 | 37 | import mediaServerEdit from './dialog/MediaServerEdit' |
| 45 | 38 | export default { | ... | ... |
web_src/src/components/ParentPlatformList.vue
| 1 | 1 | <template> |
| 2 | - <div id="app"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: bold;">上级平台列表</span> | |
| 10 | - </div> | |
| 11 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> | |
| 12 | - <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addParentPlatform">添加</el-button> | |
| 13 | - </div> | |
| 14 | - <!--设备列表--> | |
| 15 | - <el-table :data="platformList" border style="width: 100%" :height="winHeight"> | |
| 16 | - <el-table-column prop="name" label="名称" align="center"></el-table-column> | |
| 17 | - <el-table-column prop="serverGBId" label="平台编号" width="180" align="center"></el-table-column> | |
| 18 | - <el-table-column label="是否启用" width="120" align="center"> | |
| 19 | - <template slot-scope="scope"> | |
| 20 | - <div slot="reference" class="name-wrapper"> | |
| 21 | - <el-tag size="medium" v-if="scope.row.enable">已启用</el-tag> | |
| 22 | - <el-tag size="medium" type="info" v-if="!scope.row.enable">未启用</el-tag> | |
| 23 | - </div> | |
| 24 | - </template> | |
| 25 | - </el-table-column> | |
| 26 | - <el-table-column label="状态" width="120" align="center"> | |
| 27 | - <template slot-scope="scope"> | |
| 28 | - <div slot="reference" class="name-wrapper"> | |
| 29 | - <el-tag size="medium" v-if="scope.row.status">在线</el-tag> | |
| 30 | - <el-tag size="medium" type="info" v-if="!scope.row.status">离线</el-tag> | |
| 31 | - </div> | |
| 32 | - </template> | |
| 33 | - </el-table-column> | |
| 34 | - <el-table-column label="地址" width="180" align="center"> | |
| 35 | - <template slot-scope="scope"> | |
| 36 | - <div slot="reference" class="name-wrapper"> | |
| 37 | - <el-tag size="medium">{{ scope.row.serverIP}}:{{scope.row.serverPort }}</el-tag> | |
| 38 | - </div> | |
| 39 | - </template> | |
| 40 | - </el-table-column> | |
| 41 | - <el-table-column prop="deviceGBId" label="设备国标编号" width="200" align="center"></el-table-column> | |
| 42 | - <el-table-column prop="transport" label="信令传输模式" width="120" align="center"></el-table-column> | |
| 43 | - <el-table-column prop="channelCount" label="通道数" width="120" align="center"></el-table-column> | |
| 44 | - <el-table-column label="订阅信息" width="240" align="center" fixed="right"> | |
| 45 | - <template slot-scope="scope"> | |
| 46 | - <i v-if="scope.row.alarmSubscribe" style="font-size: 20px" title="报警订阅" class="iconfont icon-gbaojings subscribe-on " ></i> | |
| 47 | - <i v-if="!scope.row.alarmSubscribe" style="font-size: 20px" title="报警订阅" class="iconfont icon-gbaojings subscribe-off " ></i> | |
| 48 | - <i v-if="scope.row.catalogSubscribe" title="目录订阅" class="iconfont icon-gjichus subscribe-on" ></i> | |
| 49 | - <i v-if="!scope.row.catalogSubscribe" title="目录订阅" class="iconfont icon-gjichus subscribe-off" ></i> | |
| 50 | - <i v-if="scope.row.mobilePositionSubscribe" title="位置订阅" class="iconfont icon-gxunjians subscribe-on" ></i> | |
| 51 | - <i v-if="!scope.row.mobilePositionSubscribe" title="位置订阅" class="iconfont icon-gxunjians subscribe-off" ></i> | |
| 52 | - </template> | |
| 53 | - </el-table-column> | |
| 2 | + <div id="app" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title">上级平台列表</div> | |
| 5 | + <div class="page-header-btn"> | |
| 6 | + <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addParentPlatform">添加</el-button> | |
| 7 | + </div> | |
| 8 | + </div> | |
| 54 | 9 | |
| 55 | - <el-table-column label="操作" width="300" align="center" fixed="right"> | |
| 56 | - <template slot-scope="scope"> | |
| 57 | - <el-button size="mini" icon="el-icon-edit" @click="editPlatform(scope.row)">编辑</el-button> | |
| 58 | - <el-button size="mini" icon="el-icon-share" type="primary" @click="chooseChannel(scope.row)">选择通道</el-button> | |
| 59 | - <el-button size="mini" icon="el-icon-delete" type="danger" @click="deletePlatform(scope.row)">删除</el-button> | |
| 60 | - </template> | |
| 61 | - </el-table-column> | |
| 62 | - </el-table> | |
| 63 | - <el-pagination | |
| 64 | - style="float: right" | |
| 65 | - @size-change="handleSizeChange" | |
| 66 | - @current-change="currentChange" | |
| 67 | - :current-page="currentPage" | |
| 68 | - :page-size="count" | |
| 69 | - :page-sizes="[15, 25, 35, 50]" | |
| 70 | - layout="total, sizes, prev, pager, next" | |
| 71 | - :total="total"> | |
| 72 | - </el-pagination> | |
| 73 | - <platformEdit ref="platformEdit" ></platformEdit> | |
| 74 | - <chooseChannelDialog ref="chooseChannelDialog" ></chooseChannelDialog> | |
| 75 | - </el-main> | |
| 76 | - </el-container> | |
| 10 | + <!--设备列表--> | |
| 11 | + <el-table :data="platformList" border style="width: 100%" :height="winHeight"> | |
| 12 | + <el-table-column prop="name" label="名称" align="center"></el-table-column> | |
| 13 | + <el-table-column prop="serverGBId" label="平台编号" align="center"></el-table-column> | |
| 14 | + <el-table-column label="是否启用" width="120" align="center"> | |
| 15 | + <template slot-scope="scope"> | |
| 16 | + <div slot="reference" class="name-wrapper"> | |
| 17 | + <el-tag size="medium" v-if="scope.row.enable">已启用</el-tag> | |
| 18 | + <el-tag size="medium" type="info" v-if="!scope.row.enable">未启用</el-tag> | |
| 19 | + </div> | |
| 20 | + </template> | |
| 21 | + </el-table-column> | |
| 22 | + <el-table-column label="状态" width="120" align="center"> | |
| 23 | + <template slot-scope="scope"> | |
| 24 | + <div slot="reference" class="name-wrapper"> | |
| 25 | + <el-tag size="medium" v-if="scope.row.status">在线</el-tag> | |
| 26 | + <el-tag size="medium" type="info" v-if="!scope.row.status">离线</el-tag> | |
| 27 | + </div> | |
| 28 | + </template> | |
| 29 | + </el-table-column> | |
| 30 | + <el-table-column label="地址" width="180" align="center"> | |
| 31 | + <template slot-scope="scope"> | |
| 32 | + <div slot="reference" class="name-wrapper"> | |
| 33 | + <el-tag size="medium">{{ scope.row.serverIP}}:{{scope.row.serverPort }}</el-tag> | |
| 34 | + </div> | |
| 35 | + </template> | |
| 36 | + </el-table-column> | |
| 37 | + <el-table-column prop="deviceGBId" label="设备国标编号" width="200" align="center"></el-table-column> | |
| 38 | + <el-table-column prop="transport" label="信令传输模式" width="120" align="center"></el-table-column> | |
| 39 | + <el-table-column prop="channelCount" label="通道数" width="120" align="center"></el-table-column> | |
| 40 | + <el-table-column label="订阅信息" width="240" align="center" fixed="right"> | |
| 41 | + <template slot-scope="scope"> | |
| 42 | + <i v-if="scope.row.alarmSubscribe" style="font-size: 20px" title="报警订阅" class="iconfont icon-gbaojings subscribe-on " ></i> | |
| 43 | + <i v-if="!scope.row.alarmSubscribe" style="font-size: 20px" title="报警订阅" class="iconfont icon-gbaojings subscribe-off " ></i> | |
| 44 | + <i v-if="scope.row.catalogSubscribe" title="目录订阅" class="iconfont icon-gjichus subscribe-on" ></i> | |
| 45 | + <i v-if="!scope.row.catalogSubscribe" title="目录订阅" class="iconfont icon-gjichus subscribe-off" ></i> | |
| 46 | + <i v-if="scope.row.mobilePositionSubscribe" title="位置订阅" class="iconfont icon-gxunjians subscribe-on" ></i> | |
| 47 | + <i v-if="!scope.row.mobilePositionSubscribe" title="位置订阅" class="iconfont icon-gxunjians subscribe-off" ></i> | |
| 48 | + </template> | |
| 49 | + </el-table-column> | |
| 50 | + | |
| 51 | + <el-table-column label="操作" width="300" align="center" fixed="right"> | |
| 52 | + <template slot-scope="scope"> | |
| 53 | + <el-button size="mini" icon="el-icon-edit" @click="editPlatform(scope.row)">编辑</el-button> | |
| 54 | + <el-button size="mini" icon="el-icon-share" type="primary" @click="chooseChannel(scope.row)">选择通道</el-button> | |
| 55 | + <el-button size="mini" icon="el-icon-delete" type="danger" @click="deletePlatform(scope.row)">删除</el-button> | |
| 56 | + </template> | |
| 57 | + </el-table-column> | |
| 58 | + </el-table> | |
| 59 | + <el-pagination | |
| 60 | + style="float: right" | |
| 61 | + @size-change="handleSizeChange" | |
| 62 | + @current-change="currentChange" | |
| 63 | + :current-page="currentPage" | |
| 64 | + :page-size="count" | |
| 65 | + :page-sizes="[15, 25, 35, 50]" | |
| 66 | + layout="total, sizes, prev, pager, next" | |
| 67 | + :total="total"> | |
| 68 | + </el-pagination> | |
| 69 | + <platformEdit ref="platformEdit" ></platformEdit> | |
| 70 | + <chooseChannelDialog ref="chooseChannelDialog" ></chooseChannelDialog> | |
| 77 | 71 | </div> |
| 78 | 72 | </template> |
| 79 | 73 | |
| 80 | 74 | <script> |
| 81 | 75 | import platformEdit from './dialog/platformEdit.vue' |
| 82 | -import uiHeader from './UiHeader.vue' | |
| 76 | +import uiHeader from '../layout/UiHeader.vue' | |
| 83 | 77 | import chooseChannelDialog from './dialog/chooseChannel.vue' |
| 84 | 78 | export default { |
| 85 | 79 | name: 'app', | ... | ... |
web_src/src/components/PushVideoList.vue
| 1 | 1 | <template> |
| 2 | - <div id="pushVideoList"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: bold;">推流列表</span> | |
| 10 | - </div> | |
| 11 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> | |
| 12 | - | |
| 13 | - 搜索: <el-input @input="getPushList" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input> | |
| 14 | - | |
| 15 | - 流媒体: <el-select size="mini" @change="getPushList" style="margin-right: 1rem;" v-model="mediaServerId" placeholder="请选择" default-first-option> | |
| 2 | + <div id="pushVideoList" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title">推流列表</div> | |
| 5 | + <div class="page-header-btn"> | |
| 6 | + 搜索: | |
| 7 | + <el-input @input="getPushList" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" | |
| 8 | + prefix-icon="el-icon-search" v-model="searchSrt" clearable></el-input> | |
| 9 | + 流媒体: | |
| 10 | + <el-select size="mini" @change="getPushList" style="margin-right: 1rem;" v-model="mediaServerId" | |
| 11 | + placeholder="请选择" default-first-option> | |
| 16 | 12 | <el-option label="全部" value=""></el-option> |
| 17 | 13 | <el-option |
| 18 | 14 | v-for="item in mediaServerList" |
| ... | ... | @@ -21,309 +17,327 @@ |
| 21 | 17 | :value="item.id"> |
| 22 | 18 | </el-option> |
| 23 | 19 | </el-select> |
| 24 | - 推流状态: <el-select size="mini" style="margin-right: 1rem;" @change="getPushList" v-model="pushing" placeholder="请选择" default-first-option> | |
| 20 | + 推流状态: | |
| 21 | + <el-select size="mini" style="margin-right: 1rem;" @change="getPushList" v-model="pushing" placeholder="请选择" | |
| 22 | + default-first-option> | |
| 25 | 23 | <el-option label="全部" value=""></el-option> |
| 26 | 24 | <el-option label="推流进行中" value="true"></el-option> |
| 27 | 25 | <el-option label="推流未进行" value="false"></el-option> |
| 28 | 26 | </el-select> |
| 29 | - <el-button icon="el-icon-upload2" size="mini" style="margin-right: 1rem;" type="primary" @click="importChannel">通道导入</el-button> | |
| 30 | - <el-button icon="el-icon-download" size="mini" style="margin-right: 1rem;" type="primary" > | |
| 31 | - <a style="color: #FFFFFF; text-align: center; text-decoration: none" href="/static/file/推流通道导入.zip" download='推流通道导入.zip' >下载模板</a> | |
| 32 | - </el-button> | |
| 33 | - <el-button icon="el-icon-delete" size="mini" style="margin-right: 1rem;" :disabled="multipleSelection.length === 0" type="danger" @click="batchDel">批量移除</el-button> | |
| 34 | - </div> | |
| 35 | - <devicePlayer ref="devicePlayer"></devicePlayer> | |
| 36 | - <addStreamTOGB ref="addStreamTOGB"></addStreamTOGB> | |
| 37 | - <el-table ref="pushListTable" :data="pushList" border style="width: 100%" :height="winHeight" @selection-change="handleSelectionChange" :row-key="(row)=> row.app + row.stream"> | |
| 38 | - <el-table-column align="center" type="selection" :reserve-selection="true" width="55"> | |
| 39 | - </el-table-column> | |
| 40 | - <el-table-column prop="name" label="名称" align="center"> | |
| 41 | - </el-table-column> | |
| 42 | - <el-table-column prop="app" label="APP" align="center"> | |
| 43 | - </el-table-column> | |
| 44 | - <el-table-column prop="stream" label="流ID" align="center"> | |
| 45 | - </el-table-column> | |
| 46 | - <el-table-column prop="gbId" label="国标编码" width="200" align="center"> | |
| 47 | - </el-table-column> | |
| 48 | - <el-table-column prop="mediaServerId" label="流媒体" width="200" align="center"> | |
| 49 | - </el-table-column> | |
| 50 | - <el-table-column label="开始时间" align="center" width="200"> | |
| 51 | - <template slot-scope="scope"> | |
| 52 | - <el-button-group> | |
| 53 | - {{dateFormat(parseInt(scope.row.createStamp))}} | |
| 54 | - </el-button-group> | |
| 55 | - </template> | |
| 56 | - </el-table-column> | |
| 57 | - <el-table-column label="正在推流" align="center" width="100"> | |
| 58 | - <template slot-scope="scope"> | |
| 59 | - {{(scope.row.status == false && scope.row.gbId == null) || scope.row.status ?'是':'否'}} | |
| 60 | - </template> | |
| 61 | - </el-table-column> | |
| 27 | + <el-button icon="el-icon-upload2" size="mini" style="margin-right: 1rem;" type="primary" @click="importChannel"> | |
| 28 | + 通道导入 | |
| 29 | + </el-button> | |
| 30 | + <el-button icon="el-icon-download" size="mini" style="margin-right: 1rem;" type="primary"> | |
| 31 | + <a style="color: #FFFFFF; text-align: center; text-decoration: none" href="/static/file/推流通道导入.zip" | |
| 32 | + download='推流通道导入.zip'>下载模板</a> | |
| 33 | + </el-button> | |
| 34 | + <el-button icon="el-icon-delete" size="mini" style="margin-right: 1rem;" | |
| 35 | + :disabled="multipleSelection.length === 0" type="danger" @click="batchDel">批量移除 | |
| 36 | + </el-button> | |
| 37 | + </div> | |
| 38 | + </div> | |
| 39 | + <devicePlayer ref="devicePlayer"></devicePlayer> | |
| 40 | + <addStreamTOGB ref="addStreamTOGB"></addStreamTOGB> | |
| 41 | + <el-table ref="pushListTable" :data="pushList" border style="width: 100%" :height="winHeight" | |
| 42 | + @selection-change="handleSelectionChange" :row-key="(row)=> row.app + row.stream"> | |
| 43 | + <el-table-column align="center" type="selection" :reserve-selection="true" width="55"> | |
| 44 | + </el-table-column> | |
| 45 | + <el-table-column prop="name" label="名称" align="center"> | |
| 46 | + </el-table-column> | |
| 47 | + <el-table-column prop="app" label="APP" align="center"> | |
| 48 | + </el-table-column> | |
| 49 | + <el-table-column prop="stream" label="流ID" align="center"> | |
| 50 | + </el-table-column> | |
| 51 | + <el-table-column prop="gbId" label="国标编码" width="200" align="center"> | |
| 52 | + </el-table-column> | |
| 53 | + <el-table-column prop="mediaServerId" label="流媒体" width="200" align="center"> | |
| 54 | + </el-table-column> | |
| 55 | + <el-table-column label="开始时间" align="center" width="200"> | |
| 56 | + <template slot-scope="scope"> | |
| 57 | + <el-button-group> | |
| 58 | + {{ dateFormat(parseInt(scope.row.createStamp)) }} | |
| 59 | + </el-button-group> | |
| 60 | + </template> | |
| 61 | + </el-table-column> | |
| 62 | + <el-table-column label="正在推流" align="center" width="100"> | |
| 63 | + <template slot-scope="scope"> | |
| 64 | + {{ (scope.row.status == false && scope.row.gbId == null) || scope.row.status ? '是' : '否' }} | |
| 65 | + </template> | |
| 66 | + </el-table-column> | |
| 62 | 67 | |
| 63 | - <el-table-column label="操作" width="360" align="center" fixed="right"> | |
| 64 | - <template slot-scope="scope"> | |
| 65 | - <el-button-group> | |
| 66 | - <el-button size="mini" icon="el-icon-video-play" v-if="(scope.row.status == false && scope.row.gbId == null) || scope.row.status" @click="playPush(scope.row)">播放</el-button> | |
| 67 | - <el-button size="mini" icon="el-icon-delete" type="danger" @click="stopPush(scope.row)">移除</el-button> | |
| 68 | - <el-button size="mini" icon="el-icon-position" type="primary" v-if="!!!scope.row.gbId" @click="addToGB(scope.row)">加入国标</el-button> | |
| 69 | - <el-button size="mini" icon="el-icon-position" type="primary" v-if="!!scope.row.gbId" @click="removeFromGB(scope.row)">移出国标</el-button> | |
| 70 | - </el-button-group> | |
| 71 | - </template> | |
| 72 | - </el-table-column> | |
| 73 | - </el-table> | |
| 74 | - <el-pagination | |
| 75 | - style="float: right" | |
| 76 | - @size-change="handleSizeChange" | |
| 77 | - @current-change="currentChange" | |
| 78 | - :current-page="currentPage" | |
| 79 | - :page-size="count" | |
| 80 | - :page-sizes="[15, 25, 35, 50]" | |
| 81 | - layout="total, sizes, prev, pager, next" | |
| 82 | - :total="total"> | |
| 83 | - </el-pagination> | |
| 84 | - <streamProxyEdit ref="streamProxyEdit" ></streamProxyEdit> | |
| 85 | - <importChannel ref="importChannel" ></importChannel> | |
| 86 | - </el-main> | |
| 87 | - </el-container> | |
| 88 | - </div> | |
| 68 | + <el-table-column label="操作" width="360" align="center" fixed="right"> | |
| 69 | + <template slot-scope="scope"> | |
| 70 | + <el-button-group> | |
| 71 | + <el-button size="mini" icon="el-icon-video-play" | |
| 72 | + v-if="(scope.row.status == false && scope.row.gbId == null) || scope.row.status" | |
| 73 | + @click="playPush(scope.row)">播放 | |
| 74 | + </el-button> | |
| 75 | + <el-button size="mini" icon="el-icon-delete" type="danger" @click="stopPush(scope.row)">移除</el-button> | |
| 76 | + <el-button size="mini" icon="el-icon-position" type="primary" v-if="!!!scope.row.gbId" | |
| 77 | + @click="addToGB(scope.row)">加入国标 | |
| 78 | + </el-button> | |
| 79 | + <el-button size="mini" icon="el-icon-position" type="primary" v-if="!!scope.row.gbId" | |
| 80 | + @click="removeFromGB(scope.row)">移出国标 | |
| 81 | + </el-button> | |
| 82 | + </el-button-group> | |
| 83 | + </template> | |
| 84 | + </el-table-column> | |
| 85 | + </el-table> | |
| 86 | + <el-pagination | |
| 87 | + style="float: right" | |
| 88 | + @size-change="handleSizeChange" | |
| 89 | + @current-change="currentChange" | |
| 90 | + :current-page="currentPage" | |
| 91 | + :page-size="count" | |
| 92 | + :page-sizes="[15, 25, 35, 50]" | |
| 93 | + layout="total, sizes, prev, pager, next" | |
| 94 | + :total="total"> | |
| 95 | + </el-pagination> | |
| 96 | + <streamProxyEdit ref="streamProxyEdit"></streamProxyEdit> | |
| 97 | + <importChannel ref="importChannel"></importChannel> | |
| 98 | + </div> | |
| 89 | 99 | </template> |
| 90 | 100 | |
| 91 | 101 | <script> |
| 92 | - import streamProxyEdit from './dialog/StreamProxyEdit.vue' | |
| 93 | - import devicePlayer from './dialog/devicePlayer.vue' | |
| 94 | - import addStreamTOGB from './dialog/addStreamTOGB.vue' | |
| 95 | - import uiHeader from './UiHeader.vue' | |
| 96 | - import importChannel from './dialog/importChannel.vue' | |
| 97 | - import MediaServer from './service/MediaServer' | |
| 98 | - export default { | |
| 99 | - name: 'pushVideoList', | |
| 100 | - components: { | |
| 101 | - devicePlayer, | |
| 102 | - addStreamTOGB, | |
| 103 | - streamProxyEdit, | |
| 104 | - uiHeader, | |
| 105 | - importChannel, | |
| 106 | - }, | |
| 107 | - data() { | |
| 108 | - return { | |
| 109 | - pushList: [], //设备列表 | |
| 110 | - currentPusher: {}, //当前操作设备对象 | |
| 111 | - updateLooper: 0, //数据刷新轮训标志 | |
| 112 | - currentDeviceChannelsLenth:0, | |
| 113 | - winHeight: window.innerHeight - 250, | |
| 114 | - mediaServerObj : new MediaServer(), | |
| 115 | - currentPage:1, | |
| 116 | - count:15, | |
| 117 | - total:0, | |
| 118 | - searchSrt: "", | |
| 119 | - pushing: "", | |
| 120 | - mediaServerId: "", | |
| 121 | - mediaServerList: [], | |
| 122 | - multipleSelection: [], | |
| 123 | - getDeviceListLoading: false | |
| 124 | - }; | |
| 125 | - }, | |
| 126 | - computed: { | |
| 127 | - }, | |
| 128 | - mounted() { | |
| 129 | - this.initData(); | |
| 130 | - this.updateLooper = setInterval(this.getPushList, 2000); | |
| 131 | - }, | |
| 132 | - destroyed() { | |
| 133 | - clearTimeout(this.updateLooper); | |
| 134 | - }, | |
| 135 | - methods: { | |
| 136 | - initData: function() { | |
| 137 | - this.mediaServerObj.getOnlineMediaServerList((data)=>{ | |
| 138 | - this.mediaServerList = data.data; | |
| 139 | - }) | |
| 140 | - this.getPushList(); | |
| 141 | - }, | |
| 142 | - currentChange: function(val){ | |
| 143 | - this.currentPage = val; | |
| 144 | - this.getPushList(); | |
| 145 | - }, | |
| 146 | - handleSizeChange: function(val){ | |
| 147 | - this.count = val; | |
| 148 | - this.getPushList(); | |
| 149 | - }, | |
| 150 | - getPushList: function() { | |
| 151 | - let that = this; | |
| 152 | - this.getDeviceListLoading = true; | |
| 153 | - this.$axios({ | |
| 154 | - method: 'get', | |
| 155 | - url:`/api/push/list`, | |
| 156 | - params: { | |
| 157 | - page: that.currentPage, | |
| 158 | - count: that.count, | |
| 159 | - query: that.searchSrt, | |
| 160 | - pushing: that.pushing, | |
| 161 | - mediaServerId: that.mediaServerId, | |
| 162 | - } | |
| 163 | - }).then(function (res) { | |
| 164 | - that.total = res.data.total; | |
| 165 | - that.pushList = res.data.list; | |
| 166 | - that.getDeviceListLoading = false; | |
| 167 | - }).catch(function (error) { | |
| 168 | - console.error(error); | |
| 169 | - that.getDeviceListLoading = false; | |
| 170 | - }); | |
| 171 | - }, | |
| 102 | +import streamProxyEdit from './dialog/StreamProxyEdit.vue' | |
| 103 | +import devicePlayer from './dialog/devicePlayer.vue' | |
| 104 | +import addStreamTOGB from './dialog/addStreamTOGB.vue' | |
| 105 | +import uiHeader from '../layout/UiHeader.vue' | |
| 106 | +import importChannel from './dialog/importChannel.vue' | |
| 107 | +import MediaServer from './service/MediaServer' | |
| 108 | + | |
| 109 | +export default { | |
| 110 | + name: 'pushVideoList', | |
| 111 | + components: { | |
| 112 | + devicePlayer, | |
| 113 | + addStreamTOGB, | |
| 114 | + streamProxyEdit, | |
| 115 | + uiHeader, | |
| 116 | + importChannel, | |
| 117 | + }, | |
| 118 | + data() { | |
| 119 | + return { | |
| 120 | + pushList: [], //设备列表 | |
| 121 | + currentPusher: {}, //当前操作设备对象 | |
| 122 | + updateLooper: 0, //数据刷新轮训标志 | |
| 123 | + currentDeviceChannelsLenth: 0, | |
| 124 | + winHeight: window.innerHeight - 250, | |
| 125 | + mediaServerObj: new MediaServer(), | |
| 126 | + currentPage: 1, | |
| 127 | + count: 15, | |
| 128 | + total: 0, | |
| 129 | + searchSrt: "", | |
| 130 | + pushing: "", | |
| 131 | + mediaServerId: "", | |
| 132 | + mediaServerList: [], | |
| 133 | + multipleSelection: [], | |
| 134 | + getDeviceListLoading: false | |
| 135 | + }; | |
| 136 | + }, | |
| 137 | + computed: {}, | |
| 138 | + mounted() { | |
| 139 | + this.initData(); | |
| 140 | + this.updateLooper = setInterval(this.getPushList, 2000); | |
| 141 | + }, | |
| 142 | + destroyed() { | |
| 143 | + clearTimeout(this.updateLooper); | |
| 144 | + }, | |
| 145 | + methods: { | |
| 146 | + initData: function () { | |
| 147 | + this.mediaServerObj.getOnlineMediaServerList((data) => { | |
| 148 | + this.mediaServerList = data.data; | |
| 149 | + }) | |
| 150 | + this.getPushList(); | |
| 151 | + }, | |
| 152 | + currentChange: function (val) { | |
| 153 | + this.currentPage = val; | |
| 154 | + this.getPushList(); | |
| 155 | + }, | |
| 156 | + handleSizeChange: function (val) { | |
| 157 | + this.count = val; | |
| 158 | + this.getPushList(); | |
| 159 | + }, | |
| 160 | + getPushList: function () { | |
| 161 | + let that = this; | |
| 162 | + this.getDeviceListLoading = true; | |
| 163 | + this.$axios({ | |
| 164 | + method: 'get', | |
| 165 | + url: `/api/push/list`, | |
| 166 | + params: { | |
| 167 | + page: that.currentPage, | |
| 168 | + count: that.count, | |
| 169 | + query: that.searchSrt, | |
| 170 | + pushing: that.pushing, | |
| 171 | + mediaServerId: that.mediaServerId, | |
| 172 | + } | |
| 173 | + }).then(function (res) { | |
| 174 | + that.total = res.data.total; | |
| 175 | + that.pushList = res.data.list; | |
| 176 | + that.getDeviceListLoading = false; | |
| 177 | + }).catch(function (error) { | |
| 178 | + console.error(error); | |
| 179 | + that.getDeviceListLoading = false; | |
| 180 | + }); | |
| 181 | + }, | |
| 172 | 182 | |
| 173 | - playPush: function(row){ | |
| 174 | - let that = this; | |
| 175 | - this.getListLoading = true; | |
| 176 | - this.$axios({ | |
| 177 | - method: 'get', | |
| 178 | - url: '/api/media/stream_info_by_app_and_stream', | |
| 179 | - params: { | |
| 180 | - app: row.app, | |
| 181 | - stream: row.stream, | |
| 182 | - mediaServerId: row.mediaServerId | |
| 183 | - } | |
| 184 | - }).then(function (res) { | |
| 185 | - that.getListLoading = false; | |
| 186 | - that.$refs.devicePlayer.openDialog("streamPlay", null, null, { | |
| 187 | - streamInfo: res.data.data, | |
| 188 | - hasAudio: true | |
| 189 | - }); | |
| 190 | - }).catch(function (error) { | |
| 191 | - console.error(error); | |
| 192 | - that.getListLoading = false; | |
| 193 | - }); | |
| 194 | - }, | |
| 195 | - stopPush: function(row){ | |
| 183 | + playPush: function (row) { | |
| 184 | + let that = this; | |
| 185 | + this.getListLoading = true; | |
| 186 | + this.$axios({ | |
| 187 | + method: 'get', | |
| 188 | + url: '/api/media/stream_info_by_app_and_stream', | |
| 189 | + params: { | |
| 190 | + app: row.app, | |
| 191 | + stream: row.stream, | |
| 192 | + mediaServerId: row.mediaServerId | |
| 193 | + } | |
| 194 | + }).then(function (res) { | |
| 195 | + that.getListLoading = false; | |
| 196 | + that.$refs.devicePlayer.openDialog("streamPlay", null, null, { | |
| 197 | + streamInfo: res.data.data, | |
| 198 | + hasAudio: true | |
| 199 | + }); | |
| 200 | + }).catch(function (error) { | |
| 201 | + console.error(error); | |
| 202 | + that.getListLoading = false; | |
| 203 | + }); | |
| 204 | + }, | |
| 205 | + stopPush: function (row) { | |
| 206 | + let that = this; | |
| 207 | + that.$axios({ | |
| 208 | + method: "post", | |
| 209 | + url: "/api/push/stop", | |
| 210 | + params: { | |
| 211 | + app: row.app, | |
| 212 | + streamId: row.stream | |
| 213 | + } | |
| 214 | + }).then((res) => { | |
| 215 | + if (res.data == "success") { | |
| 216 | + that.initData() | |
| 217 | + } | |
| 218 | + }).catch(function (error) { | |
| 219 | + console.error(error); | |
| 220 | + }); | |
| 221 | + }, | |
| 222 | + addToGB: function (row) { | |
| 223 | + this.$refs.addStreamTOGB.openDialog({ | |
| 224 | + app: row.app, | |
| 225 | + stream: row.stream, | |
| 226 | + mediaServerId: row.mediaServerId | |
| 227 | + }, this.initData); | |
| 228 | + }, | |
| 229 | + removeFromGB: function (row) { | |
| 230 | + let that = this; | |
| 231 | + that.$axios({ | |
| 232 | + method: "delete", | |
| 233 | + url: "/api/push/remove_form_gb", | |
| 234 | + data: row | |
| 235 | + }).then((res) => { | |
| 236 | + if (res.data == "success") { | |
| 237 | + that.initData() | |
| 238 | + } | |
| 239 | + }).catch(function (error) { | |
| 240 | + console.error(error); | |
| 241 | + }); | |
| 242 | + }, | |
| 243 | + dateFormat: function (/** timestamp=0 **/) { | |
| 244 | + let ts = arguments[0] || 0; | |
| 245 | + let t, y, m, d, h, i, s; | |
| 246 | + t = ts ? new Date(ts) : new Date(); | |
| 247 | + y = t.getFullYear(); | |
| 248 | + m = t.getMonth() + 1; | |
| 249 | + d = t.getDate(); | |
| 250 | + h = t.getHours(); | |
| 251 | + i = t.getMinutes(); | |
| 252 | + s = t.getSeconds(); | |
| 253 | + // 可根据需要在这里定义时间格式 | |
| 254 | + return y + '-' + (m < 10 ? '0' + m : m) + '-' + (d < 10 ? '0' + d : d) + ' ' + (h < 10 ? '0' + h : h) + ':' + (i < 10 ? '0' + i : i) + ':' + (s < 10 ? '0' + s : s); | |
| 255 | + }, | |
| 256 | + importChannel: function () { | |
| 257 | + this.$refs.importChannel.openDialog(() => { | |
| 258 | + | |
| 259 | + }) | |
| 260 | + }, | |
| 261 | + batchDel: function () { | |
| 262 | + this.$confirm(`确定删除选中的${this.multipleSelection.length}个通道?`, '提示', { | |
| 263 | + confirmButtonText: '确定', | |
| 264 | + cancelButtonText: '取消', | |
| 265 | + type: 'warning' | |
| 266 | + }).then(() => { | |
| 196 | 267 | let that = this; |
| 197 | 268 | that.$axios({ |
| 198 | - method:"post", | |
| 199 | - url:"/api/push/stop", | |
| 200 | - params: { | |
| 201 | - app: row.app, | |
| 202 | - streamId: row.stream | |
| 203 | - } | |
| 204 | - }).then((res)=>{ | |
| 205 | - if (res.data == "success") { | |
| 206 | - that.initData() | |
| 269 | + method: "delete", | |
| 270 | + url: "/api/push/batchStop", | |
| 271 | + data: { | |
| 272 | + gbStreams: this.multipleSelection | |
| 207 | 273 | } |
| 274 | + }).then((res) => { | |
| 275 | + this.initData(); | |
| 276 | + this.$refs.pushListTable.clearSelection(); | |
| 208 | 277 | }).catch(function (error) { |
| 209 | 278 | console.error(error); |
| 210 | 279 | }); |
| 211 | - }, | |
| 212 | - addToGB: function(row){ | |
| 213 | - this.$refs.addStreamTOGB.openDialog({app: row.app, stream: row.stream, mediaServerId: row.mediaServerId}, this.initData); | |
| 214 | - }, | |
| 215 | - removeFromGB: function(row){ | |
| 216 | - let that = this; | |
| 217 | - that.$axios({ | |
| 218 | - method:"delete", | |
| 219 | - url:"/api/push/remove_form_gb", | |
| 220 | - data:row | |
| 221 | - }).then((res)=>{ | |
| 222 | - if (res.data == "success") { | |
| 223 | - that.initData() | |
| 224 | - } | |
| 225 | - }).catch(function (error) { | |
| 226 | - console.error(error); | |
| 227 | - }); | |
| 228 | - }, | |
| 229 | - dateFormat: function(/** timestamp=0 **/) { | |
| 230 | - let ts = arguments[0] || 0; | |
| 231 | - let t,y,m,d,h,i,s; | |
| 232 | - t = ts ? new Date(ts) : new Date(); | |
| 233 | - y = t.getFullYear(); | |
| 234 | - m = t.getMonth()+1; | |
| 235 | - d = t.getDate(); | |
| 236 | - h = t.getHours(); | |
| 237 | - i = t.getMinutes(); | |
| 238 | - s = t.getSeconds(); | |
| 239 | - // 可根据需要在这里定义时间格式 | |
| 240 | - return y+'-'+(m<10?'0'+m:m)+'-'+(d<10?'0'+d:d)+' '+(h<10?'0'+h:h)+':'+(i<10?'0'+i:i)+':'+(s<10?'0'+s:s); | |
| 241 | - }, | |
| 242 | - importChannel: function () { | |
| 243 | - this.$refs.importChannel.openDialog(()=>{ | |
| 280 | + }).catch(() => { | |
| 244 | 281 | |
| 245 | - }) | |
| 246 | - }, | |
| 247 | - batchDel: function () { | |
| 248 | - this.$confirm(`确定删除选中的${this.multipleSelection.length}个通道?`, '提示', { | |
| 249 | - confirmButtonText: '确定', | |
| 250 | - cancelButtonText: '取消', | |
| 251 | - type: 'warning' | |
| 252 | - }).then(() => { | |
| 253 | - let that = this; | |
| 254 | - that.$axios({ | |
| 255 | - method:"delete", | |
| 256 | - url:"/api/push/batchStop", | |
| 257 | - data: { | |
| 258 | - gbStreams: this.multipleSelection | |
| 259 | - } | |
| 260 | - }).then((res)=>{ | |
| 261 | - this.initData(); | |
| 262 | - this.$refs.pushListTable.clearSelection(); | |
| 263 | - }).catch(function (error) { | |
| 264 | - console.error(error); | |
| 265 | - }); | |
| 266 | - }).catch(() => { | |
| 267 | - | |
| 268 | - }); | |
| 269 | - }, | |
| 270 | - handleSelectionChange: function (val) { | |
| 271 | - this.multipleSelection = val; | |
| 272 | - }, | |
| 273 | - } | |
| 274 | - }; | |
| 282 | + }); | |
| 283 | + }, | |
| 284 | + handleSelectionChange: function (val) { | |
| 285 | + this.multipleSelection = val; | |
| 286 | + }, | |
| 287 | + } | |
| 288 | +}; | |
| 275 | 289 | </script> |
| 276 | 290 | |
| 277 | 291 | <style> |
| 278 | - .videoList { | |
| 279 | - display: flex; | |
| 280 | - flex-wrap: wrap; | |
| 281 | - align-content: flex-start; | |
| 282 | - } | |
| 292 | +.videoList { | |
| 293 | + display: flex; | |
| 294 | + flex-wrap: wrap; | |
| 295 | + align-content: flex-start; | |
| 296 | +} | |
| 283 | 297 | |
| 284 | - .video-item { | |
| 285 | - position: relative; | |
| 286 | - width: 15rem; | |
| 287 | - height: 10rem; | |
| 288 | - margin-right: 1rem; | |
| 289 | - background-color: #000000; | |
| 290 | - } | |
| 298 | +.video-item { | |
| 299 | + position: relative; | |
| 300 | + width: 15rem; | |
| 301 | + height: 10rem; | |
| 302 | + margin-right: 1rem; | |
| 303 | + background-color: #000000; | |
| 304 | +} | |
| 291 | 305 | |
| 292 | - .video-item-img { | |
| 293 | - position: absolute; | |
| 294 | - top: 0; | |
| 295 | - bottom: 0; | |
| 296 | - left: 0; | |
| 297 | - right: 0; | |
| 298 | - margin: auto; | |
| 299 | - width: 100%; | |
| 300 | - height: 100%; | |
| 301 | - } | |
| 306 | +.video-item-img { | |
| 307 | + position: absolute; | |
| 308 | + top: 0; | |
| 309 | + bottom: 0; | |
| 310 | + left: 0; | |
| 311 | + right: 0; | |
| 312 | + margin: auto; | |
| 313 | + width: 100%; | |
| 314 | + height: 100%; | |
| 315 | +} | |
| 302 | 316 | |
| 303 | - .video-item-img:after { | |
| 304 | - content: ""; | |
| 305 | - display: inline-block; | |
| 306 | - position: absolute; | |
| 307 | - z-index: 2; | |
| 308 | - top: 0; | |
| 309 | - bottom: 0; | |
| 310 | - left: 0; | |
| 311 | - right: 0; | |
| 312 | - margin: auto; | |
| 313 | - width: 3rem; | |
| 314 | - height: 3rem; | |
| 315 | - background-image: url("../assets/loading.png"); | |
| 316 | - background-size: cover; | |
| 317 | - background-color: #000000; | |
| 318 | - } | |
| 317 | +.video-item-img:after { | |
| 318 | + content: ""; | |
| 319 | + display: inline-block; | |
| 320 | + position: absolute; | |
| 321 | + z-index: 2; | |
| 322 | + top: 0; | |
| 323 | + bottom: 0; | |
| 324 | + left: 0; | |
| 325 | + right: 0; | |
| 326 | + margin: auto; | |
| 327 | + width: 3rem; | |
| 328 | + height: 3rem; | |
| 329 | + background-image: url("../assets/loading.png"); | |
| 330 | + background-size: cover; | |
| 331 | + background-color: #000000; | |
| 332 | +} | |
| 319 | 333 | |
| 320 | - .video-item-title { | |
| 321 | - position: absolute; | |
| 322 | - bottom: 0; | |
| 323 | - color: #000000; | |
| 324 | - background-color: #ffffff; | |
| 325 | - line-height: 1.5rem; | |
| 326 | - padding: 0.3rem; | |
| 327 | - width: 14.4rem; | |
| 328 | - } | |
| 334 | +.video-item-title { | |
| 335 | + position: absolute; | |
| 336 | + bottom: 0; | |
| 337 | + color: #000000; | |
| 338 | + background-color: #ffffff; | |
| 339 | + line-height: 1.5rem; | |
| 340 | + padding: 0.3rem; | |
| 341 | + width: 14.4rem; | |
| 342 | +} | |
| 329 | 343 | </style> | ... | ... |
web_src/src/components/StreamProxyList.vue
| 1 | 1 | <template> |
| 2 | - <div id="streamProxyList"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: bold;">拉流代理列表</span> | |
| 10 | - </div> | |
| 11 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> | |
| 12 | - <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addStreamProxy">添加代理</el-button> | |
| 13 | - <el-button v-if="false" icon="el-icon-search" size="mini" style="margin-right: 1rem;" type="primary" @click="addOnvif">搜索ONVIF</el-button> | |
| 14 | - </div> | |
| 15 | - <devicePlayer ref="devicePlayer"></devicePlayer> | |
| 16 | - <el-table :data="streamProxyList" border style="width: 100%" :height="winHeight"> | |
| 17 | - <el-table-column prop="name" label="名称" align="center" show-overflow-tooltip/> | |
| 18 | - <el-table-column prop="app" label="流应用名" align="center" show-overflow-tooltip/> | |
| 19 | - <el-table-column prop="stream" label="流ID" align="center" show-overflow-tooltip/> | |
| 20 | - <el-table-column label="流地址" width="400" align="center" show-overflow-tooltip > | |
| 21 | - <template slot-scope="scope"> | |
| 22 | - <div slot="reference" class="name-wrapper"> | |
| 2 | + <div id="streamProxyList" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title">拉流代理列表</div> | |
| 5 | + <div class="page-header-btn"> | |
| 6 | + <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addStreamProxy">添加代理</el-button> | |
| 7 | + <el-button v-if="false" icon="el-icon-search" size="mini" style="margin-right: 1rem;" type="primary" @click="addOnvif">搜索ONVIF</el-button> | |
| 8 | + </div> | |
| 9 | + </div> | |
| 10 | + <devicePlayer ref="devicePlayer"></devicePlayer> | |
| 11 | + <el-table :data="streamProxyList" border style="width: 100%" :height="winHeight"> | |
| 12 | + <el-table-column prop="name" label="名称" align="center" show-overflow-tooltip/> | |
| 13 | + <el-table-column prop="app" label="流应用名" align="center" show-overflow-tooltip/> | |
| 14 | + <el-table-column prop="stream" label="流ID" align="center" show-overflow-tooltip/> | |
| 15 | + <el-table-column label="流地址" width="400" align="center" show-overflow-tooltip > | |
| 16 | + <template slot-scope="scope"> | |
| 17 | + <div slot="reference" class="name-wrapper"> | |
| 23 | 18 | |
| 24 | - <el-tag size="medium" v-if="scope.row.type == 'default'"> | |
| 25 | - <i class="cpoy-btn el-icon-document-copy" title="点击拷贝" v-clipboard="scope.row.url" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></i> | |
| 26 | - {{scope.row.url}} | |
| 27 | - </el-tag> | |
| 28 | - <el-tag size="medium" v-if="scope.row.type != 'default'"> | |
| 29 | - <i class="cpoy-btn el-icon-document-copy" title="点击拷贝" v-clipboard="scope.row.src_url" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></i> | |
| 30 | - {{scope.row.src_url}} | |
| 31 | - </el-tag> | |
| 32 | - </div> | |
| 33 | - </template> | |
| 34 | - </el-table-column> | |
| 35 | - <el-table-column prop="mediaServerId" label="流媒体" width="150" align="center"></el-table-column> | |
| 36 | - <el-table-column label="类型" width="100" align="center"> | |
| 37 | - <template slot-scope="scope"> | |
| 38 | - <div slot="reference" class="name-wrapper"> | |
| 39 | - <el-tag size="medium">{{scope.row.type}}</el-tag> | |
| 40 | - </div> | |
| 41 | - </template> | |
| 42 | - </el-table-column> | |
| 19 | + <el-tag size="medium" v-if="scope.row.type == 'default'"> | |
| 20 | + <i class="cpoy-btn el-icon-document-copy" title="点击拷贝" v-clipboard="scope.row.url" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></i> | |
| 21 | + {{scope.row.url}} | |
| 22 | + </el-tag> | |
| 23 | + <el-tag size="medium" v-if="scope.row.type != 'default'"> | |
| 24 | + <i class="cpoy-btn el-icon-document-copy" title="点击拷贝" v-clipboard="scope.row.src_url" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></i> | |
| 25 | + {{scope.row.src_url}} | |
| 26 | + </el-tag> | |
| 27 | + </div> | |
| 28 | + </template> | |
| 29 | + </el-table-column> | |
| 30 | + <el-table-column prop="mediaServerId" label="流媒体" width="150" align="center"></el-table-column> | |
| 31 | + <el-table-column label="类型" width="100" align="center"> | |
| 32 | + <template slot-scope="scope"> | |
| 33 | + <div slot="reference" class="name-wrapper"> | |
| 34 | + <el-tag size="medium">{{scope.row.type}}</el-tag> | |
| 35 | + </div> | |
| 36 | + </template> | |
| 37 | + </el-table-column> | |
| 43 | 38 | |
| 44 | - <el-table-column prop="gbId" label="国标编码" width="180" align="center" show-overflow-tooltip/> | |
| 45 | - <el-table-column label="状态" width="120" align="center"> | |
| 46 | - <template slot-scope="scope"> | |
| 47 | - <div slot="reference" class="name-wrapper"> | |
| 48 | - <el-tag size="medium" v-if="scope.row.status">在线</el-tag> | |
| 49 | - <el-tag size="medium" type="info" v-if="!scope.row.status">离线</el-tag> | |
| 50 | - </div> | |
| 51 | - </template> | |
| 52 | - </el-table-column> | |
| 53 | - <el-table-column label="启用" width="120" align="center"> | |
| 54 | - <template slot-scope="scope"> | |
| 55 | - <div slot="reference" class="name-wrapper"> | |
| 56 | - <el-tag size="medium" v-if="scope.row.enable">已启用</el-tag> | |
| 57 | - <el-tag size="medium" type="info" v-if="!scope.row.enable">未启用</el-tag> | |
| 58 | - </div> | |
| 59 | - </template> | |
| 60 | - </el-table-column> | |
| 61 | - <el-table-column prop="createTime" label="创建时间" align="center" width="150" show-overflow-tooltip/> | |
| 62 | - <el-table-column label="转HLS" width="120" align="center"> | |
| 63 | - <template slot-scope="scope"> | |
| 64 | - <div slot="reference" class="name-wrapper"> | |
| 65 | - <el-tag size="medium" v-if="scope.row.enable_hls">已启用</el-tag> | |
| 66 | - <el-tag size="medium" type="info" v-if="!scope.row.enable_hls">未启用</el-tag> | |
| 67 | - </div> | |
| 68 | - </template> | |
| 69 | - </el-table-column> | |
| 70 | - <el-table-column label="MP4录制" width="120" align="center"> | |
| 71 | - <template slot-scope="scope"> | |
| 72 | - <div slot="reference" class="name-wrapper"> | |
| 73 | - <el-tag size="medium" v-if="scope.row.enable_mp4">已启用</el-tag> | |
| 74 | - <el-tag size="medium" type="info" v-if="!scope.row.enable_mp4">未启用</el-tag> | |
| 75 | - </div> | |
| 76 | - </template> | |
| 77 | - </el-table-column> | |
| 78 | - <el-table-column label="无人观看自动删除" width="160" align="center"> | |
| 79 | - <template slot-scope="scope"> | |
| 80 | - <div slot="reference" class="name-wrapper"> | |
| 81 | - <el-tag size="medium" v-if="scope.row.enable_remove_none_reader">已启用</el-tag> | |
| 82 | - <el-tag size="medium" type="info" v-if="!scope.row.enable_remove_none_reader">未启用</el-tag> | |
| 83 | - </div> | |
| 84 | - </template> | |
| 85 | - </el-table-column> | |
| 39 | + <el-table-column prop="gbId" label="国标编码" width="180" align="center" show-overflow-tooltip/> | |
| 40 | + <el-table-column label="状态" width="120" align="center"> | |
| 41 | + <template slot-scope="scope"> | |
| 42 | + <div slot="reference" class="name-wrapper"> | |
| 43 | + <el-tag size="medium" v-if="scope.row.status">在线</el-tag> | |
| 44 | + <el-tag size="medium" type="info" v-if="!scope.row.status">离线</el-tag> | |
| 45 | + </div> | |
| 46 | + </template> | |
| 47 | + </el-table-column> | |
| 48 | + <el-table-column label="启用" width="120" align="center"> | |
| 49 | + <template slot-scope="scope"> | |
| 50 | + <div slot="reference" class="name-wrapper"> | |
| 51 | + <el-tag size="medium" v-if="scope.row.enable">已启用</el-tag> | |
| 52 | + <el-tag size="medium" type="info" v-if="!scope.row.enable">未启用</el-tag> | |
| 53 | + </div> | |
| 54 | + </template> | |
| 55 | + </el-table-column> | |
| 56 | + <el-table-column prop="createTime" label="创建时间" align="center" width="150" show-overflow-tooltip/> | |
| 57 | + <el-table-column label="转HLS" width="120" align="center"> | |
| 58 | + <template slot-scope="scope"> | |
| 59 | + <div slot="reference" class="name-wrapper"> | |
| 60 | + <el-tag size="medium" v-if="scope.row.enable_hls">已启用</el-tag> | |
| 61 | + <el-tag size="medium" type="info" v-if="!scope.row.enable_hls">未启用</el-tag> | |
| 62 | + </div> | |
| 63 | + </template> | |
| 64 | + </el-table-column> | |
| 65 | + <el-table-column label="MP4录制" width="120" align="center"> | |
| 66 | + <template slot-scope="scope"> | |
| 67 | + <div slot="reference" class="name-wrapper"> | |
| 68 | + <el-tag size="medium" v-if="scope.row.enable_mp4">已启用</el-tag> | |
| 69 | + <el-tag size="medium" type="info" v-if="!scope.row.enable_mp4">未启用</el-tag> | |
| 70 | + </div> | |
| 71 | + </template> | |
| 72 | + </el-table-column> | |
| 73 | + <el-table-column label="无人观看自动删除" width="160" align="center"> | |
| 74 | + <template slot-scope="scope"> | |
| 75 | + <div slot="reference" class="name-wrapper"> | |
| 76 | + <el-tag size="medium" v-if="scope.row.enable_remove_none_reader">已启用</el-tag> | |
| 77 | + <el-tag size="medium" type="info" v-if="!scope.row.enable_remove_none_reader">未启用</el-tag> | |
| 78 | + </div> | |
| 79 | + </template> | |
| 80 | + </el-table-column> | |
| 86 | 81 | |
| 87 | 82 | |
| 88 | - <el-table-column label="操作" width="360" align="center" fixed="right"> | |
| 89 | - <template slot-scope="scope"> | |
| 90 | - <el-button-group> | |
| 91 | - <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.enable" @click="play(scope.row)">播放</el-button> | |
| 92 | - <el-button size="mini" icon="el-icon-close" type="success" v-if="scope.row.enable" @click="stop(scope.row)">停用</el-button> | |
| 93 | - <el-button size="mini" icon="el-icon-check" type="primary" :loading="startBtnLaoding" v-if="!scope.row.enable" @click="start(scope.row)">启用</el-button> | |
| 94 | - <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteStreamProxy(scope.row)">删除</el-button> | |
| 95 | - </el-button-group> | |
| 96 | - </template> | |
| 97 | - </el-table-column> | |
| 98 | - </el-table> | |
| 99 | - <el-pagination | |
| 100 | - style="float: right" | |
| 101 | - @size-change="handleSizeChange" | |
| 102 | - @current-change="currentChange" | |
| 103 | - :current-page="currentPage" | |
| 104 | - :page-size="count" | |
| 105 | - :page-sizes="[15, 25, 35, 50]" | |
| 106 | - layout="total, sizes, prev, pager, next" | |
| 107 | - :total="total"> | |
| 108 | - </el-pagination> | |
| 109 | - <streamProxyEdit ref="streamProxyEdit" ></streamProxyEdit> | |
| 110 | - <onvifEdit ref="onvifEdit" ></onvifEdit> | |
| 111 | - </el-main> | |
| 112 | - </el-container> | |
| 83 | + <el-table-column label="操作" width="360" align="center" fixed="right"> | |
| 84 | + <template slot-scope="scope"> | |
| 85 | + <el-button-group> | |
| 86 | + <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.enable" @click="play(scope.row)">播放</el-button> | |
| 87 | + <el-button size="mini" icon="el-icon-close" type="success" v-if="scope.row.enable" @click="stop(scope.row)">停用</el-button> | |
| 88 | + <el-button size="mini" icon="el-icon-check" type="primary" :loading="startBtnLaoding" v-if="!scope.row.enable" @click="start(scope.row)">启用</el-button> | |
| 89 | + <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteStreamProxy(scope.row)">删除</el-button> | |
| 90 | + </el-button-group> | |
| 91 | + </template> | |
| 92 | + </el-table-column> | |
| 93 | + </el-table> | |
| 94 | + <el-pagination | |
| 95 | + style="float: right" | |
| 96 | + @size-change="handleSizeChange" | |
| 97 | + @current-change="currentChange" | |
| 98 | + :current-page="currentPage" | |
| 99 | + :page-size="count" | |
| 100 | + :page-sizes="[15, 25, 35, 50]" | |
| 101 | + layout="total, sizes, prev, pager, next" | |
| 102 | + :total="total"> | |
| 103 | + </el-pagination> | |
| 104 | + <streamProxyEdit ref="streamProxyEdit" ></streamProxyEdit> | |
| 105 | + <onvifEdit ref="onvifEdit" ></onvifEdit> | |
| 113 | 106 | </div> |
| 114 | 107 | </template> |
| 115 | 108 | |
| ... | ... | @@ -117,7 +110,7 @@ |
| 117 | 110 | import streamProxyEdit from './dialog/StreamProxyEdit.vue' |
| 118 | 111 | import onvifEdit from './dialog/onvifEdit.vue' |
| 119 | 112 | import devicePlayer from './dialog/devicePlayer.vue' |
| 120 | - import uiHeader from './UiHeader.vue' | |
| 113 | + import uiHeader from '../layout/UiHeader.vue' | |
| 121 | 114 | export default { |
| 122 | 115 | name: 'streamProxyList', |
| 123 | 116 | components: { | ... | ... |
web_src/src/components/channelList.vue
| 1 | 1 | <template> |
| 2 | -<div id="channelList"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #FFFFFF; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: 500; ">通道列表({{parentChannelId ==0 ? deviceId:parentChannelId}})</span> | |
| 2 | + <div id="channelList" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title"> | |
| 5 | + <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem;" type="primary" @click="showDevice"> | |
| 6 | + 返回 | |
| 7 | + </el-button> | |
| 8 | + 通道列表({{ parentChannelId == 0 ? deviceId : parentChannelId }})</div> | |
| 9 | + <div class="page-header-btn"> | |
| 10 | + 搜索: | |
| 11 | + <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" | |
| 12 | + prefix-icon="el-icon-search" v-model="searchSrt" clearable></el-input> | |
| 10 | 13 | |
| 11 | - </div> | |
| 12 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> | |
| 13 | - <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem;" type="primary" @click="showDevice">返回</el-button> | |
| 14 | - 搜索: <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input> | |
| 14 | + 通道类型: | |
| 15 | + <el-select size="mini" @change="search" style="margin-right: 1rem;" v-model="channelType" placeholder="请选择" | |
| 16 | + default-first-option> | |
| 17 | + <el-option label="全部" value=""></el-option> | |
| 18 | + <el-option label="设备" value="false"></el-option> | |
| 19 | + <el-option label="子目录" value="true"></el-option> | |
| 20 | + </el-select> | |
| 21 | + 在线状态: | |
| 22 | + <el-select size="mini" style="margin-right: 1rem;" @change="search" v-model="online" placeholder="请选择" | |
| 23 | + default-first-option> | |
| 24 | + <el-option label="全部" value=""></el-option> | |
| 25 | + <el-option label="在线" value="true"></el-option> | |
| 26 | + <el-option label="离线" value="false"></el-option> | |
| 27 | + </el-select> | |
| 28 | + <el-checkbox size="mini" v-model="autoList" @change="autoListChange"> | |
| 29 | + 自动刷新 | |
| 30 | + </el-checkbox> | |
| 31 | + </div> | |
| 32 | + </div> | |
| 33 | + <devicePlayer ref="devicePlayer" v-loading="isLoging"></devicePlayer> | |
| 34 | + <!--设备列表--> | |
| 35 | + <el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" border style="width: 100%"> | |
| 36 | + <el-table-column prop="channelId" label="通道编号" width="200"> | |
| 37 | + </el-table-column> | |
| 38 | + <el-table-column prop="name" label="通道名称"> | |
| 39 | + </el-table-column> | |
| 40 | + <el-table-column label="快照" width="80" align="center"> | |
| 41 | + <template slot-scope="scope"> | |
| 42 | + <img style="max-height: 3rem;max-width: 4rem;" | |
| 43 | + :id="scope.row.deviceId + '_' + scope.row.channelId" | |
| 44 | + :src="getSnap(scope.row)" | |
| 45 | + @error="getSnapErrorEvent($event.target.id)" | |
| 46 | + alt=""> | |
| 47 | + <!-- <el-image--> | |
| 48 | + <!-- :id="'snapImg_' + scope.row.deviceId + '_' + scope.row.channelId"--> | |
| 49 | + <!-- :src="getSnap(scope.row)"--> | |
| 50 | + <!-- @error="getSnapErrorEvent($event, scope.row)"--> | |
| 51 | + <!-- :fit="'contain'">--> | |
| 52 | + <!-- <div slot="error" class="image-slot">--> | |
| 53 | + <!-- <i class="el-icon-picture-outline"></i>--> | |
| 54 | + <!-- </div>--> | |
| 55 | + <!-- </el-image>--> | |
| 56 | + </template> | |
| 57 | + </el-table-column> | |
| 58 | + <el-table-column prop="subCount" label="子节点数"> | |
| 59 | + </el-table-column> | |
| 60 | + <el-table-column prop="manufacture" label="厂家"> | |
| 61 | + </el-table-column> | |
| 62 | + <el-table-column label="位置信息" align="center"> | |
| 63 | + <template slot-scope="scope"> | |
| 64 | + <span>{{ scope.row.longitude }},{{ scope.row.latitude }}</span> | |
| 65 | + </template> | |
| 66 | + </el-table-column> | |
| 67 | + <el-table-column prop="ptztypeText" label="云台类型"/> | |
| 68 | + <el-table-column label="开启音频" align="center"> | |
| 69 | + <template slot-scope="scope"> | |
| 70 | + <el-switch @change="updateChannel(scope.row)" v-model="scope.row.hasAudio" active-color="#409EFF"> | |
| 71 | + </el-switch> | |
| 72 | + </template> | |
| 73 | + </el-table-column> | |
| 74 | + <el-table-column label="状态" width="180" align="center"> | |
| 75 | + <template slot-scope="scope"> | |
| 76 | + <div slot="reference" class="name-wrapper"> | |
| 77 | + <el-tag size="medium" v-if="scope.row.status == 1">开启</el-tag> | |
| 78 | + <el-tag size="medium" type="info" v-if="scope.row.status == 0">关闭</el-tag> | |
| 79 | + </div> | |
| 80 | + </template> | |
| 81 | + </el-table-column> | |
| 15 | 82 | |
| 16 | - 通道类型: <el-select size="mini" @change="search" style="margin-right: 1rem;" v-model="channelType" placeholder="请选择" default-first-option> | |
| 17 | - <el-option label="全部" value=""></el-option> | |
| 18 | - <el-option label="设备" value="false"></el-option> | |
| 19 | - <el-option label="子目录" value="true"></el-option> | |
| 20 | - </el-select> | |
| 21 | - 在线状态: <el-select size="mini" style="margin-right: 1rem;" @change="search" v-model="online" placeholder="请选择" default-first-option> | |
| 22 | - <el-option label="全部" value=""></el-option> | |
| 23 | - <el-option label="在线" value="true"></el-option> | |
| 24 | - <el-option label="离线" value="false"></el-option> | |
| 25 | - </el-select> | |
| 26 | - <el-checkbox size="mini" style="margin-right: 1rem; float: right;" v-model="autoList" @change="autoListChange">自动刷新</el-checkbox> | |
| 27 | - </div> | |
| 28 | - <devicePlayer ref="devicePlayer" v-loading="isLoging"></devicePlayer> | |
| 29 | - <!--设备列表--> | |
| 30 | - <el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" border style="width: 100%"> | |
| 31 | - <el-table-column prop="channelId" label="通道编号" width="200"> | |
| 32 | - </el-table-column> | |
| 33 | - <el-table-column prop="name" label="通道名称"> | |
| 34 | - </el-table-column> | |
| 35 | - <el-table-column label="快照" width="80" align="center"> | |
| 36 | - <template slot-scope="scope"> | |
| 37 | - <img style="max-height: 3rem;max-width: 4rem;" | |
| 38 | - :id="scope.row.deviceId + '_' + scope.row.channelId" | |
| 39 | - :src="getSnap(scope.row)" | |
| 40 | - @error="getSnapErrorEvent($event.target.id)" | |
| 41 | - alt=""> | |
| 42 | -<!-- <el-image--> | |
| 43 | -<!-- :id="'snapImg_' + scope.row.deviceId + '_' + scope.row.channelId"--> | |
| 44 | -<!-- :src="getSnap(scope.row)"--> | |
| 45 | -<!-- @error="getSnapErrorEvent($event, scope.row)"--> | |
| 46 | -<!-- :fit="'contain'">--> | |
| 47 | -<!-- <div slot="error" class="image-slot">--> | |
| 48 | -<!-- <i class="el-icon-picture-outline"></i>--> | |
| 49 | -<!-- </div>--> | |
| 50 | -<!-- </el-image>--> | |
| 51 | - </template> | |
| 52 | - </el-table-column> | |
| 53 | - <el-table-column prop="subCount" label="子节点数"> | |
| 54 | - </el-table-column> | |
| 55 | - <el-table-column prop="manufacture" label="厂家"> | |
| 56 | - </el-table-column> | |
| 57 | - <el-table-column label="位置信息" align="center"> | |
| 58 | - <template slot-scope="scope"> | |
| 59 | - <span>{{scope.row.longitude}},{{scope.row.latitude}}</span> | |
| 60 | - </template> | |
| 61 | - </el-table-column> | |
| 62 | - <el-table-column prop="ptztypeText" label="云台类型"/> | |
| 63 | - <el-table-column label="开启音频" align="center"> | |
| 64 | - <template slot-scope="scope"> | |
| 65 | - <el-switch @change="updateChannel(scope.row)" v-model="scope.row.hasAudio" active-color="#409EFF"> | |
| 66 | - </el-switch> | |
| 67 | - </template> | |
| 68 | - </el-table-column> | |
| 69 | - <el-table-column label="状态" width="180" align="center"> | |
| 70 | - <template slot-scope="scope"> | |
| 71 | - <div slot="reference" class="name-wrapper"> | |
| 72 | - <el-tag size="medium" v-if="scope.row.status == 1">开启</el-tag> | |
| 73 | - <el-tag size="medium" type="info" v-if="scope.row.status == 0">关闭</el-tag> | |
| 74 | - </div> | |
| 75 | - </template> | |
| 76 | - </el-table-column> | |
| 77 | 83 | |
| 78 | - | |
| 79 | - <el-table-column label="操作" width="280" align="center" fixed="right"> | |
| 80 | - <template slot-scope="scope"> | |
| 81 | - <el-button-group> | |
| 82 | - <!-- <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">播放</el-button> --> | |
| 83 | - <el-button size="mini" icon="el-icon-video-play" @click="sendDevicePush(scope.row)">播放</el-button> | |
| 84 | - <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="!!scope.row.streamId" @click="stopDevicePush(scope.row)">停止</el-button> | |
| 85 | - <el-button size="mini" icon="el-icon-s-open" type="primary" v-if="scope.row.subCount > 0" @click="changeSubchannel(scope.row)">查看</el-button> | |
| 86 | - <el-button size="mini" icon="el-icon-video-camera" type="primary" @click="queryRecords(scope.row)">设备录象</el-button> | |
| 87 | - <!-- <el-button size="mini" @click="sendDevicePush(scope.row)">录像查询</el-button> --> | |
| 88 | - </el-button-group> | |
| 89 | - </template> | |
| 90 | - </el-table-column> | |
| 91 | - </el-table> | |
| 92 | - <el-pagination style="float: right" @size-change="handleSizeChange" @current-change="currentChange" :current-page="currentPage" :page-size="count" :page-sizes="[15, 20, 30, 50]" layout="total, sizes, prev, pager, next" :total="total"> | |
| 93 | - </el-pagination> | |
| 94 | - | |
| 95 | - </el-main> | |
| 96 | - </el-container> | |
| 97 | -</div> | |
| 84 | + <el-table-column label="操作" width="280" align="center" fixed="right"> | |
| 85 | + <template slot-scope="scope"> | |
| 86 | + <el-button-group> | |
| 87 | + <!-- <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">播放</el-button> --> | |
| 88 | + <el-button size="mini" icon="el-icon-video-play" @click="sendDevicePush(scope.row)">播放</el-button> | |
| 89 | + <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="!!scope.row.streamId" | |
| 90 | + @click="stopDevicePush(scope.row)">停止 | |
| 91 | + </el-button> | |
| 92 | + <el-button size="mini" icon="el-icon-s-open" type="primary" v-if="scope.row.subCount > 0" | |
| 93 | + @click="changeSubchannel(scope.row)">查看 | |
| 94 | + </el-button> | |
| 95 | + <el-button size="mini" icon="el-icon-video-camera" type="primary" @click="queryRecords(scope.row)">设备录象 | |
| 96 | + </el-button> | |
| 97 | + <!-- <el-button size="mini" @click="sendDevicePush(scope.row)">录像查询</el-button> --> | |
| 98 | + </el-button-group> | |
| 99 | + </template> | |
| 100 | + </el-table-column> | |
| 101 | + </el-table> | |
| 102 | + <el-pagination style="float: right" @size-change="handleSizeChange" @current-change="currentChange" | |
| 103 | + :current-page="currentPage" :page-size="count" :page-sizes="[15, 20, 30, 50]" | |
| 104 | + layout="total, sizes, prev, pager, next" :total="total"> | |
| 105 | + </el-pagination> | |
| 106 | + </div> | |
| 98 | 107 | </template> |
| 99 | 108 | |
| 100 | 109 | <script> |
| 101 | 110 | import devicePlayer from './dialog/devicePlayer.vue' |
| 102 | -import uiHeader from './UiHeader.vue' | |
| 111 | +import uiHeader from '../layout/UiHeader.vue' | |
| 103 | 112 | import moment from "moment"; |
| 113 | + | |
| 104 | 114 | export default { |
| 105 | - name: 'channelList', | |
| 106 | - components: { | |
| 107 | - devicePlayer, | |
| 108 | - uiHeader | |
| 109 | - }, | |
| 110 | - data() { | |
| 111 | - return { | |
| 112 | - deviceId: this.$route.params.deviceId, | |
| 113 | - parentChannelId: this.$route.params.parentChannelId, | |
| 114 | - deviceChannelList: [], | |
| 115 | - videoComponentList: [], | |
| 116 | - currentPlayerInfo: {}, //当前播放对象 | |
| 117 | - updateLooper: 0, //数据刷新轮训标志 | |
| 118 | - searchSrt: "", | |
| 119 | - channelType: "", | |
| 120 | - online: "", | |
| 121 | - winHeight: window.innerHeight - 250, | |
| 122 | - currentPage: parseInt(this.$route.params.page), | |
| 123 | - count: parseInt(this.$route.params.count), | |
| 124 | - total: 0, | |
| 125 | - beforeUrl: "/deviceList", | |
| 126 | - isLoging: false, | |
| 127 | - autoList: true, | |
| 128 | - loadSnap:{} | |
| 129 | - }; | |
| 115 | + name: 'channelList', | |
| 116 | + components: { | |
| 117 | + devicePlayer, | |
| 118 | + uiHeader | |
| 119 | + }, | |
| 120 | + data() { | |
| 121 | + return { | |
| 122 | + deviceId: this.$route.params.deviceId, | |
| 123 | + parentChannelId: this.$route.params.parentChannelId, | |
| 124 | + deviceChannelList: [], | |
| 125 | + videoComponentList: [], | |
| 126 | + currentPlayerInfo: {}, //当前播放对象 | |
| 127 | + updateLooper: 0, //数据刷新轮训标志 | |
| 128 | + searchSrt: "", | |
| 129 | + channelType: "", | |
| 130 | + online: "", | |
| 131 | + winHeight: window.innerHeight - 250, | |
| 132 | + currentPage: parseInt(this.$route.params.page), | |
| 133 | + count: parseInt(this.$route.params.count), | |
| 134 | + total: 0, | |
| 135 | + beforeUrl: "/deviceList", | |
| 136 | + isLoging: false, | |
| 137 | + autoList: true, | |
| 138 | + loadSnap: {} | |
| 139 | + }; | |
| 140 | + }, | |
| 141 | + | |
| 142 | + mounted() { | |
| 143 | + this.initData(); | |
| 144 | + if (this.autoList) { | |
| 145 | + this.updateLooper = setInterval(this.initData, 5000); | |
| 146 | + } | |
| 147 | + | |
| 148 | + }, | |
| 149 | + destroyed() { | |
| 150 | + this.$destroy('videojs'); | |
| 151 | + clearTimeout(this.updateLooper); | |
| 152 | + }, | |
| 153 | + methods: { | |
| 154 | + initData: function () { | |
| 155 | + if (typeof (this.parentChannelId) == "undefined" || this.parentChannelId == 0) { | |
| 156 | + this.getDeviceChannelList(); | |
| 157 | + } else { | |
| 158 | + this.showSubchannels(); | |
| 159 | + } | |
| 130 | 160 | }, |
| 161 | + initParam: function () { | |
| 162 | + this.deviceId = this.$route.params.deviceId; | |
| 163 | + this.parentChannelId = this.$route.params.parentChannelId; | |
| 164 | + this.currentPage = parseInt(this.$route.params.page); | |
| 165 | + this.count = parseInt(this.$route.params.count); | |
| 166 | + if (this.parentChannelId == "" || this.parentChannelId == 0) { | |
| 167 | + this.beforeUrl = "/deviceList" | |
| 168 | + } | |
| 131 | 169 | |
| 132 | - mounted() { | |
| 170 | + }, | |
| 171 | + currentChange: function (val) { | |
| 172 | + var url = `/${this.$router.currentRoute.name}/${this.deviceId}/${this.parentChannelId}/${this.count}/${val}` | |
| 173 | + this.$router.push(url).then(() => { | |
| 174 | + this.initParam(); | |
| 133 | 175 | this.initData(); |
| 134 | - if (this.autoList) { | |
| 135 | - this.updateLooper = setInterval(this.initData, 5000); | |
| 136 | - } | |
| 176 | + }) | |
| 177 | + }, | |
| 178 | + handleSizeChange: function (val) { | |
| 179 | + var url = `/${this.$router.currentRoute.name}/${this.$router.params.deviceId}/${this.$router.params.parentChannelId}/${val}/1` | |
| 180 | + this.$router.push(url).then(() => { | |
| 181 | + this.initParam(); | |
| 182 | + this.initData(); | |
| 183 | + }) | |
| 137 | 184 | |
| 138 | 185 | }, |
| 139 | - destroyed() { | |
| 140 | - this.$destroy('videojs'); | |
| 141 | - clearTimeout(this.updateLooper); | |
| 186 | + getDeviceChannelList: function () { | |
| 187 | + let that = this; | |
| 188 | + if (typeof (this.$route.params.deviceId) == "undefined") return; | |
| 189 | + this.$axios({ | |
| 190 | + method: 'get', | |
| 191 | + url: `/api/device/query/devices/${this.$route.params.deviceId}/channels`, | |
| 192 | + params: { | |
| 193 | + page: that.currentPage, | |
| 194 | + count: that.count, | |
| 195 | + query: that.searchSrt, | |
| 196 | + online: that.online, | |
| 197 | + channelType: that.channelType | |
| 198 | + } | |
| 199 | + }).then(function (res) { | |
| 200 | + that.total = res.data.total; | |
| 201 | + that.deviceChannelList = res.data.list; | |
| 202 | + // 防止出现表格错位 | |
| 203 | + that.$nextTick(() => { | |
| 204 | + that.$refs.channelListTable.doLayout(); | |
| 205 | + }) | |
| 206 | + }).catch(function (error) { | |
| 207 | + console.log(error); | |
| 208 | + }); | |
| 142 | 209 | }, |
| 143 | - methods: { | |
| 144 | - initData: function () { | |
| 145 | - if (typeof (this.parentChannelId) == "undefined" || this.parentChannelId == 0) { | |
| 146 | - this.getDeviceChannelList(); | |
| 147 | - } else { | |
| 148 | - this.showSubchannels(); | |
| 149 | - } | |
| 150 | - }, | |
| 151 | - initParam: function () { | |
| 152 | - this.deviceId = this.$route.params.deviceId; | |
| 153 | - this.parentChannelId = this.$route.params.parentChannelId; | |
| 154 | - this.currentPage = parseInt(this.$route.params.page); | |
| 155 | - this.count = parseInt(this.$route.params.count); | |
| 156 | - if (this.parentChannelId == "" || this.parentChannelId == 0) { | |
| 157 | - this.beforeUrl = "/deviceList" | |
| 158 | - } | |
| 159 | 210 | |
| 160 | - }, | |
| 161 | - currentChange: function (val) { | |
| 162 | - var url = `/${this.$router.currentRoute.name}/${this.deviceId}/${this.parentChannelId}/${this.count}/${val}` | |
| 163 | - this.$router.push(url).then(() => { | |
| 164 | - this.initParam(); | |
| 165 | - this.initData(); | |
| 166 | - }) | |
| 167 | - }, | |
| 168 | - handleSizeChange: function (val) { | |
| 169 | - var url = `/${this.$router.currentRoute.name}/${this.$router.params.deviceId}/${this.$router.params.parentChannelId}/${val}/1` | |
| 170 | - this.$router.push(url).then(() => { | |
| 171 | - this.initParam(); | |
| 172 | - this.initData(); | |
| 173 | - }) | |
| 211 | + //通知设备上传媒体流 | |
| 212 | + sendDevicePush: function (itemData) { | |
| 213 | + let deviceId = this.deviceId; | |
| 214 | + this.isLoging = true; | |
| 215 | + let channelId = itemData.channelId; | |
| 216 | + console.log("通知设备推流1:" + deviceId + " : " + channelId); | |
| 217 | + let that = this; | |
| 218 | + this.$axios({ | |
| 219 | + method: 'get', | |
| 220 | + url: '/api/play/start/' + deviceId + '/' + channelId | |
| 221 | + }).then(function (res) { | |
| 222 | + that.isLoging = false; | |
| 223 | + if (res.data.code === 0) { | |
| 174 | 224 | |
| 175 | - }, | |
| 176 | - getDeviceChannelList: function () { | |
| 177 | - let that = this; | |
| 178 | - if (typeof (this.$route.params.deviceId) == "undefined") return; | |
| 179 | - this.$axios({ | |
| 180 | - method: 'get', | |
| 181 | - url: `/api/device/query/devices/${this.$route.params.deviceId}/channels`, | |
| 182 | - params:{ | |
| 183 | - page: that.currentPage, | |
| 184 | - count: that.count, | |
| 185 | - query: that.searchSrt, | |
| 186 | - online: that.online, | |
| 187 | - channelType: that.channelType | |
| 188 | - } | |
| 189 | - }).then(function (res) { | |
| 190 | - that.total = res.data.total; | |
| 191 | - that.deviceChannelList = res.data.list; | |
| 192 | - // 防止出现表格错位 | |
| 193 | - that.$nextTick(() => { | |
| 194 | - that.$refs.channelListTable.doLayout(); | |
| 195 | - }) | |
| 196 | - }).catch(function (error) { | |
| 197 | - console.log(error); | |
| 198 | - }); | |
| 199 | - }, | |
| 225 | + setTimeout(() => { | |
| 200 | 226 | |
| 201 | - //通知设备上传媒体流 | |
| 202 | - sendDevicePush: function (itemData) { | |
| 203 | - let deviceId = this.deviceId; | |
| 204 | - this.isLoging = true; | |
| 205 | - let channelId = itemData.channelId; | |
| 206 | - console.log("通知设备推流1:" + deviceId + " : " + channelId ); | |
| 207 | - let that = this; | |
| 208 | - this.$axios({ | |
| 209 | - method: 'get', | |
| 210 | - url: '/api/play/start/' + deviceId + '/' + channelId | |
| 211 | - }).then(function (res) { | |
| 212 | - that.isLoging = false; | |
| 213 | - if (res.data.code === 0) { | |
| 227 | + let snapId = deviceId + "_" + channelId; | |
| 228 | + that.loadSnap[snapId] = 0; | |
| 229 | + that.getSnapErrorEvent(snapId) | |
| 230 | + }, 5000) | |
| 231 | + that.$refs.devicePlayer.openDialog("media", deviceId, channelId, { | |
| 232 | + streamInfo: res.data.data, | |
| 233 | + hasAudio: itemData.hasAudio | |
| 234 | + }); | |
| 235 | + setTimeout(() => { | |
| 236 | + that.initData(); | |
| 237 | + }, 1000) | |
| 214 | 238 | |
| 215 | - setTimeout(()=>{ | |
| 216 | - | |
| 217 | - let snapId = deviceId + "_" + channelId; | |
| 218 | - that.loadSnap[snapId] = 0; | |
| 219 | - that.getSnapErrorEvent(snapId) | |
| 220 | - },5000) | |
| 221 | - that.$refs.devicePlayer.openDialog("media", deviceId, channelId, { | |
| 222 | - streamInfo: res.data.data, | |
| 223 | - hasAudio: itemData.hasAudio | |
| 224 | - }); | |
| 225 | - setTimeout(()=>{ | |
| 226 | - that.initData(); | |
| 227 | - },1000) | |
| 228 | - | |
| 229 | - }else { | |
| 230 | - that.$message.error(res.data.msg); | |
| 231 | - } | |
| 232 | - }).catch(function (e) {}); | |
| 233 | - }, | |
| 234 | - queryRecords: function (itemData) { | |
| 235 | - var format = moment().format("YYYY-M-D"); | |
| 236 | - let deviceId = this.deviceId; | |
| 237 | - let channelId = itemData.channelId; | |
| 238 | - this.$refs.devicePlayer.openDialog("record", deviceId, channelId, {date: format}) | |
| 239 | - }, | |
| 240 | - stopDevicePush: function (itemData) { | |
| 241 | - var that = this; | |
| 242 | - this.$axios({ | |
| 243 | - method: 'get', | |
| 244 | - url: '/api/play/stop/' + this.deviceId + "/" + itemData.channelId | |
| 245 | - }).then(function (res) { | |
| 246 | - that.initData(); | |
| 247 | - }).catch(function (error) { | |
| 248 | - if (error.response.status === 402) { // 已经停止过 | |
| 249 | - that.initData(); | |
| 250 | - }else { | |
| 251 | - console.log(error) | |
| 252 | - } | |
| 253 | - }); | |
| 254 | - }, | |
| 255 | - getSnap: function (row){ | |
| 256 | - return '/static/snap/' + row.deviceId + '_' + row.channelId + '.jpg' | |
| 257 | - }, | |
| 258 | - getSnapErrorEvent: function (id){ | |
| 239 | + } else { | |
| 240 | + that.$message.error(res.data.msg); | |
| 241 | + } | |
| 242 | + }).catch(function (e) { | |
| 243 | + }); | |
| 244 | + }, | |
| 245 | + queryRecords: function (itemData) { | |
| 246 | + var format = moment().format("YYYY-M-D"); | |
| 247 | + let deviceId = this.deviceId; | |
| 248 | + let channelId = itemData.channelId; | |
| 249 | + this.$refs.devicePlayer.openDialog("record", deviceId, channelId, {date: format}) | |
| 250 | + }, | |
| 251 | + stopDevicePush: function (itemData) { | |
| 252 | + var that = this; | |
| 253 | + this.$axios({ | |
| 254 | + method: 'get', | |
| 255 | + url: '/api/play/stop/' + this.deviceId + "/" + itemData.channelId | |
| 256 | + }).then(function (res) { | |
| 257 | + that.initData(); | |
| 258 | + }).catch(function (error) { | |
| 259 | + if (error.response.status === 402) { // 已经停止过 | |
| 260 | + that.initData(); | |
| 261 | + } else { | |
| 262 | + console.log(error) | |
| 263 | + } | |
| 264 | + }); | |
| 265 | + }, | |
| 266 | + getSnap: function (row) { | |
| 267 | + return '/static/snap/' + row.deviceId + '_' + row.channelId + '.jpg' | |
| 268 | + }, | |
| 269 | + getSnapErrorEvent: function (id) { | |
| 259 | 270 | |
| 260 | - if (typeof (this.loadSnap[id]) != "undefined") { | |
| 261 | - console.log("下载截图" + this.loadSnap[id]) | |
| 262 | - if (this.loadSnap[id] > 5) { | |
| 263 | - delete this.loadSnap[id]; | |
| 264 | - return; | |
| 265 | - } | |
| 266 | - setTimeout(()=>{ | |
| 267 | - this.loadSnap[id] ++ | |
| 268 | - document.getElementById(id).setAttribute("src", '/static/snap/' + id + '.jpg?' + new Date().getTime()) | |
| 269 | - },1000) | |
| 271 | + if (typeof (this.loadSnap[id]) != "undefined") { | |
| 272 | + console.log("下载截图" + this.loadSnap[id]) | |
| 273 | + if (this.loadSnap[id] > 5) { | |
| 274 | + delete this.loadSnap[id]; | |
| 275 | + return; | |
| 276 | + } | |
| 277 | + setTimeout(() => { | |
| 278 | + this.loadSnap[id]++ | |
| 279 | + document.getElementById(id).setAttribute("src", '/static/snap/' + id + '.jpg?' + new Date().getTime()) | |
| 280 | + }, 1000) | |
| 270 | 281 | |
| 271 | - } | |
| 272 | - }, | |
| 273 | - showDevice: function () { | |
| 274 | - this.$router.push(this.beforeUrl).then(() => { | |
| 275 | - this.initParam(); | |
| 276 | - this.initData(); | |
| 277 | - }) | |
| 278 | - }, | |
| 279 | - changeSubchannel(itemData) { | |
| 280 | - this.beforeUrl = this.$router.currentRoute.path; | |
| 282 | + } | |
| 283 | + }, | |
| 284 | + showDevice: function () { | |
| 285 | + this.$router.push(this.beforeUrl).then(() => { | |
| 286 | + this.initParam(); | |
| 287 | + this.initData(); | |
| 288 | + }) | |
| 289 | + }, | |
| 290 | + changeSubchannel(itemData) { | |
| 291 | + this.beforeUrl = this.$router.currentRoute.path; | |
| 281 | 292 | |
| 282 | - var url = `/${this.$router.currentRoute.name}/${this.$router.currentRoute.params.deviceId}/${itemData.channelId}/${this.$router.currentRoute.params.count}/1` | |
| 283 | - this.$router.push(url).then(() => { | |
| 284 | - this.searchSrt = ""; | |
| 285 | - this.channelType = ""; | |
| 286 | - this.online = ""; | |
| 287 | - this.initParam(); | |
| 288 | - this.initData(); | |
| 289 | - }) | |
| 290 | - }, | |
| 291 | - showSubchannels: function (channelId) { | |
| 292 | - let that = this; | |
| 293 | + var url = `/${this.$router.currentRoute.name}/${this.$router.currentRoute.params.deviceId}/${itemData.channelId}/${this.$router.currentRoute.params.count}/1` | |
| 294 | + this.$router.push(url).then(() => { | |
| 295 | + this.searchSrt = ""; | |
| 296 | + this.channelType = ""; | |
| 297 | + this.online = ""; | |
| 298 | + this.initParam(); | |
| 299 | + this.initData(); | |
| 300 | + }) | |
| 301 | + }, | |
| 302 | + showSubchannels: function (channelId) { | |
| 303 | + let that = this; | |
| 293 | 304 | |
| 294 | - this.$axios({ | |
| 295 | - method: 'get', | |
| 296 | - url:`/api/device/query/sub_channels/${this.deviceId}/${this.parentChannelId}/channels`, | |
| 297 | - params: { | |
| 298 | - page: that.currentPage, | |
| 299 | - count: that.count, | |
| 300 | - query: that.searchSrt, | |
| 301 | - online: that.online, | |
| 302 | - channelType: that.channelType | |
| 303 | - } | |
| 304 | - }).then(function (res) { | |
| 305 | - that.total = res.data.total; | |
| 306 | - that.deviceChannelList = res.data.list; | |
| 307 | - // 防止出现表格错位 | |
| 308 | - that.$nextTick(() => { | |
| 309 | - that.$refs.channelListTable.doLayout(); | |
| 310 | - }) | |
| 311 | - }).catch(function (error) { | |
| 312 | - console.log(error); | |
| 313 | - }); | |
| 314 | - }, | |
| 315 | - search: function () { | |
| 316 | - this.currentPage = 1; | |
| 317 | - this.total = 0; | |
| 318 | - this.initData(); | |
| 319 | - }, | |
| 320 | - updateChannel: function (row) { | |
| 321 | - this.$axios({ | |
| 322 | - method: 'post', | |
| 323 | - url: `/api/device/query/channel/update/${this.deviceId}`, | |
| 324 | - params: row | |
| 325 | - }).then(function (res) { | |
| 326 | - console.log(JSON.stringify(res)); | |
| 327 | - }); | |
| 328 | - }, | |
| 329 | - autoListChange: function () { | |
| 330 | - if (this.autoList) { | |
| 331 | - this.updateLooper = setInterval(this.initData, 1500); | |
| 332 | - }else{ | |
| 333 | - window.clearInterval(this.updateLooper); | |
| 334 | - } | |
| 305 | + this.$axios({ | |
| 306 | + method: 'get', | |
| 307 | + url: `/api/device/query/sub_channels/${this.deviceId}/${this.parentChannelId}/channels`, | |
| 308 | + params: { | |
| 309 | + page: that.currentPage, | |
| 310 | + count: that.count, | |
| 311 | + query: that.searchSrt, | |
| 312 | + online: that.online, | |
| 313 | + channelType: that.channelType | |
| 335 | 314 | } |
| 336 | - | |
| 315 | + }).then(function (res) { | |
| 316 | + that.total = res.data.total; | |
| 317 | + that.deviceChannelList = res.data.list; | |
| 318 | + // 防止出现表格错位 | |
| 319 | + that.$nextTick(() => { | |
| 320 | + that.$refs.channelListTable.doLayout(); | |
| 321 | + }) | |
| 322 | + }).catch(function (error) { | |
| 323 | + console.log(error); | |
| 324 | + }); | |
| 325 | + }, | |
| 326 | + search: function () { | |
| 327 | + this.currentPage = 1; | |
| 328 | + this.total = 0; | |
| 329 | + this.initData(); | |
| 330 | + }, | |
| 331 | + updateChannel: function (row) { | |
| 332 | + this.$axios({ | |
| 333 | + method: 'post', | |
| 334 | + url: `/api/device/query/channel/update/${this.deviceId}`, | |
| 335 | + params: row | |
| 336 | + }).then(function (res) { | |
| 337 | + console.log(JSON.stringify(res)); | |
| 338 | + }); | |
| 339 | + }, | |
| 340 | + autoListChange: function () { | |
| 341 | + if (this.autoList) { | |
| 342 | + this.updateLooper = setInterval(this.initData, 1500); | |
| 343 | + } else { | |
| 344 | + window.clearInterval(this.updateLooper); | |
| 345 | + } | |
| 337 | 346 | } |
| 347 | + | |
| 348 | + } | |
| 338 | 349 | }; |
| 339 | 350 | </script> |
| 340 | 351 | |
| 341 | 352 | <style> |
| 342 | 353 | .videoList { |
| 343 | - display: flex; | |
| 344 | - flex-wrap: wrap; | |
| 345 | - align-content: flex-start; | |
| 354 | + display: flex; | |
| 355 | + flex-wrap: wrap; | |
| 356 | + align-content: flex-start; | |
| 346 | 357 | } |
| 347 | 358 | |
| 348 | 359 | .video-item { |
| 349 | - position: relative; | |
| 350 | - width: 15rem; | |
| 351 | - height: 10rem; | |
| 352 | - margin-right: 1rem; | |
| 353 | - background-color: #000000; | |
| 360 | + position: relative; | |
| 361 | + width: 15rem; | |
| 362 | + height: 10rem; | |
| 363 | + margin-right: 1rem; | |
| 364 | + background-color: #000000; | |
| 354 | 365 | } |
| 355 | 366 | |
| 356 | 367 | .video-item-img { |
| 357 | - position: absolute; | |
| 358 | - top: 0; | |
| 359 | - bottom: 0; | |
| 360 | - left: 0; | |
| 361 | - right: 0; | |
| 362 | - margin: auto; | |
| 363 | - width: 100%; | |
| 364 | - height: 100%; | |
| 368 | + position: absolute; | |
| 369 | + top: 0; | |
| 370 | + bottom: 0; | |
| 371 | + left: 0; | |
| 372 | + right: 0; | |
| 373 | + margin: auto; | |
| 374 | + width: 100%; | |
| 375 | + height: 100%; | |
| 365 | 376 | } |
| 366 | 377 | |
| 367 | 378 | .video-item-img:after { |
| 368 | - content: ""; | |
| 369 | - display: inline-block; | |
| 370 | - position: absolute; | |
| 371 | - z-index: 2; | |
| 372 | - top: 0; | |
| 373 | - bottom: 0; | |
| 374 | - left: 0; | |
| 375 | - right: 0; | |
| 376 | - margin: auto; | |
| 377 | - width: 3rem; | |
| 378 | - height: 3rem; | |
| 379 | - background-image: url("../assets/loading.png"); | |
| 380 | - background-size: cover; | |
| 381 | - background-color: #000000; | |
| 379 | + content: ""; | |
| 380 | + display: inline-block; | |
| 381 | + position: absolute; | |
| 382 | + z-index: 2; | |
| 383 | + top: 0; | |
| 384 | + bottom: 0; | |
| 385 | + left: 0; | |
| 386 | + right: 0; | |
| 387 | + margin: auto; | |
| 388 | + width: 3rem; | |
| 389 | + height: 3rem; | |
| 390 | + background-image: url("../assets/loading.png"); | |
| 391 | + background-size: cover; | |
| 392 | + background-color: #000000; | |
| 382 | 393 | } |
| 383 | 394 | |
| 384 | 395 | .video-item-title { |
| 385 | - position: absolute; | |
| 386 | - bottom: 0; | |
| 387 | - color: #000000; | |
| 388 | - background-color: #ffffff; | |
| 389 | - line-height: 1.5rem; | |
| 390 | - padding: 0.3rem; | |
| 391 | - width: 14.4rem; | |
| 396 | + position: absolute; | |
| 397 | + bottom: 0; | |
| 398 | + color: #000000; | |
| 399 | + background-color: #ffffff; | |
| 400 | + line-height: 1.5rem; | |
| 401 | + padding: 0.3rem; | |
| 402 | + width: 14.4rem; | |
| 392 | 403 | } |
| 393 | 404 | </style> | ... | ... |
web_src/src/components/control.vue
| 1 | 1 | <template> |
| 2 | -<div id="app"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: bold;">控制台</span> | |
| 10 | - <div style="position: absolute; right: 17rem; top: 0.3rem;"> | |
| 11 | - 节点选择: <el-select size="mini" @change="chooseMediaChange" style="width: 18rem; margin-right: 8rem;" v-model="mediaServerChoose" placeholder="请选择" default-first-option> | |
| 12 | - <el-option | |
| 13 | - v-for="item in mediaServerList" | |
| 14 | - :key="item.id" | |
| 15 | - :label="item.id + '( ' + item.streamIp + ' )'" | |
| 16 | - :value="item.id"> | |
| 17 | - </el-option> | |
| 18 | - </el-select> | |
| 19 | - <span >{{loadCount}}</span> | |
| 20 | - </div> | |
| 21 | - <div style="position: absolute; right: 1rem; top: 0.3rem;"> | |
| 22 | - <el-popover placement="bottom" width="900" height="300" trigger="click"> | |
| 23 | - <div style="height: 600px; overflow:auto; padding: 20px"> | |
| 24 | - <el-descriptions v-for="(value, key, index) in serverConfig" :key="key" border :column="1" style="margin-bottom: 1rem"> | |
| 25 | - <template slot="title"> | |
| 26 | - {{key}} | |
| 27 | - </template> | |
| 28 | - <el-descriptions-item v-for="(value1, key1, index1) in serverConfig[key]" :key="key1"> | |
| 29 | - <template slot="label" > | |
| 30 | - {{ getMediaKeyNameFromKey(key1) }} | |
| 31 | - </template> | |
| 32 | - {{ value1 }} | |
| 33 | - </el-descriptions-item> | |
| 34 | - </el-descriptions> | |
| 35 | - </div> | |
| 36 | - <el-button type="primary" slot="reference" size="mini" @click="getServerConfig()">媒体服务器配置</el-button> | |
| 37 | - </el-popover> | |
| 38 | - <el-popover placement="bottom" width="900" height="300" trigger="click"> | |
| 39 | - <div style="height: 600px;overflow:auto; padding: 20px"> | |
| 40 | - <el-descriptions title="国标配置" border :column="1"> | |
| 41 | - <template slot="extra"> | |
| 42 | - <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="点击拷贝" v-clipboard="JSON.stringify(wvpServerConfig.sip)|| ''" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></el-button> | |
| 43 | - </template> | |
| 44 | - <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.sip"> | |
| 45 | - <template slot="label"> | |
| 46 | - {{ getNameFromKey(key) }} | |
| 47 | - </template> | |
| 48 | - {{ value }} | |
| 49 | - </el-descriptions-item> | |
| 50 | - </el-descriptions> | |
| 2 | + <div id="app" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title">控制台</div> | |
| 5 | + <div class="page-header-btn"> | |
| 6 | + 节点选择: | |
| 7 | + <el-select size="mini" @change="chooseMediaChange" style="width: 18rem; margin-right: 8rem;" | |
| 8 | + v-model="mediaServerChoose" placeholder="请选择" default-first-option> | |
| 9 | + <el-option | |
| 10 | + v-for="item in mediaServerList" | |
| 11 | + :key="item.id" | |
| 12 | + :label="item.id + '( ' + item.streamIp + ' )'" | |
| 13 | + :value="item.id"> | |
| 14 | + </el-option> | |
| 15 | + </el-select> | |
| 16 | + <span>{{ loadCount }}</span> | |
| 17 | + </div> | |
| 18 | + <div class="page-header-btn"> | |
| 19 | + <el-popover placement="bottom" width="900" height="300" trigger="click"> | |
| 20 | + <div style="height: 600px; overflow:auto; padding: 20px"> | |
| 21 | + <el-descriptions v-for="(value, key, index) in serverConfig" :key="key" border :column="1" | |
| 22 | + style="margin-bottom: 1rem"> | |
| 23 | + <template slot="title"> | |
| 24 | + {{ key }} | |
| 25 | + </template> | |
| 26 | + <el-descriptions-item v-for="(value1, key1, index1) in serverConfig[key]" :key="key1"> | |
| 27 | + <template slot="label"> | |
| 28 | + {{ getMediaKeyNameFromKey(key1) }} | |
| 29 | + </template> | |
| 30 | + {{ value1 }} | |
| 31 | + </el-descriptions-item> | |
| 32 | + </el-descriptions> | |
| 33 | + </div> | |
| 34 | + <el-button type="primary" slot="reference" size="mini" @click="getServerConfig()">媒体服务器配置</el-button> | |
| 35 | + </el-popover> | |
| 36 | + <el-popover placement="bottom" width="900" height="300" trigger="click"> | |
| 37 | + <div style="height: 600px;overflow:auto; padding: 20px"> | |
| 38 | + <el-descriptions title="国标配置" border :column="1"> | |
| 39 | + <template slot="extra"> | |
| 40 | + <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="点击拷贝" | |
| 41 | + v-clipboard="JSON.stringify(wvpServerConfig.sip)|| ''" | |
| 42 | + @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></el-button> | |
| 43 | + </template> | |
| 44 | + <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.sip" :key="key"> | |
| 45 | + <template slot="label"> | |
| 46 | + {{ getNameFromKey(key) }} | |
| 47 | + </template> | |
| 48 | + {{ value }} | |
| 49 | + </el-descriptions-item> | |
| 50 | + </el-descriptions> | |
| 51 | 51 | |
| 52 | - <div style="margin-top: 1rem"> | |
| 53 | - <el-descriptions title="基础配置" border :column="1"> | |
| 54 | - <template slot="extra"> | |
| 55 | - <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="点击拷贝" v-clipboard="JSON.stringify(wvpServerConfig.base)|| ''" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></el-button> | |
| 56 | - </template> | |
| 57 | - <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.base" :key="key"> | |
| 58 | - <template slot="label" > | |
| 59 | - {{ getNameFromKey(key) }} | |
| 60 | - </template> | |
| 61 | - <div v-if="key === 'interfaceAuthenticationExcludes'"> | |
| 62 | - <el-dropdown> | |
| 52 | + <div style="margin-top: 1rem"> | |
| 53 | + <el-descriptions title="基础配置" border :column="1"> | |
| 54 | + <template slot="extra"> | |
| 55 | + <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="点击拷贝" | |
| 56 | + v-clipboard="JSON.stringify(wvpServerConfig.base)|| ''" | |
| 57 | + @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></el-button> | |
| 58 | + </template> | |
| 59 | + <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.base" :key="key"> | |
| 60 | + <template slot="label"> | |
| 61 | + {{ getNameFromKey(key) }} | |
| 62 | + </template> | |
| 63 | + <div v-if="key === 'interfaceAuthenticationExcludes'"> | |
| 64 | + <el-dropdown> | |
| 63 | 65 | <span class="el-dropdown-link"> |
| 64 | 66 | 查看<i class="el-icon-arrow-down el-icon--right"></i> |
| 65 | 67 | </span> |
| 66 | - <el-dropdown-menu slot="dropdown"> | |
| 67 | - <el-dropdown-item v-for="(value, key, index) in wvpServerConfig.base.interfaceAuthenticationExcludes" :key="key">{{value}}</el-dropdown-item> | |
| 68 | - </el-dropdown-menu> | |
| 69 | - </el-dropdown> | |
| 70 | - </div> | |
| 71 | - <div v-if="key !== 'interfaceAuthenticationExcludes'"> | |
| 72 | - <div v-if="value === true"> | |
| 73 | - 已启用 | |
| 74 | - </div> | |
| 75 | - <div v-if="value === false"> | |
| 76 | - 未启用 | |
| 77 | - </div> | |
| 78 | - <div v-if="value !== true && value !== false"> | |
| 79 | - {{ value }} | |
| 80 | - </div> | |
| 81 | - </div> | |
| 68 | + <el-dropdown-menu slot="dropdown"> | |
| 69 | + <el-dropdown-item | |
| 70 | + v-for="(value, key, index) in wvpServerConfig.base.interfaceAuthenticationExcludes" | |
| 71 | + :key="key">{{ value }} | |
| 72 | + </el-dropdown-item> | |
| 73 | + </el-dropdown-menu> | |
| 74 | + </el-dropdown> | |
| 75 | + </div> | |
| 76 | + <div v-if="key !== 'interfaceAuthenticationExcludes'"> | |
| 77 | + <div v-if="value === true"> | |
| 78 | + 已启用 | |
| 79 | + </div> | |
| 80 | + <div v-if="value === false"> | |
| 81 | + 未启用 | |
| 82 | + </div> | |
| 83 | + <div v-if="value !== true && value !== false"> | |
| 84 | + {{ value }} | |
| 85 | + </div> | |
| 86 | + </div> | |
| 82 | 87 | |
| 83 | - </el-descriptions-item> | |
| 84 | - </el-descriptions> | |
| 85 | - </div> | |
| 86 | - <div style="margin-top: 1rem"> | |
| 87 | - <el-descriptions title="版本信息" border :column="1"> | |
| 88 | - <template slot="extra"> | |
| 89 | - <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="点击拷贝" v-clipboard="JSON.stringify(wvpServerVersion) || ''" @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></el-button> | |
| 90 | - </template> | |
| 91 | - <el-descriptions-item v-for="(value, key, index) in wvpServerVersion" :key="key"> | |
| 92 | - <template slot="label"> | |
| 93 | - {{ getNameFromKey(key) }} | |
| 94 | - </template> | |
| 95 | - {{ value }} | |
| 96 | - </el-descriptions-item> | |
| 97 | - </el-descriptions> | |
| 88 | + </el-descriptions-item> | |
| 89 | + </el-descriptions> | |
| 90 | + </div> | |
| 91 | + <div style="margin-top: 1rem"> | |
| 92 | + <el-descriptions title="版本信息" border :column="1"> | |
| 93 | + <template slot="extra"> | |
| 94 | + <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="点击拷贝" | |
| 95 | + v-clipboard="JSON.stringify(wvpServerVersion) || ''" | |
| 96 | + @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></el-button> | |
| 97 | + </template> | |
| 98 | + <el-descriptions-item v-for="(value, key, index) in wvpServerVersion" :key="key"> | |
| 99 | + <template slot="label"> | |
| 100 | + {{ getNameFromKey(key) }} | |
| 101 | + </template> | |
| 102 | + {{ value }} | |
| 103 | + </el-descriptions-item> | |
| 104 | + </el-descriptions> | |
| 98 | 105 | |
| 99 | 106 | |
| 100 | - </div> | |
| 101 | - </div> | |
| 102 | - <el-button type="primary" slot="reference" size="mini" @click="getWVPServerConfig()">信令服务器配置</el-button> | |
| 103 | - </el-popover> | |
| 104 | - <el-button style="margin-left: 1rem;" type="danger" size="mini" @click="reStartServer()">重启媒体服务器</el-button> | |
| 105 | - </div> | |
| 106 | 107 | </div> |
| 107 | - <el-row :gutter="30"> | |
| 108 | - <el-col :span="12"> | |
| 109 | - <div class="control-table" id="ThreadsLoad">table1</div> | |
| 110 | - </el-col> | |
| 111 | - <el-col :span="12"> | |
| 112 | - <div class="control-table" id="WorkThreadsLoad">table2</div> | |
| 113 | - </el-col> | |
| 114 | - </el-row> | |
| 115 | - <el-table :data="allSessionData" style="margin-top: 1rem;"> | |
| 116 | - <el-table-column prop="peer_ip" label="远端"></el-table-column> | |
| 117 | - <el-table-column prop="local_ip" label="本地"></el-table-column> | |
| 118 | - <el-table-column prop="typeid" label="类型"></el-table-column> | |
| 119 | - <el-table-column align="right"> | |
| 120 | - <template slot="header" slot-scope="scope"> | |
| 121 | - <el-button icon="el-icon-refresh-right" circle @click="getAllSession()"></el-button> | |
| 122 | - </template> | |
| 123 | - <template slot-scope="scope"> | |
| 124 | - <el-button @click.native.prevent="deleteRow(scope.$index, allSessionData)" type="text" size="small">移除</el-button> | |
| 125 | - </template> | |
| 126 | - </el-table-column> | |
| 127 | - </el-table> | |
| 108 | + </div> | |
| 109 | + <el-button type="primary" slot="reference" size="mini" @click="getWVPServerConfig()">信令服务器配置</el-button> | |
| 110 | + </el-popover> | |
| 111 | + <el-button style="margin-left: 1rem;" type="danger" size="mini" @click="reStartServer()">重启媒体服务器</el-button> | |
| 112 | + </div> | |
| 113 | + </div> | |
| 114 | + <!-- <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;">--> | |
| 115 | + <!-- <span style="font-size: 1rem; font-weight: bold;">控制台</span>--> | |
| 116 | + <!-- <div style="position: absolute; right: 17rem; top: 0.3rem;">--> | |
| 117 | + <!-- 节点选择:--> | |
| 118 | + <!-- <el-select size="mini" @change="chooseMediaChange" style="width: 18rem; margin-right: 8rem;"--> | |
| 119 | + <!-- v-model="mediaServerChoose" placeholder="请选择" default-first-option>--> | |
| 120 | + <!-- <el-option--> | |
| 121 | + <!-- v-for="item in mediaServerList"--> | |
| 122 | + <!-- :key="item.id"--> | |
| 123 | + <!-- :label="item.id + '( ' + item.streamIp + ' )'"--> | |
| 124 | + <!-- :value="item.id">--> | |
| 125 | + <!-- </el-option>--> | |
| 126 | + <!-- </el-select>--> | |
| 127 | + <!-- <span>{{ loadCount }}</span>--> | |
| 128 | + <!-- </div>--> | |
| 129 | + <!-- <div style="position: absolute; right: 1rem; top: 0.3rem;">--> | |
| 130 | + <!-- <el-popover placement="bottom" width="900" height="300" trigger="click">--> | |
| 131 | + <!-- <div style="height: 600px; overflow:auto; padding: 20px">--> | |
| 132 | + <!-- <el-descriptions v-for="(value, key, index) in serverConfig" :key="key" border :column="1"--> | |
| 133 | + <!-- style="margin-bottom: 1rem">--> | |
| 134 | + <!-- <template slot="title">--> | |
| 135 | + <!-- {{ key }}--> | |
| 136 | + <!-- </template>--> | |
| 137 | + <!-- <el-descriptions-item v-for="(value1, key1, index1) in serverConfig[key]" :key="key1">--> | |
| 138 | + <!-- <template slot="label">--> | |
| 139 | + <!-- {{ getMediaKeyNameFromKey(key1) }}--> | |
| 140 | + <!-- </template>--> | |
| 141 | + <!-- {{ value1 }}--> | |
| 142 | + <!-- </el-descriptions-item>--> | |
| 143 | + <!-- </el-descriptions>--> | |
| 144 | + <!-- </div>--> | |
| 145 | + <!-- <el-button type="primary" slot="reference" size="mini" @click="getServerConfig()">媒体服务器配置</el-button>--> | |
| 146 | + <!-- </el-popover>--> | |
| 147 | + <!-- <el-popover placement="bottom" width="900" height="300" trigger="click">--> | |
| 148 | + <!-- <div style="height: 600px;overflow:auto; padding: 20px">--> | |
| 149 | + <!-- <el-descriptions title="国标配置" border :column="1">--> | |
| 150 | + <!-- <template slot="extra">--> | |
| 151 | + <!-- <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="点击拷贝"--> | |
| 152 | + <!-- v-clipboard="JSON.stringify(wvpServerConfig.sip)|| ''"--> | |
| 153 | + <!-- @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></el-button>--> | |
| 154 | + <!-- </template>--> | |
| 155 | + <!-- <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.sip" :key="key">--> | |
| 156 | + <!-- <template slot="label">--> | |
| 157 | + <!-- {{ getNameFromKey(key) }}--> | |
| 158 | + <!-- </template>--> | |
| 159 | + <!-- {{ value }}--> | |
| 160 | + <!-- </el-descriptions-item>--> | |
| 161 | + <!-- </el-descriptions>--> | |
| 162 | + | |
| 163 | + <!-- <div style="margin-top: 1rem">--> | |
| 164 | + <!-- <el-descriptions title="基础配置" border :column="1">--> | |
| 165 | + <!-- <template slot="extra">--> | |
| 166 | + <!-- <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="点击拷贝"--> | |
| 167 | + <!-- v-clipboard="JSON.stringify(wvpServerConfig.base)|| ''"--> | |
| 168 | + <!-- @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></el-button>--> | |
| 169 | + <!-- </template>--> | |
| 170 | + <!-- <el-descriptions-item v-for="(value, key, index) in wvpServerConfig.base" :key="key">--> | |
| 171 | + <!-- <template slot="label">--> | |
| 172 | + <!-- {{ getNameFromKey(key) }}--> | |
| 173 | + <!-- </template>--> | |
| 174 | + <!-- <div v-if="key === 'interfaceAuthenticationExcludes'">--> | |
| 175 | + <!-- <el-dropdown>--> | |
| 176 | + <!-- <span class="el-dropdown-link">--> | |
| 177 | + <!-- 查看<i class="el-icon-arrow-down el-icon--right"></i>--> | |
| 178 | + <!-- </span>--> | |
| 179 | + <!-- <el-dropdown-menu slot="dropdown">--> | |
| 180 | + <!-- <el-dropdown-item--> | |
| 181 | + <!-- v-for="(value, key, index) in wvpServerConfig.base.interfaceAuthenticationExcludes"--> | |
| 182 | + <!-- :key="key">{{ value }}--> | |
| 183 | + <!-- </el-dropdown-item>--> | |
| 184 | + <!-- </el-dropdown-menu>--> | |
| 185 | + <!-- </el-dropdown>--> | |
| 186 | + <!-- </div>--> | |
| 187 | + <!-- <div v-if="key !== 'interfaceAuthenticationExcludes'">--> | |
| 188 | + <!-- <div v-if="value === true">--> | |
| 189 | + <!-- 已启用--> | |
| 190 | + <!-- </div>--> | |
| 191 | + <!-- <div v-if="value === false">--> | |
| 192 | + <!-- 未启用--> | |
| 193 | + <!-- </div>--> | |
| 194 | + <!-- <div v-if="value !== true && value !== false">--> | |
| 195 | + <!-- {{ value }}--> | |
| 196 | + <!-- </div>--> | |
| 197 | + <!-- </div>--> | |
| 128 | 198 | |
| 129 | - </el-main> | |
| 130 | - <!-- <el-footer style="position: absolute; bottom: 0; width: 100%;">ZLMediaKit-VUE_UI v1</el-footer> --> | |
| 131 | - </el-container> | |
| 199 | + <!-- </el-descriptions-item>--> | |
| 200 | + <!-- </el-descriptions>--> | |
| 201 | + <!-- </div>--> | |
| 202 | + <!-- <div style="margin-top: 1rem">--> | |
| 203 | + <!-- <el-descriptions title="版本信息" border :column="1">--> | |
| 204 | + <!-- <template slot="extra">--> | |
| 205 | + <!-- <el-button style="float: right;" type="primary" size="mini" icon="el-icon-document-copy" title="点击拷贝"--> | |
| 206 | + <!-- v-clipboard="JSON.stringify(wvpServerVersion) || ''"--> | |
| 207 | + <!-- @success="$message({type:'success', message:'成功拷贝到粘贴板'})"></el-button>--> | |
| 208 | + <!-- </template>--> | |
| 209 | + <!-- <el-descriptions-item v-for="(value, key, index) in wvpServerVersion" :key="key">--> | |
| 210 | + <!-- <template slot="label">--> | |
| 211 | + <!-- {{ getNameFromKey(key) }}--> | |
| 212 | + <!-- </template>--> | |
| 213 | + <!-- {{ value }}--> | |
| 214 | + <!-- </el-descriptions-item>--> | |
| 215 | + <!-- </el-descriptions>--> | |
| 132 | 216 | |
| 133 | -</div> | |
| 217 | + | |
| 218 | + <!-- </div>--> | |
| 219 | + <!-- </div>--> | |
| 220 | + <!-- <el-button type="primary" slot="reference" size="mini" @click="getWVPServerConfig()">信令服务器配置</el-button>--> | |
| 221 | + <!-- </el-popover>--> | |
| 222 | + <!-- <el-button style="margin-left: 1rem;" type="danger" size="mini" @click="reStartServer()">重启媒体服务器</el-button>--> | |
| 223 | + <!-- </div>--> | |
| 224 | + <!-- </div>--> | |
| 225 | + <el-row style="width: 100%"> | |
| 226 | + <el-col :span="12"> | |
| 227 | + <div class="control-table" id="ThreadsLoad" style="margin-right:10px;">table1</div> | |
| 228 | + </el-col> | |
| 229 | + <el-col :span="12"> | |
| 230 | + <div class="control-table" id="WorkThreadsLoad" style="margin-left:10px;">table2</div> | |
| 231 | + </el-col> | |
| 232 | + </el-row> | |
| 233 | + <el-table :data="allSessionData" style="margin-top: 1rem;"> | |
| 234 | + <el-table-column prop="peer_ip" label="远端"></el-table-column> | |
| 235 | + <el-table-column prop="local_ip" label="本地"></el-table-column> | |
| 236 | + <el-table-column prop="typeid" label="类型"></el-table-column> | |
| 237 | + <el-table-column align="right"> | |
| 238 | + <template slot="header" slot-scope="scope"> | |
| 239 | + <el-button icon="el-icon-refresh-right" circle @click="getAllSession()"></el-button> | |
| 240 | + </template> | |
| 241 | + <template slot-scope="scope"> | |
| 242 | + <el-button @click.native.prevent="deleteRow(scope.$index, allSessionData)" type="text" size="small">移除 | |
| 243 | + </el-button> | |
| 244 | + </template> | |
| 245 | + </el-table-column> | |
| 246 | + </el-table> | |
| 247 | + </div> | |
| 134 | 248 | </template> |
| 135 | 249 | |
| 136 | 250 | <script> |
| 137 | -import uiHeader from './UiHeader.vue' | |
| 251 | +import uiHeader from '../layout/UiHeader.vue' | |
| 138 | 252 | import MediaServer from './service/MediaServer' |
| 139 | 253 | |
| 140 | 254 | import echarts from 'echarts'; |
| 141 | -export default { | |
| 142 | - name: 'app', | |
| 143 | - components: { | |
| 144 | - echarts, | |
| 145 | - uiHeader | |
| 146 | - }, | |
| 147 | - data() { | |
| 148 | - return { | |
| 149 | - tableOption: { | |
| 150 | - // legend: {}, | |
| 151 | - xAxis: {}, | |
| 152 | - yAxis: {}, | |
| 153 | - label: {}, | |
| 154 | - tooltip: {}, | |
| 155 | - dataZoom: [], | |
| 156 | - series: [] | |
| 157 | - }, | |
| 158 | - table1Option: { | |
| 159 | - // legend: {}, | |
| 160 | - xAxis: {}, | |
| 161 | - yAxis: {}, | |
| 162 | - label: {}, | |
| 163 | - tooltip: {}, | |
| 164 | - series: [] | |
| 165 | - }, | |
| 166 | - mChart: null, | |
| 167 | - mChart1: null, | |
| 168 | - charZoomStart: 0, | |
| 169 | - charZoomEnd: 100, | |
| 170 | - chartInterval: 0, //更新图表统计图定时任务标识 | |
| 171 | - allSessionData: [], | |
| 172 | - visible: false, | |
| 173 | - wvpVisible: false, | |
| 174 | - serverConfig: {}, | |
| 175 | - wvpServerConfig: {}, | |
| 176 | - wvpServerVersion: {}, | |
| 177 | - mediaServer : new MediaServer(), | |
| 178 | - mediaServerChoose : null, | |
| 179 | - loadCount : 0, | |
| 180 | - mediaServerList : [] | |
| 181 | - }; | |
| 182 | - }, | |
| 183 | - mounted() { | |
| 184 | 255 | |
| 185 | - this.initTable(); | |
| 186 | - this.chartInterval = setInterval(this.updateData, 3000); | |
| 187 | - this.mediaServer.getOnlineMediaServerList((data)=>{ | |
| 188 | - this.mediaServerList = data.data; | |
| 189 | - if (this.mediaServerList && this.mediaServerList.length > 0) { | |
| 190 | - this.mediaServerChoose = this.mediaServerList[0].id | |
| 191 | - this.loadCount = this.mediaServerList[0].count; | |
| 192 | - this.updateData(); | |
| 193 | - } | |
| 194 | - }) | |
| 256 | +export default { | |
| 257 | + name: 'app', | |
| 258 | + components: { | |
| 259 | + echarts, | |
| 260 | + uiHeader | |
| 261 | + }, | |
| 262 | + data() { | |
| 263 | + return { | |
| 264 | + tableOption: { | |
| 265 | + // legend: {}, | |
| 266 | + xAxis: {}, | |
| 267 | + yAxis: {}, | |
| 268 | + label: {}, | |
| 269 | + tooltip: {}, | |
| 270 | + dataZoom: [], | |
| 271 | + series: [] | |
| 272 | + }, | |
| 273 | + table1Option: { | |
| 274 | + // legend: {}, | |
| 275 | + xAxis: {}, | |
| 276 | + yAxis: {}, | |
| 277 | + label: {}, | |
| 278 | + tooltip: {}, | |
| 279 | + series: [] | |
| 280 | + }, | |
| 281 | + mChart: null, | |
| 282 | + mChart1: null, | |
| 283 | + charZoomStart: 0, | |
| 284 | + charZoomEnd: 100, | |
| 285 | + chartInterval: 0, //更新图表统计图定时任务标识 | |
| 286 | + allSessionData: [], | |
| 287 | + visible: false, | |
| 288 | + wvpVisible: false, | |
| 289 | + serverConfig: {}, | |
| 290 | + wvpServerConfig: {}, | |
| 291 | + wvpServerVersion: {}, | |
| 292 | + mediaServer: new MediaServer(), | |
| 293 | + mediaServerChoose: null, | |
| 294 | + loadCount: 0, | |
| 295 | + mediaServerList: [] | |
| 296 | + }; | |
| 297 | + }, | |
| 298 | + mounted() { | |
| 299 | + this.initTable() | |
| 300 | + this.chartInterval = setInterval(this.updateData, 3000); | |
| 301 | + this.mediaServer.getOnlineMediaServerList((data) => { | |
| 302 | + this.mediaServerList = data.data; | |
| 303 | + if (this.mediaServerList && this.mediaServerList.length > 0) { | |
| 304 | + this.mediaServerChoose = this.mediaServerList[0].id | |
| 305 | + this.loadCount = this.mediaServerList[0].count; | |
| 306 | + this.updateData(); | |
| 307 | + } | |
| 308 | + }) | |
| 309 | + }, | |
| 310 | + destroyed() { | |
| 311 | + clearInterval(this.chartInterval); //释放定时任务 | |
| 312 | + }, | |
| 313 | + methods: { | |
| 314 | + chooseMediaChange: function (val) { | |
| 315 | + this.loadCount = 0 | |
| 316 | + this.initTable() | |
| 317 | + this.updateData(); | |
| 195 | 318 | }, |
| 196 | - destroyed() { | |
| 197 | - clearInterval(this.chartInterval); //释放定时任务 | |
| 319 | + updateData: function () { | |
| 320 | + this.getThreadsLoad(); | |
| 321 | + this.getLoadCount(); | |
| 322 | + this.getAllSession(); | |
| 198 | 323 | }, |
| 199 | - methods: { | |
| 200 | - chooseMediaChange: function (val) { | |
| 201 | - this.loadCount = 0 | |
| 202 | - this.initTable() | |
| 203 | - this.updateData(); | |
| 204 | - }, | |
| 205 | - updateData: function () { | |
| 206 | - this.getThreadsLoad(); | |
| 207 | - this.getLoadCount(); | |
| 208 | - this.getAllSession(); | |
| 209 | - }, | |
| 210 | - /** | |
| 211 | - * 获取线程状态 | |
| 212 | - */ | |
| 213 | - getThreadsLoad: function () { | |
| 214 | - let that = this; | |
| 215 | - if (that.mediaServerChoose != null) { | |
| 216 | - this.$axios({ | |
| 217 | - method: 'get', | |
| 218 | - url: '/zlm/' + that.mediaServerChoose +'/index/api/getThreadsLoad' | |
| 219 | - }).then(function (res) { | |
| 220 | - if (res.data.code == 0) { | |
| 221 | - that.tableOption.xAxis.data.push(new Date().toLocaleTimeString('chinese', { | |
| 222 | - hour12: false | |
| 223 | - })); | |
| 224 | - that.table1Option.xAxis.data.push(new Date().toLocaleTimeString('chinese', { | |
| 225 | - hour12: false | |
| 226 | - })); | |
| 324 | + /** | |
| 325 | + * 获取线程状态 | |
| 326 | + */ | |
| 327 | + getThreadsLoad: function () { | |
| 328 | + let that = this; | |
| 329 | + if (that.mediaServerChoose != null) { | |
| 330 | + this.$axios({ | |
| 331 | + method: 'get', | |
| 332 | + url: '/zlm/' + that.mediaServerChoose + '/index/api/getThreadsLoad' | |
| 333 | + }).then(function (res) { | |
| 334 | + if (res.data.code == 0) { | |
| 335 | + that.tableOption.xAxis.data.push(new Date().toLocaleTimeString('chinese', { | |
| 336 | + hour12: false | |
| 337 | + })); | |
| 338 | + that.table1Option.xAxis.data.push(new Date().toLocaleTimeString('chinese', { | |
| 339 | + hour12: false | |
| 340 | + })); | |
| 227 | 341 | |
| 228 | - for (var i = 0; i < res.data.data.length; i++) { | |
| 229 | - if (that.tableOption.series[i] === undefined) { | |
| 230 | - let data = { | |
| 231 | - data: [], | |
| 232 | - type: 'line' | |
| 233 | - }; | |
| 234 | - let data1 = { | |
| 235 | - data: [], | |
| 236 | - type: 'line' | |
| 237 | - }; | |
| 238 | - data.data.push(res.data.data[i].delay); | |
| 239 | - data1.data.push(res.data.data[i].load); | |
| 240 | - that.tableOption.series.push(data); | |
| 241 | - that.table1Option.series.push(data1); | |
| 242 | - } else { | |
| 243 | - that.tableOption.series[i].data.push(res.data.data[i].delay); | |
| 244 | - that.table1Option.series[i].data.push(res.data.data[i].load); | |
| 245 | - } | |
| 246 | - } | |
| 247 | - that.tableOption.dataZoom[0].start = that.charZoomStart; | |
| 248 | - that.tableOption.dataZoom[0].end = that.charZoomEnd; | |
| 249 | - that.table1Option.dataZoom[0].start = that.charZoomStart; | |
| 250 | - that.table1Option.dataZoom[0].end = that.charZoomEnd; | |
| 251 | - //that.myChart = echarts.init(document.getElementById('ThreadsLoad')); | |
| 252 | - that.myChart.setOption(that.tableOption, true); | |
| 253 | - // that.myChart1 = echarts.init(document.getElementById('WorkThreadsLoad')); | |
| 254 | - that.myChart1.setOption(that.table1Option, true); | |
| 255 | - } | |
| 256 | - }); | |
| 257 | - } | |
| 258 | - | |
| 259 | - }, | |
| 260 | - getLoadCount: function (){ | |
| 261 | - let that = this; | |
| 262 | - if (that.mediaServerChoose != null) { | |
| 263 | - that.mediaServer.getMediaServer(that.mediaServerChoose, (data)=>{ | |
| 264 | - if (data.code == 0) { | |
| 265 | - that.loadCount = data.data.count | |
| 342 | + for (var i = 0; i < res.data.data.length; i++) { | |
| 343 | + if (that.tableOption.series[i] === undefined) { | |
| 344 | + let data = { | |
| 345 | + data: [], | |
| 346 | + type: 'line' | |
| 347 | + }; | |
| 348 | + let data1 = { | |
| 349 | + data: [], | |
| 350 | + type: 'line' | |
| 351 | + }; | |
| 352 | + data.data.push(res.data.data[i].delay); | |
| 353 | + data1.data.push(res.data.data[i].load); | |
| 354 | + that.tableOption.series.push(data); | |
| 355 | + that.table1Option.series.push(data1); | |
| 356 | + } else { | |
| 357 | + that.tableOption.series[i].data.push(res.data.data[i].delay); | |
| 358 | + that.table1Option.series[i].data.push(res.data.data[i].load); | |
| 266 | 359 | } |
| 360 | + } | |
| 361 | + that.tableOption.dataZoom[0].start = that.charZoomStart; | |
| 362 | + that.tableOption.dataZoom[0].end = that.charZoomEnd; | |
| 363 | + that.table1Option.dataZoom[0].start = that.charZoomStart; | |
| 364 | + that.table1Option.dataZoom[0].end = that.charZoomEnd; | |
| 365 | + //that.myChart = echarts.init(document.getElementById('ThreadsLoad')); | |
| 366 | + that.myChart.setOption(that.tableOption, true); | |
| 367 | + // that.myChart1 = echarts.init(document.getElementById('WorkThreadsLoad')); | |
| 368 | + that.myChart1.setOption(that.table1Option, true); | |
| 369 | + that.$nextTick(() => { | |
| 370 | + that.myChart.resize() | |
| 371 | + that.myChart1.resize() | |
| 267 | 372 | }) |
| 268 | 373 | } |
| 269 | - }, | |
| 270 | - initTable: function () { | |
| 271 | - let that = this; | |
| 272 | - this.tableOption.xAxis = { | |
| 273 | - type: 'category', | |
| 274 | - data: [], // x轴数据 | |
| 275 | - name: '时间', // x轴名称 | |
| 276 | - // x轴名称样式 | |
| 277 | - nameTextStyle: { | |
| 278 | - fontWeight: 300, | |
| 279 | - fontSize: 15 | |
| 280 | - } | |
| 281 | - }; | |
| 282 | - this.tableOption.yAxis = { | |
| 283 | - type: 'value', | |
| 284 | - name: '延迟率', // y轴名称 | |
| 285 | - boundaryGap: [0, '100%'], | |
| 286 | - max: 100, | |
| 287 | - axisLabel: { | |
| 288 | - show: true, | |
| 289 | - interval: 'auto', | |
| 290 | - formatter: '{value} %' | |
| 291 | - }, | |
| 292 | - // y轴名称样式 | |
| 293 | - nameTextStyle: { | |
| 294 | - fontWeight: 300, | |
| 295 | - fontSize: 15 | |
| 296 | - } | |
| 297 | - }; | |
| 298 | - this.tableOption.dataZoom = [{ | |
| 299 | - show: true, | |
| 300 | - start: this.charZoomStart, | |
| 301 | - end: this.charZoomEnd | |
| 302 | - }]; | |
| 303 | - this.myChart = echarts.init(document.getElementById('ThreadsLoad')); | |
| 304 | - this.myChart.setOption(this.tableOption); | |
| 305 | - this.myChart.on('dataZoom', function (event) { | |
| 306 | - if (event.batch) { | |
| 307 | - that.charZoomStart = event.batch[0].start; | |
| 308 | - that.charZoomEnd = event.batch[0].end; | |
| 309 | - } else { | |
| 310 | - that.charZoomStart = event.start; | |
| 311 | - that.charZoomEnd = event.end; | |
| 312 | - } | |
| 313 | - }); | |
| 374 | + }); | |
| 375 | + } | |
| 314 | 376 | |
| 315 | - this.table1Option.xAxis = { | |
| 316 | - type: 'category', | |
| 317 | - data: [], // x轴数据 | |
| 318 | - name: '时间', // x轴名称 | |
| 319 | - // x轴名称样式 | |
| 320 | - nameTextStyle: { | |
| 321 | - fontWeight: 300, | |
| 322 | - fontSize: 15 | |
| 323 | - } | |
| 324 | - }; | |
| 325 | - this.table1Option.yAxis = { | |
| 326 | - type: 'value', | |
| 327 | - name: '负载率', // y轴名称 | |
| 328 | - boundaryGap: [0, '100%'], | |
| 329 | - max: 100, | |
| 330 | - axisLabel: { | |
| 331 | - show: true, | |
| 332 | - interval: 'auto', | |
| 333 | - formatter: '{value} %' | |
| 334 | - }, | |
| 335 | - // y轴名称样式 | |
| 336 | - nameTextStyle: { | |
| 337 | - fontWeight: 300, | |
| 338 | - fontSize: 15 | |
| 339 | - } | |
| 340 | - }; | |
| 341 | - this.table1Option.dataZoom = [{ | |
| 342 | - show: true, | |
| 343 | - start: this.charZoomStart, | |
| 344 | - end: this.charZoomEnd | |
| 345 | - }]; | |
| 346 | - this.myChart1 = echarts.init(document.getElementById('WorkThreadsLoad')); | |
| 347 | - this.myChart1.setOption(this.table1Option); | |
| 348 | - this.myChart1.on('dataZoom', function (event) { | |
| 349 | - if (event.batch) { | |
| 350 | - that.charZoomStart = event.batch[0].start; | |
| 351 | - that.charZoomEnd = event.batch[0].end; | |
| 352 | - } else { | |
| 353 | - that.charZoomStart = event.start; | |
| 354 | - that.charZoomEnd = event.end; | |
| 355 | - } | |
| 356 | - }); | |
| 377 | + }, | |
| 378 | + getLoadCount: function () { | |
| 379 | + let that = this; | |
| 380 | + if (that.mediaServerChoose != null) { | |
| 381 | + that.mediaServer.getMediaServer(that.mediaServerChoose, (data) => { | |
| 382 | + if (data.code == 0) { | |
| 383 | + that.loadCount = data.data.count | |
| 384 | + } | |
| 385 | + }) | |
| 386 | + } | |
| 387 | + }, | |
| 388 | + initTable: function () { | |
| 389 | + let that = this; | |
| 390 | + this.tableOption.xAxis = { | |
| 391 | + type: 'category', | |
| 392 | + data: [], // x轴数据 | |
| 393 | + name: '时间', // x轴名称 | |
| 394 | + // x轴名称样式 | |
| 395 | + nameTextStyle: { | |
| 396 | + fontWeight: 300, | |
| 397 | + fontSize: 15 | |
| 398 | + } | |
| 399 | + }; | |
| 400 | + this.tableOption.yAxis = { | |
| 401 | + type: 'value', | |
| 402 | + name: '延迟率', // y轴名称 | |
| 403 | + boundaryGap: [0, '100%'], | |
| 404 | + max: 100, | |
| 405 | + axisLabel: { | |
| 406 | + show: true, | |
| 407 | + interval: 'auto', | |
| 408 | + formatter: '{value} %' | |
| 357 | 409 | }, |
| 410 | + // y轴名称样式 | |
| 411 | + nameTextStyle: { | |
| 412 | + fontWeight: 300, | |
| 413 | + fontSize: 15 | |
| 414 | + } | |
| 415 | + }; | |
| 416 | + this.tableOption.dataZoom = [{ | |
| 417 | + show: true, | |
| 418 | + start: this.charZoomStart, | |
| 419 | + end: this.charZoomEnd | |
| 420 | + }]; | |
| 421 | + this.myChart = echarts.init(document.getElementById('ThreadsLoad')); | |
| 422 | + this.myChart.setOption(this.tableOption); | |
| 423 | + this.myChart.on('dataZoom', function (event) { | |
| 424 | + if (event.batch) { | |
| 425 | + that.charZoomStart = event.batch[0].start; | |
| 426 | + that.charZoomEnd = event.batch[0].end; | |
| 427 | + } else { | |
| 428 | + that.charZoomStart = event.start; | |
| 429 | + that.charZoomEnd = event.end; | |
| 430 | + } | |
| 431 | + }); | |
| 358 | 432 | |
| 359 | - getAllSession: function () { | |
| 360 | - let that = this; | |
| 361 | - that.allSessionData = []; | |
| 362 | - this.$axios({ | |
| 363 | - method: 'get', | |
| 364 | - url: '/zlm/' + that.mediaServerChoose +'/index/api/getAllSession' | |
| 365 | - }).then(function (res) { | |
| 366 | - res.data.data.forEach(item => { | |
| 367 | - let data = { | |
| 368 | - peer_ip: item.peer_ip, | |
| 369 | - local_ip: item.local_ip, | |
| 370 | - typeid: item.typeid, | |
| 371 | - id: item.id | |
| 372 | - }; | |
| 373 | - that.allSessionData.push(data); | |
| 374 | - }); | |
| 375 | - }); | |
| 433 | + this.table1Option.xAxis = { | |
| 434 | + type: 'category', | |
| 435 | + data: [], // x轴数据 | |
| 436 | + name: '时间', // x轴名称 | |
| 437 | + // x轴名称样式 | |
| 438 | + nameTextStyle: { | |
| 439 | + fontWeight: 300, | |
| 440 | + fontSize: 15 | |
| 441 | + } | |
| 442 | + }; | |
| 443 | + this.table1Option.yAxis = { | |
| 444 | + type: 'value', | |
| 445 | + name: '负载率', // y轴名称 | |
| 446 | + boundaryGap: [0, '100%'], | |
| 447 | + max: 100, | |
| 448 | + axisLabel: { | |
| 449 | + show: true, | |
| 450 | + interval: 'auto', | |
| 451 | + formatter: '{value} %' | |
| 376 | 452 | }, |
| 377 | - getServerConfig: function () { | |
| 378 | - let that = this; | |
| 379 | - this.$axios({ | |
| 380 | - method: 'get', | |
| 381 | - url: '/zlm/' + that.mediaServerChoose +'/index/api/getServerConfig' | |
| 382 | - }).then(function (res) { | |
| 383 | - let info = res.data.data[0]; | |
| 384 | - let serverInfo = {} | |
| 385 | - for (let i = 0; i < Object.keys(info).length; i++) { | |
| 386 | - let key = Object.keys(info)[i]; | |
| 387 | - let group = key.substring(0, key.indexOf(".")) | |
| 388 | - let itemKey = key.substring(key.indexOf(".") + 1) | |
| 389 | - if (!serverInfo[group]) serverInfo[group] = {} | |
| 390 | - serverInfo[group][itemKey] = info[key] | |
| 391 | - } | |
| 453 | + // y轴名称样式 | |
| 454 | + nameTextStyle: { | |
| 455 | + fontWeight: 300, | |
| 456 | + fontSize: 15 | |
| 457 | + } | |
| 458 | + }; | |
| 459 | + this.table1Option.dataZoom = [{ | |
| 460 | + show: true, | |
| 461 | + start: this.charZoomStart, | |
| 462 | + end: this.charZoomEnd | |
| 463 | + }]; | |
| 464 | + this.myChart1 = echarts.init(document.getElementById('WorkThreadsLoad')); | |
| 465 | + this.myChart1.setOption(this.table1Option); | |
| 466 | + this.myChart1.on('dataZoom', function (event) { | |
| 467 | + if (event.batch) { | |
| 468 | + that.charZoomStart = event.batch[0].start; | |
| 469 | + that.charZoomEnd = event.batch[0].end; | |
| 470 | + } else { | |
| 471 | + that.charZoomStart = event.start; | |
| 472 | + that.charZoomEnd = event.end; | |
| 473 | + } | |
| 474 | + }); | |
| 475 | + }, | |
| 392 | 476 | |
| 393 | - that.serverConfig = serverInfo; | |
| 394 | - that.visible = true; | |
| 395 | - }); | |
| 396 | - }, | |
| 397 | - getWVPServerConfig: function () { | |
| 398 | - let that = this; | |
| 399 | - this.$axios({ | |
| 400 | - method: 'get', | |
| 401 | - url: '/api/server/config' | |
| 402 | - }).then(function (res) { | |
| 403 | - console.log(res) | |
| 404 | - that.wvpServerConfig = res.data.data; | |
| 405 | - that.wvpVisible = true; | |
| 406 | - }); | |
| 407 | - this.$axios({ | |
| 408 | - method: 'get', | |
| 409 | - url: '/api/server/version' | |
| 410 | - }).then(function (res) { | |
| 411 | - console.log(res) | |
| 412 | - that.wvpServerVersion = res.data.data; | |
| 413 | - that.wvpVisible = true; | |
| 414 | - }); | |
| 415 | - }, | |
| 416 | - reStartServer: function () { | |
| 417 | - let that = this; | |
| 418 | - this.$confirm('此操作将重启媒体服务器, 是否继续?', '提示', { | |
| 419 | - confirmButtonText: '确定', | |
| 420 | - cancelButtonText: '取消', | |
| 421 | - type: 'warning' | |
| 422 | - }).then(() => { | |
| 423 | - let that = this; | |
| 424 | - this.$axios({ | |
| 425 | - method: 'get', | |
| 426 | - url: '/zlm/' + that.mediaServerChoose +'/index/api/restartServer' | |
| 427 | - }).then(function (res) { | |
| 428 | - that.getAllSession(); | |
| 429 | - if (res.data.code == 0) { | |
| 430 | - that.$message({ | |
| 431 | - type: 'success', | |
| 432 | - message: '操作完成' | |
| 433 | - }); | |
| 434 | - } | |
| 435 | - }); | |
| 436 | - }); | |
| 437 | - }, | |
| 438 | - deleteRow: function (index, tabledata) { | |
| 439 | - let that = this; | |
| 440 | - this.$confirm('此操作将断开该通信链路, 是否继续?', '提示', { | |
| 441 | - confirmButtonText: '确定', | |
| 442 | - cancelButtonText: '取消', | |
| 443 | - type: 'warning' | |
| 444 | - }) | |
| 445 | - .then(() => { | |
| 446 | - that.deleteSession(tabledata[index].id); | |
| 447 | - }) | |
| 448 | - .catch(() => { | |
| 449 | - console.log('id:' + JSON.stringify(tabledata[index])); | |
| 450 | - this.$message({ | |
| 451 | - type: 'info', | |
| 452 | - message: '已取消删除' | |
| 453 | - }); | |
| 454 | - }); | |
| 455 | - console.log(JSON.stringify(tabledata[index])); | |
| 456 | - }, | |
| 457 | - deleteSession: function (id) { | |
| 458 | - let that = this; | |
| 459 | - this.$axios({ | |
| 460 | - method: 'get', | |
| 461 | - url: '/zlm/' + that.mediaServerChoose +'/index/api/kick_session&id=' + id | |
| 462 | - }).then(function (res) { | |
| 463 | - that.getAllSession(); | |
| 464 | - that.$message({ | |
| 465 | - type: 'success', | |
| 466 | - message: '删除成功!' | |
| 467 | - }); | |
| 468 | - }); | |
| 469 | - }, | |
| 470 | - getNameFromKey: function(key) { | |
| 471 | - let nameData = { | |
| 472 | - "waitTrack": "等待编码信息", | |
| 473 | - "interfaceAuthenticationExcludes": "不进行鉴权的接口", | |
| 474 | - "playTimeout": "点播超时时间", | |
| 475 | - "autoApplyPlay": "自动点播", | |
| 476 | - "recordPushLive": "推流录像", | |
| 477 | - "redisConfig": "自动配置redis", | |
| 478 | - "thirdPartyGBIdReg": "stream信息正则", | |
| 479 | - "savePositionHistory": "保存轨迹信息", | |
| 480 | - "interfaceAuthentication": "接口鉴权", | |
| 481 | - "serverId": "服务ID", | |
| 482 | - "logInDatebase": "日志存储进数据库", | |
| 483 | - "seniorSdp": "扩展SDP", | |
| 484 | - "password": "密码", | |
| 485 | - "port": "端口号", | |
| 486 | - "keepaliveTimeOut": "心跳超时", | |
| 487 | - "domain": "国标域", | |
| 488 | - "ip": "IP地址", | |
| 489 | - "monitorIp": "监听IP", | |
| 490 | - "alarm": "存储报警信息", | |
| 491 | - "ptzSpeed": "云台控制速度", | |
| 492 | - "id": "国标ID", | |
| 493 | - "registerTimeInterval": "注册间隔", | |
| 494 | - "artifactId": "模块名称", | |
| 495 | - "version": "版本", | |
| 496 | - "project": "工程", | |
| 497 | - "git_Revision": "GIT修订版本", | |
| 498 | - "git_BRANCH": "GIT分支", | |
| 499 | - "git_URL": "GIT地址", | |
| 500 | - "build_DATE": "构建时间", | |
| 501 | - "create_By": "作者", | |
| 502 | - "git_Revision_SHORT": "GIT修订版本(短)", | |
| 503 | - "build_Jdk": "构建用JDK", | |
| 477 | + getAllSession: function () { | |
| 478 | + let that = this; | |
| 479 | + that.allSessionData = []; | |
| 480 | + this.$axios({ | |
| 481 | + method: 'get', | |
| 482 | + url: '/zlm/' + that.mediaServerChoose + '/index/api/getAllSession' | |
| 483 | + }).then(function (res) { | |
| 484 | + res.data.data.forEach(item => { | |
| 485 | + let data = { | |
| 486 | + peer_ip: item.peer_ip, | |
| 487 | + local_ip: item.local_ip, | |
| 488 | + typeid: item.typeid, | |
| 489 | + id: item.id | |
| 504 | 490 | }; |
| 505 | - console.log(key + ": " + nameData[key]) | |
| 491 | + that.allSessionData.push(data); | |
| 492 | + }); | |
| 493 | + }); | |
| 494 | + }, | |
| 495 | + getServerConfig: function () { | |
| 496 | + let that = this; | |
| 497 | + this.$axios({ | |
| 498 | + method: 'get', | |
| 499 | + url: '/zlm/' + that.mediaServerChoose + '/index/api/getServerConfig' | |
| 500 | + }).then(function (res) { | |
| 501 | + let info = res.data.data[0]; | |
| 502 | + let serverInfo = {} | |
| 503 | + for (let i = 0; i < Object.keys(info).length; i++) { | |
| 504 | + let key = Object.keys(info)[i]; | |
| 505 | + let group = key.substring(0, key.indexOf(".")) | |
| 506 | + let itemKey = key.substring(key.indexOf(".") + 1) | |
| 507 | + if (!serverInfo[group]) serverInfo[group] = {} | |
| 508 | + serverInfo[group][itemKey] = info[key] | |
| 509 | + } | |
| 506 | 510 | |
| 507 | - if (nameData[key]) { | |
| 508 | - return nameData[key] | |
| 509 | - }else { | |
| 510 | - return key; | |
| 511 | + that.serverConfig = serverInfo; | |
| 512 | + that.visible = true; | |
| 513 | + }); | |
| 514 | + }, | |
| 515 | + getWVPServerConfig: function () { | |
| 516 | + let that = this; | |
| 517 | + this.$axios({ | |
| 518 | + method: 'get', | |
| 519 | + url: '/api/server/config' | |
| 520 | + }).then(function (res) { | |
| 521 | + console.log(res) | |
| 522 | + that.wvpServerConfig = res.data.data; | |
| 523 | + that.wvpVisible = true; | |
| 524 | + }); | |
| 525 | + this.$axios({ | |
| 526 | + method: 'get', | |
| 527 | + url: '/api/server/version' | |
| 528 | + }).then(function (res) { | |
| 529 | + console.log(res) | |
| 530 | + that.wvpServerVersion = res.data.data; | |
| 531 | + that.wvpVisible = true; | |
| 532 | + }); | |
| 533 | + }, | |
| 534 | + reStartServer: function () { | |
| 535 | + let that = this; | |
| 536 | + this.$confirm('此操作将重启媒体服务器, 是否继续?', '提示', { | |
| 537 | + confirmButtonText: '确定', | |
| 538 | + cancelButtonText: '取消', | |
| 539 | + type: 'warning' | |
| 540 | + }).then(() => { | |
| 541 | + let that = this; | |
| 542 | + this.$axios({ | |
| 543 | + method: 'get', | |
| 544 | + url: '/zlm/' + that.mediaServerChoose + '/index/api/restartServer' | |
| 545 | + }).then(function (res) { | |
| 546 | + that.getAllSession(); | |
| 547 | + if (res.data.code == 0) { | |
| 548 | + that.$message({ | |
| 549 | + type: 'success', | |
| 550 | + message: '操作完成' | |
| 551 | + }); | |
| 511 | 552 | } |
| 512 | - }, | |
| 513 | - getMediaKeyNameFromKey: function(key) { | |
| 514 | - let nameData = { | |
| 515 | - "waitTrack": "等待编码信息", | |
| 516 | - "interfaceAuthenticationExcludes": "不进行鉴权的接口", | |
| 517 | - "playTimeout": "点播超时时间", | |
| 518 | - "autoApplyPlay": "自动点播", | |
| 519 | - "recordPushLive": "推流录像", | |
| 520 | - "redisConfig": "自动配置redis", | |
| 521 | - "thirdPartyGBIdReg": "stream信息正则", | |
| 522 | - "savePositionHistory": "保存轨迹信息", | |
| 523 | - "interfaceAuthentication": "接口鉴权", | |
| 524 | - "serverId": "服务ID", | |
| 525 | - "logInDatebase": "日志存储进数据库", | |
| 526 | - "seniorSdp": "扩展SDP", | |
| 527 | - "password": "密码", | |
| 528 | - "port": "端口号", | |
| 529 | - "keepaliveTimeOut": "心跳超时", | |
| 530 | - "domain": "国标域", | |
| 531 | - "ip": "IP地址", | |
| 532 | - "monitorIp": "监听IP", | |
| 533 | - "alarm": "存储报警信息", | |
| 534 | - "ptzSpeed": "云台控制速度", | |
| 535 | - "id": "国标ID", | |
| 536 | - "registerTimeInterval": "注册间隔", | |
| 537 | - "artifactId": "模块名称", | |
| 538 | - "version": "版本", | |
| 539 | - "project": "工程", | |
| 540 | - "git_Revision": "GIT修订版本", | |
| 541 | - "git_BRANCH": "GIT分支", | |
| 542 | - "git_URL": "GIT地址", | |
| 543 | - "build_DATE": "构建时间", | |
| 544 | - "create_By": "作者", | |
| 545 | - "git_Revision_SHORT": "GIT修订版本(短)", | |
| 546 | - "build_Jdk": "构建用JDK", | |
| 547 | - }; | |
| 548 | - console.log(key + ": " + nameData[key]) | |
| 553 | + }); | |
| 554 | + }); | |
| 555 | + }, | |
| 556 | + deleteRow: function (index, tabledata) { | |
| 557 | + let that = this; | |
| 558 | + this.$confirm('此操作将断开该通信链路, 是否继续?', '提示', { | |
| 559 | + confirmButtonText: '确定', | |
| 560 | + cancelButtonText: '取消', | |
| 561 | + type: 'warning' | |
| 562 | + }) | |
| 563 | + .then(() => { | |
| 564 | + that.deleteSession(tabledata[index].id); | |
| 565 | + }) | |
| 566 | + .catch(() => { | |
| 567 | + console.log('id:' + JSON.stringify(tabledata[index])); | |
| 568 | + this.$message({ | |
| 569 | + type: 'info', | |
| 570 | + message: '已取消删除' | |
| 571 | + }); | |
| 572 | + }); | |
| 573 | + console.log(JSON.stringify(tabledata[index])); | |
| 574 | + }, | |
| 575 | + deleteSession: function (id) { | |
| 576 | + let that = this; | |
| 577 | + this.$axios({ | |
| 578 | + method: 'get', | |
| 579 | + url: '/zlm/' + that.mediaServerChoose + '/index/api/kick_session&id=' + id | |
| 580 | + }).then(function (res) { | |
| 581 | + that.getAllSession(); | |
| 582 | + that.$message({ | |
| 583 | + type: 'success', | |
| 584 | + message: '删除成功!' | |
| 585 | + }); | |
| 586 | + }); | |
| 587 | + }, | |
| 588 | + getNameFromKey: function (key) { | |
| 589 | + let nameData = { | |
| 590 | + "waitTrack": "等待编码信息", | |
| 591 | + "interfaceAuthenticationExcludes": "不进行鉴权的接口", | |
| 592 | + "playTimeout": "点播超时时间", | |
| 593 | + "autoApplyPlay": "自动点播", | |
| 594 | + "recordPushLive": "推流录像", | |
| 595 | + "redisConfig": "自动配置redis", | |
| 596 | + "thirdPartyGBIdReg": "stream信息正则", | |
| 597 | + "savePositionHistory": "保存轨迹信息", | |
| 598 | + "interfaceAuthentication": "接口鉴权", | |
| 599 | + "serverId": "服务ID", | |
| 600 | + "logInDatebase": "日志存储进数据库", | |
| 601 | + "seniorSdp": "扩展SDP", | |
| 602 | + "password": "密码", | |
| 603 | + "port": "端口号", | |
| 604 | + "keepaliveTimeOut": "心跳超时", | |
| 605 | + "domain": "国标域", | |
| 606 | + "ip": "IP地址", | |
| 607 | + "monitorIp": "监听IP", | |
| 608 | + "alarm": "存储报警信息", | |
| 609 | + "ptzSpeed": "云台控制速度", | |
| 610 | + "id": "国标ID", | |
| 611 | + "registerTimeInterval": "注册间隔", | |
| 612 | + "artifactId": "模块名称", | |
| 613 | + "version": "版本", | |
| 614 | + "project": "工程", | |
| 615 | + "git_Revision": "GIT修订版本", | |
| 616 | + "git_BRANCH": "GIT分支", | |
| 617 | + "git_URL": "GIT地址", | |
| 618 | + "build_DATE": "构建时间", | |
| 619 | + "create_By": "作者", | |
| 620 | + "git_Revision_SHORT": "GIT修订版本(短)", | |
| 621 | + "build_Jdk": "构建用JDK", | |
| 622 | + }; | |
| 623 | + console.log(key + ": " + nameData[key]) | |
| 549 | 624 | |
| 550 | - if (nameData[key]) { | |
| 551 | - return nameData[key] | |
| 552 | - }else { | |
| 553 | - return key; | |
| 554 | - } | |
| 555 | - } | |
| 625 | + if (nameData[key]) { | |
| 626 | + return nameData[key] | |
| 627 | + } else { | |
| 628 | + return key; | |
| 629 | + } | |
| 630 | + }, | |
| 631 | + getMediaKeyNameFromKey: function (key) { | |
| 632 | + let nameData = { | |
| 633 | + "waitTrack": "等待编码信息", | |
| 634 | + "interfaceAuthenticationExcludes": "不进行鉴权的接口", | |
| 635 | + "playTimeout": "点播超时时间", | |
| 636 | + "autoApplyPlay": "自动点播", | |
| 637 | + "recordPushLive": "推流录像", | |
| 638 | + "redisConfig": "自动配置redis", | |
| 639 | + "thirdPartyGBIdReg": "stream信息正则", | |
| 640 | + "savePositionHistory": "保存轨迹信息", | |
| 641 | + "interfaceAuthentication": "接口鉴权", | |
| 642 | + "serverId": "服务ID", | |
| 643 | + "logInDatebase": "日志存储进数据库", | |
| 644 | + "seniorSdp": "扩展SDP", | |
| 645 | + "password": "密码", | |
| 646 | + "port": "端口号", | |
| 647 | + "keepaliveTimeOut": "心跳超时", | |
| 648 | + "domain": "国标域", | |
| 649 | + "ip": "IP地址", | |
| 650 | + "monitorIp": "监听IP", | |
| 651 | + "alarm": "存储报警信息", | |
| 652 | + "ptzSpeed": "云台控制速度", | |
| 653 | + "id": "国标ID", | |
| 654 | + "registerTimeInterval": "注册间隔", | |
| 655 | + "artifactId": "模块名称", | |
| 656 | + "version": "版本", | |
| 657 | + "project": "工程", | |
| 658 | + "git_Revision": "GIT修订版本", | |
| 659 | + "git_BRANCH": "GIT分支", | |
| 660 | + "git_URL": "GIT地址", | |
| 661 | + "build_DATE": "构建时间", | |
| 662 | + "create_By": "作者", | |
| 663 | + "git_Revision_SHORT": "GIT修订版本(短)", | |
| 664 | + "build_Jdk": "构建用JDK", | |
| 665 | + }; | |
| 666 | + console.log(key + ": " + nameData[key]) | |
| 667 | + | |
| 668 | + if (nameData[key]) { | |
| 669 | + return nameData[key] | |
| 670 | + } else { | |
| 671 | + return key; | |
| 672 | + } | |
| 556 | 673 | } |
| 674 | + } | |
| 557 | 675 | }; |
| 558 | 676 | </script> |
| 559 | 677 | |
| 560 | 678 | <style> |
| 561 | 679 | #app { |
| 562 | - height: 100%; | |
| 680 | + height: 100%; | |
| 563 | 681 | } |
| 564 | 682 | |
| 565 | 683 | .control-table { |
| 566 | - background-color: #ffffff; | |
| 567 | - height: 25rem; | |
| 684 | + background-color: #ffffff; | |
| 685 | + height: 25rem; | |
| 568 | 686 | } |
| 569 | 687 | |
| 570 | 688 | .table-c { |
| 571 | - border-right: 1px solid #dcdcdc; | |
| 572 | - border-bottom: 1px solid #dcdcdc; | |
| 689 | + border-right: 1px solid #dcdcdc; | |
| 690 | + border-bottom: 1px solid #dcdcdc; | |
| 573 | 691 | } |
| 574 | 692 | |
| 575 | 693 | .table-c td { |
| 576 | - border-left: 1px solid #dcdcdc; | |
| 577 | - border-top: 1px solid #dcdcdc; | |
| 578 | - padding: 0.2rem; | |
| 694 | + border-left: 1px solid #dcdcdc; | |
| 695 | + border-top: 1px solid #dcdcdc; | |
| 696 | + padding: 0.2rem; | |
| 579 | 697 | } |
| 580 | 698 | |
| 581 | 699 | .el-table { |
| 582 | - width: 99.9% !important; | |
| 700 | + width: 99.9% !important; | |
| 583 | 701 | } |
| 584 | 702 | </style> | ... | ... |
web_src/src/components/devicePosition.vue
| 1 | 1 | <template> |
| 2 | 2 | <div id="devicePosition" style="height: 100%"> |
| 3 | - <el-container style="height: 100%"> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #ffffff; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: 500">设备定位 ({{ parentChannelId == 0 ? deviceId : parentChannelId }})</span> | |
| 10 | - </div> | |
| 11 | - <div style="background-color: #ffffff; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left; font-size: 14px;"> | |
| 12 | - <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem" type="primary" @click="showDevice">返回</el-button> | |
| 13 | - <!-- <span class="demonstration">从</span> --> | |
| 14 | - <el-date-picker v-model="searchFrom" type="datetime" placeholder="选择开始日期时间" default-time="00:00:00" size="mini" style="width: 11rem;" align="right" :picker-options="pickerOptions"></el-date-picker> | |
| 15 | - <el-date-picker v-model="searchTo" type="datetime" placeholder="选择结束日期时间" default-time="00:00:00" size="mini" style="width: 11rem;" align="right" :picker-options="pickerOptions"></el-date-picker> | |
| 16 | - <el-button-group> | |
| 17 | - <el-button icon="el-icon-search" size="mini" type="primary" @click="showHistoryPath">历史轨迹</el-button> | |
| 18 | - <el-button icon="el-icon-search" size="mini" style="margin-right: 1rem" type="primary" @click="showLatestPosition">最新位置</el-button> | |
| 19 | - </el-button-group> | |
| 20 | - <el-tag style="width: 5rem; text-align: center" size="medium">过期时间</el-tag> | |
| 21 | - <el-input-number size="mini" v-model="expired" :min="300" :controls="false" style="width: 4rem;"></el-input-number> | |
| 22 | - <el-tag style="width: 5rem; text-align: center" size="medium">上报周期</el-tag> | |
| 23 | - <el-input-number size="mini" v-model="interval" :min="1" :controls="false" style="width: 4rem;"></el-input-number> | |
| 24 | - <el-button-group> | |
| 25 | - <el-button icon="el-icon-search" size="mini" type="primary" @click="subscribeMobilePosition">位置订阅</el-button> | |
| 26 | - <el-button icon="el-icon-search" size="mini" type="primary" @click="unSubscribeMobilePosition">取消订阅</el-button> | |
| 27 | - </el-button-group> | |
| 28 | - <el-checkbox size="mini" style="margin-right: 1rem; float: right" v-model="autoList" @change="autoListChange" >自动刷新</el-checkbox> | |
| 29 | - </div> | |
| 30 | - <div class="mapContainer" style="background-color: #ffffff; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center; height: calc(100% - 10rem);"> | |
| 31 | - <div class="baidumap" id="allmap"></div> | |
| 32 | - </div> | |
| 33 | - </el-main> | |
| 34 | - </el-container> | |
| 3 | + <div style="background-color: #ffffff; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center;"> | |
| 4 | + <span style="font-size: 1rem; font-weight: 500">设备定位 ({{ parentChannelId == 0 ? deviceId : parentChannelId }})</span> | |
| 5 | + </div> | |
| 6 | + <div style="background-color: #ffffff; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left; font-size: 14px;"> | |
| 7 | + <el-button icon="el-icon-arrow-left" size="mini" style="margin-right: 1rem" type="primary" @click="showDevice">返回</el-button> | |
| 8 | + <!-- <span class="demonstration">从</span> --> | |
| 9 | + <el-date-picker v-model="searchFrom" type="datetime" placeholder="选择开始日期时间" default-time="00:00:00" size="mini" style="width: 11rem;" align="right" :picker-options="pickerOptions"></el-date-picker> | |
| 10 | + <el-date-picker v-model="searchTo" type="datetime" placeholder="选择结束日期时间" default-time="00:00:00" size="mini" style="width: 11rem;" align="right" :picker-options="pickerOptions"></el-date-picker> | |
| 11 | + <el-button-group> | |
| 12 | + <el-button icon="el-icon-search" size="mini" type="primary" @click="showHistoryPath">历史轨迹</el-button> | |
| 13 | + <el-button icon="el-icon-search" size="mini" style="margin-right: 1rem" type="primary" @click="showLatestPosition">最新位置</el-button> | |
| 14 | + </el-button-group> | |
| 15 | + <el-tag style="width: 5rem; text-align: center" size="medium">过期时间</el-tag> | |
| 16 | + <el-input-number size="mini" v-model="expired" :min="300" :controls="false" style="width: 4rem;"></el-input-number> | |
| 17 | + <el-tag style="width: 5rem; text-align: center" size="medium">上报周期</el-tag> | |
| 18 | + <el-input-number size="mini" v-model="interval" :min="1" :controls="false" style="width: 4rem;"></el-input-number> | |
| 19 | + <el-button-group> | |
| 20 | + <el-button icon="el-icon-search" size="mini" type="primary" @click="subscribeMobilePosition">位置订阅</el-button> | |
| 21 | + <el-button icon="el-icon-search" size="mini" type="primary" @click="unSubscribeMobilePosition">取消订阅</el-button> | |
| 22 | + </el-button-group> | |
| 23 | + <el-checkbox size="mini" style="margin-right: 1rem; float: right" v-model="autoList" @change="autoListChange" >自动刷新</el-checkbox> | |
| 24 | + </div> | |
| 25 | + <div class="mapContainer" style="background-color: #ffffff; position: relative; padding: 1rem 0.5rem 0.5rem 0.5rem; text-align: center; height: calc(100% - 10rem);"> | |
| 26 | + <div class="baidumap" id="allmap"></div> | |
| 27 | + </div> | |
| 35 | 28 | </div> |
| 36 | 29 | </template> |
| 37 | 30 | |
| 38 | 31 | <script> |
| 39 | -import uiHeader from "./UiHeader.vue"; | |
| 40 | -import moment from "moment"; | |
| 32 | +import uiHeader from "../layout/UiHeader.vue"; | |
| 41 | 33 | import geoTools from "./GeoConvertTools.js"; |
| 42 | 34 | export default { |
| 43 | 35 | name: "devicePosition", |
| ... | ... | @@ -173,7 +165,7 @@ export default { |
| 173 | 165 | let self = this; |
| 174 | 166 | this.$axios({ |
| 175 | 167 | method: 'get', |
| 176 | - url:`/api/position/history/${this.deviceId}`, | |
| 168 | + url:`/api/position/history/${this.deviceId}`, | |
| 177 | 169 | params: { |
| 178 | 170 | start: self.startTime, |
| 179 | 171 | end: self.endTime, |
| ... | ... | @@ -259,7 +251,7 @@ export default { |
| 259 | 251 | }, |
| 260 | 252 | toGBString: function (dateTime) { |
| 261 | 253 | return ( |
| 262 | - dateTime.getFullYear() + | |
| 254 | + dateTime.getFullYear() + | |
| 263 | 255 | "-" + this.twoDigits(dateTime.getMonth() + 1) + |
| 264 | 256 | "-" + this.twoDigits(dateTime.getDate()) + |
| 265 | 257 | "T" + this.twoDigits(dateTime.getHours()) + | ... | ... |
web_src/src/components/dialog/catalogEdit.vue
| ... | ... | @@ -13,11 +13,24 @@ |
| 13 | 13 | <div id="shared" style="margin-top: 1rem;margin-right: 100px;"> |
| 14 | 14 | <el-form ref="form" :rules="rules" :model="form" label-width="140px" > |
| 15 | 15 | <el-form-item label="节点编号" prop="id" > |
| 16 | - <el-input v-model="form.id" :disabled="isEdit"></el-input> | |
| 16 | + <el-tooltip class="item" effect="dark" content="" placement="top-start"> | |
| 17 | + <div slot="content"> | |
| 18 | + 建议的类型: | |
| 19 | + <br/> | |
| 20 | +   行政区划(可选2位/4位/6位/8位/10位数字,例如:130432,表示河北省邯郸市广平县) | |
| 21 | + <br/> | |
| 22 | +   业务分组(第11、12、13位215,例如:34020000002150000001) | |
| 23 | + <br/> | |
| 24 | +   虚拟组织(第11、12、13位216,例如:34020000002160000001) | |
| 25 | + </div> | |
| 26 | + <el-input v-model="form.id" :disabled="isEdit"></el-input> | |
| 27 | + </el-tooltip> | |
| 17 | 28 | </el-form-item> |
| 18 | 29 | <el-form-item label="节点名称" prop="name"> |
| 19 | 30 | <el-input v-model="form.name" clearable></el-input> |
| 20 | 31 | </el-form-item> |
| 32 | + | |
| 33 | + | |
| 21 | 34 | <el-form-item> |
| 22 | 35 | <div style="float: right;"> |
| 23 | 36 | <el-button type="primary" @click="onSubmit" >确认</el-button> | ... | ... |
web_src/src/components/dialog/deviceEdit.vue
| ... | ... | @@ -45,6 +45,9 @@ |
| 45 | 45 | <el-form-item v-if="form.subscribeCycleForMobilePosition > 0" label="移动位置报送间隔" prop="subscribeCycleForCatalog" > |
| 46 | 46 | <el-input v-model="form.mobilePositionSubmissionInterval" clearable ></el-input> |
| 47 | 47 | </el-form-item> |
| 48 | + <el-form-item label="其他选项"> | |
| 49 | + <el-checkbox label="SSRC校验" v-model="form.ssrcCheck" style="float: left"></el-checkbox> | |
| 50 | + </el-form-item> | |
| 48 | 51 | <el-form-item> |
| 49 | 52 | <div style="float: right;"> |
| 50 | 53 | <el-button type="primary" @click="onSubmit" >确认</el-button> | ... | ... |
web_src/src/components/dialog/platformEdit.vue
| ... | ... | @@ -44,6 +44,9 @@ |
| 44 | 44 | <el-form-item label="SIP认证用户名" prop="username"> |
| 45 | 45 | <el-input v-model="platform.username"></el-input> |
| 46 | 46 | </el-form-item> |
| 47 | + <el-form-item label="行政区划" prop="administrativeDivision"> | |
| 48 | + <el-input v-model="platform.administrativeDivision" clearable></el-input> | |
| 49 | + </el-form-item> | |
| 47 | 50 | <el-form-item label="SIP认证密码" prop="password"> |
| 48 | 51 | <el-input v-model="platform.password" ></el-input> |
| 49 | 52 | </el-form-item> |
| ... | ... | @@ -63,6 +66,18 @@ |
| 63 | 66 | <el-option label="TCP" value="TCP"></el-option> |
| 64 | 67 | </el-select> |
| 65 | 68 | </el-form-item> |
| 69 | + <el-form-item label="目录分组" prop="catalogGroup"> | |
| 70 | + <el-select | |
| 71 | + v-model="platform.catalogGroup" | |
| 72 | + style="width: 100%" | |
| 73 | + placeholder="请选择目录分组" | |
| 74 | + > | |
| 75 | + <el-option label="1" value="1"></el-option> | |
| 76 | + <el-option label="2" value="2"></el-option> | |
| 77 | + <el-option label="4" value="4"></el-option> | |
| 78 | + <el-option label="8" value="8"></el-option> | |
| 79 | + </el-select> | |
| 80 | + </el-form-item> | |
| 66 | 81 | <el-form-item label="字符集" prop="characterSet"> |
| 67 | 82 | <el-select |
| 68 | 83 | v-model="platform.characterSet" |
| ... | ... | @@ -77,6 +92,7 @@ |
| 77 | 92 | <el-checkbox label="启用" v-model="platform.enable" @change="checkExpires"></el-checkbox> |
| 78 | 93 | <el-checkbox label="云台控制" v-model="platform.ptz"></el-checkbox> |
| 79 | 94 | <el-checkbox label="共享所有直播流" v-model="platform.shareAllLiveStream"></el-checkbox> |
| 95 | + <el-checkbox label="拉起离线推流" v-model="platform.startOfflinePush"></el-checkbox> | |
| 80 | 96 | </el-form-item> |
| 81 | 97 | <el-form-item> |
| 82 | 98 | <el-button type="primary" @click="onSubmit">{{ |
| ... | ... | @@ -138,6 +154,9 @@ export default { |
| 138 | 154 | transport: "UDP", |
| 139 | 155 | characterSet: "GB2312", |
| 140 | 156 | shareAllLiveStream: false, |
| 157 | + startOfflinePush: false, | |
| 158 | + catalogGroup: 1, | |
| 159 | + administrativeDivision: null, | |
| 141 | 160 | }, |
| 142 | 161 | rules: { |
| 143 | 162 | name: [{ required: true, message: "请输入平台名称", trigger: "blur" }], |
| ... | ... | @@ -175,6 +194,7 @@ export default { |
| 175 | 194 | that.platform.devicePort = res.data.devicePort; |
| 176 | 195 | that.platform.username = res.data.username; |
| 177 | 196 | that.platform.password = res.data.password; |
| 197 | + that.platform.administrativeDivision = res.data.username.substr(0, 6); | |
| 178 | 198 | }).catch(function (error) { |
| 179 | 199 | console.log(error); |
| 180 | 200 | }); |
| ... | ... | @@ -199,6 +219,9 @@ export default { |
| 199 | 219 | this.platform.characterSet = platform.characterSet; |
| 200 | 220 | this.platform.shareAllLiveStream = platform.shareAllLiveStream; |
| 201 | 221 | this.platform.catalogId = platform.catalogId; |
| 222 | + this.platform.startOfflinePush = platform.startOfflinePush; | |
| 223 | + this.platform.catalogGroup = platform.catalogGroup; | |
| 224 | + this.platform.administrativeDivision = platform.administrativeDivision; | |
| 202 | 225 | this.onSubmit_text = "保存"; |
| 203 | 226 | this.saveUrl = "/api/platform/save"; |
| 204 | 227 | } |
| ... | ... | @@ -213,6 +236,10 @@ export default { |
| 213 | 236 | deviceGBIdChange: function () { |
| 214 | 237 | |
| 215 | 238 | this.platform.username = this.platform.deviceGBId ; |
| 239 | + if (this.platform.administrativeDivision == null) { | |
| 240 | + this.platform.administrativeDivision = this.platform.deviceGBId.substr(0, 6); | |
| 241 | + } | |
| 242 | + | |
| 216 | 243 | }, |
| 217 | 244 | onSubmit: function () { |
| 218 | 245 | var that = this; |
| ... | ... | @@ -253,6 +280,7 @@ export default { |
| 253 | 280 | rtcp: false, |
| 254 | 281 | name: null, |
| 255 | 282 | serverGBId: null, |
| 283 | + administrativeDivision: null, | |
| 256 | 284 | serverGBDomain: null, |
| 257 | 285 | serverIP: null, |
| 258 | 286 | serverPort: null, |
| ... | ... | @@ -266,6 +294,8 @@ export default { |
| 266 | 294 | transport: "UDP", |
| 267 | 295 | characterSet: "GB2312", |
| 268 | 296 | shareAllLiveStream: false, |
| 297 | + startOfflinePush: false, | |
| 298 | + catalogGroup: 1, | |
| 269 | 299 | } |
| 270 | 300 | }, |
| 271 | 301 | deviceGBIdExit: async function (deviceGbId) { | ... | ... |
web_src/src/components/live.vue
| 1 | 1 | <template> |
| 2 | - <div id="devicePosition" style="height: 100%"> | |
| 3 | - <el-container style="height: 100%"> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-container v-loading="loading" element-loading-text="拼命加载中"> | |
| 8 | - <el-aside width="300px" style="background-color: #ffffff"> | |
| 9 | - <div style="text-align: center;padding-top: 20px;">设备列表</div> | |
| 10 | - <el-menu v-loading="loading"> | |
| 11 | - <el-submenu v-for="device in deviceList" :key="device.deviceId" :index="device.deviceId" @click="sendDevicePush(item)"> | |
| 12 | - <template slot="title" > | |
| 13 | - <i class="el-icon-location-outline"></i> | |
| 14 | - {{device.name}} | |
| 15 | - </template> | |
| 16 | - <ChannelTree :device="device" @sendDevicePush="sendDevicePush"></ChannelTree> | |
| 17 | - </el-submenu> | |
| 18 | - </el-menu> | |
| 19 | - </el-aside> | |
| 20 | - <el-container> | |
| 21 | - <!-- <LivePlay></LivePlay> --> | |
| 22 | - <el-header height="40px" style="text-align: left;font-size: 17px;line-height: 40px;"> | |
| 23 | - 分屏: | |
| 24 | - <i class="el-icon-full-screen btn" :class="{active:spilt==1}" @click="spilt=1"/> | |
| 25 | - <i class="el-icon-menu btn" :class="{active:spilt==4}" @click="spilt=4"/> | |
| 26 | - <i class="el-icon-s-grid btn" :class="{active:spilt==9}" @click="spilt=9"/> | |
| 27 | - </el-header> | |
| 28 | - <el-main> | |
| 29 | - <div style="width: 100%;height: calc( 100vh - 110px );display: flex;flex-wrap: wrap;background-color: #000;"> | |
| 30 | - <div v-for="i in spilt" :key="i" class="play-box" | |
| 31 | - :style="liveStyle" :class="{redborder:playerIdx == (i-1)}" | |
| 32 | - @click="playerIdx = (i-1)" | |
| 33 | - > | |
| 34 | - <div v-if="!videoUrl[i-1]" style="color: #ffffff;font-size: 30px;font-weight: bold;">{{i}}</div> | |
| 35 | - <player v-else :ref="'player'+i" :videoUrl="videoUrl[i-1]" fluent autoplay :height="true" | |
| 36 | - :containerId="'player'+i" @screenshot="shot" @destroy="destroy"></player> | |
| 37 | - <!-- <player v-else ref="'player'+i" :idx="'player'+i" :visible.sync="showVideoDialog" :videoUrl="videoUrl[i-1]" :height="true" :hasAudio="hasAudio" fluent autoplay live ></player> --> | |
| 38 | - </div> | |
| 39 | - </div> | |
| 40 | - </el-main> | |
| 41 | - </el-container> | |
| 2 | + <div id="devicePosition" style="height: 100%;width: 100%"> | |
| 3 | + <el-container v-loading="loading" element-loading-text="拼命加载中"> | |
| 4 | + <el-aside width="300px" style="background-color: #ffffff"> | |
| 5 | + <div style="text-align: center;padding-top: 20px;">设备列表</div> | |
| 6 | + <el-menu v-loading="loading"> | |
| 7 | + <el-submenu v-for="device in deviceList" :key="device.deviceId" :index="device.deviceId" @click="sendDevicePush(item)"> | |
| 8 | + <template slot="title" > | |
| 9 | + <i class="el-icon-location-outline"></i> | |
| 10 | + {{device.name}} | |
| 11 | + </template> | |
| 12 | + <ChannelTree :device="device" @sendDevicePush="sendDevicePush"></ChannelTree> | |
| 13 | + </el-submenu> | |
| 14 | + </el-menu> | |
| 15 | + </el-aside> | |
| 16 | + <el-container> | |
| 17 | + <!-- <LivePlay></LivePlay> --> | |
| 18 | + <el-header height="40px" style="text-align: left;font-size: 17px;line-height: 40px;"> | |
| 19 | + 分屏: | |
| 20 | + <i class="el-icon-full-screen btn" :class="{active:spilt==1}" @click="spilt=1"/> | |
| 21 | + <i class="el-icon-menu btn" :class="{active:spilt==4}" @click="spilt=4"/> | |
| 22 | + <i class="el-icon-s-grid btn" :class="{active:spilt==9}" @click="spilt=9"/> | |
| 23 | + </el-header> | |
| 24 | + <el-main> | |
| 25 | + <div style="width: 100%;height: calc( 100vh - 150px );display: flex;flex-wrap: wrap;background-color: #000;"> | |
| 26 | + <div v-for="i in spilt" :key="i" class="play-box" | |
| 27 | + :style="liveStyle" :class="{redborder:playerIdx == (i-1)}" | |
| 28 | + @click="playerIdx = (i-1)" | |
| 29 | + > | |
| 30 | + <div v-if="!videoUrl[i-1]" style="color: #ffffff;font-size: 30px;font-weight: bold;">{{i}}</div> | |
| 31 | + <player v-else :ref="'player'+i" :videoUrl="videoUrl[i-1]" fluent autoplay :height="true" | |
| 32 | + :containerId="'player'+i" @screenshot="shot" @destroy="destroy"></player> | |
| 33 | + <!-- <player v-else ref="'player'+i" :idx="'player'+i" :visible.sync="showVideoDialog" :videoUrl="videoUrl[i-1]" :height="true" :hasAudio="hasAudio" fluent autoplay live ></player> --> | |
| 34 | + </div> | |
| 35 | + </div> | |
| 36 | + </el-main> | |
| 42 | 37 | </el-container> |
| 43 | 38 | </el-container> |
| 44 | 39 | </div> |
| 45 | 40 | </template> |
| 46 | 41 | |
| 47 | 42 | <script> |
| 48 | - import uiHeader from "./UiHeader.vue"; | |
| 43 | + import uiHeader from "../layout/UiHeader.vue"; | |
| 49 | 44 | import player from './dialog/jessibuca.vue' |
| 50 | 45 | import ChannelTree from './channelTree.vue' |
| 51 | 46 | ... | ... |
web_src/src/components/setting/Media.vue
| 1 | 1 | <template> |
| 2 | - <div id="SettingForMedia"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: bold;">媒体服务</span> | |
| 10 | - </div> | |
| 11 | - <div style="width: 60%; margin:0 auto; background-color: #FFFFFF; position: relative; padding: 5rem 6.5rem; text-align: left;font-size: 14px; max-width: 400px"> | |
| 12 | - <el-form ref="form" :rules="rules" :model="form" label-width="140px"> | |
| 13 | - <el-form-item label="IP" prop="IP"> | |
| 14 | - <el-input v-model="form.IP" clearable></el-input> | |
| 15 | - </el-form-item> | |
| 16 | - <el-form-item label="公网IP" prop="wanIp"> | |
| 17 | - <el-input v-model="form.wanIp" clearable></el-input> | |
| 18 | - </el-form-item> | |
| 19 | - <el-form-item label="HOOK IP" prop="hookIp"> | |
| 20 | - <el-input v-model="form.hookIp" clearable></el-input> | |
| 21 | - </el-form-item> | |
| 22 | - <el-form-item label="HTTP端口" > | |
| 23 | - <el-input v-model.number="form.httpPort" clearable></el-input> | |
| 24 | - </el-form-item> | |
| 25 | - <el-form-item label="HTTP SSL端口" > | |
| 26 | - <el-input v-model.number="form.httpSSlPort" clearable></el-input> | |
| 27 | - </el-form-item> | |
| 28 | - <el-form-item label="RTMP端口" > | |
| 29 | - <el-input v-model.number="form.rtmpPort" clearable></el-input> | |
| 30 | - </el-form-item> | |
| 31 | - <el-form-item label="RTMP SSL端口" > | |
| 32 | - <el-input v-model.number="form.rtmpSSlPort" clearable></el-input> | |
| 33 | - </el-form-item> | |
| 34 | - <el-form-item label="RTSP端口" > | |
| 35 | - <el-input v-model.number="form.rtspPort" clearable></el-input> | |
| 36 | - </el-form-item> | |
| 37 | - <el-form-item label="RTSP SSL端口" > | |
| 38 | - <el-input v-model.number="form.rtspSSLPort" clearable></el-input> | |
| 39 | - </el-form-item> | |
| 40 | - <el-form-item label="RTP端口" > | |
| 41 | - <el-input v-model.number="form.rtpProxyPort" clearable></el-input> | |
| 42 | - </el-form-item> | |
| 43 | - <el-form-item label="自动点播" > | |
| 44 | - <el-switch v-model="form.autoApplyPlay"></el-switch> | |
| 45 | - </el-form-item> | |
| 46 | - <el-form-item label="接口密钥" prop="secret"> | |
| 47 | - <el-input v-model="form.secret" clearable></el-input> | |
| 48 | - </el-form-item> | |
| 49 | - <el-form-item label="无人观看触发时长" > | |
| 50 | - <el-input v-model.number="form.streamNoneReaderDelayMS" clearable></el-input> | |
| 51 | - </el-form-item> | |
| 52 | - <el-form-item label="自动配置" > | |
| 53 | - <el-switch v-model="form.autoConfig"></el-switch> | |
| 54 | - </el-form-item> | |
| 55 | - <el-form-item label="使用多端口" > | |
| 56 | - <el-switch v-model="form.rtp.enable"></el-switch> | |
| 57 | - </el-form-item> | |
| 58 | - <el-form-item label="端口范围" > | |
| 59 | - <el-input v-model.number="form.rtp.portRange" clearable></el-input> | |
| 60 | - </el-form-item> | |
| 61 | - <el-form-item label="DOCKER智能识别"> | |
| 62 | - <el-input type="textarea" v-model="dockerStr"></el-input> | |
| 63 | - </el-form-item> | |
| 2 | + <div id="SettingForMedia" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title">媒体服务</div> | |
| 5 | + </div> | |
| 6 | + <div | |
| 7 | + style="width: 60%; margin:0 auto; background-color: #FFFFFF; position: relative; padding: 5rem 6.5rem; text-align: left;font-size: 14px; max-width: 400px"> | |
| 8 | + <el-form ref="form" :rules="rules" :model="form" label-width="140px"> | |
| 9 | + <el-form-item label="IP" prop="IP"> | |
| 10 | + <el-input v-model="form.IP" clearable></el-input> | |
| 11 | + </el-form-item> | |
| 12 | + <el-form-item label="公网IP" prop="wanIp"> | |
| 13 | + <el-input v-model="form.wanIp" clearable></el-input> | |
| 14 | + </el-form-item> | |
| 15 | + <el-form-item label="HOOK IP" prop="hookIp"> | |
| 16 | + <el-input v-model="form.hookIp" clearable></el-input> | |
| 17 | + </el-form-item> | |
| 18 | + <el-form-item label="HTTP端口"> | |
| 19 | + <el-input v-model.number="form.httpPort" clearable></el-input> | |
| 20 | + </el-form-item> | |
| 21 | + <el-form-item label="HTTP SSL端口"> | |
| 22 | + <el-input v-model.number="form.httpSSlPort" clearable></el-input> | |
| 23 | + </el-form-item> | |
| 24 | + <el-form-item label="RTMP端口"> | |
| 25 | + <el-input v-model.number="form.rtmpPort" clearable></el-input> | |
| 26 | + </el-form-item> | |
| 27 | + <el-form-item label="RTMP SSL端口"> | |
| 28 | + <el-input v-model.number="form.rtmpSSlPort" clearable></el-input> | |
| 29 | + </el-form-item> | |
| 30 | + <el-form-item label="RTSP端口"> | |
| 31 | + <el-input v-model.number="form.rtspPort" clearable></el-input> | |
| 32 | + </el-form-item> | |
| 33 | + <el-form-item label="RTSP SSL端口"> | |
| 34 | + <el-input v-model.number="form.rtspSSLPort" clearable></el-input> | |
| 35 | + </el-form-item> | |
| 36 | + <el-form-item label="RTP端口"> | |
| 37 | + <el-input v-model.number="form.rtpProxyPort" clearable></el-input> | |
| 38 | + </el-form-item> | |
| 39 | + <el-form-item label="自动点播"> | |
| 40 | + <el-switch v-model="form.autoApplyPlay"></el-switch> | |
| 41 | + </el-form-item> | |
| 42 | + <el-form-item label="接口密钥" prop="secret"> | |
| 43 | + <el-input v-model="form.secret" clearable></el-input> | |
| 44 | + </el-form-item> | |
| 45 | + <el-form-item label="无人观看触发时长"> | |
| 46 | + <el-input v-model.number="form.streamNoneReaderDelayMS" clearable></el-input> | |
| 47 | + </el-form-item> | |
| 48 | + <el-form-item label="自动配置"> | |
| 49 | + <el-switch v-model="form.autoConfig"></el-switch> | |
| 50 | + </el-form-item> | |
| 51 | + <el-form-item label="使用多端口"> | |
| 52 | + <el-switch v-model="form.rtp.enable"></el-switch> | |
| 53 | + </el-form-item> | |
| 54 | + <el-form-item label="端口范围"> | |
| 55 | + <el-input v-model.number="form.rtp.portRange" clearable></el-input> | |
| 56 | + </el-form-item> | |
| 57 | + <el-form-item label="DOCKER智能识别"> | |
| 58 | + <el-input type="textarea" v-model="dockerStr"></el-input> | |
| 59 | + </el-form-item> | |
| 64 | 60 | |
| 65 | - <el-form-item> | |
| 66 | - <div style="float: right;"> | |
| 67 | - <el-button type="primary" @click="onSubmit">保存</el-button> | |
| 68 | -<!-- <el-button @click="close">取消</el-button>--> | |
| 69 | - </div> | |
| 61 | + <el-form-item> | |
| 62 | + <div style="float: right;"> | |
| 63 | + <el-button type="primary" @click="onSubmit">保存</el-button> | |
| 64 | + <!-- <el-button @click="close">取消</el-button>--> | |
| 65 | + </div> | |
| 70 | 66 | |
| 71 | - </el-form-item> | |
| 72 | - </el-form> | |
| 73 | - </div> | |
| 74 | - | |
| 75 | - | |
| 76 | - </el-main> | |
| 77 | - </el-container> | |
| 67 | + </el-form-item> | |
| 68 | + </el-form> | |
| 69 | + </div> | |
| 78 | 70 | </div> |
| 79 | 71 | </template> |
| 80 | 72 | |
| 81 | 73 | <script> |
| 82 | -import uiHeader from '../UiHeader.vue' | |
| 74 | +import uiHeader from '../../layout/UiHeader.vue' | |
| 75 | + | |
| 83 | 76 | export default { |
| 84 | 77 | name: "SettingForMedia", |
| 85 | 78 | components: { |
| ... | ... | @@ -107,9 +100,9 @@ export default { |
| 107 | 100 | }, |
| 108 | 101 | |
| 109 | 102 | rules: { |
| 110 | - IP: [{ required: true, message: "请输入名称", trigger: "blur" }], | |
| 111 | - wanIp: [{ required: false, message: "请输入应用名", trigger: "blur" }], | |
| 112 | - hookIp: [{ required: false, message: "请输入流ID", trigger: "blur" }], | |
| 103 | + IP: [{required: true, message: "请输入名称", trigger: "blur"}], | |
| 104 | + wanIp: [{required: false, message: "请输入应用名", trigger: "blur"}], | |
| 105 | + hookIp: [{required: false, message: "请输入流ID", trigger: "blur"}], | |
| 113 | 106 | }, |
| 114 | 107 | } |
| 115 | 108 | } | ... | ... |
web_src/src/components/setting/Sip.vue
| 1 | 1 | <template> |
| 2 | - <div id="SettingForSip"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: bold;">国标服务</span> | |
| 10 | - </div> | |
| 11 | - <div style="width: 60%; margin:0 auto; background-color: #FFFFFF; position: relative; padding: 5rem 6.5rem; text-align: left;font-size: 14px; max-width: 400px"> | |
| 12 | - <el-form ref="form" :rules="rules" :model="form" label-width="140px"> | |
| 13 | - <el-form-item label="ip" prop="ip"> | |
| 14 | - <el-input v-model="form.ip" clearable></el-input> | |
| 15 | - </el-form-item> | |
| 16 | - <el-form-item label="端口" prop="port"> | |
| 17 | - <el-input v-model.number="form.port" clearable></el-input> | |
| 18 | - </el-form-item> | |
| 19 | - <el-form-item label="域" prop="domain"> | |
| 20 | - <el-input v-model="form.domain" clearable></el-input> | |
| 21 | - </el-form-item> | |
| 22 | - <el-form-item label="id" prop="id"> | |
| 23 | - <el-input v-model="form.id" clearable></el-input> | |
| 24 | - </el-form-item> | |
| 25 | - <el-form-item label="密码" prop="password"> | |
| 26 | - <el-input v-model="form.password" clearable></el-input> | |
| 27 | - </el-form-item> | |
| 2 | + <div id="SettingForSip" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title">国标服务</div> | |
| 5 | + </div> | |
| 6 | + <div | |
| 7 | + style="width: 60%; margin:0 auto; background-color: #FFFFFF; position: relative; padding: 5rem 6.5rem; text-align: left;font-size: 14px; max-width: 400px"> | |
| 8 | + <el-form ref="form" :rules="rules" :model="form" label-width="140px"> | |
| 9 | + <el-form-item label="ip" prop="ip"> | |
| 10 | + <el-input v-model="form.ip" clearable></el-input> | |
| 11 | + </el-form-item> | |
| 12 | + <el-form-item label="端口" prop="port"> | |
| 13 | + <el-input v-model.number="form.port" clearable></el-input> | |
| 14 | + </el-form-item> | |
| 15 | + <el-form-item label="域" prop="domain"> | |
| 16 | + <el-input v-model="form.domain" clearable></el-input> | |
| 17 | + </el-form-item> | |
| 18 | + <el-form-item label="id" prop="id"> | |
| 19 | + <el-input v-model="form.id" clearable></el-input> | |
| 20 | + </el-form-item> | |
| 21 | + <el-form-item label="密码" prop="password"> | |
| 22 | + <el-input v-model="form.password" clearable></el-input> | |
| 23 | + </el-form-item> | |
| 28 | 24 | |
| 29 | 25 | |
| 30 | - <el-form-item> | |
| 31 | - <div style="float: right;"> | |
| 32 | - <el-button type="primary" @click="onSubmit">保存</el-button> | |
| 33 | -<!-- <el-button @click="close">取消</el-button>--> | |
| 34 | - </div> | |
| 26 | + <el-form-item> | |
| 27 | + <div style="float: right;"> | |
| 28 | + <el-button type="primary" @click="onSubmit">保存</el-button> | |
| 29 | + <!-- <el-button @click="close">取消</el-button>--> | |
| 30 | + </div> | |
| 35 | 31 | |
| 36 | - </el-form-item> | |
| 37 | - </el-form> | |
| 38 | - </div> | |
| 39 | - | |
| 40 | - | |
| 41 | - </el-main> | |
| 42 | - </el-container> | |
| 32 | + </el-form-item> | |
| 33 | + </el-form> | |
| 34 | + </div> | |
| 43 | 35 | </div> |
| 44 | 36 | </template> |
| 45 | 37 | |
| 46 | 38 | <script> |
| 47 | -import uiHeader from '../UiHeader.vue' | |
| 39 | +import uiHeader from '../../layout/UiHeader.vue' | |
| 40 | + | |
| 48 | 41 | export default { |
| 49 | 42 | name: "SettingForSip", |
| 50 | 43 | components: { |
| ... | ... | @@ -61,11 +54,11 @@ export default { |
| 61 | 54 | }, |
| 62 | 55 | |
| 63 | 56 | rules: { |
| 64 | - ip: [{ required: true, message: "请输入名称", trigger: "blur" }], | |
| 65 | - port: [{ required: true, message: "请输入应用名", trigger: "blur" }], | |
| 66 | - domain: [{ required: true, message: "请输入流ID", trigger: "blur" }], | |
| 67 | - id: [{ required: true, message: "请输入国标编码", trigger: "blur" }], | |
| 68 | - password: [{ required: true, message: "请输入国标编码", trigger: "blur" }], | |
| 57 | + ip: [{required: true, message: "请输入名称", trigger: "blur"}], | |
| 58 | + port: [{required: true, message: "请输入应用名", trigger: "blur"}], | |
| 59 | + domain: [{required: true, message: "请输入流ID", trigger: "blur"}], | |
| 60 | + id: [{required: true, message: "请输入国标编码", trigger: "blur"}], | |
| 61 | + password: [{required: true, message: "请输入国标编码", trigger: "blur"}], | |
| 69 | 62 | }, |
| 70 | 63 | } |
| 71 | 64 | } | ... | ... |
web_src/src/components/setting/Web.vue
| 1 | 1 | <template> |
| 2 | - <div id="SettingForWeb"> | |
| 3 | - <el-container> | |
| 4 | - <el-header> | |
| 5 | - <uiHeader></uiHeader> | |
| 6 | - </el-header> | |
| 7 | - <el-main> | |
| 8 | - <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> | |
| 9 | - <span style="font-size: 1rem; font-weight: bold;">WEB服务</span> | |
| 2 | + <div id="SettingForWeb" style="width: 100%"> | |
| 3 | + <div class="page-header"> | |
| 4 | + <div class="page-title">WEB服务</div> | |
| 10 | 5 | </div> |
| 11 | 6 | <div style="width: 60%; margin:0 auto; background-color: #FFFFFF; position: relative; padding: 5rem 6.5rem; text-align: left;font-size: 14px; max-width: 400px"> |
| 12 | 7 | <el-form ref="form" :rules="rules" :model="form" label-width="140px"> |
| ... | ... | @@ -41,15 +36,11 @@ |
| 41 | 36 | </el-form-item> |
| 42 | 37 | </el-form> |
| 43 | 38 | </div> |
| 44 | - | |
| 45 | - | |
| 46 | - </el-main> | |
| 47 | - </el-container> | |
| 48 | 39 | </div> |
| 49 | 40 | </template> |
| 50 | 41 | |
| 51 | 42 | <script> |
| 52 | -import uiHeader from '../UiHeader.vue' | |
| 43 | +import uiHeader from '../../layout/UiHeader.vue' | |
| 53 | 44 | export default { |
| 54 | 45 | name: "SettingForWeb", |
| 55 | 46 | components: { | ... | ... |
web_src/src/components/UiHeader.vue renamed to web_src/src/layout/UiHeader.vue
| 1 | 1 | <template> |
| 2 | - <div id="UiHeader"> | |
| 3 | - <el-menu router :default-active="activeIndex" menu-trigger="click" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" mode="horizontal"> | |
| 4 | - <el-menu-item index="/">控制台</el-menu-item> | |
| 5 | - <el-menu-item index="/live">实时监控</el-menu-item> | |
| 6 | - <el-menu-item index="/deviceList">国标设备</el-menu-item> | |
| 7 | - <el-menu-item index="/pushVideoList">推流列表</el-menu-item> | |
| 8 | - <el-menu-item index="/streamProxyList">拉流代理</el-menu-item> | |
| 9 | - <el-menu-item index="/cloudRecord">云端录像</el-menu-item> | |
| 10 | - <el-menu-item index="/mediaServerManger">节点管理</el-menu-item> | |
| 11 | - <el-menu-item index="/parentPlatformList/15/1">国标级联</el-menu-item> | |
| 12 | - <el-menu-item @click="openDoc">在线文档</el-menu-item> | |
| 13 | -<!-- <el-submenu index="/setting">--> | |
| 14 | -<!-- <template slot="title">系统设置</template>--> | |
| 15 | -<!-- <el-menu-item index="/setting/web">WEB服务</el-menu-item>--> | |
| 16 | -<!-- <el-menu-item index="/setting/sip">国标服务</el-menu-item>--> | |
| 17 | -<!-- <el-menu-item index="/setting/media">媒体服务</el-menu-item>--> | |
| 18 | -<!-- </el-submenu>--> | |
| 19 | - <el-switch v-model="alarmNotify" active-text="报警信息推送" style="display: block float: right" @change="alarmNotifyChannge"></el-switch> | |
| 20 | -<!-- <el-menu-item style="float: right;" @click="loginout">退出</el-menu-item>--> | |
| 21 | - <el-submenu index="" style="float: right;" > | |
| 22 | - <template slot="title">欢迎,{{this.$cookies.get("session").username}}</template> | |
| 23 | - <el-menu-item @click="changePassword">修改密码</el-menu-item> | |
| 24 | - <el-menu-item @click="loginout">注销</el-menu-item> | |
| 25 | - </el-submenu> | |
| 26 | - </el-menu> | |
| 2 | + <div id="UiHeader"> | |
| 3 | + <el-menu router :default-active="activeIndex" menu-trigger="click" background-color="#545c64" text-color="#fff" | |
| 4 | + active-text-color="#ffd04b" mode="horizontal"> | |
| 5 | + <el-menu-item index="/control">控制台</el-menu-item> | |
| 6 | + <el-menu-item index="/live">实时监控</el-menu-item> | |
| 7 | + <el-menu-item index="/deviceList">国标设备</el-menu-item> | |
| 8 | + <el-menu-item index="/pushVideoList">推流列表</el-menu-item> | |
| 9 | + <el-menu-item index="/streamProxyList">拉流代理</el-menu-item> | |
| 10 | + <el-menu-item index="/cloudRecord">云端录像</el-menu-item> | |
| 11 | + <el-menu-item index="/mediaServerManger">节点管理</el-menu-item> | |
| 12 | + <el-menu-item index="/parentPlatformList/15/1">国标级联</el-menu-item> | |
| 13 | + <el-menu-item @click="openDoc">在线文档</el-menu-item> | |
| 14 | + <!-- <el-submenu index="/setting">--> | |
| 15 | + <!-- <template slot="title">系统设置</template>--> | |
| 16 | + <!-- <el-menu-item index="/setting/web">WEB服务</el-menu-item>--> | |
| 17 | + <!-- <el-menu-item index="/setting/sip">国标服务</el-menu-item>--> | |
| 18 | + <!-- <el-menu-item index="/setting/media">媒体服务</el-menu-item>--> | |
| 19 | + <!-- </el-submenu>--> | |
| 20 | + <el-switch v-model="alarmNotify" active-text="报警信息推送" @change="alarmNotifyChannge"></el-switch> | |
| 21 | + <!-- <el-menu-item style="float: right;" @click="loginout">退出</el-menu-item>--> | |
| 22 | + <el-submenu index="" style="float: right;"> | |
| 23 | + <template slot="title">欢迎,{{ this.$cookies.get("session").username }}</template> | |
| 24 | + <el-menu-item @click="changePassword">修改密码</el-menu-item> | |
| 25 | + <el-menu-item @click="loginout">注销</el-menu-item> | |
| 26 | + </el-submenu> | |
| 27 | + </el-menu> | |
| 27 | 28 | <changePasswordDialog ref="changePasswordDialog"></changePasswordDialog> |
| 28 | - </div> | |
| 29 | + </div> | |
| 29 | 30 | </template> |
| 30 | 31 | |
| 31 | 32 | <script> |
| 32 | 33 | |
| 33 | -import changePasswordDialog from './dialog/changePassword.vue' | |
| 34 | +import changePasswordDialog from '../components/dialog/changePassword.vue' | |
| 35 | + | |
| 34 | 36 | export default { |
| 35 | - name: "UiHeader", | |
| 36 | - components: { Notification, changePasswordDialog }, | |
| 37 | - data() { | |
| 38 | - return { | |
| 39 | - alarmNotify: false, | |
| 40 | - sseSource: null, | |
| 41 | - activeIndex: this.$route.path, | |
| 42 | - }; | |
| 43 | - }, | |
| 44 | - created(){ | |
| 45 | - if (this.$route.path.startsWith("/channelList")){ | |
| 46 | - this.activeIndex = "/deviceList" | |
| 47 | - } | |
| 37 | + name: "UiHeader", | |
| 38 | + components: {Notification, changePasswordDialog}, | |
| 39 | + data() { | |
| 40 | + return { | |
| 41 | + alarmNotify: false, | |
| 42 | + sseSource: null, | |
| 43 | + activeIndex: this.$route.path, | |
| 44 | + }; | |
| 45 | + }, | |
| 46 | + created() { | |
| 47 | + if (this.$route.path.startsWith("/channelList")) { | |
| 48 | + this.activeIndex = "/deviceList" | |
| 49 | + } | |
| 48 | 50 | |
| 51 | + }, | |
| 52 | + mounted() { | |
| 53 | + window.addEventListener('beforeunload', e => this.beforeunloadHandler(e)) | |
| 54 | + // window.addEventListener('unload', e => this.unloadHandler(e)) | |
| 55 | + this.alarmNotify = this.getAlarmSwitchStatus() === "true"; | |
| 56 | + this.sseControl(); | |
| 57 | + }, | |
| 58 | + methods: { | |
| 59 | + loginout() { | |
| 60 | + this.$axios({ | |
| 61 | + method: 'get', | |
| 62 | + url: "/api/user/logout" | |
| 63 | + }).then((res) => { | |
| 64 | + // 删除cookie,回到登录页面 | |
| 65 | + this.$cookies.remove("session"); | |
| 66 | + this.$router.push('/login'); | |
| 67 | + this.sseSource.close(); | |
| 68 | + }).catch((error) => { | |
| 69 | + console.error("登出失败") | |
| 70 | + console.error(error) | |
| 71 | + }); | |
| 72 | + }, | |
| 73 | + changePassword() { | |
| 74 | + this.$refs.changePasswordDialog.openDialog() | |
| 49 | 75 | }, |
| 50 | - mounted() { | |
| 51 | - window.addEventListener('beforeunload', e => this.beforeunloadHandler(e)) | |
| 52 | - // window.addEventListener('unload', e => this.unloadHandler(e)) | |
| 53 | - this.alarmNotify = this.getAlarmSwitchStatus() === "true"; | |
| 54 | - this.sseControl(); | |
| 76 | + openDoc() { | |
| 77 | + console.log(process.env.BASE_API) | |
| 78 | + window.open(!!process.env.BASE_API ? process.env.BASE_API + "/doc.html" : "/doc.html") | |
| 55 | 79 | }, |
| 56 | - methods:{ | |
| 57 | - loginout(){ | |
| 58 | - this.$axios({ | |
| 59 | - method: 'get', | |
| 60 | - url:"/api/user/logout" | |
| 61 | - }).then((res)=> { | |
| 62 | - // 删除cookie,回到登录页面 | |
| 63 | - this.$cookies.remove("session"); | |
| 64 | - this.$router.push('/login'); | |
| 65 | - this.sseSource.close(); | |
| 66 | - }).catch((error)=> { | |
| 67 | - console.error("登出失败") | |
| 68 | - console.error(error) | |
| 80 | + beforeunloadHandler() { | |
| 81 | + this.sseSource.close(); | |
| 82 | + }, | |
| 83 | + alarmNotifyChannge() { | |
| 84 | + this.setAlarmSwitchStatus() | |
| 85 | + this.sseControl() | |
| 86 | + }, | |
| 87 | + sseControl() { | |
| 88 | + let that = this; | |
| 89 | + if (this.alarmNotify) { | |
| 90 | + console.log("申请SSE推送API调用,浏览器ID: " + this.$browserId); | |
| 91 | + this.sseSource = new EventSource('/api/emit?browserId=' + this.$browserId); | |
| 92 | + this.sseSource.addEventListener('message', function (evt) { | |
| 93 | + that.$notify({ | |
| 94 | + title: '收到报警信息', | |
| 95 | + dangerouslyUseHTMLString: true, | |
| 96 | + message: evt.data, | |
| 97 | + type: 'warning' | |
| 69 | 98 | }); |
| 70 | - }, | |
| 71 | - changePassword(){ | |
| 72 | - this.$refs.changePasswordDialog.openDialog() | |
| 73 | - }, | |
| 74 | - openDoc(){ | |
| 75 | - console.log(process.env.BASE_API) | |
| 76 | - window.open( !!process.env.BASE_API? process.env.BASE_API + "/doc.html": "/doc.html") | |
| 77 | - }, | |
| 78 | - beforeunloadHandler() { | |
| 79 | - this.sseSource.close(); | |
| 80 | - }, | |
| 81 | - alarmNotifyChannge(){ | |
| 82 | - this.setAlarmSwitchStatus() | |
| 83 | - this.sseControl() | |
| 84 | - }, | |
| 85 | - sseControl() { | |
| 86 | - let that = this; | |
| 87 | - if (this.alarmNotify) { | |
| 88 | - console.log("申请SSE推送API调用,浏览器ID: " + this.$browserId); | |
| 89 | - this.sseSource = new EventSource('/api/emit?browserId=' + this.$browserId); | |
| 90 | - this.sseSource.addEventListener('message', function(evt) { | |
| 91 | - that.$notify({ | |
| 92 | - title: '收到报警信息', | |
| 93 | - dangerouslyUseHTMLString: true, | |
| 94 | - message: evt.data, | |
| 95 | - type: 'warning' | |
| 96 | - }); | |
| 97 | - console.log("收到信息:" + evt.data); | |
| 98 | - }); | |
| 99 | - this.sseSource.addEventListener('open', function(e) { | |
| 100 | - console.log("SSE连接打开."); | |
| 101 | - }, false); | |
| 102 | - this.sseSource.addEventListener('error', function(e) { | |
| 103 | - if (e.target.readyState == EventSource.CLOSED) { | |
| 104 | - console.log("SSE连接关闭"); | |
| 105 | - } else { | |
| 106 | - console.log(e.target.readyState); | |
| 107 | - } | |
| 108 | - }, false); | |
| 109 | - } else { | |
| 110 | - if (this.sseSource != null) { | |
| 111 | - this.sseSource.removeEventListener('open', null); | |
| 112 | - this.sseSource.removeEventListener('message', null); | |
| 113 | - this.sseSource.removeEventListener('error', null); | |
| 114 | - this.sseSource.close(); | |
| 115 | - } | |
| 116 | - | |
| 117 | - } | |
| 118 | - }, | |
| 119 | - getAlarmSwitchStatus(){ | |
| 120 | - if (localStorage.getItem("alarmSwitchStatus") == null) { | |
| 121 | - localStorage.setItem("alarmSwitchStatus", false); | |
| 99 | + console.log("收到信息:" + evt.data); | |
| 100 | + }); | |
| 101 | + this.sseSource.addEventListener('open', function (e) { | |
| 102 | + console.log("SSE连接打开."); | |
| 103 | + }, false); | |
| 104 | + this.sseSource.addEventListener('error', function (e) { | |
| 105 | + if (e.target.readyState == EventSource.CLOSED) { | |
| 106 | + console.log("SSE连接关闭"); | |
| 107 | + } else { | |
| 108 | + console.log(e.target.readyState); | |
| 122 | 109 | } |
| 123 | - return localStorage.getItem("alarmSwitchStatus"); | |
| 124 | - }, | |
| 125 | - setAlarmSwitchStatus(){ | |
| 126 | - localStorage.setItem("alarmSwitchStatus", this.alarmNotify); | |
| 127 | - } | |
| 128 | - }, | |
| 129 | - destroyed() { | |
| 130 | - window.removeEventListener('beforeunload', e => this.beforeunloadHandler(e)) | |
| 110 | + }, false); | |
| 111 | + } else { | |
| 131 | 112 | if (this.sseSource != null) { |
| 132 | 113 | this.sseSource.removeEventListener('open', null); |
| 133 | 114 | this.sseSource.removeEventListener('message', null); |
| 134 | 115 | this.sseSource.removeEventListener('error', null); |
| 135 | 116 | this.sseSource.close(); |
| 136 | 117 | } |
| 118 | + | |
| 119 | + } | |
| 120 | + }, | |
| 121 | + getAlarmSwitchStatus() { | |
| 122 | + if (localStorage.getItem("alarmSwitchStatus") == null) { | |
| 123 | + localStorage.setItem("alarmSwitchStatus", false); | |
| 124 | + } | |
| 125 | + return localStorage.getItem("alarmSwitchStatus"); | |
| 137 | 126 | }, |
| 127 | + setAlarmSwitchStatus() { | |
| 128 | + localStorage.setItem("alarmSwitchStatus", this.alarmNotify); | |
| 129 | + } | |
| 130 | + }, | |
| 131 | + destroyed() { | |
| 132 | + window.removeEventListener('beforeunload', e => this.beforeunloadHandler(e)) | |
| 133 | + if (this.sseSource != null) { | |
| 134 | + this.sseSource.removeEventListener('open', null); | |
| 135 | + this.sseSource.removeEventListener('message', null); | |
| 136 | + this.sseSource.removeEventListener('error', null); | |
| 137 | + this.sseSource.close(); | |
| 138 | + } | |
| 139 | + }, | |
| 138 | 140 | |
| 139 | - } | |
| 141 | +} | |
| 140 | 142 | |
| 141 | 143 | </script> |
| 144 | +<style> | |
| 145 | +#UiHeader .el-switch__label { | |
| 146 | + color: white; | |
| 147 | +} | |
| 148 | +#UiHeader .el-switch__label.is-active{ | |
| 149 | + color: #409EFF; | |
| 150 | +} | |
| 151 | +</style> | ... | ... |
web_src/src/layout/index.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <el-container style="height: 100%"> | |
| 3 | + <el-header> | |
| 4 | + <ui-header/> | |
| 5 | + </el-header> | |
| 6 | + <el-main> | |
| 7 | + <el-container> | |
| 8 | + <transition name="fade"> | |
| 9 | + <router-view></router-view> | |
| 10 | + </transition> | |
| 11 | + </el-container> | |
| 12 | + </el-main> | |
| 13 | + </el-container> | |
| 14 | +</template> | |
| 15 | + | |
| 16 | +<script> | |
| 17 | +import uiHeader from "./UiHeader.vue"; | |
| 18 | + | |
| 19 | +export default { | |
| 20 | + name: "index", | |
| 21 | + components: { | |
| 22 | + uiHeader | |
| 23 | + }, | |
| 24 | +} | |
| 25 | +</script> | |
| 26 | +<style> | |
| 27 | +/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/ | |
| 28 | +::-webkit-scrollbar { | |
| 29 | + width: 8px; | |
| 30 | + height: 8px; | |
| 31 | +} | |
| 32 | + | |
| 33 | +/*定义滚动条轨道 内阴影+圆角*/ | |
| 34 | +::-webkit-scrollbar-track { | |
| 35 | + border-radius: 4px; | |
| 36 | + background-color: #F5F5F5; | |
| 37 | +} | |
| 38 | + | |
| 39 | +/*定义滑块 内阴影+圆角*/ | |
| 40 | +::-webkit-scrollbar-thumb { | |
| 41 | + border-radius: 4px; | |
| 42 | + background-color: #c8c8c8; | |
| 43 | + box-shadow: inset 0 0 6px rgba(0, 0, 0, .1); | |
| 44 | + -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .1); | |
| 45 | +} | |
| 46 | + | |
| 47 | +/*定义标题栏*/ | |
| 48 | +.page-header { | |
| 49 | + background-color: #FFFFFF; | |
| 50 | + margin-bottom: 1rem; | |
| 51 | + padding: 0.5rem; | |
| 52 | + display: flex; | |
| 53 | + justify-content: space-between; | |
| 54 | + align-items: center; | |
| 55 | +} | |
| 56 | + | |
| 57 | +.page-title { | |
| 58 | + font-weight: bold; | |
| 59 | + text-align: left; | |
| 60 | +} | |
| 61 | + | |
| 62 | +.page-header-btn { | |
| 63 | + text-align: right; | |
| 64 | +} | |
| 65 | +</style> | |
| 66 | +<style scoped> | |
| 67 | +.el-main { | |
| 68 | + margin: 0; | |
| 69 | +} | |
| 70 | + | |
| 71 | +.fade-enter { | |
| 72 | + visibility: hidden; | |
| 73 | + opacity: 0; | |
| 74 | +} | |
| 75 | + | |
| 76 | +.fade-leave-to { | |
| 77 | + display: none; | |
| 78 | +} | |
| 79 | + | |
| 80 | +.fade-enter-active, | |
| 81 | +.fade-leave-active { | |
| 82 | + transition: opacity .5s ease; | |
| 83 | +} | |
| 84 | + | |
| 85 | +.fade-enter-to, | |
| 86 | +.fade-leave { | |
| 87 | + visibility: visible; | |
| 88 | + opacity: 1; | |
| 89 | +} | |
| 90 | +</style> | ... | ... |
web_src/src/router/index.js
| 1 | 1 | import Vue from 'vue' |
| 2 | 2 | import VueRouter from 'vue-router' |
| 3 | +import Layout from "../layout/index.vue" | |
| 3 | 4 | |
| 4 | 5 | import control from '../components/control.vue' |
| 5 | 6 | import deviceList from '../components/DeviceList.vue' |
| ... | ... | @@ -32,78 +33,86 @@ export default new VueRouter({ |
| 32 | 33 | routes: [ |
| 33 | 34 | { |
| 34 | 35 | path: '/', |
| 35 | - component: control, | |
| 36 | - }, | |
| 37 | - { | |
| 38 | - path: '/live', | |
| 39 | - component: live, | |
| 40 | - }, | |
| 41 | - { | |
| 42 | - path: '/deviceList', | |
| 43 | - component: deviceList, | |
| 44 | - }, | |
| 45 | - { | |
| 46 | - path: '/pushVideoList', | |
| 47 | - component: pushVideoList, | |
| 48 | - }, | |
| 49 | - { | |
| 50 | - path: '/streamProxyList', | |
| 51 | - component: streamProxyList, | |
| 36 | + name: 'home', | |
| 37 | + component: Layout, | |
| 38 | + redirect: '/control', | |
| 39 | + children: [ | |
| 40 | + { | |
| 41 | + path: '/control', | |
| 42 | + component: control, | |
| 43 | + }, | |
| 44 | + { | |
| 45 | + path: '/live', | |
| 46 | + component: live, | |
| 47 | + }, | |
| 48 | + { | |
| 49 | + path: '/deviceList', | |
| 50 | + component: deviceList, | |
| 51 | + }, | |
| 52 | + { | |
| 53 | + path: '/pushVideoList', | |
| 54 | + component: pushVideoList, | |
| 55 | + }, | |
| 56 | + { | |
| 57 | + path: '/streamProxyList', | |
| 58 | + component: streamProxyList, | |
| 59 | + }, | |
| 60 | + { | |
| 61 | + path: '/channelList/:deviceId/:parentChannelId/:count/:page', | |
| 62 | + name: 'channelList', | |
| 63 | + component: channelList, | |
| 64 | + }, | |
| 65 | + { | |
| 66 | + path: '/parentPlatformList/:count/:page', | |
| 67 | + name: 'parentPlatformList', | |
| 68 | + component: parentPlatformList, | |
| 69 | + }, | |
| 70 | + { | |
| 71 | + path: '/devicePosition/:deviceId/:parentChannelId/:count/:page', | |
| 72 | + name: 'devicePosition', | |
| 73 | + component: devicePosition, | |
| 74 | + }, | |
| 75 | + { | |
| 76 | + path: '/cloudRecord', | |
| 77 | + name: 'cloudRecord', | |
| 78 | + component: cloudRecord, | |
| 79 | + }, | |
| 80 | + { | |
| 81 | + path: '/mediaServerManger', | |
| 82 | + name: 'mediaServerManger', | |
| 83 | + component: mediaServerManger, | |
| 84 | + }, | |
| 85 | + { | |
| 86 | + path: '/setting/web', | |
| 87 | + name: 'web', | |
| 88 | + component: web, | |
| 89 | + }, | |
| 90 | + { | |
| 91 | + path: '/setting/sip', | |
| 92 | + name: 'sip', | |
| 93 | + component: sip, | |
| 94 | + }, | |
| 95 | + { | |
| 96 | + path: '/setting/media', | |
| 97 | + name: 'media', | |
| 98 | + component: media, | |
| 99 | + }, | |
| 100 | + { | |
| 101 | + path: '/play/wasm/:url', | |
| 102 | + name: 'wasmPlayer', | |
| 103 | + component: wasmPlayer, | |
| 104 | + }, | |
| 105 | + { | |
| 106 | + path: '/play/rtc/:url', | |
| 107 | + name: 'rtcPlayer', | |
| 108 | + component: rtcPlayer, | |
| 109 | + }, | |
| 110 | + ] | |
| 52 | 111 | }, |
| 53 | 112 | { |
| 54 | 113 | path: '/login', |
| 55 | 114 | name: '登录', |
| 56 | 115 | component: login, |
| 57 | 116 | }, |
| 58 | - { | |
| 59 | - path: '/channelList/:deviceId/:parentChannelId/:count/:page', | |
| 60 | - name: 'channelList', | |
| 61 | - component: channelList, | |
| 62 | - }, | |
| 63 | - { | |
| 64 | - path: '/parentPlatformList/:count/:page', | |
| 65 | - name: 'parentPlatformList', | |
| 66 | - component: parentPlatformList, | |
| 67 | - }, | |
| 68 | - { | |
| 69 | - path: '/devicePosition/:deviceId/:parentChannelId/:count/:page', | |
| 70 | - name: 'devicePosition', | |
| 71 | - component: devicePosition, | |
| 72 | - }, | |
| 73 | - { | |
| 74 | - path: '/cloudRecord', | |
| 75 | - name: 'cloudRecord', | |
| 76 | - component: cloudRecord, | |
| 77 | - }, | |
| 78 | - { | |
| 79 | - path: '/mediaServerManger', | |
| 80 | - name: 'mediaServerManger', | |
| 81 | - component: mediaServerManger, | |
| 82 | - }, | |
| 83 | - { | |
| 84 | - path: '/setting/web', | |
| 85 | - name: 'web', | |
| 86 | - component: web, | |
| 87 | - }, | |
| 88 | - { | |
| 89 | - path: '/setting/sip', | |
| 90 | - name: 'sip', | |
| 91 | - component: sip, | |
| 92 | - }, | |
| 93 | - { | |
| 94 | - path: '/setting/media', | |
| 95 | - name: 'media', | |
| 96 | - component: media, | |
| 97 | - }, | |
| 98 | - { | |
| 99 | - path: '/play/wasm/:url', | |
| 100 | - name: 'wasmPlayer', | |
| 101 | - component: wasmPlayer, | |
| 102 | - }, | |
| 103 | - { | |
| 104 | - path: '/play/rtc/:url', | |
| 105 | - name: 'rtcPlayer', | |
| 106 | - component: rtcPlayer, | |
| 107 | - }, | |
| 108 | 117 | ] |
| 109 | 118 | }) | ... | ... |