Commit 3469271ec25c69e4528b085ba3be7d9d85ec519e
1 parent
379830f7
优化集群方案, 每个zlm一套ssrc;
优化集群下的docker接入逻辑; 更正sql脚本; 支持重启不设置设备离线。重启SIP事务不丢失
Showing
56 changed files
with
1312 additions
and
1070 deletions
pom.xml
| @@ -46,6 +46,7 @@ | @@ -46,6 +46,7 @@ | ||
| 46 | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | 46 | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| 47 | <maven.build.timestamp.format>MMddHHmm</maven.build.timestamp.format> | 47 | <maven.build.timestamp.format>MMddHHmm</maven.build.timestamp.format> |
| 48 | <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version> | 48 | <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version> |
| 49 | + <jedis-version>3.1.0</jedis-version> | ||
| 49 | 50 | ||
| 50 | <!-- 依赖版本 --> | 51 | <!-- 依赖版本 --> |
| 51 | <pagehelper.version>5.2.0</pagehelper.version> | 52 | <pagehelper.version>5.2.0</pagehelper.version> |
| @@ -80,6 +81,12 @@ | @@ -80,6 +81,12 @@ | ||
| 80 | <artifactId>spring-boot-starter-security</artifactId> | 81 | <artifactId>spring-boot-starter-security</artifactId> |
| 81 | </dependency> | 82 | </dependency> |
| 82 | 83 | ||
| 84 | + <dependency> | ||
| 85 | + <groupId>redis.clients</groupId> | ||
| 86 | + <artifactId>jedis</artifactId> | ||
| 87 | + <version>${jedis-version}</version> | ||
| 88 | + </dependency> | ||
| 89 | + | ||
| 83 | <!-- druid数据库连接池 --> | 90 | <!-- druid数据库连接池 --> |
| 84 | <dependency> | 91 | <dependency> |
| 85 | <groupId>com.alibaba</groupId> | 92 | <groupId>com.alibaba</groupId> |
sql/mysql.sql
| 1 | -- auto-generated definition | 1 | -- auto-generated definition |
| 2 | -create schema wvp collate utf8_bin; | 2 | + |
| 3 | + | ||
| 4 | +CREATE DATABASE `wvp` /*!40100 DEFAULT CHARACTER SET utf8mb3 COLLATE utf8mb3_bin */; | ||
| 5 | + | ||
| 6 | +use wvp; | ||
| 3 | 7 | ||
| 4 | create table device | 8 | create table device |
| 5 | ( | 9 | ( |
| 6 | - deviceId varchar(50) not null | 10 | + deviceId varchar(50) not null |
| 7 | primary key, | 11 | primary key, |
| 8 | - name varchar(255) null, | ||
| 9 | - manufacturer varchar(255) null, | ||
| 10 | - model varchar(255) null, | ||
| 11 | - firmware varchar(255) null, | ||
| 12 | - transport varchar(50) null, | ||
| 13 | - streamMode varchar(50) null, | ||
| 14 | - online varchar(50) null, | ||
| 15 | - registerTime varchar(50) null, | ||
| 16 | - keepaliveTime varchar(50) null, | ||
| 17 | - ip varchar(50) not null, | ||
| 18 | - createTime varchar(50) not null, | ||
| 19 | - updateTime varchar(50) not null, | ||
| 20 | - port int not null, | ||
| 21 | - expires int not null, | ||
| 22 | - hostAddress varchar(50) not null | 12 | + name varchar(255) null, |
| 13 | + manufacturer varchar(255) null, | ||
| 14 | + model varchar(255) null, | ||
| 15 | + firmware varchar(255) null, | ||
| 16 | + transport varchar(50) null, | ||
| 17 | + streamMode varchar(50) null, | ||
| 18 | + online varchar(50) null, | ||
| 19 | + registerTime varchar(50) null, | ||
| 20 | + keepaliveTime varchar(50) null, | ||
| 21 | + ip varchar(50) not null, | ||
| 22 | + createTime varchar(50) not null, | ||
| 23 | + updateTime varchar(50) not null, | ||
| 24 | + port int not null, | ||
| 25 | + expires int not null, | ||
| 26 | + hostAddress varchar(50) not null | ||
| 23 | ); | 27 | ); |
| 24 | 28 | ||
| 25 | create table device_channel | 29 | create table device_channel |
| 26 | ( | 30 | ( |
| 27 | - channelId varchar(50) not null, | 31 | + channelId varchar(50) not null, |
| 28 | name varchar(255) null, | 32 | name varchar(255) null, |
| 29 | - manufacture varchar(50) null, | ||
| 30 | - model varchar(50) null, | ||
| 31 | - owner varchar(50) null, | ||
| 32 | - civilCode varchar(50) null, | ||
| 33 | - block varchar(50) null, | ||
| 34 | - address varchar(50) null, | ||
| 35 | - parentId varchar(50) null, | 33 | + manufacture varchar(50) null, |
| 34 | + model varchar(50) null, | ||
| 35 | + owner varchar(50) null, | ||
| 36 | + civilCode varchar(50) null, | ||
| 37 | + block varchar(50) null, | ||
| 38 | + address varchar(50) null, | ||
| 39 | + parentId varchar(50) null, | ||
| 36 | safetyWay int null, | 40 | safetyWay int null, |
| 37 | registerWay int null, | 41 | registerWay int null, |
| 38 | - certNum varchar(50) null, | 42 | + certNum varchar(50) null, |
| 39 | certifiable int null, | 43 | certifiable int null, |
| 40 | errCode int null, | 44 | errCode int null, |
| 41 | - endTime varchar(50) null, | ||
| 42 | - secrecy varchar(50) null, | ||
| 43 | - ipAddress varchar(50) null, | 45 | + endTime varchar(50) null, |
| 46 | + secrecy varchar(50) null, | ||
| 47 | + ipAddress varchar(50) null, | ||
| 44 | port int null, | 48 | port int null, |
| 45 | password varchar(255) null, | 49 | password varchar(255) null, |
| 46 | PTZType int null, | 50 | PTZType int null, |
| 47 | status int null, | 51 | status int null, |
| 48 | longitude double null, | 52 | longitude double null, |
| 49 | latitude double null, | 53 | latitude double null, |
| 50 | - streamId varchar(50) null, | ||
| 51 | - deviceId varchar(50) not null, | ||
| 52 | - parental varchar(50) null, | ||
| 53 | - hasAudio bit(1) null, | ||
| 54 | - createTime varchar(50) not null, | ||
| 55 | - updateTime varchar(50) not null, | 54 | + streamId varchar(50) null, |
| 55 | + deviceId varchar(50) not null, | ||
| 56 | + parental varchar(50) null, | ||
| 57 | + hasAudio bit null, | ||
| 58 | + createTime varchar(50) not null, | ||
| 59 | + updateTime varchar(50) not null, | ||
| 56 | primary key (channelId, deviceId) | 60 | primary key (channelId, deviceId) |
| 57 | ); | 61 | ); |
| 58 | 62 | ||
| 59 | create table device_mobile_position | 63 | create table device_mobile_position |
| 60 | ( | 64 | ( |
| 61 | - deviceId varchar(50) not null, | 65 | + deviceId varchar(50) not null, |
| 62 | deviceName varchar(255) null, | 66 | deviceName varchar(255) null, |
| 63 | - time varchar(50) not null, | 67 | + time varchar(50) not null, |
| 64 | longitude double not null, | 68 | longitude double not null, |
| 65 | latitude double not null, | 69 | latitude double not null, |
| 66 | altitude double null, | 70 | altitude double null, |
| 67 | speed double null, | 71 | speed double null, |
| 68 | direction double null, | 72 | direction double null, |
| 69 | - reportSource varchar(50) null, | ||
| 70 | - geodeticSystem varchar(50) null, | ||
| 71 | - cnLng varchar(50) null, | ||
| 72 | - cnLat varchar(50) null, | 73 | + reportSource varchar(50) null, |
| 74 | + geodeticSystem varchar(50) null, | ||
| 75 | + cnLng varchar(50) null, | ||
| 76 | + cnLat varchar(50) null, | ||
| 73 | primary key (deviceId, time) | 77 | primary key (deviceId, time) |
| 74 | ); | 78 | ); |
| 75 | 79 | ||
| 76 | create table gb_stream | 80 | create table gb_stream |
| 77 | ( | 81 | ( |
| 78 | - app varchar(255) not null, | ||
| 79 | - stream varchar(255) not null, | ||
| 80 | - gbId varchar(50) not null, | ||
| 81 | - name varchar(255) null, | ||
| 82 | - longitude double null, | ||
| 83 | - latitude double null, | ||
| 84 | - streamType varchar(50) null, | ||
| 85 | - status int null, | 82 | + app varchar(255) not null, |
| 83 | + stream varchar(255) not null, | ||
| 84 | + gbId varchar(50) not null, | ||
| 85 | + name varchar(255) null, | ||
| 86 | + longitude double null, | ||
| 87 | + latitude double null, | ||
| 88 | + streamType varchar(50) null, | ||
| 89 | + mediaServerId varchar(50) null, | ||
| 90 | + status int null, | ||
| 86 | primary key (app, stream, gbId) | 91 | primary key (app, stream, gbId) |
| 87 | ); | 92 | ); |
| 88 | 93 | ||
| 94 | +create table media_server | ||
| 95 | +( | ||
| 96 | + id varchar(255) not null | ||
| 97 | + primary key, | ||
| 98 | + ip varchar(50) not null, | ||
| 99 | + hookIp varchar(50) not null, | ||
| 100 | + sdpIp varchar(50) not null, | ||
| 101 | + streamIp varchar(50) not null, | ||
| 102 | + httpPort int not null, | ||
| 103 | + httpSSlPort int not null, | ||
| 104 | + rtmpPort int not null, | ||
| 105 | + rtmpSSlPort int not null, | ||
| 106 | + rtpProxyPort int not null, | ||
| 107 | + rtspPort int not null, | ||
| 108 | + rtspSSLPort int not null, | ||
| 109 | + autoConfig int not null, | ||
| 110 | + secret varchar(50) not null, | ||
| 111 | + streamNoneReaderDelayMS int not null, | ||
| 112 | + rtpEnable int not null, | ||
| 113 | + rtpPortRange varchar(50) not null, | ||
| 114 | + recordAssistPort int not null, | ||
| 115 | + defaultServer int not null, | ||
| 116 | + createTime varchar(50) not null, | ||
| 117 | + updateTime varchar(50) not null, | ||
| 118 | + constraint media_server_i | ||
| 119 | + unique (ip, httpPort) | ||
| 120 | +); | ||
| 121 | + | ||
| 89 | create table parent_platform | 122 | create table parent_platform |
| 90 | ( | 123 | ( |
| 91 | - id int auto_increment, | 124 | + id int auto_increment, |
| 92 | enable int null, | 125 | enable int null, |
| 93 | name varchar(255) null, | 126 | name varchar(255) null, |
| 94 | - serverGBId varchar(50) not null, | ||
| 95 | - serverGBDomain varchar(50) null, | ||
| 96 | - serverIP varchar(50) null, | 127 | + serverGBId varchar(50) not null, |
| 128 | + serverGBDomain varchar(50) null, | ||
| 129 | + serverIP varchar(50) null, | ||
| 97 | serverPort int null, | 130 | serverPort int null, |
| 98 | - deviceGBId varchar(50) not null, | ||
| 99 | - deviceIp varchar(50) null, | ||
| 100 | - devicePort varchar(50) null, | 131 | + deviceGBId varchar(50) not null, |
| 132 | + deviceIp varchar(50) null, | ||
| 133 | + devicePort varchar(50) null, | ||
| 101 | username varchar(255) null, | 134 | username varchar(255) null, |
| 102 | - password varchar(50) null, | ||
| 103 | - expires varchar(50) null, | ||
| 104 | - keepTimeout varchar(50) null, | ||
| 105 | - transport varchar(50) null, | ||
| 106 | - characterSet varchar(50) null, | 135 | + password varchar(50) null, |
| 136 | + expires varchar(50) null, | ||
| 137 | + keepTimeout varchar(50) null, | ||
| 138 | + transport varchar(50) null, | ||
| 139 | + characterSet varchar(50) null, | ||
| 107 | ptz int null, | 140 | ptz int null, |
| 108 | rtcp int null, | 141 | rtcp int null, |
| 109 | - status bit(1) null, | 142 | + status bit null, |
| 110 | primary key (id, serverGBId) | 143 | primary key (id, serverGBId) |
| 111 | ); | 144 | ); |
| 112 | 145 | ||
| @@ -121,7 +154,7 @@ create table platform_gb_channel | @@ -121,7 +154,7 @@ create table platform_gb_channel | ||
| 121 | 154 | ||
| 122 | create table platform_gb_stream | 155 | create table platform_gb_stream |
| 123 | ( | 156 | ( |
| 124 | - platformId varchar(50) not null, | 157 | + platformId varchar(50) not null, |
| 125 | app varchar(255) not null, | 158 | app varchar(255) not null, |
| 126 | stream varchar(255) not null, | 159 | stream varchar(255) not null, |
| 127 | primary key (platformId, app, stream) | 160 | primary key (platformId, app, stream) |
| @@ -129,7 +162,7 @@ create table platform_gb_stream | @@ -129,7 +162,7 @@ create table platform_gb_stream | ||
| 129 | 162 | ||
| 130 | create table stream_proxy | 163 | create table stream_proxy |
| 131 | ( | 164 | ( |
| 132 | - type varchar(50) not null, | 165 | + type varchar(50) not null, |
| 133 | app varchar(255) not null, | 166 | app varchar(255) not null, |
| 134 | stream varchar(255) not null, | 167 | stream varchar(255) not null, |
| 135 | url varchar(255) null, | 168 | url varchar(255) null, |
| @@ -137,11 +170,12 @@ create table stream_proxy | @@ -137,11 +170,12 @@ create table stream_proxy | ||
| 137 | dst_url varchar(255) null, | 170 | dst_url varchar(255) null, |
| 138 | timeout_ms int null, | 171 | timeout_ms int null, |
| 139 | ffmpeg_cmd_key varchar(255) null, | 172 | ffmpeg_cmd_key varchar(255) null, |
| 140 | - rtp_type varchar(50) null, | ||
| 141 | - mediaServerId varchar(50) null, | ||
| 142 | - enable_hls bit(1) null, | ||
| 143 | - enable_mp4 bit(1) null, | ||
| 144 | - enable bit(1) not null, | 173 | + rtp_type varchar(50) null, |
| 174 | + mediaServerId varchar(50) null, | ||
| 175 | + enable_hls bit null, | ||
| 176 | + enable_mp4 bit null, | ||
| 177 | + enable bit not null, | ||
| 178 | + createTime varchar(50) not null, | ||
| 145 | primary key (app, stream) | 179 | primary key (app, stream) |
| 146 | ); | 180 | ); |
| 147 | 181 | ||
| @@ -149,11 +183,12 @@ create table stream_push | @@ -149,11 +183,12 @@ create table stream_push | ||
| 149 | ( | 183 | ( |
| 150 | app varchar(255) not null, | 184 | app varchar(255) not null, |
| 151 | stream varchar(255) not null, | 185 | stream varchar(255) not null, |
| 152 | - totalReaderCount varchar(50) null, | 186 | + totalReaderCount varchar(50) null, |
| 153 | originType int null, | 187 | originType int null, |
| 154 | - originTypeStr varchar(50) null, | 188 | + originTypeStr varchar(50) null, |
| 155 | createStamp int null, | 189 | createStamp int null, |
| 156 | aliveSecond int null, | 190 | aliveSecond int null, |
| 191 | + mediaServerId varchar(50) null, | ||
| 157 | primary key (app, stream) | 192 | primary key (app, stream) |
| 158 | ); | 193 | ); |
| 159 | 194 | ||
| @@ -164,31 +199,6 @@ create table user | @@ -164,31 +199,6 @@ create table user | ||
| 164 | username varchar(255) not null, | 199 | username varchar(255) not null, |
| 165 | password varchar(255) not null, | 200 | password varchar(255) not null, |
| 166 | roleId int not null, | 201 | roleId int not null, |
| 167 | - create_time varchar(50) not null | 202 | + create_time varchar(50) not null |
| 168 | ); | 203 | ); |
| 169 | 204 | ||
| 170 | -insert into user (username, password, roleId, create_time) values ('admin', '21232f297a57a5a743894a0e4a801fc3', '0', '2021-04-13 14:14:57'); | ||
| 171 | - | ||
| 172 | -create table media_server ( | ||
| 173 | - id varchar(255) | ||
| 174 | - primary key, | ||
| 175 | - ip varchar(50) NOT NULL, | ||
| 176 | - hookIp varchar(50) NOT NULL, | ||
| 177 | - sdpIp varchar(50) NOT NULL, | ||
| 178 | - streamIp varchar(50) NOT NULL, | ||
| 179 | - httpPort int NOT NULL, | ||
| 180 | - httpSSlPort int NOT NULL, | ||
| 181 | - rtmpPort int NOT NULL, | ||
| 182 | - rtmpSSlPort int NOT NULL, | ||
| 183 | - rtpProxyPort int NOT NULL, | ||
| 184 | - rtspPort int NOT NULL, | ||
| 185 | - rtspSSLPort int NOT NULL, | ||
| 186 | - autoConfig int NOT NULL, | ||
| 187 | - secret varchar(50) NOT NULL, | ||
| 188 | - streamNoneReaderDelayMS int NOT NULL, | ||
| 189 | - rtpEnable int NOT NULL, | ||
| 190 | - rtpPortRange varchar(50) NOT NULL, | ||
| 191 | - recordAssistPort int NOT NULL, | ||
| 192 | - createTime varchar(50) not null, | ||
| 193 | - updateTime varchar(50) not null | ||
| 194 | -); | ||
| 195 | \ No newline at end of file | 205 | \ No newline at end of file |
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
| @@ -12,6 +12,8 @@ public class VideoManagerConstants { | @@ -12,6 +12,8 @@ public class VideoManagerConstants { | ||
| 12 | 12 | ||
| 13 | public static final String MEDIA_SERVER_PREFIX = "VMP_MEDIA_SERVER_"; | 13 | public static final String MEDIA_SERVER_PREFIX = "VMP_MEDIA_SERVER_"; |
| 14 | 14 | ||
| 15 | + public static final String MEDIA_SERVERS_ONLINE_PREFIX = "VMP_MEDIA_ONLINE_SERVERS"; | ||
| 16 | + | ||
| 15 | public static final String MEDIA_STREAM_PREFIX = "VMP_MEDIA_STREAM"; | 17 | public static final String MEDIA_STREAM_PREFIX = "VMP_MEDIA_STREAM"; |
| 16 | 18 | ||
| 17 | public static final String DEVICE_PREFIX = "VMP_DEVICE_"; | 19 | public static final String DEVICE_PREFIX = "VMP_DEVICE_"; |
| @@ -45,4 +47,8 @@ public class VideoManagerConstants { | @@ -45,4 +47,8 @@ public class VideoManagerConstants { | ||
| 45 | public static final String EVENT_OUTLINE_UNREGISTER = "1"; | 47 | public static final String EVENT_OUTLINE_UNREGISTER = "1"; |
| 46 | 48 | ||
| 47 | public static final String EVENT_OUTLINE_TIMEOUT = "2"; | 49 | public static final String EVENT_OUTLINE_TIMEOUT = "2"; |
| 50 | + | ||
| 51 | + public static final String MEDIA_SSRC_USED_PREFIX = "VMP_media_used_ssrc_"; | ||
| 52 | + | ||
| 53 | + public static final String MEDIA_TRANSACTION_USED_PREFIX = "VMP_media_transaction_"; | ||
| 48 | } | 54 | } |
src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
| 1 | package com.genersoft.iot.vmp.conf; | 1 | package com.genersoft.iot.vmp.conf; |
| 2 | 2 | ||
| 3 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | 3 | +import com.genersoft.iot.vmp.gb28181.session.SsrcConfig; |
| 4 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 4 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 5 | import org.springframework.beans.factory.annotation.Value; | 5 | import org.springframework.beans.factory.annotation.Value; |
| 6 | import org.springframework.context.annotation.Configuration; | 6 | import org.springframework.context.annotation.Configuration; |
| 7 | import org.springframework.util.StringUtils; | 7 | import org.springframework.util.StringUtils; |
| 8 | 8 | ||
| 9 | +import java.text.SimpleDateFormat; | ||
| 10 | +import java.util.Date; | ||
| 11 | + | ||
| 9 | @Configuration("mediaConfig") | 12 | @Configuration("mediaConfig") |
| 10 | -public class MediaConfig implements IMediaServerItem { | 13 | +public class MediaConfig{ |
| 11 | 14 | ||
| 12 | @Value("${media.id:}") | 15 | @Value("${media.id:}") |
| 13 | private String id; | 16 | private String id; |
| @@ -21,6 +24,9 @@ public class MediaConfig implements IMediaServerItem { | @@ -21,6 +24,9 @@ public class MediaConfig implements IMediaServerItem { | ||
| 21 | @Value("${sip.ip}") | 24 | @Value("${sip.ip}") |
| 22 | private String sipIp; | 25 | private String sipIp; |
| 23 | 26 | ||
| 27 | + @Value("${sip.domain}") | ||
| 28 | + private String sipDomain; | ||
| 29 | + | ||
| 24 | @Value("${media.sdp-ip:${media.ip}}") | 30 | @Value("${media.sdp-ip:${media.ip}}") |
| 25 | private String sdpIp; | 31 | private String sdpIp; |
| 26 | 32 | ||
| @@ -66,31 +72,14 @@ public class MediaConfig implements IMediaServerItem { | @@ -66,31 +72,14 @@ public class MediaConfig implements IMediaServerItem { | ||
| 66 | @Value("${media.record-assist-port:0}") | 72 | @Value("${media.record-assist-port:0}") |
| 67 | private Integer recordAssistPort = 0; | 73 | private Integer recordAssistPort = 0; |
| 68 | 74 | ||
| 69 | - private String updateTime; | ||
| 70 | - | ||
| 71 | - private String createTime; | ||
| 72 | - | ||
| 73 | - private boolean docker = false; | ||
| 74 | - | ||
| 75 | - private int count; | ||
| 76 | - | ||
| 77 | - | ||
| 78 | public String getId() { | 75 | public String getId() { |
| 79 | return id; | 76 | return id; |
| 80 | } | 77 | } |
| 81 | 78 | ||
| 82 | - public void setId(String id) { | ||
| 83 | - this.id = id; | ||
| 84 | - } | ||
| 85 | - | ||
| 86 | public String getIp() { | 79 | public String getIp() { |
| 87 | return ip; | 80 | return ip; |
| 88 | } | 81 | } |
| 89 | 82 | ||
| 90 | - public void setIp(String ip) { | ||
| 91 | - this.ip = ip; | ||
| 92 | - } | ||
| 93 | - | ||
| 94 | public String getHookIp() { | 83 | public String getHookIp() { |
| 95 | if (StringUtils.isEmpty(hookIp)){ | 84 | if (StringUtils.isEmpty(hookIp)){ |
| 96 | return sipIp; | 85 | return sipIp; |
| @@ -100,78 +89,26 @@ public class MediaConfig implements IMediaServerItem { | @@ -100,78 +89,26 @@ public class MediaConfig implements IMediaServerItem { | ||
| 100 | 89 | ||
| 101 | } | 90 | } |
| 102 | 91 | ||
| 103 | - public void setHookIp(String hookIp) { | ||
| 104 | - this.hookIp = hookIp; | ||
| 105 | - } | ||
| 106 | - | ||
| 107 | public String getSipIp() { | 92 | public String getSipIp() { |
| 108 | return sipIp; | 93 | return sipIp; |
| 109 | } | 94 | } |
| 110 | 95 | ||
| 111 | - public void setSipIp(String sipIp) { | ||
| 112 | - this.sipIp = sipIp; | ||
| 113 | - } | ||
| 114 | - | ||
| 115 | - public void setSdpIp(String sdpIp) { | ||
| 116 | - this.sdpIp = sdpIp; | ||
| 117 | - } | ||
| 118 | - | ||
| 119 | - public void setStreamIp(String streamIp) { | ||
| 120 | - this.streamIp = streamIp; | ||
| 121 | - } | ||
| 122 | - | ||
| 123 | public int getHttpPort() { | 96 | public int getHttpPort() { |
| 124 | return httpPort; | 97 | return httpPort; |
| 125 | } | 98 | } |
| 126 | 99 | ||
| 127 | - @Override | ||
| 128 | - public void setHttpPort(int httpPort) { | ||
| 129 | - | ||
| 130 | - } | ||
| 131 | - | ||
| 132 | - public void setHttpPort(Integer httpPort) { | ||
| 133 | - this.httpPort = httpPort; | ||
| 134 | - } | ||
| 135 | - | ||
| 136 | public int getHttpSSlPort() { | 100 | public int getHttpSSlPort() { |
| 137 | return httpSSlPort; | 101 | return httpSSlPort; |
| 138 | } | 102 | } |
| 139 | 103 | ||
| 140 | - @Override | ||
| 141 | - public void setHttpSSlPort(int httpSSlPort) { | ||
| 142 | - | ||
| 143 | - } | ||
| 144 | - | ||
| 145 | - public void setHttpSSlPort(Integer httpSSlPort) { | ||
| 146 | - this.httpSSlPort = httpSSlPort; | ||
| 147 | - } | ||
| 148 | - | ||
| 149 | public int getRtmpPort() { | 104 | public int getRtmpPort() { |
| 150 | return rtmpPort; | 105 | return rtmpPort; |
| 151 | } | 106 | } |
| 152 | - | ||
| 153 | - @Override | ||
| 154 | - public void setRtmpPort(int rtmpPort) { | ||
| 155 | - | ||
| 156 | - } | ||
| 157 | - | ||
| 158 | - public void setRtmpPort(Integer rtmpPort) { | ||
| 159 | - this.rtmpPort = rtmpPort; | ||
| 160 | - } | ||
| 161 | - | 107 | + |
| 162 | public int getRtmpSSlPort() { | 108 | public int getRtmpSSlPort() { |
| 163 | return rtmpSSlPort; | 109 | return rtmpSSlPort; |
| 164 | } | 110 | } |
| 165 | 111 | ||
| 166 | - @Override | ||
| 167 | - public void setRtmpSSlPort(int rtmpSSlPort) { | ||
| 168 | - | ||
| 169 | - } | ||
| 170 | - | ||
| 171 | - public void setRtmpSSlPort(Integer rtmpSSlPort) { | ||
| 172 | - this.rtmpSSlPort = rtmpSSlPort; | ||
| 173 | - } | ||
| 174 | - | ||
| 175 | public int getRtpProxyPort() { | 112 | public int getRtpProxyPort() { |
| 176 | if (rtpProxyPort == null) { | 113 | if (rtpProxyPort == null) { |
| 177 | return 0; | 114 | return 0; |
| @@ -181,104 +118,38 @@ public class MediaConfig implements IMediaServerItem { | @@ -181,104 +118,38 @@ public class MediaConfig implements IMediaServerItem { | ||
| 181 | 118 | ||
| 182 | } | 119 | } |
| 183 | 120 | ||
| 184 | - @Override | ||
| 185 | - public void setRtpProxyPort(int rtpProxyPort) { | ||
| 186 | - | ||
| 187 | - } | ||
| 188 | - | ||
| 189 | - public void setRtpProxyPort(Integer rtpProxyPort) { | ||
| 190 | - this.rtpProxyPort = rtpProxyPort; | ||
| 191 | - } | ||
| 192 | - | ||
| 193 | public int getRtspPort() { | 121 | public int getRtspPort() { |
| 194 | return rtspPort; | 122 | return rtspPort; |
| 195 | } | 123 | } |
| 196 | 124 | ||
| 197 | - @Override | ||
| 198 | - public void setRtspPort(int rtspPort) { | ||
| 199 | - | ||
| 200 | - } | ||
| 201 | - | ||
| 202 | - public void setRtspPort(Integer rtspPort) { | ||
| 203 | - this.rtspPort = rtspPort; | ||
| 204 | - } | ||
| 205 | - | ||
| 206 | public int getRtspSSLPort() { | 125 | public int getRtspSSLPort() { |
| 207 | return rtspSSLPort; | 126 | return rtspSSLPort; |
| 208 | } | 127 | } |
| 209 | 128 | ||
| 210 | - @Override | ||
| 211 | - public void setRtspSSLPort(int rtspSSLPort) { | ||
| 212 | - | ||
| 213 | - } | ||
| 214 | - | ||
| 215 | - public void setRtspSSLPort(Integer rtspSSLPort) { | ||
| 216 | - this.rtspSSLPort = rtspSSLPort; | ||
| 217 | - } | ||
| 218 | - | ||
| 219 | public boolean isAutoConfig() { | 129 | public boolean isAutoConfig() { |
| 220 | return autoConfig; | 130 | return autoConfig; |
| 221 | } | 131 | } |
| 222 | 132 | ||
| 223 | - public void setAutoConfig(boolean autoConfig) { | ||
| 224 | - this.autoConfig = autoConfig; | ||
| 225 | - } | ||
| 226 | - | ||
| 227 | public String getSecret() { | 133 | public String getSecret() { |
| 228 | return secret; | 134 | return secret; |
| 229 | } | 135 | } |
| 230 | 136 | ||
| 231 | - public void setSecret(String secret) { | ||
| 232 | - this.secret = secret; | ||
| 233 | - } | ||
| 234 | - | ||
| 235 | public String getStreamNoneReaderDelayMS() { | 137 | public String getStreamNoneReaderDelayMS() { |
| 236 | return streamNoneReaderDelayMS; | 138 | return streamNoneReaderDelayMS; |
| 237 | } | 139 | } |
| 238 | 140 | ||
| 239 | - public void setStreamNoneReaderDelayMS(String streamNoneReaderDelayMS) { | ||
| 240 | - this.streamNoneReaderDelayMS = streamNoneReaderDelayMS; | ||
| 241 | - } | ||
| 242 | - | ||
| 243 | public boolean isRtpEnable() { | 141 | public boolean isRtpEnable() { |
| 244 | return rtpEnable; | 142 | return rtpEnable; |
| 245 | } | 143 | } |
| 246 | 144 | ||
| 247 | - public void setRtpEnable(boolean rtpEnable) { | ||
| 248 | - this.rtpEnable = rtpEnable; | ||
| 249 | - } | ||
| 250 | - | ||
| 251 | public String getRtpPortRange() { | 145 | public String getRtpPortRange() { |
| 252 | return rtpPortRange; | 146 | return rtpPortRange; |
| 253 | } | 147 | } |
| 254 | - | ||
| 255 | - public void setRtpPortRange(String rtpPortRange) { | ||
| 256 | - this.rtpPortRange = rtpPortRange; | ||
| 257 | - } | ||
| 258 | - | 148 | + |
| 259 | public int getRecordAssistPort() { | 149 | public int getRecordAssistPort() { |
| 260 | return recordAssistPort; | 150 | return recordAssistPort; |
| 261 | } | 151 | } |
| 262 | 152 | ||
| 263 | - @Override | ||
| 264 | - public void setRecordAssistPort(int recordAssistPort) { | ||
| 265 | - | ||
| 266 | - } | ||
| 267 | - | ||
| 268 | - public void setRecordAssistPort(Integer recordAssistPort) { | ||
| 269 | - this.recordAssistPort = recordAssistPort; | ||
| 270 | - } | ||
| 271 | - | ||
| 272 | - @Override | ||
| 273 | - public boolean isDocker() { | ||
| 274 | - return docker; | ||
| 275 | - } | ||
| 276 | - | ||
| 277 | - @Override | ||
| 278 | - public void setDocker(boolean docker) { | ||
| 279 | - this.docker = docker; | ||
| 280 | - } | ||
| 281 | - | ||
| 282 | public String getSdpIp() { | 153 | public String getSdpIp() { |
| 283 | if (StringUtils.isEmpty(sdpIp)){ | 154 | if (StringUtils.isEmpty(sdpIp)){ |
| 284 | return ip; | 155 | return ip; |
| @@ -295,13 +166,11 @@ public class MediaConfig implements IMediaServerItem { | @@ -295,13 +166,11 @@ public class MediaConfig implements IMediaServerItem { | ||
| 295 | } | 166 | } |
| 296 | } | 167 | } |
| 297 | 168 | ||
| 298 | - | ||
| 299 | - | ||
| 300 | public MediaServerItem getMediaSerItem(){ | 169 | public MediaServerItem getMediaSerItem(){ |
| 301 | MediaServerItem mediaServerItem = new MediaServerItem(); | 170 | MediaServerItem mediaServerItem = new MediaServerItem(); |
| 302 | mediaServerItem.setId(id); | 171 | mediaServerItem.setId(id); |
| 303 | mediaServerItem.setIp(ip); | 172 | mediaServerItem.setIp(ip); |
| 304 | - mediaServerItem.setDocker(true); | 173 | + mediaServerItem.setDefaultServer(true); |
| 305 | mediaServerItem.setHookIp(hookIp); | 174 | mediaServerItem.setHookIp(hookIp); |
| 306 | mediaServerItem.setSdpIp(sdpIp); | 175 | mediaServerItem.setSdpIp(sdpIp); |
| 307 | mediaServerItem.setStreamIp(streamIp); | 176 | mediaServerItem.setStreamIp(streamIp); |
| @@ -318,39 +187,12 @@ public class MediaConfig implements IMediaServerItem { | @@ -318,39 +187,12 @@ public class MediaConfig implements IMediaServerItem { | ||
| 318 | mediaServerItem.setRtpEnable(rtpEnable); | 187 | mediaServerItem.setRtpEnable(rtpEnable); |
| 319 | mediaServerItem.setRtpPortRange(rtpPortRange); | 188 | mediaServerItem.setRtpPortRange(rtpPortRange); |
| 320 | mediaServerItem.setRecordAssistPort(recordAssistPort); | 189 | mediaServerItem.setRecordAssistPort(recordAssistPort); |
| 321 | - mediaServerItem.setCreateTime(createTime); | ||
| 322 | - mediaServerItem.setUpdateTime(updateTime); | ||
| 323 | - mediaServerItem.setCount(count); | ||
| 324 | - return mediaServerItem; | ||
| 325 | - } | ||
| 326 | - | ||
| 327 | - @Override | ||
| 328 | - public String getUpdateTime() { | ||
| 329 | - return updateTime; | ||
| 330 | - } | ||
| 331 | 190 | ||
| 332 | - @Override | ||
| 333 | - public void setUpdateTime(String updateTime) { | ||
| 334 | - this.updateTime = updateTime; | ||
| 335 | - } | 191 | + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| 192 | + mediaServerItem.setCreateTime(format.format(new Date(System.currentTimeMillis()))); | ||
| 193 | + mediaServerItem.setUpdateTime(format.format(new Date(System.currentTimeMillis()))); | ||
| 336 | 194 | ||
| 337 | - @Override | ||
| 338 | - public String getCreateTime() { | ||
| 339 | - return createTime; | ||
| 340 | - } | ||
| 341 | - | ||
| 342 | - @Override | ||
| 343 | - public void setCreateTime(String createTime) { | ||
| 344 | - this.createTime = createTime; | ||
| 345 | - } | ||
| 346 | - | ||
| 347 | - @Override | ||
| 348 | - public int getCount() { | ||
| 349 | - return count; | 195 | + return mediaServerItem; |
| 350 | } | 196 | } |
| 351 | 197 | ||
| 352 | - @Override | ||
| 353 | - public void setCount(int count) { | ||
| 354 | - this.count = count; | ||
| 355 | - } | ||
| 356 | } | 198 | } |
src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java
| 1 | package com.genersoft.iot.vmp.conf; | 1 | package com.genersoft.iot.vmp.conf; |
| 2 | 2 | ||
| 3 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | 3 | +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 4 | import com.genersoft.iot.vmp.service.IMediaServerService; | 4 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 5 | import org.apache.catalina.connector.ClientAbortException; | 5 | import org.apache.catalina.connector.ClientAbortException; |
| 6 | import org.apache.http.HttpHost; | 6 | import org.apache.http.HttpHost; |
| @@ -49,7 +49,7 @@ public class ProxyServletConfig { | @@ -49,7 +49,7 @@ public class ProxyServletConfig { | ||
| 49 | @Override | 49 | @Override |
| 50 | protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) { | 50 | protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) { |
| 51 | String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString); | 51 | String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString); |
| 52 | - IMediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI()); | 52 | + MediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI()); |
| 53 | if (mediaInfo != null) { | 53 | if (mediaInfo != null) { |
| 54 | if (!StringUtils.isEmpty(queryStr)) { | 54 | if (!StringUtils.isEmpty(queryStr)) { |
| 55 | queryStr += "&secret=" + mediaInfo.getSecret(); | 55 | queryStr += "&secret=" + mediaInfo.getSecret(); |
| @@ -88,7 +88,7 @@ public class ProxyServletConfig { | @@ -88,7 +88,7 @@ public class ProxyServletConfig { | ||
| 88 | @Override | 88 | @Override |
| 89 | protected String getTargetUri(HttpServletRequest servletRequest) { | 89 | protected String getTargetUri(HttpServletRequest servletRequest) { |
| 90 | String requestURI = servletRequest.getRequestURI(); | 90 | String requestURI = servletRequest.getRequestURI(); |
| 91 | - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); | 91 | + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); |
| 92 | 92 | ||
| 93 | String uri = null; | 93 | String uri = null; |
| 94 | if (mediaInfo != null) { | 94 | if (mediaInfo != null) { |
| @@ -106,7 +106,7 @@ public class ProxyServletConfig { | @@ -106,7 +106,7 @@ public class ProxyServletConfig { | ||
| 106 | @Override | 106 | @Override |
| 107 | protected HttpHost getTargetHost(HttpServletRequest servletRequest) { | 107 | protected HttpHost getTargetHost(HttpServletRequest servletRequest) { |
| 108 | String requestURI = servletRequest.getRequestURI(); | 108 | String requestURI = servletRequest.getRequestURI(); |
| 109 | - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); | 109 | + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); |
| 110 | HttpHost host; | 110 | HttpHost host; |
| 111 | if (mediaInfo != null) { | 111 | if (mediaInfo != null) { |
| 112 | host = new HttpHost(mediaInfo.getIp(), mediaInfo.getHttpPort()); | 112 | host = new HttpHost(mediaInfo.getIp(), mediaInfo.getHttpPort()); |
| @@ -120,7 +120,7 @@ public class ProxyServletConfig { | @@ -120,7 +120,7 @@ public class ProxyServletConfig { | ||
| 120 | /** | 120 | /** |
| 121 | * 根据uri获取流媒体信息 | 121 | * 根据uri获取流媒体信息 |
| 122 | */ | 122 | */ |
| 123 | - IMediaServerItem getMediaInfoByUri(String uri){ | 123 | + MediaServerItem getMediaInfoByUri(String uri){ |
| 124 | String[] split = uri.split("/"); | 124 | String[] split = uri.split("/"); |
| 125 | String mediaServerId = split[2]; | 125 | String mediaServerId = split[2]; |
| 126 | return mediaServerService.getOne(mediaServerId); | 126 | return mediaServerService.getOne(mediaServerId); |
| @@ -132,7 +132,7 @@ public class ProxyServletConfig { | @@ -132,7 +132,7 @@ public class ProxyServletConfig { | ||
| 132 | @Override | 132 | @Override |
| 133 | protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) { | 133 | protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) { |
| 134 | String requestURI = servletRequest.getRequestURI(); | 134 | String requestURI = servletRequest.getRequestURI(); |
| 135 | - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); | 135 | + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); |
| 136 | String url = super.rewriteUrlFromRequest(servletRequest); | 136 | String url = super.rewriteUrlFromRequest(servletRequest); |
| 137 | if (mediaInfo == null) { | 137 | if (mediaInfo == null) { |
| 138 | return url; | 138 | return url; |
| @@ -186,7 +186,7 @@ public class ProxyServletConfig { | @@ -186,7 +186,7 @@ public class ProxyServletConfig { | ||
| 186 | @Override | 186 | @Override |
| 187 | protected String getTargetUri(HttpServletRequest servletRequest) { | 187 | protected String getTargetUri(HttpServletRequest servletRequest) { |
| 188 | String requestURI = servletRequest.getRequestURI(); | 188 | String requestURI = servletRequest.getRequestURI(); |
| 189 | - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); | 189 | + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); |
| 190 | 190 | ||
| 191 | String uri = null; | 191 | String uri = null; |
| 192 | if (mediaInfo != null) { | 192 | if (mediaInfo != null) { |
| @@ -204,7 +204,7 @@ public class ProxyServletConfig { | @@ -204,7 +204,7 @@ public class ProxyServletConfig { | ||
| 204 | @Override | 204 | @Override |
| 205 | protected HttpHost getTargetHost(HttpServletRequest servletRequest) { | 205 | protected HttpHost getTargetHost(HttpServletRequest servletRequest) { |
| 206 | String requestURI = servletRequest.getRequestURI(); | 206 | String requestURI = servletRequest.getRequestURI(); |
| 207 | - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); | 207 | + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); |
| 208 | HttpHost host; | 208 | HttpHost host; |
| 209 | if (mediaInfo != null) { | 209 | if (mediaInfo != null) { |
| 210 | host = new HttpHost(mediaInfo.getIp(), mediaInfo.getRecordAssistPort()); | 210 | host = new HttpHost(mediaInfo.getIp(), mediaInfo.getRecordAssistPort()); |
| @@ -218,7 +218,7 @@ public class ProxyServletConfig { | @@ -218,7 +218,7 @@ public class ProxyServletConfig { | ||
| 218 | /** | 218 | /** |
| 219 | * 根据uri获取流媒体信息 | 219 | * 根据uri获取流媒体信息 |
| 220 | */ | 220 | */ |
| 221 | - IMediaServerItem getMediaInfoByUri(String uri){ | 221 | + MediaServerItem getMediaInfoByUri(String uri){ |
| 222 | String[] split = uri.split("/"); | 222 | String[] split = uri.split("/"); |
| 223 | String mediaServerId = split[2]; | 223 | String mediaServerId = split[2]; |
| 224 | return mediaServerService.getOne(mediaServerId); | 224 | return mediaServerService.getOne(mediaServerId); |
| @@ -230,7 +230,7 @@ public class ProxyServletConfig { | @@ -230,7 +230,7 @@ public class ProxyServletConfig { | ||
| 230 | @Override | 230 | @Override |
| 231 | protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) { | 231 | protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) { |
| 232 | String requestURI = servletRequest.getRequestURI(); | 232 | String requestURI = servletRequest.getRequestURI(); |
| 233 | - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); | 233 | + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); |
| 234 | String url = super.rewriteUrlFromRequest(servletRequest); | 234 | String url = super.rewriteUrlFromRequest(servletRequest); |
| 235 | if (mediaInfo == null) { | 235 | if (mediaInfo == null) { |
| 236 | return url; | 236 | return url; |
src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java
| 1 | package com.genersoft.iot.vmp.conf; | 1 | package com.genersoft.iot.vmp.conf; |
| 2 | 2 | ||
| 3 | +import org.apache.commons.lang3.StringUtils; | ||
| 4 | +import org.springframework.beans.factory.annotation.Value; | ||
| 3 | import org.springframework.cache.annotation.CachingConfigurerSupport; | 5 | import org.springframework.cache.annotation.CachingConfigurerSupport; |
| 4 | import org.springframework.context.annotation.Bean; | 6 | import org.springframework.context.annotation.Bean; |
| 5 | import org.springframework.context.annotation.Configuration; | 7 | import org.springframework.context.annotation.Configuration; |
| @@ -10,6 +12,8 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; | @@ -10,6 +12,8 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; | ||
| 10 | 12 | ||
| 11 | import com.alibaba.fastjson.parser.ParserConfig; | 13 | import com.alibaba.fastjson.parser.ParserConfig; |
| 12 | import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer; | 14 | import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer; |
| 15 | +import redis.clients.jedis.JedisPool; | ||
| 16 | +import redis.clients.jedis.JedisPoolConfig; | ||
| 13 | 17 | ||
| 14 | /** | 18 | /** |
| 15 | * @Description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置 | 19 | * @Description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置 |
| @@ -20,6 +24,37 @@ import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer; | @@ -20,6 +24,37 @@ import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer; | ||
| 20 | @Configuration | 24 | @Configuration |
| 21 | public class RedisConfig extends CachingConfigurerSupport { | 25 | public class RedisConfig extends CachingConfigurerSupport { |
| 22 | 26 | ||
| 27 | + @Value("${spring.redis.host}") | ||
| 28 | + private String host; | ||
| 29 | + @Value("${spring.redis.port}") | ||
| 30 | + private int port; | ||
| 31 | + @Value("${spring.redis.database}") | ||
| 32 | + private int database; | ||
| 33 | + @Value("${spring.redis.password}") | ||
| 34 | + private String password; | ||
| 35 | + @Value("${spring.redis.timeout}") | ||
| 36 | + private int timeout; | ||
| 37 | + @Value("${spring.redis.poolMaxTotal:1000}") | ||
| 38 | + private int poolMaxTotal; | ||
| 39 | + @Value("${spring.redis.poolMaxIdle:500}") | ||
| 40 | + private int poolMaxIdle; | ||
| 41 | + @Value("${spring.redis.poolMaxWait:5}") | ||
| 42 | + private int poolMaxWait; | ||
| 43 | + | ||
| 44 | + @Bean | ||
| 45 | + public JedisPool jedisPool() { | ||
| 46 | + if (StringUtils.isBlank(password)) { | ||
| 47 | + password = null; | ||
| 48 | + } | ||
| 49 | + JedisPoolConfig poolConfig = new JedisPoolConfig(); | ||
| 50 | + poolConfig.setMaxIdle(poolMaxIdle); | ||
| 51 | + poolConfig.setMaxTotal(poolMaxTotal); | ||
| 52 | + // 秒转毫秒 | ||
| 53 | + poolConfig.setMaxWaitMillis(poolMaxWait * 1000L); | ||
| 54 | + JedisPool jp = new JedisPool(poolConfig, host, port, timeout * 1000, password, database); | ||
| 55 | + return jp; | ||
| 56 | + } | ||
| 57 | + | ||
| 23 | @Bean("redisTemplate") | 58 | @Bean("redisTemplate") |
| 24 | public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { | 59 | public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { |
| 25 | RedisTemplate<Object, Object> template = new RedisTemplate<>(); | 60 | RedisTemplate<Object, Object> template = new RedisTemplate<>(); |
| @@ -34,7 +69,7 @@ public class RedisConfig extends CachingConfigurerSupport { | @@ -34,7 +69,7 @@ public class RedisConfig extends CachingConfigurerSupport { | ||
| 34 | template.setHashKeySerializer(new StringRedisSerializer()); | 69 | template.setHashKeySerializer(new StringRedisSerializer()); |
| 35 | template.setConnectionFactory(redisConnectionFactory); | 70 | template.setConnectionFactory(redisConnectionFactory); |
| 36 | // 使用fastjson时需设置此项,否则会报异常not support type | 71 | // 使用fastjson时需设置此项,否则会报异常not support type |
| 37 | - ParserConfig.getGlobalInstance().setAutoTypeSupport(true); | 72 | + ParserConfig.getGlobalInstance().setAutoTypeSupport(true); |
| 38 | return template; | 73 | return template; |
| 39 | } | 74 | } |
| 40 | 75 |
src/main/java/com/genersoft/iot/vmp/conf/SipDeviceRunner.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.conf; | ||
| 2 | - | ||
| 3 | -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | ||
| 4 | -import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | ||
| 5 | -import org.springframework.beans.factory.annotation.Autowired; | ||
| 6 | -import org.springframework.boot.CommandLineRunner; | ||
| 7 | -import org.springframework.core.annotation.Order; | ||
| 8 | -import org.springframework.stereotype.Component; | ||
| 9 | - | ||
| 10 | - | ||
| 11 | -/** | ||
| 12 | - * 系统启动时控制设备离线 | ||
| 13 | - */ | ||
| 14 | -@Component | ||
| 15 | -@Order(value=4) | ||
| 16 | -public class SipDeviceRunner implements CommandLineRunner { | ||
| 17 | - | ||
| 18 | - @Autowired | ||
| 19 | - private IVideoManagerStorager storager; | ||
| 20 | - | ||
| 21 | - @Autowired | ||
| 22 | - private IRedisCatchStorage redisCatchStorage; | ||
| 23 | - | ||
| 24 | - @Override | ||
| 25 | - public void run(String... args) throws Exception { | ||
| 26 | - // 设置所有设备离线 | ||
| 27 | - storager.outlineForAll(); | ||
| 28 | - // 设置所有设备离线 | ||
| 29 | - redisCatchStorage.outlineForAll(); | ||
| 30 | - } | ||
| 31 | -} |
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
| @@ -12,6 +12,7 @@ import javax.sip.header.CallIdHeader; | @@ -12,6 +12,7 @@ import javax.sip.header.CallIdHeader; | ||
| 12 | import javax.sip.message.Response; | 12 | import javax.sip.message.Response; |
| 13 | 13 | ||
| 14 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | 14 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| 15 | +import gov.nist.javax.sip.SipProviderImpl; | ||
| 15 | import org.slf4j.Logger; | 16 | import org.slf4j.Logger; |
| 16 | import org.slf4j.LoggerFactory; | 17 | import org.slf4j.LoggerFactory; |
| 17 | import org.springframework.beans.factory.annotation.Autowired; | 18 | import org.springframework.beans.factory.annotation.Autowired; |
| @@ -39,7 +40,7 @@ public class SipLayer implements SipListener { | @@ -39,7 +40,7 @@ public class SipLayer implements SipListener { | ||
| 39 | @Autowired | 40 | @Autowired |
| 40 | private SipSubscribe sipSubscribe; | 41 | private SipSubscribe sipSubscribe; |
| 41 | 42 | ||
| 42 | - private SipStack sipStack; | 43 | + private SipStackImpl sipStack; |
| 43 | 44 | ||
| 44 | private SipFactory sipFactory; | 45 | private SipFactory sipFactory; |
| 45 | 46 | ||
| @@ -52,7 +53,7 @@ public class SipLayer implements SipListener { | @@ -52,7 +53,7 @@ public class SipLayer implements SipListener { | ||
| 52 | private ThreadPoolExecutor initSipServer() { | 53 | private ThreadPoolExecutor initSipServer() { |
| 53 | 54 | ||
| 54 | int processThreadNum = Runtime.getRuntime().availableProcessors() * 10; | 55 | int processThreadNum = Runtime.getRuntime().availableProcessors() * 10; |
| 55 | - LinkedBlockingQueue<Runnable> processQueue = new LinkedBlockingQueue<Runnable>(10000); | 56 | + LinkedBlockingQueue<Runnable> processQueue = new LinkedBlockingQueue<>(10000); |
| 56 | processThreadPool = new ThreadPoolExecutor(processThreadNum,processThreadNum, | 57 | processThreadPool = new ThreadPoolExecutor(processThreadNum,processThreadNum, |
| 57 | 0L,TimeUnit.MILLISECONDS,processQueue, | 58 | 0L,TimeUnit.MILLISECONDS,processQueue, |
| 58 | new ThreadPoolExecutor.CallerRunsPolicy()); | 59 | new ThreadPoolExecutor.CallerRunsPolicy()); |
| @@ -88,17 +89,14 @@ public class SipLayer implements SipListener { | @@ -88,17 +89,14 @@ public class SipLayer implements SipListener { | ||
| 88 | 89 | ||
| 89 | @Bean("tcpSipProvider") | 90 | @Bean("tcpSipProvider") |
| 90 | @DependsOn("sipStack") | 91 | @DependsOn("sipStack") |
| 91 | - private SipProvider startTcpListener() { | 92 | + private SipProviderImpl startTcpListener() { |
| 92 | ListeningPoint tcpListeningPoint = null; | 93 | ListeningPoint tcpListeningPoint = null; |
| 93 | - SipProvider tcpSipProvider = null; | 94 | + SipProviderImpl tcpSipProvider = null; |
| 94 | try { | 95 | try { |
| 95 | tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getSipPort(), "TCP"); | 96 | tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getSipPort(), "TCP"); |
| 96 | - tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint); | 97 | + tcpSipProvider = (SipProviderImpl)sipStack.createSipProvider(tcpListeningPoint); |
| 97 | tcpSipProvider.addSipListener(this); | 98 | tcpSipProvider.addSipListener(this); |
| 98 | logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getMonitorIp() + ":" + sipConfig.getSipPort() + "}"); | 99 | logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getMonitorIp() + ":" + sipConfig.getSipPort() + "}"); |
| 99 | -// } catch (TransportNotSupportedException | InvalidArgumentException | TooManyListenersException | ObjectInUseException e) { | ||
| 100 | -// logger.error(String.format("创建SIP服务失败: %s", e.getMessage())); | ||
| 101 | -// } | ||
| 102 | } catch (TransportNotSupportedException e) { | 100 | } catch (TransportNotSupportedException e) { |
| 103 | e.printStackTrace(); | 101 | e.printStackTrace(); |
| 104 | } catch (InvalidArgumentException e) { | 102 | } catch (InvalidArgumentException e) { |
| @@ -114,13 +112,14 @@ public class SipLayer implements SipListener { | @@ -114,13 +112,14 @@ public class SipLayer implements SipListener { | ||
| 114 | 112 | ||
| 115 | @Bean("udpSipProvider") | 113 | @Bean("udpSipProvider") |
| 116 | @DependsOn("sipStack") | 114 | @DependsOn("sipStack") |
| 117 | - private SipProvider startUdpListener() { | 115 | + private SipProviderImpl startUdpListener() { |
| 118 | ListeningPoint udpListeningPoint = null; | 116 | ListeningPoint udpListeningPoint = null; |
| 119 | - SipProvider udpSipProvider = null; | 117 | + SipProviderImpl udpSipProvider = null; |
| 120 | try { | 118 | try { |
| 121 | udpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getSipPort(), "UDP"); | 119 | udpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getSipPort(), "UDP"); |
| 122 | - udpSipProvider = sipStack.createSipProvider(udpListeningPoint); | 120 | + udpSipProvider = (SipProviderImpl)sipStack.createSipProvider(udpListeningPoint); |
| 123 | udpSipProvider.addSipListener(this); | 121 | udpSipProvider.addSipListener(this); |
| 122 | +// udpSipProvider.setAutomaticDialogSupportEnabled(false); | ||
| 124 | } catch (TransportNotSupportedException e) { | 123 | } catch (TransportNotSupportedException e) { |
| 125 | e.printStackTrace(); | 124 | e.printStackTrace(); |
| 126 | } catch (InvalidArgumentException e) { | 125 | } catch (InvalidArgumentException e) { |
| @@ -141,7 +140,7 @@ public class SipLayer implements SipListener { | @@ -141,7 +140,7 @@ public class SipLayer implements SipListener { | ||
| 141 | */ | 140 | */ |
| 142 | @Override | 141 | @Override |
| 143 | public void processRequest(RequestEvent evt) { | 142 | public void processRequest(RequestEvent evt) { |
| 144 | -// logger.debug(evt.getRequest().toString()); | 143 | + logger.debug(evt.getRequest().toString()); |
| 145 | // 由于jainsip是单线程程序,为提高性能并发处理 | 144 | // 由于jainsip是单线程程序,为提高性能并发处理 |
| 146 | processThreadPool.execute(() -> { | 145 | processThreadPool.execute(() -> { |
| 147 | if (processorFactory != null) { | 146 | if (processorFactory != null) { |
| @@ -153,7 +152,7 @@ public class SipLayer implements SipListener { | @@ -153,7 +152,7 @@ public class SipLayer implements SipListener { | ||
| 153 | @Override | 152 | @Override |
| 154 | public void processResponse(ResponseEvent evt) { | 153 | public void processResponse(ResponseEvent evt) { |
| 155 | Response response = evt.getResponse(); | 154 | Response response = evt.getResponse(); |
| 156 | -// logger.debug(evt.getResponse().toString()); | 155 | + logger.debug(evt.getResponse().toString()); |
| 157 | int status = response.getStatusCode(); | 156 | int status = response.getStatusCode(); |
| 158 | if (((status >= 200) && (status < 300)) || status == 401) { // Success! | 157 | if (((status >= 200) && (status < 300)) || status == 401) { // Success! |
| 159 | ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt); | 158 | ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt); |
| @@ -163,6 +162,7 @@ public class SipLayer implements SipListener { | @@ -163,6 +162,7 @@ public class SipLayer implements SipListener { | ||
| 163 | // TODO Auto-generated catch block | 162 | // TODO Auto-generated catch block |
| 164 | e.printStackTrace(); | 163 | e.printStackTrace(); |
| 165 | } | 164 | } |
| 165 | + | ||
| 166 | if (evt.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) { | 166 | if (evt.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) { |
| 167 | CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME); | 167 | CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME); |
| 168 | if (callIdHeader != null) { | 168 | if (callIdHeader != null) { |
| @@ -220,7 +220,6 @@ public class SipLayer implements SipListener { | @@ -220,7 +220,6 @@ public class SipLayer implements SipListener { | ||
| 220 | @Override | 220 | @Override |
| 221 | public void processIOException(IOExceptionEvent exceptionEvent) { | 221 | public void processIOException(IOExceptionEvent exceptionEvent) { |
| 222 | // TODO Auto-generated method stub | 222 | // TODO Auto-generated method stub |
| 223 | - | ||
| 224 | } | 223 | } |
| 225 | 224 | ||
| 226 | /** | 225 | /** |
| @@ -236,7 +235,6 @@ public class SipLayer implements SipListener { | @@ -236,7 +235,6 @@ public class SipLayer implements SipListener { | ||
| 236 | @Override | 235 | @Override |
| 237 | public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) { | 236 | public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) { |
| 238 | // TODO Auto-generated method stub | 237 | // TODO Auto-generated method stub |
| 239 | - | ||
| 240 | } | 238 | } |
| 241 | 239 | ||
| 242 | /** | 240 | /** |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SsrcTransaction.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.gb28181.bean; | ||
| 2 | + | ||
| 3 | +import javax.sip.message.Request; | ||
| 4 | + | ||
| 5 | +public class SsrcTransaction { | ||
| 6 | + | ||
| 7 | + private String deviceId; | ||
| 8 | + private String channelId; | ||
| 9 | + private String ssrc; | ||
| 10 | + private String streamId; | ||
| 11 | + private byte[] transaction; | ||
| 12 | + private byte[] dialog; | ||
| 13 | + private String mediaServerId; | ||
| 14 | + | ||
| 15 | + public String getDeviceId() { | ||
| 16 | + return deviceId; | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + public void setDeviceId(String deviceId) { | ||
| 20 | + this.deviceId = deviceId; | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + public String getChannelId() { | ||
| 24 | + return channelId; | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + public void setChannelId(String channelId) { | ||
| 28 | + this.channelId = channelId; | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + public String getSsrc() { | ||
| 32 | + return ssrc; | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + public void setSsrc(String ssrc) { | ||
| 36 | + this.ssrc = ssrc; | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + public String getStreamId() { | ||
| 40 | + return streamId; | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + public void setStreamId(String streamId) { | ||
| 44 | + this.streamId = streamId; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + public byte[] getTransaction() { | ||
| 48 | + return transaction; | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + public void setTransaction(byte[] transaction) { | ||
| 52 | + this.transaction = transaction; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + public byte[] getDialog() { | ||
| 56 | + return dialog; | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + public void setDialog(byte[] dialog) { | ||
| 60 | + this.dialog = dialog; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + public String getMediaServerId() { | ||
| 64 | + return mediaServerId; | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + public void setMediaServerId(String mediaServerId) { | ||
| 68 | + this.mediaServerId = mediaServerId; | ||
| 69 | + } | ||
| 70 | +} |
src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java
| @@ -6,7 +6,6 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | @@ -6,7 +6,6 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | ||
| 6 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | 6 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| 7 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; | 7 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; |
| 8 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | 8 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 9 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 10 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 9 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 11 | import com.genersoft.iot.vmp.service.IMediaServerService; | 10 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 12 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 11 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| @@ -77,7 +76,7 @@ public class PlatformNotRegisterEventLister implements ApplicationListener<Platf | @@ -77,7 +76,7 @@ public class PlatformNotRegisterEventLister implements ApplicationListener<Platf | ||
| 77 | } | 76 | } |
| 78 | stream.append(sendRtpItem.getStreamId()); | 77 | stream.append(sendRtpItem.getStreamId()); |
| 79 | redisCatchStorage.deleteSendRTPServer(event.getPlatformGbID(), sendRtpItem.getChannelId()); | 78 | redisCatchStorage.deleteSendRTPServer(event.getPlatformGbID(), sendRtpItem.getChannelId()); |
| 80 | - IMediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | 79 | + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); |
| 81 | Map<String, Object> param = new HashMap<>(); | 80 | Map<String, Object> param = new HashMap<>(); |
| 82 | param.put("vhost", "__defaultVhost__"); | 81 | param.put("vhost", "__defaultVhost__"); |
| 83 | param.put("app", app.toString()); | 82 | param.put("app", app.toString()); |
src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcUtil.java renamed to src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcConfig.java
| 1 | -package com.genersoft.iot.vmp.gb28181.session; | ||
| 2 | - | ||
| 3 | -import java.util.ArrayList; | ||
| 4 | -import java.util.List; | ||
| 5 | -import java.util.Random; | ||
| 6 | - | ||
| 7 | -import com.genersoft.iot.vmp.conf.SipConfig; | ||
| 8 | -import com.genersoft.iot.vmp.utils.SpringBeanFactory; | ||
| 9 | -import org.slf4j.Logger; | ||
| 10 | -import org.slf4j.LoggerFactory; | ||
| 11 | - | ||
| 12 | -/** | ||
| 13 | - * @Description:SIP信令中的SSRC工具类。SSRC值由10位十进制整数组成的字符串,第一位为0代表实况,为1则代表回放;第二位至第六位由监控域ID的第4位到第8位组成;最后4位为不重复的4个整数 | ||
| 14 | - * @author: swwheihei | ||
| 15 | - * @date: 2020年5月10日 上午11:57:57 | ||
| 16 | - */ | ||
| 17 | -public class SsrcUtil { | ||
| 18 | - | ||
| 19 | - private final static Logger logger = LoggerFactory.getLogger(SsrcUtil.class); | ||
| 20 | - | ||
| 21 | - private static String ssrcPrefix; | ||
| 22 | - | ||
| 23 | - private static List<String> isUsed; | ||
| 24 | - | ||
| 25 | - private static List<String> notUsed; | ||
| 26 | - | ||
| 27 | - private static void init() { | ||
| 28 | - SipConfig sipConfig = (SipConfig) SpringBeanFactory.getBean("sipConfig"); | ||
| 29 | - ssrcPrefix = sipConfig.getSipDomain().substring(3, 8); | ||
| 30 | - isUsed = new ArrayList<String>(); | ||
| 31 | - notUsed = new ArrayList<String>(); | ||
| 32 | - for (int i = 1; i < 10000; i++) { | ||
| 33 | - if (i < 10) { | ||
| 34 | - notUsed.add("000" + i); | ||
| 35 | - } else if (i < 100) { | ||
| 36 | - notUsed.add("00" + i); | ||
| 37 | - } else if (i < 1000) { | ||
| 38 | - notUsed.add("0" + i); | ||
| 39 | - } else { | ||
| 40 | - notUsed.add(String.valueOf(i)); | ||
| 41 | - } | ||
| 42 | - } | ||
| 43 | - } | ||
| 44 | - | ||
| 45 | - /** | ||
| 46 | - * 获取视频预览的SSRC值,第一位固定为0 | ||
| 47 | - * | ||
| 48 | - */ | ||
| 49 | - public static String getPlaySsrc() { | ||
| 50 | - return "0" + getSsrcPrefix() + getSN(); | ||
| 51 | - } | ||
| 52 | - | ||
| 53 | - /** | ||
| 54 | - * 获取录像回放的SSRC值,第一位固定为1 | ||
| 55 | - * | ||
| 56 | - */ | ||
| 57 | - public static String getPlayBackSsrc() { | ||
| 58 | - return "1" + getSsrcPrefix() + getSN(); | ||
| 59 | - } | ||
| 60 | - | ||
| 61 | - /** | ||
| 62 | - * 释放ssrc,主要用完的ssrc一定要释放,否则会耗尽 | ||
| 63 | - * | ||
| 64 | - */ | ||
| 65 | - public static void releaseSsrc(String ssrc) { | ||
| 66 | - if (ssrc == null) { | ||
| 67 | - logger.error("要释放ssrc为null"); | ||
| 68 | - return; | ||
| 69 | - } | ||
| 70 | - String sn = ssrc.substring(6); | ||
| 71 | - isUsed.remove(sn); | ||
| 72 | - notUsed.add(sn); | ||
| 73 | - } | ||
| 74 | - | ||
| 75 | - /** | ||
| 76 | - * 获取后四位数SN,随机数 | ||
| 77 | - * | ||
| 78 | - */ | ||
| 79 | - private static String getSN() { | ||
| 80 | - String sn = null; | ||
| 81 | - int index = 0; | ||
| 82 | - if (notUsed.size() == 0) { | ||
| 83 | - throw new RuntimeException("ssrc已经用完"); | ||
| 84 | - } else if (notUsed.size() == 1) { | ||
| 85 | - sn = notUsed.get(0); | ||
| 86 | - } else { | ||
| 87 | - index = new Random().nextInt(notUsed.size() - 1); | ||
| 88 | - sn = notUsed.get(index); | ||
| 89 | - } | ||
| 90 | - notUsed.remove(index); | ||
| 91 | - isUsed.add(sn); | ||
| 92 | - return sn; | ||
| 93 | - } | ||
| 94 | - | ||
| 95 | - private static String getSsrcPrefix() { | ||
| 96 | - if (ssrcPrefix == null) { | ||
| 97 | - init(); | ||
| 98 | - } | ||
| 99 | - return ssrcPrefix; | ||
| 100 | - } | ||
| 101 | -} | 1 | +package com.genersoft.iot.vmp.gb28181.session; |
| 2 | + | ||
| 3 | +import com.genersoft.iot.vmp.utils.ConfigConst; | ||
| 4 | + | ||
| 5 | +import java.util.ArrayList; | ||
| 6 | +import java.util.List; | ||
| 7 | +import java.util.Random; | ||
| 8 | +import java.util.Set; | ||
| 9 | + | ||
| 10 | +public class SsrcConfig { | ||
| 11 | + | ||
| 12 | + /** | ||
| 13 | + * zlm流媒体服务器Id | ||
| 14 | + */ | ||
| 15 | + private String mediaServerId; | ||
| 16 | + | ||
| 17 | + private String ssrcPrefix; | ||
| 18 | + /** | ||
| 19 | + * zlm流媒体服务器已用会话句柄 | ||
| 20 | + */ | ||
| 21 | + private List<String> isUsed; | ||
| 22 | + /** | ||
| 23 | + * zlm流媒体服务器可用会话句柄 | ||
| 24 | + */ | ||
| 25 | + private List<String> notUsed; | ||
| 26 | + | ||
| 27 | + public SsrcConfig() { | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + public SsrcConfig(String mediaServerId, Set<String> usedSet, String sipDomain) { | ||
| 31 | + this.mediaServerId = mediaServerId; | ||
| 32 | + this.isUsed = new ArrayList<>(); | ||
| 33 | + this.ssrcPrefix = sipDomain.substring(3, 8); | ||
| 34 | + this.notUsed = new ArrayList<>(); | ||
| 35 | + for (int i = 1; i < ConfigConst.MAX_STRTEAM_COUNT; i++) { | ||
| 36 | + String ssrc; | ||
| 37 | + if (i < 10) { | ||
| 38 | + ssrc = "000" + i; | ||
| 39 | + } else if (i < 100) { | ||
| 40 | + ssrc = "00" + i; | ||
| 41 | + } else if (i < 1000) { | ||
| 42 | + ssrc = "0" + i; | ||
| 43 | + } else { | ||
| 44 | + ssrc = String.valueOf(i); | ||
| 45 | + } | ||
| 46 | + if (null == usedSet || !usedSet.contains(ssrc)) { | ||
| 47 | + this.notUsed.add(ssrc); | ||
| 48 | + } else { | ||
| 49 | + this.isUsed.add(ssrc); | ||
| 50 | + } | ||
| 51 | + } | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + | ||
| 55 | + /** | ||
| 56 | + * 获取视频预览的SSRC值,第一位固定为0 | ||
| 57 | + * @return ssrc | ||
| 58 | + */ | ||
| 59 | + public String getPlaySsrc() { | ||
| 60 | + return "0" + getSsrcPrefix() + getSN(); | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + /** | ||
| 64 | + * 获取录像回放的SSRC值,第一位固定为1 | ||
| 65 | + * | ||
| 66 | + */ | ||
| 67 | + public String getPlayBackSsrc() { | ||
| 68 | + return "1" + getSsrcPrefix() + getSN(); | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * 释放ssrc,主要用完的ssrc一定要释放,否则会耗尽 | ||
| 73 | + * @param ssrc 需要重置的ssrc | ||
| 74 | + */ | ||
| 75 | + public void releaseSsrc(String ssrc) { | ||
| 76 | + if (ssrc == null) { | ||
| 77 | + return; | ||
| 78 | + } | ||
| 79 | + String sn = ssrc.substring(6); | ||
| 80 | + try { | ||
| 81 | + isUsed.remove(sn); | ||
| 82 | + notUsed.add(sn); | ||
| 83 | + }catch (NullPointerException e){ | ||
| 84 | + System.out.printf("11111"); | ||
| 85 | + } | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + /** | ||
| 89 | + * 获取后四位数SN,随机数 | ||
| 90 | + * | ||
| 91 | + */ | ||
| 92 | + private String getSN() { | ||
| 93 | + String sn = null; | ||
| 94 | + int index = 0; | ||
| 95 | + if (notUsed.size() == 0) { | ||
| 96 | + throw new RuntimeException("ssrc已经用完"); | ||
| 97 | + } else if (notUsed.size() == 1) { | ||
| 98 | + sn = notUsed.get(0); | ||
| 99 | + } else { | ||
| 100 | + index = new Random().nextInt(notUsed.size() - 1); | ||
| 101 | + sn = notUsed.get(index); | ||
| 102 | + } | ||
| 103 | + notUsed.remove(index); | ||
| 104 | + isUsed.add(sn); | ||
| 105 | + return sn; | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + public String getSsrcPrefix() { | ||
| 109 | + return ssrcPrefix; | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | + public String getMediaServerId() { | ||
| 113 | + return mediaServerId; | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + public void setMediaServerId(String mediaServerId) { | ||
| 117 | + this.mediaServerId = mediaServerId; | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + public void setSsrcPrefix(String ssrcPrefix) { | ||
| 121 | + this.ssrcPrefix = ssrcPrefix; | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + public List<String> getIsUsed() { | ||
| 125 | + return isUsed; | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + public void setIsUsed(List<String> isUsed) { | ||
| 129 | + this.isUsed = isUsed; | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + public List<String> getNotUsed() { | ||
| 133 | + return notUsed; | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + public void setNotUsed(List<String> notUsed) { | ||
| 137 | + this.notUsed = notUsed; | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | +} |
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
| 1 | package com.genersoft.iot.vmp.gb28181.session; | 1 | package com.genersoft.iot.vmp.gb28181.session; |
| 2 | 2 | ||
| 3 | +import java.util.ArrayList; | ||
| 4 | +import java.util.List; | ||
| 5 | +import java.util.Map; | ||
| 3 | import java.util.concurrent.ConcurrentHashMap; | 6 | import java.util.concurrent.ConcurrentHashMap; |
| 4 | 7 | ||
| 5 | import javax.sip.ClientTransaction; | 8 | import javax.sip.ClientTransaction; |
| 9 | +import javax.sip.Dialog; | ||
| 10 | +import javax.sip.message.Request; | ||
| 6 | 11 | ||
| 12 | +import com.genersoft.iot.vmp.common.VideoManagerConstants; | ||
| 13 | +import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; | ||
| 14 | +import com.genersoft.iot.vmp.service.IMediaServerService; | ||
| 15 | +import com.genersoft.iot.vmp.utils.SerializeUtils; | ||
| 16 | +import com.genersoft.iot.vmp.utils.redis.JedisUtil; | ||
| 17 | +import com.genersoft.iot.vmp.utils.redis.RedisUtil; | ||
| 18 | +import gov.nist.javax.sip.stack.SIPDialog; | ||
| 19 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 20 | +import org.springframework.data.redis.core.RedisTemplate; | ||
| 7 | import org.springframework.stereotype.Component; | 21 | import org.springframework.stereotype.Component; |
| 8 | 22 | ||
| 9 | /** | 23 | /** |
| @@ -14,50 +28,85 @@ import org.springframework.stereotype.Component; | @@ -14,50 +28,85 @@ import org.springframework.stereotype.Component; | ||
| 14 | @Component | 28 | @Component |
| 15 | public class VideoStreamSessionManager { | 29 | public class VideoStreamSessionManager { |
| 16 | 30 | ||
| 17 | - private ConcurrentHashMap<String, ClientTransaction> sessionMap = new ConcurrentHashMap<>(); | ||
| 18 | - private ConcurrentHashMap<String, String> ssrcMap = new ConcurrentHashMap<>(); | ||
| 19 | - private ConcurrentHashMap<String, String> streamIdMap = new ConcurrentHashMap<>(); | 31 | + @Autowired |
| 32 | + private RedisUtil redisUtil; | ||
| 20 | 33 | ||
| 21 | - public String createPlaySsrc(){ | ||
| 22 | - return SsrcUtil.getPlaySsrc(); | ||
| 23 | - } | ||
| 24 | - | ||
| 25 | - public String createPlayBackSsrc(){ | ||
| 26 | - return SsrcUtil.getPlayBackSsrc(); | 34 | + public void put(String deviceId, String channelId ,String ssrc, String streamId, String mediaServerId, ClientTransaction transaction){ |
| 35 | + SsrcTransaction ssrcTransaction = new SsrcTransaction(); | ||
| 36 | + ssrcTransaction.setDeviceId(deviceId); | ||
| 37 | + ssrcTransaction.setChannelId(channelId); | ||
| 38 | + ssrcTransaction.setStreamId(streamId); | ||
| 39 | + byte[] transactionByteArray = SerializeUtils.serialize(transaction); | ||
| 40 | + ssrcTransaction.setTransaction(transactionByteArray); | ||
| 41 | + ssrcTransaction.setSsrc(ssrc); | ||
| 42 | + ssrcTransaction.setMediaServerId(mediaServerId); | ||
| 43 | + | ||
| 44 | + redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + deviceId + "_" + channelId, ssrcTransaction); | ||
| 27 | } | 45 | } |
| 28 | - | ||
| 29 | - public void put(String deviceId, String channelId ,String ssrc, String streamId, ClientTransaction transaction){ | ||
| 30 | - sessionMap.put(deviceId + "_" + channelId, transaction); | ||
| 31 | - ssrcMap.put(deviceId + "_" + channelId, ssrc); | ||
| 32 | - streamIdMap.put(deviceId + "_" + channelId, streamId); | 46 | + |
| 47 | + public void put(String deviceId, String channelId , Dialog dialog){ | ||
| 48 | + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); | ||
| 49 | + if (ssrcTransaction != null) { | ||
| 50 | + byte[] dialogByteArray = SerializeUtils.serialize(dialog); | ||
| 51 | + ssrcTransaction.setDialog(dialogByteArray); | ||
| 52 | + } | ||
| 53 | + redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + deviceId + "_" + channelId, ssrcTransaction); | ||
| 33 | } | 54 | } |
| 55 | + | ||
| 34 | 56 | ||
| 35 | public ClientTransaction getTransaction(String deviceId, String channelId){ | 57 | public ClientTransaction getTransaction(String deviceId, String channelId){ |
| 36 | - return sessionMap.get(deviceId + "_" + channelId); | 58 | + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); |
| 59 | + if (ssrcTransaction == null) return null; | ||
| 60 | + byte[] transactionByteArray = ssrcTransaction.getTransaction(); | ||
| 61 | + ClientTransaction clientTransaction = (ClientTransaction)SerializeUtils.deSerialize(transactionByteArray); | ||
| 62 | + return clientTransaction; | ||
| 37 | } | 63 | } |
| 38 | 64 | ||
| 39 | - public String getStreamId(String deviceId, String channelId){ | ||
| 40 | - return streamIdMap.get(deviceId + "_" + channelId); | 65 | + public SIPDialog getDialog(String deviceId, String channelId){ |
| 66 | + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); | ||
| 67 | + if (ssrcTransaction == null) return null; | ||
| 68 | + byte[] dialogByteArray = ssrcTransaction.getDialog(); | ||
| 69 | + if (dialogByteArray == null) return null; | ||
| 70 | + SIPDialog dialog = (SIPDialog)SerializeUtils.deSerialize(dialogByteArray); | ||
| 71 | + return dialog; | ||
| 41 | } | 72 | } |
| 42 | - | ||
| 43 | - public void remove(String deviceId, String channelId) { | ||
| 44 | - sessionMap.remove(deviceId + "_" + channelId); | ||
| 45 | - if (ssrcMap.get(deviceId + "_" + channelId) != null) { | ||
| 46 | - SsrcUtil.releaseSsrc(ssrcMap.get(deviceId + "_" + channelId)); | ||
| 47 | - } | ||
| 48 | - ssrcMap.remove(deviceId + "_" + channelId); | ||
| 49 | - streamIdMap.remove(deviceId + "_" + channelId); | 73 | + |
| 74 | + public SsrcTransaction getSsrcTransaction(String deviceId, String channelId){ | ||
| 75 | + SsrcTransaction ssrcTransaction = (SsrcTransaction)redisUtil.get(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + deviceId + "_" + channelId); | ||
| 76 | + return ssrcTransaction; | ||
| 50 | } | 77 | } |
| 51 | 78 | ||
| 52 | - public ConcurrentHashMap<String, ClientTransaction> getSessionMap() { | ||
| 53 | - return sessionMap; | 79 | + public String getStreamId(String deviceId, String channelId){ |
| 80 | + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); | ||
| 81 | + if (ssrcTransaction == null) return null; | ||
| 82 | + return ssrcTransaction.getStreamId(); | ||
| 83 | + } | ||
| 84 | + public String getMediaServerId(String deviceId, String channelId){ | ||
| 85 | + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); | ||
| 86 | + if (ssrcTransaction == null) return null; | ||
| 87 | + return ssrcTransaction.getMediaServerId(); | ||
| 54 | } | 88 | } |
| 55 | 89 | ||
| 56 | - public ConcurrentHashMap<String, String> getSsrcMap() { | ||
| 57 | - return ssrcMap; | 90 | + public String getSSRC(String deviceId, String channelId){ |
| 91 | + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); | ||
| 92 | + if (ssrcTransaction == null) return null; | ||
| 93 | + return ssrcTransaction.getSsrc(); | ||
| 94 | + } | ||
| 95 | + | ||
| 96 | + public void remove(String deviceId, String channelId) { | ||
| 97 | + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); | ||
| 98 | + if (ssrcTransaction == null) return; | ||
| 99 | + redisUtil.del(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + deviceId + "_" + channelId); | ||
| 58 | } | 100 | } |
| 59 | 101 | ||
| 60 | - public ConcurrentHashMap<String, String> getStreamIdMap() { | ||
| 61 | - return streamIdMap; | 102 | + public List<SsrcTransaction> getAllSsrc() { |
| 103 | + List<Object> ssrcTransactionKeys = redisUtil.scan(String.format("%s_*_*", VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX)); | ||
| 104 | + List<SsrcTransaction> result= new ArrayList<>(); | ||
| 105 | + for (int i = 0; i < ssrcTransactionKeys.size(); i++) { | ||
| 106 | + String key = (String)ssrcTransactionKeys.get(i); | ||
| 107 | + SsrcTransaction ssrcTransaction = (SsrcTransaction)redisUtil.get(key); | ||
| 108 | + result.add(ssrcTransaction); | ||
| 109 | + } | ||
| 110 | + return result; | ||
| 62 | } | 111 | } |
| 63 | } | 112 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
| @@ -7,6 +7,7 @@ import javax.sip.header.CSeqHeader; | @@ -7,6 +7,7 @@ import javax.sip.header.CSeqHeader; | ||
| 7 | import javax.sip.message.Request; | 7 | import javax.sip.message.Request; |
| 8 | import javax.sip.message.Response; | 8 | import javax.sip.message.Response; |
| 9 | 9 | ||
| 10 | +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | ||
| 10 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; | 11 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; |
| 11 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | 12 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 12 | import com.genersoft.iot.vmp.service.IMediaServerService; | 13 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| @@ -108,7 +109,6 @@ public class SIPProcessorFactory { | @@ -108,7 +109,6 @@ public class SIPProcessorFactory { | ||
| 108 | @Autowired | 109 | @Autowired |
| 109 | private IMediaServerService mediaServerService; | 110 | private IMediaServerService mediaServerService; |
| 110 | 111 | ||
| 111 | - | ||
| 112 | // 注:这里使用注解会导致循环依赖注入,暂用springBean | 112 | // 注:这里使用注解会导致循环依赖注入,暂用springBean |
| 113 | private SipProvider tcpSipProvider; | 113 | private SipProvider tcpSipProvider; |
| 114 | 114 |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
| @@ -3,8 +3,8 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd; | @@ -3,8 +3,8 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd; | ||
| 3 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 3 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 4 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | 4 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| 5 | import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; | 5 | import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; |
| 6 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 7 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 6 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 7 | +import com.genersoft.iot.vmp.service.bean.SSRCInfo; | ||
| 8 | 8 | ||
| 9 | /** | 9 | /** |
| 10 | * @Description:设备能力接口,用于定义设备的控制、查询能力 | 10 | * @Description:设备能力接口,用于定义设备的控制、查询能力 |
| @@ -92,7 +92,7 @@ public interface ISIPCommander { | @@ -92,7 +92,7 @@ public interface ISIPCommander { | ||
| 92 | * @param device 视频设备 | 92 | * @param device 视频设备 |
| 93 | * @param channelId 预览通道 | 93 | * @param channelId 预览通道 |
| 94 | */ | 94 | */ |
| 95 | - void playStreamCmd(IMediaServerItem mediaServerItem, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); | 95 | + void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); |
| 96 | 96 | ||
| 97 | /** | 97 | /** |
| 98 | * 请求回放视频流 | 98 | * 请求回放视频流 |
| @@ -102,7 +102,7 @@ public interface ISIPCommander { | @@ -102,7 +102,7 @@ public interface ISIPCommander { | ||
| 102 | * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss | 102 | * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss |
| 103 | * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss | 103 | * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss |
| 104 | */ | 104 | */ |
| 105 | - void playbackStreamCmd(IMediaServerItem mediaServerItem,Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); | 105 | + void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInf, Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); |
| 106 | 106 | ||
| 107 | /** | 107 | /** |
| 108 | * 请求历史媒体下载 | 108 | * 请求历史媒体下载 |
| @@ -113,12 +113,10 @@ public interface ISIPCommander { | @@ -113,12 +113,10 @@ public interface ISIPCommander { | ||
| 113 | * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss | 113 | * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss |
| 114 | * @param downloadSpeed 下载倍速参数 | 114 | * @param downloadSpeed 下载倍速参数 |
| 115 | */ | 115 | */ |
| 116 | - void downloadStreamCmd(IMediaServerItem mediaServerItem,Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); | 116 | + void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); |
| 117 | 117 | ||
| 118 | /** | 118 | /** |
| 119 | * 视频流停止 | 119 | * 视频流停止 |
| 120 | - * | ||
| 121 | - * @param ssrc ssrc | ||
| 122 | */ | 120 | */ |
| 123 | void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent); | 121 | void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent); |
| 124 | void streamByeCmd(String deviceId, String channelId); | 122 | void streamByeCmd(String deviceId, String channelId); |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
| 1 | package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; | 1 | package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; |
| 2 | 2 | ||
| 3 | +import java.lang.reflect.Field; | ||
| 3 | import java.text.ParseException; | 4 | import java.text.ParseException; |
| 5 | +import java.util.HashSet; | ||
| 4 | 6 | ||
| 5 | import javax.sip.*; | 7 | import javax.sip.*; |
| 6 | import javax.sip.address.SipURI; | 8 | import javax.sip.address.SipURI; |
| @@ -8,18 +10,21 @@ import javax.sip.header.CallIdHeader; | @@ -8,18 +10,21 @@ import javax.sip.header.CallIdHeader; | ||
| 8 | import javax.sip.header.ViaHeader; | 10 | import javax.sip.header.ViaHeader; |
| 9 | import javax.sip.message.Request; | 11 | import javax.sip.message.Request; |
| 10 | 12 | ||
| 11 | -import com.alibaba.fastjson.JSONArray; | ||
| 12 | import com.alibaba.fastjson.JSONObject; | 13 | import com.alibaba.fastjson.JSONObject; |
| 13 | -import com.genersoft.iot.vmp.common.StreamInfo; | ||
| 14 | -import com.genersoft.iot.vmp.conf.MediaConfig; | ||
| 15 | import com.genersoft.iot.vmp.conf.UserSetup; | 14 | import com.genersoft.iot.vmp.conf.UserSetup; |
| 15 | +import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; | ||
| 16 | import com.genersoft.iot.vmp.media.zlm.*; | 16 | import com.genersoft.iot.vmp.media.zlm.*; |
| 17 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | 17 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| 18 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 19 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 18 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 19 | +import com.genersoft.iot.vmp.service.IMediaServerService; | ||
| 20 | +import com.genersoft.iot.vmp.service.bean.SSRCInfo; | ||
| 20 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 21 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 21 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | 22 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 23 | +import gov.nist.javax.sip.SipProviderImpl; | ||
| 24 | +import gov.nist.javax.sip.SipStackImpl; | ||
| 22 | import gov.nist.javax.sip.message.SIPRequest; | 25 | import gov.nist.javax.sip.message.SIPRequest; |
| 26 | +import gov.nist.javax.sip.stack.SIPDialog; | ||
| 27 | +import gov.nist.javax.sip.stack.SIPTransaction; | ||
| 23 | import org.slf4j.Logger; | 28 | import org.slf4j.Logger; |
| 24 | import org.slf4j.LoggerFactory; | 29 | import org.slf4j.LoggerFactory; |
| 25 | import org.springframework.beans.factory.annotation.Autowired; | 30 | import org.springframework.beans.factory.annotation.Autowired; |
| @@ -35,7 +40,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; | @@ -35,7 +40,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; | ||
| 35 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; | 40 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; |
| 36 | import com.genersoft.iot.vmp.gb28181.utils.DateUtil; | 41 | import com.genersoft.iot.vmp.gb28181.utils.DateUtil; |
| 37 | import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; | 42 | import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; |
| 38 | -import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; | ||
| 39 | import org.springframework.util.StringUtils; | 43 | import org.springframework.util.StringUtils; |
| 40 | 44 | ||
| 41 | /** | 45 | /** |
| @@ -55,12 +59,12 @@ public class SIPCommander implements ISIPCommander { | @@ -55,12 +59,12 @@ public class SIPCommander implements ISIPCommander { | ||
| 55 | @Lazy | 59 | @Lazy |
| 56 | @Autowired | 60 | @Autowired |
| 57 | @Qualifier(value="tcpSipProvider") | 61 | @Qualifier(value="tcpSipProvider") |
| 58 | - private SipProvider tcpSipProvider; | 62 | + private SipProviderImpl tcpSipProvider; |
| 59 | 63 | ||
| 60 | @Lazy | 64 | @Lazy |
| 61 | @Autowired | 65 | @Autowired |
| 62 | @Qualifier(value="udpSipProvider") | 66 | @Qualifier(value="udpSipProvider") |
| 63 | - private SipProvider udpSipProvider; | 67 | + private SipProviderImpl udpSipProvider; |
| 64 | 68 | ||
| 65 | @Autowired | 69 | @Autowired |
| 66 | private SIPRequestHeaderProvider headerProvider; | 70 | private SIPRequestHeaderProvider headerProvider; |
| @@ -75,9 +79,6 @@ public class SIPCommander implements ISIPCommander { | @@ -75,9 +79,6 @@ public class SIPCommander implements ISIPCommander { | ||
| 75 | private IRedisCatchStorage redisCatchStorage; | 79 | private IRedisCatchStorage redisCatchStorage; |
| 76 | 80 | ||
| 77 | @Autowired | 81 | @Autowired |
| 78 | - private ZLMRTPServerFactory zlmrtpServerFactory; | ||
| 79 | - | ||
| 80 | - @Autowired | ||
| 81 | private UserSetup userSetup; | 82 | private UserSetup userSetup; |
| 82 | 83 | ||
| 83 | @Autowired | 84 | @Autowired |
| @@ -86,6 +87,11 @@ public class SIPCommander implements ISIPCommander { | @@ -86,6 +87,11 @@ public class SIPCommander implements ISIPCommander { | ||
| 86 | @Autowired | 87 | @Autowired |
| 87 | private SipSubscribe sipSubscribe; | 88 | private SipSubscribe sipSubscribe; |
| 88 | 89 | ||
| 90 | + @Autowired | ||
| 91 | + private IMediaServerService mediaServerService; | ||
| 92 | + | ||
| 93 | + private SIPDialog dialog; | ||
| 94 | + | ||
| 89 | public SipConfig getSipConfig() { | 95 | public SipConfig getSipConfig() { |
| 90 | return sipConfig; | 96 | return sipConfig; |
| 91 | } | 97 | } |
| @@ -334,26 +340,13 @@ public class SIPCommander implements ISIPCommander { | @@ -334,26 +340,13 @@ public class SIPCommander implements ISIPCommander { | ||
| 334 | * @param errorEvent sip错误订阅 | 340 | * @param errorEvent sip错误订阅 |
| 335 | */ | 341 | */ |
| 336 | @Override | 342 | @Override |
| 337 | - public void playStreamCmd(IMediaServerItem mediaServerItem, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) { | ||
| 338 | - String streamId = null; | 343 | + public void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) { |
| 344 | + String streamId = ssrcInfo.getStreamId(); | ||
| 339 | try { | 345 | try { |
| 340 | if (device == null) return; | 346 | if (device == null) return; |
| 341 | String streamMode = device.getStreamMode().toUpperCase(); | 347 | String streamMode = device.getStreamMode().toUpperCase(); |
| 342 | 348 | ||
| 343 | - String ssrc = streamSession.createPlaySsrc(); | ||
| 344 | - if (mediaServerItem.isRtpEnable()) { | ||
| 345 | - streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); | ||
| 346 | - }else { | ||
| 347 | - streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); | ||
| 348 | - } | ||
| 349 | - Integer mediaPort = null; | ||
| 350 | - // 使用动态udp端口 | ||
| 351 | - if (mediaServerItem.isRtpEnable()) { | ||
| 352 | - mediaPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId); | ||
| 353 | - }else { | ||
| 354 | - mediaPort = mediaServerItem.getRtpProxyPort(); | ||
| 355 | - } | ||
| 356 | - logger.info("{} 分配的ZLM为: {} [{}:{}]", streamId, mediaServerItem.getId(), mediaServerItem.getIp(), mediaPort); | 349 | + logger.info("{} 分配的ZLM为: {} [{}:{}]", streamId, mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); |
| 357 | // 添加订阅 | 350 | // 添加订阅 |
| 358 | JSONObject subscribeKey = new JSONObject(); | 351 | JSONObject subscribeKey = new JSONObject(); |
| 359 | subscribeKey.put("app", "rtp"); | 352 | subscribeKey.put("app", "rtp"); |
| @@ -361,7 +354,7 @@ public class SIPCommander implements ISIPCommander { | @@ -361,7 +354,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 361 | subscribeKey.put("regist", true); | 354 | subscribeKey.put("regist", true); |
| 362 | subscribeKey.put("mediaServerId", mediaServerItem.getId()); | 355 | subscribeKey.put("mediaServerId", mediaServerItem.getId()); |
| 363 | subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, | 356 | subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, |
| 364 | - (IMediaServerItem mediaServerItemInUse, JSONObject json)->{ | 357 | + (MediaServerItem mediaServerItemInUse, JSONObject json)->{ |
| 365 | if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return; | 358 | if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return; |
| 366 | event.response(mediaServerItemInUse, json); | 359 | event.response(mediaServerItemInUse, json); |
| 367 | subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey); | 360 | subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey); |
| @@ -369,7 +362,6 @@ public class SIPCommander implements ISIPCommander { | @@ -369,7 +362,6 @@ public class SIPCommander implements ISIPCommander { | ||
| 369 | // | 362 | // |
| 370 | StringBuffer content = new StringBuffer(200); | 363 | StringBuffer content = new StringBuffer(200); |
| 371 | content.append("v=0\r\n"); | 364 | content.append("v=0\r\n"); |
| 372 | -// content.append("o=" + sipConfig.getSipId() + " 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n"); | ||
| 373 | content.append("o="+"00000"+" 0 0 IN IP4 "+ mediaServerItem.getSdpIp() +"\r\n"); | 365 | content.append("o="+"00000"+" 0 0 IN IP4 "+ mediaServerItem.getSdpIp() +"\r\n"); |
| 374 | content.append("s=Play\r\n"); | 366 | content.append("s=Play\r\n"); |
| 375 | content.append("c=IN IP4 "+ mediaServerItem.getSdpIp() +"\r\n"); | 367 | content.append("c=IN IP4 "+ mediaServerItem.getSdpIp() +"\r\n"); |
| @@ -377,11 +369,11 @@ public class SIPCommander implements ISIPCommander { | @@ -377,11 +369,11 @@ public class SIPCommander implements ISIPCommander { | ||
| 377 | 369 | ||
| 378 | if (userSetup.isSeniorSdp()) { | 370 | if (userSetup.isSeniorSdp()) { |
| 379 | if("TCP-PASSIVE".equals(streamMode)) { | 371 | if("TCP-PASSIVE".equals(streamMode)) { |
| 380 | - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); | 372 | + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); |
| 381 | }else if ("TCP-ACTIVE".equals(streamMode)) { | 373 | }else if ("TCP-ACTIVE".equals(streamMode)) { |
| 382 | - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); | 374 | + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); |
| 383 | }else if("UDP".equals(streamMode)) { | 375 | }else if("UDP".equals(streamMode)) { |
| 384 | - content.append("m=video "+ mediaPort +" RTP/AVP 96 126 125 99 34 98 97\r\n"); | 376 | + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 126 125 99 34 98 97\r\n"); |
| 385 | } | 377 | } |
| 386 | content.append("a=recvonly\r\n"); | 378 | content.append("a=recvonly\r\n"); |
| 387 | content.append("a=rtpmap:96 PS/90000\r\n"); | 379 | content.append("a=rtpmap:96 PS/90000\r\n"); |
| @@ -402,11 +394,11 @@ public class SIPCommander implements ISIPCommander { | @@ -402,11 +394,11 @@ public class SIPCommander implements ISIPCommander { | ||
| 402 | } | 394 | } |
| 403 | }else { | 395 | }else { |
| 404 | if("TCP-PASSIVE".equals(streamMode)) { | 396 | if("TCP-PASSIVE".equals(streamMode)) { |
| 405 | - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); | 397 | + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n"); |
| 406 | }else if ("TCP-ACTIVE".equals(streamMode)) { | 398 | }else if ("TCP-ACTIVE".equals(streamMode)) { |
| 407 | - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); | 399 | + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n"); |
| 408 | }else if("UDP".equals(streamMode)) { | 400 | }else if("UDP".equals(streamMode)) { |
| 409 | - content.append("m=video "+ mediaPort +" RTP/AVP 96 98 97\r\n"); | 401 | + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 98 97\r\n"); |
| 410 | } | 402 | } |
| 411 | content.append("a=recvonly\r\n"); | 403 | content.append("a=recvonly\r\n"); |
| 412 | content.append("a=rtpmap:96 PS/90000\r\n"); | 404 | content.append("a=rtpmap:96 PS/90000\r\n"); |
| @@ -421,20 +413,25 @@ public class SIPCommander implements ISIPCommander { | @@ -421,20 +413,25 @@ public class SIPCommander implements ISIPCommander { | ||
| 421 | } | 413 | } |
| 422 | } | 414 | } |
| 423 | 415 | ||
| 424 | - content.append("y="+ssrc+"\r\n");//ssrc | 416 | + content.append("y="+ssrcInfo.getSsrc()+"\r\n");//ssrc |
| 425 | 417 | ||
| 426 | String tm = Long.toString(System.currentTimeMillis()); | 418 | String tm = Long.toString(System.currentTimeMillis()); |
| 427 | 419 | ||
| 428 | CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() | 420 | CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() |
| 429 | : udpSipProvider.getNewCallId(); | 421 | : udpSipProvider.getNewCallId(); |
| 430 | 422 | ||
| 431 | - Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "FromInvt" + tm, null, ssrc, callIdHeader); | 423 | + Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "FromInvt" + tm, null, ssrcInfo.getSsrc(), callIdHeader); |
| 432 | 424 | ||
| 433 | - ClientTransaction transaction = transmitRequest(device, request, (e -> { | 425 | + String finalStreamId = streamId; |
| 426 | + transmitRequest(device, request, (e -> { | ||
| 434 | streamSession.remove(device.getDeviceId(), channelId); | 427 | streamSession.remove(device.getDeviceId(), channelId); |
| 428 | + mediaServerService.releaseSsrc(mediaServerItem, ssrcInfo.getSsrc()); | ||
| 435 | errorEvent.response(e); | 429 | errorEvent.response(e); |
| 436 | - })); | ||
| 437 | - streamSession.put(device.getDeviceId(), channelId ,ssrc,streamId, transaction); | 430 | + }), e ->{ |
| 431 | + streamSession.put(device.getDeviceId(), channelId ,ssrcInfo.getSsrc(), finalStreamId, mediaServerItem.getId(),e.getClientTransaction()); | ||
| 432 | + streamSession.put(device.getDeviceId(), channelId , e.getDialog()); | ||
| 433 | + }); | ||
| 434 | + | ||
| 438 | 435 | ||
| 439 | } catch ( SipException | ParseException | InvalidArgumentException e) { | 436 | } catch ( SipException | ParseException | InvalidArgumentException e) { |
| 440 | e.printStackTrace(); | 437 | e.printStackTrace(); |
| @@ -450,30 +447,21 @@ public class SIPCommander implements ISIPCommander { | @@ -450,30 +447,21 @@ public class SIPCommander implements ISIPCommander { | ||
| 450 | * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss | 447 | * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss |
| 451 | */ | 448 | */ |
| 452 | @Override | 449 | @Override |
| 453 | - public void playbackStreamCmd(IMediaServerItem mediaServerItem,Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event | 450 | + public void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event |
| 454 | , SipSubscribe.Event errorEvent) { | 451 | , SipSubscribe.Event errorEvent) { |
| 455 | try { | 452 | try { |
| 456 | - String ssrc = streamSession.createPlayBackSsrc(); | ||
| 457 | - String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); | ||
| 458 | 453 | ||
| 459 | - Integer mediaPort = null; | ||
| 460 | - // 使用动态udp端口 | ||
| 461 | - if (mediaServerItem.isRtpEnable()) { | ||
| 462 | - mediaPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId); | ||
| 463 | - }else { | ||
| 464 | - mediaPort = mediaServerItem.getRtpProxyPort(); | ||
| 465 | - } | ||
| 466 | - logger.info("{} 分配的ZLM为: {} [{}:{}]", streamId, mediaServerItem.getId(), mediaServerItem.getIp(), mediaPort); | 454 | + logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStreamId(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); |
| 467 | 455 | ||
| 468 | // 添加订阅 | 456 | // 添加订阅 |
| 469 | JSONObject subscribeKey = new JSONObject(); | 457 | JSONObject subscribeKey = new JSONObject(); |
| 470 | subscribeKey.put("app", "rtp"); | 458 | subscribeKey.put("app", "rtp"); |
| 471 | - subscribeKey.put("stream", streamId); | 459 | + subscribeKey.put("stream", ssrcInfo.getStreamId()); |
| 472 | subscribeKey.put("regist", true); | 460 | subscribeKey.put("regist", true); |
| 473 | subscribeKey.put("mediaServerId", mediaServerItem.getId()); | 461 | subscribeKey.put("mediaServerId", mediaServerItem.getId()); |
| 474 | logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString()); | 462 | logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString()); |
| 475 | subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, | 463 | subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, |
| 476 | - (IMediaServerItem mediaServerItemInUse, JSONObject json)->{ | 464 | + (MediaServerItem mediaServerItemInUse, JSONObject json)->{ |
| 477 | if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return; | 465 | if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return; |
| 478 | event.response(mediaServerItemInUse, json); | 466 | event.response(mediaServerItemInUse, json); |
| 479 | subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey); | 467 | subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey); |
| @@ -494,11 +482,11 @@ public class SIPCommander implements ISIPCommander { | @@ -494,11 +482,11 @@ public class SIPCommander implements ISIPCommander { | ||
| 494 | 482 | ||
| 495 | if (userSetup.isSeniorSdp()) { | 483 | if (userSetup.isSeniorSdp()) { |
| 496 | if("TCP-PASSIVE".equals(streamMode)) { | 484 | if("TCP-PASSIVE".equals(streamMode)) { |
| 497 | - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); | 485 | + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); |
| 498 | }else if ("TCP-ACTIVE".equals(streamMode)) { | 486 | }else if ("TCP-ACTIVE".equals(streamMode)) { |
| 499 | - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); | 487 | + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); |
| 500 | }else if("UDP".equals(streamMode)) { | 488 | }else if("UDP".equals(streamMode)) { |
| 501 | - content.append("m=video "+ mediaPort +" RTP/AVP 96 126 125 99 34 98 97\r\n"); | 489 | + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 126 125 99 34 98 97\r\n"); |
| 502 | } | 490 | } |
| 503 | content.append("a=recvonly\r\n"); | 491 | content.append("a=recvonly\r\n"); |
| 504 | content.append("a=rtpmap:96 PS/90000\r\n"); | 492 | content.append("a=rtpmap:96 PS/90000\r\n"); |
| @@ -519,11 +507,11 @@ public class SIPCommander implements ISIPCommander { | @@ -519,11 +507,11 @@ public class SIPCommander implements ISIPCommander { | ||
| 519 | } | 507 | } |
| 520 | }else { | 508 | }else { |
| 521 | if("TCP-PASSIVE".equals(streamMode)) { | 509 | if("TCP-PASSIVE".equals(streamMode)) { |
| 522 | - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); | 510 | + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n"); |
| 523 | }else if ("TCP-ACTIVE".equals(streamMode)) { | 511 | }else if ("TCP-ACTIVE".equals(streamMode)) { |
| 524 | - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); | 512 | + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n"); |
| 525 | }else if("UDP".equals(streamMode)) { | 513 | }else if("UDP".equals(streamMode)) { |
| 526 | - content.append("m=video "+ mediaPort +" RTP/AVP 96 98 97\r\n"); | 514 | + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 98 97\r\n"); |
| 527 | } | 515 | } |
| 528 | content.append("a=recvonly\r\n"); | 516 | content.append("a=recvonly\r\n"); |
| 529 | content.append("a=rtpmap:96 PS/90000\r\n"); | 517 | content.append("a=rtpmap:96 PS/90000\r\n"); |
| @@ -538,7 +526,7 @@ public class SIPCommander implements ISIPCommander { | @@ -538,7 +526,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 538 | } | 526 | } |
| 539 | } | 527 | } |
| 540 | 528 | ||
| 541 | - content.append("y="+ssrc+"\r\n");//ssrc | 529 | + content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc |
| 542 | 530 | ||
| 543 | String tm = Long.toString(System.currentTimeMillis()); | 531 | String tm = Long.toString(System.currentTimeMillis()); |
| 544 | 532 | ||
| @@ -547,9 +535,11 @@ public class SIPCommander implements ISIPCommander { | @@ -547,9 +535,11 @@ public class SIPCommander implements ISIPCommander { | ||
| 547 | 535 | ||
| 548 | Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader); | 536 | Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader); |
| 549 | 537 | ||
| 550 | - ClientTransaction transaction = transmitRequest(device, request, errorEvent); | ||
| 551 | - streamSession.put(device.getDeviceId(), channelId, ssrc, streamId, transaction); | ||
| 552 | - | 538 | + transmitRequest(device, request, errorEvent, okEvent -> { |
| 539 | + Dialog dialog = okEvent.getClientTransaction().getDialog(); | ||
| 540 | + streamSession.put(device.getDeviceId(), channelId, ssrcInfo.getSsrc(), ssrcInfo.getStreamId(), mediaServerItem.getId(), okEvent.getClientTransaction()); | ||
| 541 | + streamSession.put(device.getDeviceId(), channelId, dialog); | ||
| 542 | + }); | ||
| 553 | } catch ( SipException | ParseException | InvalidArgumentException e) { | 543 | } catch ( SipException | ParseException | InvalidArgumentException e) { |
| 554 | e.printStackTrace(); | 544 | e.printStackTrace(); |
| 555 | } | 545 | } |
| @@ -565,30 +555,20 @@ public class SIPCommander implements ISIPCommander { | @@ -565,30 +555,20 @@ public class SIPCommander implements ISIPCommander { | ||
| 565 | * @param downloadSpeed 下载倍速参数 | 555 | * @param downloadSpeed 下载倍速参数 |
| 566 | */ | 556 | */ |
| 567 | @Override | 557 | @Override |
| 568 | - public void downloadStreamCmd(IMediaServerItem mediaServerItem,Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event | 558 | + public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event |
| 569 | , SipSubscribe.Event errorEvent) { | 559 | , SipSubscribe.Event errorEvent) { |
| 570 | try { | 560 | try { |
| 571 | - String ssrc = streamSession.createPlayBackSsrc(); | ||
| 572 | - String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); | ||
| 573 | - | ||
| 574 | - Integer mediaPort = null; | ||
| 575 | - // 使用动态udp端口 | ||
| 576 | - if (mediaServerItem.isRtpEnable()) { | ||
| 577 | - mediaPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId); | ||
| 578 | - }else { | ||
| 579 | - mediaPort = mediaServerItem.getRtpProxyPort(); | ||
| 580 | - } | ||
| 581 | - logger.info("{} 分配的ZLM为: {} [{}:{}]", streamId, mediaServerItem.getId(), mediaServerItem.getIp(), mediaPort); | 561 | + logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStreamId(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); |
| 582 | 562 | ||
| 583 | // 添加订阅 | 563 | // 添加订阅 |
| 584 | JSONObject subscribeKey = new JSONObject(); | 564 | JSONObject subscribeKey = new JSONObject(); |
| 585 | subscribeKey.put("app", "rtp"); | 565 | subscribeKey.put("app", "rtp"); |
| 586 | - subscribeKey.put("stream", streamId); | 566 | + subscribeKey.put("stream", ssrcInfo.getStreamId()); |
| 587 | subscribeKey.put("regist", true); | 567 | subscribeKey.put("regist", true); |
| 588 | subscribeKey.put("mediaServerId", mediaServerItem.getId()); | 568 | subscribeKey.put("mediaServerId", mediaServerItem.getId()); |
| 589 | logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString()); | 569 | logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString()); |
| 590 | subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, | 570 | subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, |
| 591 | - (IMediaServerItem mediaServerItemInUse, JSONObject json)->{ | 571 | + (MediaServerItem mediaServerItemInUse, JSONObject json)->{ |
| 592 | if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return; | 572 | if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return; |
| 593 | event.response(mediaServerItemInUse, json); | 573 | event.response(mediaServerItemInUse, json); |
| 594 | subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey); | 574 | subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey); |
| @@ -609,11 +589,11 @@ public class SIPCommander implements ISIPCommander { | @@ -609,11 +589,11 @@ public class SIPCommander implements ISIPCommander { | ||
| 609 | 589 | ||
| 610 | if (userSetup.isSeniorSdp()) { | 590 | if (userSetup.isSeniorSdp()) { |
| 611 | if("TCP-PASSIVE".equals(streamMode)) { | 591 | if("TCP-PASSIVE".equals(streamMode)) { |
| 612 | - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); | 592 | + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); |
| 613 | }else if ("TCP-ACTIVE".equals(streamMode)) { | 593 | }else if ("TCP-ACTIVE".equals(streamMode)) { |
| 614 | - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); | 594 | + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); |
| 615 | }else if("UDP".equals(streamMode)) { | 595 | }else if("UDP".equals(streamMode)) { |
| 616 | - content.append("m=video "+ mediaPort +" RTP/AVP 96 126 125 99 34 98 97\r\n"); | 596 | + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 126 125 99 34 98 97\r\n"); |
| 617 | } | 597 | } |
| 618 | content.append("a=recvonly\r\n"); | 598 | content.append("a=recvonly\r\n"); |
| 619 | content.append("a=rtpmap:96 PS/90000\r\n"); | 599 | content.append("a=rtpmap:96 PS/90000\r\n"); |
| @@ -634,11 +614,11 @@ public class SIPCommander implements ISIPCommander { | @@ -634,11 +614,11 @@ public class SIPCommander implements ISIPCommander { | ||
| 634 | } | 614 | } |
| 635 | }else { | 615 | }else { |
| 636 | if("TCP-PASSIVE".equals(streamMode)) { | 616 | if("TCP-PASSIVE".equals(streamMode)) { |
| 637 | - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); | 617 | + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n"); |
| 638 | }else if ("TCP-ACTIVE".equals(streamMode)) { | 618 | }else if ("TCP-ACTIVE".equals(streamMode)) { |
| 639 | - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); | 619 | + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n"); |
| 640 | }else if("UDP".equals(streamMode)) { | 620 | }else if("UDP".equals(streamMode)) { |
| 641 | - content.append("m=video "+ mediaPort +" RTP/AVP 96 98 97\r\n"); | 621 | + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 98 97\r\n"); |
| 642 | } | 622 | } |
| 643 | content.append("a=recvonly\r\n"); | 623 | content.append("a=recvonly\r\n"); |
| 644 | content.append("a=rtpmap:96 PS/90000\r\n"); | 624 | content.append("a=rtpmap:96 PS/90000\r\n"); |
| @@ -654,7 +634,7 @@ public class SIPCommander implements ISIPCommander { | @@ -654,7 +634,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 654 | } | 634 | } |
| 655 | content.append("a=downloadspeed:" + downloadSpeed + "\r\n"); | 635 | content.append("a=downloadspeed:" + downloadSpeed + "\r\n"); |
| 656 | 636 | ||
| 657 | - content.append("y="+ssrc+"\r\n");//ssrc | 637 | + content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc |
| 658 | 638 | ||
| 659 | String tm = Long.toString(System.currentTimeMillis()); | 639 | String tm = Long.toString(System.currentTimeMillis()); |
| 660 | 640 | ||
| @@ -664,7 +644,7 @@ public class SIPCommander implements ISIPCommander { | @@ -664,7 +644,7 @@ public class SIPCommander implements ISIPCommander { | ||
| 664 | Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader); | 644 | Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader); |
| 665 | 645 | ||
| 666 | ClientTransaction transaction = transmitRequest(device, request, errorEvent); | 646 | ClientTransaction transaction = transmitRequest(device, request, errorEvent); |
| 667 | - streamSession.put(device.getDeviceId(), channelId, ssrc, streamId, transaction); | 647 | + streamSession.put(device.getDeviceId(), channelId, ssrcInfo.getSsrc(), ssrcInfo.getStreamId(), mediaServerItem.getId(), transaction); |
| 668 | 648 | ||
| 669 | } catch ( SipException | ParseException | InvalidArgumentException e) { | 649 | } catch ( SipException | ParseException | InvalidArgumentException e) { |
| 670 | e.printStackTrace(); | 650 | e.printStackTrace(); |
| @@ -684,53 +664,35 @@ public class SIPCommander implements ISIPCommander { | @@ -684,53 +664,35 @@ public class SIPCommander implements ISIPCommander { | ||
| 684 | */ | 664 | */ |
| 685 | @Override | 665 | @Override |
| 686 | public void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent) { | 666 | public void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent) { |
| 687 | - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); | ||
| 688 | try { | 667 | try { |
| 689 | ClientTransaction transaction = streamSession.getTransaction(deviceId, channelId); | 668 | ClientTransaction transaction = streamSession.getTransaction(deviceId, channelId); |
| 690 | - // 服务重启后, 无法直接发送bye, 通过手动构建发送 | ||
| 691 | -// if (transaction == null) { | ||
| 692 | -// | ||
| 693 | -// if (streamInfo != null) { | ||
| 694 | -// MediaServerItem mediaServerItem = redisCatchStorage.getMediaInfo(streamInfo.getMediaServerId()); | ||
| 695 | -// JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaServerItem,streamInfo.getApp(), streamInfo.getStreamId()); | ||
| 696 | -// if (mediaList != null) { // 仍在推流才发送 | ||
| 697 | -// if (mediaList.getInteger("code") == 0) { | ||
| 698 | -// JSONArray data = mediaList.getJSONArray("data"); | ||
| 699 | -// if (data != null && data.size() > 0) { | ||
| 700 | -// Device device = storager.queryVideoDevice(deviceId); | ||
| 701 | -// if (device != null) { | ||
| 702 | -// StreamInfo.TransactionInfo transactionInfo = streamInfo.getTransactionInfo(); | ||
| 703 | -// try { | ||
| 704 | -// Request byteRequest = headerProvider.createByteRequest(device, channelId, | ||
| 705 | -// transactionInfo.branch, | ||
| 706 | -// transactionInfo.localTag, | ||
| 707 | -// transactionInfo.remoteTag, | ||
| 708 | -// transactionInfo.callId); | ||
| 709 | -// transmitRequest(device, byteRequest); | ||
| 710 | -// } catch (InvalidArgumentException e) { | ||
| 711 | -// e.printStackTrace(); | ||
| 712 | -// } | ||
| 713 | -// } | ||
| 714 | -// } | ||
| 715 | -// } | ||
| 716 | -// } | ||
| 717 | -// redisCatchStorage.stopPlay(streamInfo); | ||
| 718 | -// } | ||
| 719 | -// | ||
| 720 | -// if (okEvent != null) { | ||
| 721 | -// okEvent.response(null); | ||
| 722 | -// } | ||
| 723 | -// return; | ||
| 724 | -// } | ||
| 725 | if (transaction == null) { | 669 | if (transaction == null) { |
| 726 | logger.warn("[ {} -> {}]停止视频流的时候发现事务已丢失", deviceId, channelId); | 670 | logger.warn("[ {} -> {}]停止视频流的时候发现事务已丢失", deviceId, channelId); |
| 727 | return; | 671 | return; |
| 728 | } | 672 | } |
| 729 | - Dialog dialog = transaction.getDialog(); | 673 | + SIPDialog dialog = streamSession.getDialog(deviceId, channelId); |
| 730 | if (dialog == null) { | 674 | if (dialog == null) { |
| 731 | logger.warn("[ {} -> {}]停止视频流的时候发现对话已丢失", deviceId, channelId); | 675 | logger.warn("[ {} -> {}]停止视频流的时候发现对话已丢失", deviceId, channelId); |
| 732 | return; | 676 | return; |
| 733 | } | 677 | } |
| 678 | + SipStack sipStack = udpSipProvider.getSipStack(); | ||
| 679 | + SIPDialog sipDialog = ((SipStackImpl) sipStack).putDialog(dialog); | ||
| 680 | + if (dialog != sipDialog) { | ||
| 681 | + dialog = sipDialog; | ||
| 682 | + }else { | ||
| 683 | + dialog.setSipProvider(udpSipProvider); | ||
| 684 | + try { | ||
| 685 | + Field sipStackField = SIPDialog.class.getDeclaredField("sipStack"); | ||
| 686 | + sipStackField.setAccessible(true); | ||
| 687 | + sipStackField.set(dialog, sipStack); | ||
| 688 | + Field eventListenersField = SIPDialog.class.getDeclaredField("eventListeners"); | ||
| 689 | + eventListenersField.setAccessible(true); | ||
| 690 | + eventListenersField.set(dialog, new HashSet<>()); | ||
| 691 | + } catch (NoSuchFieldException | IllegalAccessException e) { | ||
| 692 | + e.printStackTrace(); | ||
| 693 | + } | ||
| 694 | + } | ||
| 695 | + | ||
| 734 | Request byeRequest = dialog.createRequest(Request.BYE); | 696 | Request byeRequest = dialog.createRequest(Request.BYE); |
| 735 | SipURI byeURI = (SipURI) byeRequest.getRequestURI(); | 697 | SipURI byeURI = (SipURI) byeRequest.getRequestURI(); |
| 736 | SIPRequest request = (SIPRequest)transaction.getRequest(); | 698 | SIPRequest request = (SIPRequest)transaction.getRequest(); |
| @@ -752,7 +714,12 @@ public class SIPCommander implements ISIPCommander { | @@ -752,7 +714,12 @@ public class SIPCommander implements ISIPCommander { | ||
| 752 | 714 | ||
| 753 | dialog.sendRequest(clientTransaction); | 715 | dialog.sendRequest(clientTransaction); |
| 754 | 716 | ||
| 755 | - streamSession.remove(deviceId, channelId); | 717 | + SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(deviceId, channelId); |
| 718 | + if (ssrcTransaction != null) { | ||
| 719 | + MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId()); | ||
| 720 | + mediaServerService.releaseSsrc(mediaServerItem, ssrcTransaction.getSsrc()); | ||
| 721 | + streamSession.remove(deviceId, channelId); | ||
| 722 | + } | ||
| 756 | } catch (SipException | ParseException e) { | 723 | } catch (SipException | ParseException e) { |
| 757 | e.printStackTrace(); | 724 | e.printStackTrace(); |
| 758 | } | 725 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java
| @@ -13,7 +13,6 @@ import com.genersoft.iot.vmp.common.StreamInfo; | @@ -13,7 +13,6 @@ import com.genersoft.iot.vmp.common.StreamInfo; | ||
| 13 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | 13 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| 14 | import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; | 14 | import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; |
| 15 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | 15 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 16 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 17 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 16 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 18 | import com.genersoft.iot.vmp.service.IMediaServerService; | 17 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 19 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 18 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| @@ -81,7 +80,7 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor { | @@ -81,7 +80,7 @@ public class AckRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 81 | while (!rtpPushed) { | 80 | while (!rtpPushed) { |
| 82 | try { | 81 | try { |
| 83 | if (System.currentTimeMillis() - startTime < 30 * 1000) { | 82 | if (System.currentTimeMillis() - startTime < 30 * 1000) { |
| 84 | - IMediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | 83 | + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); |
| 85 | if (zlmrtpServerFactory.isStreamReady(mediaInfo, streamInfo.getApp(), streamInfo.getStreamId())) { | 84 | if (zlmrtpServerFactory.isStreamReady(mediaInfo, streamInfo.getApp(), streamInfo.getStreamId())) { |
| 86 | rtpPushed = true; | 85 | rtpPushed = true; |
| 87 | logger.info("已获取设备推流[{}/{}],开始向上级推流[{}:{}]", | 86 | logger.info("已获取设备推流[{}/{}],开始向上级推流[{}:{}]", |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java
| @@ -15,7 +15,6 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | @@ -15,7 +15,6 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | ||
| 15 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; | 15 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; |
| 16 | import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; | 16 | import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; |
| 17 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | 17 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 18 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 19 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 18 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 20 | import com.genersoft.iot.vmp.service.IMediaServerService; | 19 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 21 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 20 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| @@ -65,7 +64,7 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor { | @@ -65,7 +64,7 @@ public class ByeRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 65 | param.put("stream",streamId); | 64 | param.put("stream",streamId); |
| 66 | param.put("ssrc",sendRtpItem.getSsrc()); | 65 | param.put("ssrc",sendRtpItem.getSsrc()); |
| 67 | logger.info("停止向上级推流:" + streamId); | 66 | logger.info("停止向上级推流:" + streamId); |
| 68 | - IMediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | 67 | + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); |
| 69 | zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); | 68 | zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); |
| 70 | redisCatchStorage.deleteSendRTPServer(platformGbId, channelId); | 69 | redisCatchStorage.deleteSendRTPServer(platformGbId, channelId); |
| 71 | if (zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId) == 0) { | 70 | if (zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId) == 0) { |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
| @@ -11,14 +11,11 @@ import javax.sip.header.*; | @@ -11,14 +11,11 @@ import javax.sip.header.*; | ||
| 11 | import javax.sip.message.Request; | 11 | import javax.sip.message.Request; |
| 12 | import javax.sip.message.Response; | 12 | import javax.sip.message.Response; |
| 13 | 13 | ||
| 14 | -import com.genersoft.iot.vmp.common.StreamInfo; | ||
| 15 | -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; | ||
| 16 | import com.genersoft.iot.vmp.gb28181.bean.*; | 14 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 17 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | 15 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
| 18 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; | 16 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; |
| 19 | import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; | 17 | import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; |
| 20 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | 18 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 21 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 22 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 19 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 23 | import com.genersoft.iot.vmp.service.IMediaServerService; | 20 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 24 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 21 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| @@ -97,7 +94,7 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { | @@ -97,7 +94,7 @@ public class InviteRequestProcessor extends SIPRequestAbstractProcessor { | ||
| 97 | // 查询平台下是否有该通道 | 94 | // 查询平台下是否有该通道 |
| 98 | DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId); | 95 | DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId); |
| 99 | GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId); | 96 | GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId); |
| 100 | - IMediaServerItem mediaServerItem = null; | 97 | + MediaServerItem mediaServerItem = null; |
| 101 | // 不是通道可能是直播流 | 98 | // 不是通道可能是直播流 |
| 102 | if (channel != null && gbStream == null ) { | 99 | if (channel != null && gbStream == null ) { |
| 103 | if (channel.getStatus() == 0) { | 100 | if (channel.getStatus() == 0) { |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java
| @@ -3,14 +3,18 @@ package com.genersoft.iot.vmp.gb28181.transmit.response.impl; | @@ -3,14 +3,18 @@ package com.genersoft.iot.vmp.gb28181.transmit.response.impl; | ||
| 3 | import java.text.ParseException; | 3 | import java.text.ParseException; |
| 4 | 4 | ||
| 5 | import javax.sip.*; | 5 | import javax.sip.*; |
| 6 | +import javax.sip.address.Address; | ||
| 6 | import javax.sip.address.SipURI; | 7 | import javax.sip.address.SipURI; |
| 7 | import javax.sip.header.CSeqHeader; | 8 | import javax.sip.header.CSeqHeader; |
| 8 | import javax.sip.message.Request; | 9 | import javax.sip.message.Request; |
| 9 | import javax.sip.message.Response; | 10 | import javax.sip.message.Response; |
| 10 | 11 | ||
| 12 | +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | ||
| 11 | import gov.nist.javax.sip.ResponseEventExt; | 13 | import gov.nist.javax.sip.ResponseEventExt; |
| 14 | +import gov.nist.javax.sip.stack.SIPDialog; | ||
| 12 | import org.slf4j.Logger; | 15 | import org.slf4j.Logger; |
| 13 | import org.slf4j.LoggerFactory; | 16 | import org.slf4j.LoggerFactory; |
| 17 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 14 | import org.springframework.stereotype.Component; | 18 | import org.springframework.stereotype.Component; |
| 15 | 19 | ||
| 16 | import com.genersoft.iot.vmp.conf.SipConfig; | 20 | import com.genersoft.iot.vmp.conf.SipConfig; |
| @@ -28,6 +32,9 @@ public class InviteResponseProcessor implements ISIPResponseProcessor { | @@ -28,6 +32,9 @@ public class InviteResponseProcessor implements ISIPResponseProcessor { | ||
| 28 | 32 | ||
| 29 | private final static Logger logger = LoggerFactory.getLogger(InviteResponseProcessor.class); | 33 | private final static Logger logger = LoggerFactory.getLogger(InviteResponseProcessor.class); |
| 30 | 34 | ||
| 35 | + @Autowired | ||
| 36 | + private VideoStreamSessionManager streamSession; | ||
| 37 | + | ||
| 31 | /** | 38 | /** |
| 32 | * 处理invite响应 | 39 | * 处理invite响应 |
| 33 | * | 40 | * |
| @@ -46,7 +53,7 @@ public class InviteResponseProcessor implements ISIPResponseProcessor { | @@ -46,7 +53,7 @@ public class InviteResponseProcessor implements ISIPResponseProcessor { | ||
| 46 | // 下发ack | 53 | // 下发ack |
| 47 | if (statusCode == Response.OK) { | 54 | if (statusCode == Response.OK) { |
| 48 | ResponseEventExt event = (ResponseEventExt)evt; | 55 | ResponseEventExt event = (ResponseEventExt)evt; |
| 49 | - Dialog dialog = evt.getDialog(); | 56 | + SIPDialog dialog = (SIPDialog)evt.getDialog(); |
| 50 | CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); | 57 | CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); |
| 51 | Request reqAck = dialog.createAck(cseq.getSeqNumber()); | 58 | Request reqAck = dialog.createAck(cseq.getSeqNumber()); |
| 52 | SipURI requestURI = (SipURI) reqAck.getRequestURI(); | 59 | SipURI requestURI = (SipURI) reqAck.getRequestURI(); |
| @@ -54,7 +61,12 @@ public class InviteResponseProcessor implements ISIPResponseProcessor { | @@ -54,7 +61,12 @@ public class InviteResponseProcessor implements ISIPResponseProcessor { | ||
| 54 | requestURI.setPort(event.getRemotePort()); | 61 | requestURI.setPort(event.getRemotePort()); |
| 55 | reqAck.setRequestURI(requestURI); | 62 | reqAck.setRequestURI(requestURI); |
| 56 | logger.info("向 " + event.getRemoteIpAddress() + ":" + event.getRemotePort() + "回复ack"); | 63 | logger.info("向 " + event.getRemoteIpAddress() + ":" + event.getRemotePort() + "回复ack"); |
| 64 | + SipURI sipURI = (SipURI)dialog.getRemoteParty().getURI(); | ||
| 65 | + String deviceId = requestURI.getUser(); | ||
| 66 | + String channelId = sipURI.getUser(); | ||
| 67 | + | ||
| 57 | dialog.sendAck(reqAck); | 68 | dialog.sendAck(reqAck); |
| 69 | + | ||
| 58 | } | 70 | } |
| 59 | } catch (InvalidArgumentException | SipException e) { | 71 | } catch (InvalidArgumentException | SipException e) { |
| 60 | e.printStackTrace(); | 72 | e.printStackTrace(); |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
| @@ -3,15 +3,14 @@ package com.genersoft.iot.vmp.media.zlm; | @@ -3,15 +3,14 @@ package com.genersoft.iot.vmp.media.zlm; | ||
| 3 | import java.util.List; | 3 | import java.util.List; |
| 4 | import java.util.UUID; | 4 | import java.util.UUID; |
| 5 | 5 | ||
| 6 | -import com.alibaba.fastjson.JSON; | ||
| 7 | import com.alibaba.fastjson.JSONArray; | 6 | import com.alibaba.fastjson.JSONArray; |
| 8 | import com.genersoft.iot.vmp.common.StreamInfo; | 7 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 9 | import com.genersoft.iot.vmp.conf.MediaConfig; | 8 | import com.genersoft.iot.vmp.conf.MediaConfig; |
| 10 | import com.genersoft.iot.vmp.conf.UserSetup; | 9 | import com.genersoft.iot.vmp.conf.UserSetup; |
| 11 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 10 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 12 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 13 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 11 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 14 | import com.genersoft.iot.vmp.service.IMediaServerService; | 12 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 13 | +import com.genersoft.iot.vmp.service.bean.SSRCInfo; | ||
| 15 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 14 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 16 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | 15 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 17 | import com.genersoft.iot.vmp.service.IPlayService; | 16 | import com.genersoft.iot.vmp.service.IPlayService; |
| @@ -42,7 +41,6 @@ public class ZLMHttpHookListener { | @@ -42,7 +41,6 @@ public class ZLMHttpHookListener { | ||
| 42 | 41 | ||
| 43 | private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookListener.class); | 42 | private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookListener.class); |
| 44 | 43 | ||
| 45 | - | ||
| 46 | @Autowired | 44 | @Autowired |
| 47 | private SIPCommander cmder; | 45 | private SIPCommander cmder; |
| 48 | 46 | ||
| @@ -125,7 +123,7 @@ public class ZLMHttpHookListener { | @@ -125,7 +123,7 @@ public class ZLMHttpHookListener { | ||
| 125 | String mediaServerId = json.getString("mediaServerId"); | 123 | String mediaServerId = json.getString("mediaServerId"); |
| 126 | ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_play, json); | 124 | ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_play, json); |
| 127 | if (subscribe != null ) { | 125 | if (subscribe != null ) { |
| 128 | - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); | 126 | + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); |
| 129 | if (mediaInfo != null) { | 127 | if (mediaInfo != null) { |
| 130 | subscribe.response(mediaInfo, json); | 128 | subscribe.response(mediaInfo, json); |
| 131 | } | 129 | } |
| @@ -150,7 +148,7 @@ public class ZLMHttpHookListener { | @@ -150,7 +148,7 @@ public class ZLMHttpHookListener { | ||
| 150 | String mediaServerId = json.getString("mediaServerId"); | 148 | String mediaServerId = json.getString("mediaServerId"); |
| 151 | ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, json); | 149 | ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, json); |
| 152 | if (subscribe != null) { | 150 | if (subscribe != null) { |
| 153 | - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); | 151 | + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); |
| 154 | if (mediaInfo != null) { | 152 | if (mediaInfo != null) { |
| 155 | subscribe.response(mediaInfo, json); | 153 | subscribe.response(mediaInfo, json); |
| 156 | } | 154 | } |
| @@ -237,7 +235,7 @@ public class ZLMHttpHookListener { | @@ -237,7 +235,7 @@ public class ZLMHttpHookListener { | ||
| 237 | String mediaServerId = json.getString("mediaServerId"); | 235 | String mediaServerId = json.getString("mediaServerId"); |
| 238 | ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_shell_login, json); | 236 | ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_shell_login, json); |
| 239 | if (subscribe != null ) { | 237 | if (subscribe != null ) { |
| 240 | - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); | 238 | + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); |
| 241 | if (mediaInfo != null) { | 239 | if (mediaInfo != null) { |
| 242 | subscribe.response(mediaInfo, json); | 240 | subscribe.response(mediaInfo, json); |
| 243 | } | 241 | } |
| @@ -264,7 +262,7 @@ public class ZLMHttpHookListener { | @@ -264,7 +262,7 @@ public class ZLMHttpHookListener { | ||
| 264 | String mediaServerId = json.getString("mediaServerId"); | 262 | String mediaServerId = json.getString("mediaServerId"); |
| 265 | ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, json); | 263 | ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, json); |
| 266 | if (subscribe != null ) { | 264 | if (subscribe != null ) { |
| 267 | - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); | 265 | + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); |
| 268 | if (mediaInfo != null) { | 266 | if (mediaInfo != null) { |
| 269 | subscribe.response(mediaInfo, json); | 267 | subscribe.response(mediaInfo, json); |
| 270 | } | 268 | } |
| @@ -297,7 +295,7 @@ public class ZLMHttpHookListener { | @@ -297,7 +295,7 @@ public class ZLMHttpHookListener { | ||
| 297 | } | 295 | } |
| 298 | }else { | 296 | }else { |
| 299 | if (!"rtp".equals(app) ){ | 297 | if (!"rtp".equals(app) ){ |
| 300 | - IMediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); | 298 | + MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); |
| 301 | if (regist) { | 299 | if (regist) { |
| 302 | zlmMediaListManager.addMedia(mediaServerItem, app, streamId); | 300 | zlmMediaListManager.addMedia(mediaServerItem, app, streamId); |
| 303 | }else { | 301 | }else { |
| @@ -369,7 +367,7 @@ public class ZLMHttpHookListener { | @@ -369,7 +367,7 @@ public class ZLMHttpHookListener { | ||
| 369 | logger.debug("ZLM HOOK on_stream_not_found API调用,参数:" + json.toString()); | 367 | logger.debug("ZLM HOOK on_stream_not_found API调用,参数:" + json.toString()); |
| 370 | } | 368 | } |
| 371 | String mediaServerId = json.getString("mediaServerId"); | 369 | String mediaServerId = json.getString("mediaServerId"); |
| 372 | - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); | 370 | + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); |
| 373 | if (userSetup.isAutoApplyPlay() && mediaInfo != null) { | 371 | if (userSetup.isAutoApplyPlay() && mediaInfo != null) { |
| 374 | String app = json.getString("app"); | 372 | String app = json.getString("app"); |
| 375 | String streamId = json.getString("stream"); | 373 | String streamId = json.getString("stream"); |
| @@ -381,7 +379,13 @@ public class ZLMHttpHookListener { | @@ -381,7 +379,13 @@ public class ZLMHttpHookListener { | ||
| 381 | Device device = storager.queryVideoDevice(deviceId); | 379 | Device device = storager.queryVideoDevice(deviceId); |
| 382 | if (device != null) { | 380 | if (device != null) { |
| 383 | UUID uuid = UUID.randomUUID(); | 381 | UUID uuid = UUID.randomUUID(); |
| 384 | - cmder.playStreamCmd(mediaInfo, device, channelId, (IMediaServerItem mediaServerItemInuse, JSONObject response) -> { | 382 | + SSRCInfo ssrcInfo; |
| 383 | + String streamId2 = null; | ||
| 384 | + if (mediaInfo.isRtpEnable()) { | ||
| 385 | + streamId2 = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); | ||
| 386 | + } | ||
| 387 | + ssrcInfo = mediaServerService.openRTPServer(mediaInfo, streamId2); | ||
| 388 | + cmder.playStreamCmd(mediaInfo, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> { | ||
| 385 | logger.info("收到订阅消息: " + response.toJSONString()); | 389 | logger.info("收到订阅消息: " + response.toJSONString()); |
| 386 | playService.onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString()); | 390 | playService.onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString()); |
| 387 | }, null); | 391 | }, null); |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java
| 1 | package com.genersoft.iot.vmp.media.zlm; | 1 | package com.genersoft.iot.vmp.media.zlm; |
| 2 | 2 | ||
| 3 | import com.alibaba.fastjson.JSONObject; | 3 | import com.alibaba.fastjson.JSONObject; |
| 4 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 5 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 4 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 6 | import org.springframework.stereotype.Component; | 5 | import org.springframework.stereotype.Component; |
| 7 | 6 | ||
| @@ -32,7 +31,7 @@ public class ZLMHttpHookSubscribe { | @@ -32,7 +31,7 @@ public class ZLMHttpHookSubscribe { | ||
| 32 | } | 31 | } |
| 33 | 32 | ||
| 34 | public interface Event{ | 33 | public interface Event{ |
| 35 | - void response(IMediaServerItem mediaServerItem, JSONObject response); | 34 | + void response(MediaServerItem mediaServerItem, JSONObject response); |
| 36 | } | 35 | } |
| 37 | 36 | ||
| 38 | private Map<HookType, Map<JSONObject, ZLMHttpHookSubscribe.Event>> allSubscribes = new ConcurrentHashMap<>(); | 37 | private Map<HookType, Map<JSONObject, ZLMHttpHookSubscribe.Event>> allSubscribes = new ConcurrentHashMap<>(); |
| @@ -58,6 +57,9 @@ public class ZLMHttpHookSubscribe { | @@ -58,6 +57,9 @@ public class ZLMHttpHookSubscribe { | ||
| 58 | if (result == null) { | 57 | if (result == null) { |
| 59 | result = key.getString(s).equals(hookResponse.getString(s)); | 58 | result = key.getString(s).equals(hookResponse.getString(s)); |
| 60 | }else { | 59 | }else { |
| 60 | + if (key.getString(s) == null) { | ||
| 61 | + continue; | ||
| 62 | + } | ||
| 61 | result = result && key.getString(s).equals(hookResponse.getString(s)); | 63 | result = result && key.getString(s).equals(hookResponse.getString(s)); |
| 62 | } | 64 | } |
| 63 | 65 | ||
| @@ -83,9 +85,9 @@ public class ZLMHttpHookSubscribe { | @@ -83,9 +85,9 @@ public class ZLMHttpHookSubscribe { | ||
| 83 | if (result == null) { | 85 | if (result == null) { |
| 84 | result = key.getString(s).equals(hookResponse.getString(s)); | 86 | result = key.getString(s).equals(hookResponse.getString(s)); |
| 85 | }else { | 87 | }else { |
| 88 | + if (key.getString(s) == null) continue; | ||
| 86 | result = result && key.getString(s).equals(hookResponse.getString(s)); | 89 | result = result && key.getString(s).equals(hookResponse.getString(s)); |
| 87 | } | 90 | } |
| 88 | - | ||
| 89 | } | 91 | } |
| 90 | if (null != result && result){ | 92 | if (null != result && result){ |
| 91 | iterator.remove(); | 93 | iterator.remove(); |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
| 1 | package com.genersoft.iot.vmp.media.zlm; | 1 | package com.genersoft.iot.vmp.media.zlm; |
| 2 | 2 | ||
| 3 | -import com.alibaba.fastjson.JSONArray; | ||
| 4 | import com.alibaba.fastjson.JSONObject; | 3 | import com.alibaba.fastjson.JSONObject; |
| 5 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 6 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 4 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 7 | import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; | 5 | import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; |
| 8 | import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; | 6 | import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; |
| 9 | -import com.genersoft.iot.vmp.gb28181.bean.GbStream; | ||
| 10 | import com.genersoft.iot.vmp.service.IStreamPushService; | 7 | import com.genersoft.iot.vmp.service.IStreamPushService; |
| 11 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 8 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 12 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | 9 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| @@ -76,7 +73,7 @@ public class ZLMMediaListManager { | @@ -76,7 +73,7 @@ public class ZLMMediaListManager { | ||
| 76 | jsonObject.put("stream", streamPushItem.getStream()); | 73 | jsonObject.put("stream", streamPushItem.getStream()); |
| 77 | jsonObject.put("mediaServerId", mediaServerItem.getId()); | 74 | jsonObject.put("mediaServerId", mediaServerItem.getId()); |
| 78 | subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_play,jsonObject, | 75 | subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_play,jsonObject, |
| 79 | - (IMediaServerItem mediaServerItemInuse, JSONObject response)->{ | 76 | + (MediaServerItem mediaServerItemInuse, JSONObject response)->{ |
| 80 | updateMedia(mediaServerItem, response.getString("app"), response.getString("stream")); | 77 | updateMedia(mediaServerItem, response.getString("app"), response.getString("stream")); |
| 81 | } | 78 | } |
| 82 | ); | 79 | ); |
| @@ -86,13 +83,13 @@ public class ZLMMediaListManager { | @@ -86,13 +83,13 @@ public class ZLMMediaListManager { | ||
| 86 | 83 | ||
| 87 | } | 84 | } |
| 88 | 85 | ||
| 89 | - public void addMedia(IMediaServerItem mediaServerItem, String app, String streamId) { | 86 | + public void addMedia(MediaServerItem mediaServerItem, String app, String streamId) { |
| 90 | //使用异步更新推流 | 87 | //使用异步更新推流 |
| 91 | updateMedia(mediaServerItem, app, streamId); | 88 | updateMedia(mediaServerItem, app, streamId); |
| 92 | } | 89 | } |
| 93 | 90 | ||
| 94 | 91 | ||
| 95 | - public void updateMedia(IMediaServerItem mediaServerItem, String app, String streamId) { | 92 | + public void updateMedia(MediaServerItem mediaServerItem, String app, String streamId) { |
| 96 | //使用异步更新推流 | 93 | //使用异步更新推流 |
| 97 | zlmresTfulUtils.getMediaList(mediaServerItem, app, streamId, "rtmp", json->{ | 94 | zlmresTfulUtils.getMediaList(mediaServerItem, app, streamId, "rtmp", json->{ |
| 98 | 95 |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
| @@ -2,14 +2,11 @@ package com.genersoft.iot.vmp.media.zlm; | @@ -2,14 +2,11 @@ package com.genersoft.iot.vmp.media.zlm; | ||
| 2 | 2 | ||
| 3 | import com.alibaba.fastjson.JSON; | 3 | import com.alibaba.fastjson.JSON; |
| 4 | import com.alibaba.fastjson.JSONObject; | 4 | import com.alibaba.fastjson.JSONObject; |
| 5 | -import com.genersoft.iot.vmp.conf.MediaConfig; | ||
| 6 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 7 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 5 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 8 | import okhttp3.*; | 6 | import okhttp3.*; |
| 9 | import org.jetbrains.annotations.NotNull; | 7 | import org.jetbrains.annotations.NotNull; |
| 10 | import org.slf4j.Logger; | 8 | import org.slf4j.Logger; |
| 11 | import org.slf4j.LoggerFactory; | 9 | import org.slf4j.LoggerFactory; |
| 12 | -import org.springframework.beans.factory.annotation.Autowired; | ||
| 13 | import org.springframework.stereotype.Component; | 10 | import org.springframework.stereotype.Component; |
| 14 | 11 | ||
| 15 | import java.io.*; | 12 | import java.io.*; |
| @@ -27,7 +24,7 @@ public class ZLMRESTfulUtils { | @@ -27,7 +24,7 @@ public class ZLMRESTfulUtils { | ||
| 27 | void run(JSONObject response); | 24 | void run(JSONObject response); |
| 28 | } | 25 | } |
| 29 | 26 | ||
| 30 | - public JSONObject sendPost(IMediaServerItem mediaServerItem, String api, Map<String, Object> param, RequestCallback callback) { | 27 | + public JSONObject sendPost(MediaServerItem mediaServerItem, String api, Map<String, Object> param, RequestCallback callback) { |
| 31 | OkHttpClient client = new OkHttpClient(); | 28 | OkHttpClient client = new OkHttpClient(); |
| 32 | String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api); | 29 | String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api); |
| 33 | JSONObject responseJSON = null; | 30 | JSONObject responseJSON = null; |
| @@ -93,7 +90,7 @@ public class ZLMRESTfulUtils { | @@ -93,7 +90,7 @@ public class ZLMRESTfulUtils { | ||
| 93 | } | 90 | } |
| 94 | 91 | ||
| 95 | 92 | ||
| 96 | - public void sendPostForImg(IMediaServerItem mediaServerItem, String api, Map<String, Object> param, String targetPath, String fileName) { | 93 | + public void sendPostForImg(MediaServerItem mediaServerItem, String api, Map<String, Object> param, String targetPath, String fileName) { |
| 97 | OkHttpClient client = new OkHttpClient(); | 94 | OkHttpClient client = new OkHttpClient(); |
| 98 | String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api); | 95 | String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api); |
| 99 | JSONObject responseJSON = null; | 96 | JSONObject responseJSON = null; |
| @@ -139,7 +136,7 @@ public class ZLMRESTfulUtils { | @@ -139,7 +136,7 @@ public class ZLMRESTfulUtils { | ||
| 139 | } | 136 | } |
| 140 | 137 | ||
| 141 | 138 | ||
| 142 | - public JSONObject getMediaList(IMediaServerItem mediaServerItem,String app, String stream, String schema, RequestCallback callback){ | 139 | + public JSONObject getMediaList(MediaServerItem mediaServerItem, String app, String stream, String schema, RequestCallback callback){ |
| 143 | Map<String, Object> param = new HashMap<>(); | 140 | Map<String, Object> param = new HashMap<>(); |
| 144 | if (app != null) param.put("app",app); | 141 | if (app != null) param.put("app",app); |
| 145 | if (stream != null) param.put("stream",stream); | 142 | if (stream != null) param.put("stream",stream); |
| @@ -148,15 +145,15 @@ public class ZLMRESTfulUtils { | @@ -148,15 +145,15 @@ public class ZLMRESTfulUtils { | ||
| 148 | return sendPost(mediaServerItem, "getMediaList",param, callback); | 145 | return sendPost(mediaServerItem, "getMediaList",param, callback); |
| 149 | } | 146 | } |
| 150 | 147 | ||
| 151 | - public JSONObject getMediaList(IMediaServerItem mediaServerItem,String app, String stream){ | 148 | + public JSONObject getMediaList(MediaServerItem mediaServerItem, String app, String stream){ |
| 152 | return getMediaList(mediaServerItem, app, stream,null, null); | 149 | return getMediaList(mediaServerItem, app, stream,null, null); |
| 153 | } | 150 | } |
| 154 | 151 | ||
| 155 | - public JSONObject getMediaList(IMediaServerItem mediaServerItem,RequestCallback callback){ | 152 | + public JSONObject getMediaList(MediaServerItem mediaServerItem, RequestCallback callback){ |
| 156 | return sendPost(mediaServerItem, "getMediaList",null, callback); | 153 | return sendPost(mediaServerItem, "getMediaList",null, callback); |
| 157 | } | 154 | } |
| 158 | 155 | ||
| 159 | - public JSONObject getMediaInfo(IMediaServerItem mediaServerItem,String app, String schema, String stream){ | 156 | + public JSONObject getMediaInfo(MediaServerItem mediaServerItem, String app, String schema, String stream){ |
| 160 | Map<String, Object> param = new HashMap<>(); | 157 | Map<String, Object> param = new HashMap<>(); |
| 161 | param.put("app",app); | 158 | param.put("app",app); |
| 162 | param.put("schema",schema); | 159 | param.put("schema",schema); |
| @@ -165,13 +162,13 @@ public class ZLMRESTfulUtils { | @@ -165,13 +162,13 @@ public class ZLMRESTfulUtils { | ||
| 165 | return sendPost(mediaServerItem, "getMediaInfo",param, null); | 162 | return sendPost(mediaServerItem, "getMediaInfo",param, null); |
| 166 | } | 163 | } |
| 167 | 164 | ||
| 168 | - public JSONObject getRtpInfo(IMediaServerItem mediaServerItem,String stream_id){ | 165 | + public JSONObject getRtpInfo(MediaServerItem mediaServerItem, String stream_id){ |
| 169 | Map<String, Object> param = new HashMap<>(); | 166 | Map<String, Object> param = new HashMap<>(); |
| 170 | param.put("stream_id",stream_id); | 167 | param.put("stream_id",stream_id); |
| 171 | return sendPost(mediaServerItem, "getRtpInfo",param, null); | 168 | return sendPost(mediaServerItem, "getRtpInfo",param, null); |
| 172 | } | 169 | } |
| 173 | 170 | ||
| 174 | - public JSONObject addFFmpegSource(IMediaServerItem mediaServerItem,String src_url, String dst_url, String timeout_ms, | 171 | + public JSONObject addFFmpegSource(MediaServerItem mediaServerItem, String src_url, String dst_url, String timeout_ms, |
| 175 | boolean enable_hls, boolean enable_mp4, String ffmpeg_cmd_key){ | 172 | boolean enable_hls, boolean enable_mp4, String ffmpeg_cmd_key){ |
| 176 | logger.info(src_url); | 173 | logger.info(src_url); |
| 177 | logger.info(dst_url); | 174 | logger.info(dst_url); |
| @@ -185,41 +182,41 @@ public class ZLMRESTfulUtils { | @@ -185,41 +182,41 @@ public class ZLMRESTfulUtils { | ||
| 185 | return sendPost(mediaServerItem, "addFFmpegSource",param, null); | 182 | return sendPost(mediaServerItem, "addFFmpegSource",param, null); |
| 186 | } | 183 | } |
| 187 | 184 | ||
| 188 | - public JSONObject delFFmpegSource(IMediaServerItem mediaServerItem,String key){ | 185 | + public JSONObject delFFmpegSource(MediaServerItem mediaServerItem, String key){ |
| 189 | Map<String, Object> param = new HashMap<>(); | 186 | Map<String, Object> param = new HashMap<>(); |
| 190 | param.put("key", key); | 187 | param.put("key", key); |
| 191 | return sendPost(mediaServerItem, "delFFmpegSource",param, null); | 188 | return sendPost(mediaServerItem, "delFFmpegSource",param, null); |
| 192 | } | 189 | } |
| 193 | 190 | ||
| 194 | - public JSONObject getMediaServerConfig(IMediaServerItem mediaServerItem){ | 191 | + public JSONObject getMediaServerConfig(MediaServerItem mediaServerItem){ |
| 195 | return sendPost(mediaServerItem, "getServerConfig",null, null); | 192 | return sendPost(mediaServerItem, "getServerConfig",null, null); |
| 196 | } | 193 | } |
| 197 | 194 | ||
| 198 | - public JSONObject setServerConfig(IMediaServerItem mediaServerItem, Map<String, Object> param){ | 195 | + public JSONObject setServerConfig(MediaServerItem mediaServerItem, Map<String, Object> param){ |
| 199 | return sendPost(mediaServerItem,"setServerConfig",param, null); | 196 | return sendPost(mediaServerItem,"setServerConfig",param, null); |
| 200 | } | 197 | } |
| 201 | 198 | ||
| 202 | - public JSONObject openRtpServer(IMediaServerItem mediaServerItem,Map<String, Object> param){ | 199 | + public JSONObject openRtpServer(MediaServerItem mediaServerItem, Map<String, Object> param){ |
| 203 | return sendPost(mediaServerItem, "openRtpServer",param, null); | 200 | return sendPost(mediaServerItem, "openRtpServer",param, null); |
| 204 | } | 201 | } |
| 205 | 202 | ||
| 206 | - public JSONObject closeRtpServer(IMediaServerItem mediaServerItem,Map<String, Object> param) { | 203 | + public JSONObject closeRtpServer(MediaServerItem mediaServerItem, Map<String, Object> param) { |
| 207 | return sendPost(mediaServerItem, "closeRtpServer",param, null); | 204 | return sendPost(mediaServerItem, "closeRtpServer",param, null); |
| 208 | } | 205 | } |
| 209 | 206 | ||
| 210 | - public JSONObject listRtpServer(IMediaServerItem mediaServerItem) { | 207 | + public JSONObject listRtpServer(MediaServerItem mediaServerItem) { |
| 211 | return sendPost(mediaServerItem, "listRtpServer",null, null); | 208 | return sendPost(mediaServerItem, "listRtpServer",null, null); |
| 212 | } | 209 | } |
| 213 | 210 | ||
| 214 | - public JSONObject startSendRtp(IMediaServerItem mediaServerItem,Map<String, Object> param) { | 211 | + public JSONObject startSendRtp(MediaServerItem mediaServerItem, Map<String, Object> param) { |
| 215 | return sendPost(mediaServerItem, "startSendRtp",param, null); | 212 | return sendPost(mediaServerItem, "startSendRtp",param, null); |
| 216 | } | 213 | } |
| 217 | 214 | ||
| 218 | - public JSONObject stopSendRtp(IMediaServerItem mediaServerItem,Map<String, Object> param) { | 215 | + public JSONObject stopSendRtp(MediaServerItem mediaServerItem, Map<String, Object> param) { |
| 219 | return sendPost(mediaServerItem, "stopSendRtp",param, null); | 216 | return sendPost(mediaServerItem, "stopSendRtp",param, null); |
| 220 | } | 217 | } |
| 221 | 218 | ||
| 222 | - public JSONObject addStreamProxy(IMediaServerItem mediaServerItem,String app, String stream, String url, boolean enable_hls, boolean enable_mp4, String rtp_type) { | 219 | + public JSONObject addStreamProxy(MediaServerItem mediaServerItem, String app, String stream, String url, boolean enable_hls, boolean enable_mp4, String rtp_type) { |
| 223 | Map<String, Object> param = new HashMap<>(); | 220 | Map<String, Object> param = new HashMap<>(); |
| 224 | param.put("vhost", "__defaultVhost__"); | 221 | param.put("vhost", "__defaultVhost__"); |
| 225 | param.put("app", app); | 222 | param.put("app", app); |
| @@ -231,7 +228,7 @@ public class ZLMRESTfulUtils { | @@ -231,7 +228,7 @@ public class ZLMRESTfulUtils { | ||
| 231 | return sendPost(mediaServerItem, "addStreamProxy",param, null); | 228 | return sendPost(mediaServerItem, "addStreamProxy",param, null); |
| 232 | } | 229 | } |
| 233 | 230 | ||
| 234 | - public JSONObject closeStreams(IMediaServerItem mediaServerItem,String app, String stream) { | 231 | + public JSONObject closeStreams(MediaServerItem mediaServerItem, String app, String stream) { |
| 235 | Map<String, Object> param = new HashMap<>(); | 232 | Map<String, Object> param = new HashMap<>(); |
| 236 | param.put("vhost", "__defaultVhost__"); | 233 | param.put("vhost", "__defaultVhost__"); |
| 237 | param.put("app", app); | 234 | param.put("app", app); |
| @@ -240,17 +237,17 @@ public class ZLMRESTfulUtils { | @@ -240,17 +237,17 @@ public class ZLMRESTfulUtils { | ||
| 240 | return sendPost(mediaServerItem, "close_streams",param, null); | 237 | return sendPost(mediaServerItem, "close_streams",param, null); |
| 241 | } | 238 | } |
| 242 | 239 | ||
| 243 | - public JSONObject getAllSession(IMediaServerItem mediaServerItem) { | 240 | + public JSONObject getAllSession(MediaServerItem mediaServerItem) { |
| 244 | return sendPost(mediaServerItem, "getAllSession",null, null); | 241 | return sendPost(mediaServerItem, "getAllSession",null, null); |
| 245 | } | 242 | } |
| 246 | 243 | ||
| 247 | - public void kickSessions(IMediaServerItem mediaServerItem, String localPortSStr) { | 244 | + public void kickSessions(MediaServerItem mediaServerItem, String localPortSStr) { |
| 248 | Map<String, Object> param = new HashMap<>(); | 245 | Map<String, Object> param = new HashMap<>(); |
| 249 | param.put("local_port", localPortSStr); | 246 | param.put("local_port", localPortSStr); |
| 250 | sendPost(mediaServerItem, "kick_sessions",param, null); | 247 | sendPost(mediaServerItem, "kick_sessions",param, null); |
| 251 | } | 248 | } |
| 252 | 249 | ||
| 253 | - public void getSnap(IMediaServerItem mediaServerItem, String flvUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) { | 250 | + public void getSnap(MediaServerItem mediaServerItem, String flvUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) { |
| 254 | Map<String, Object> param = new HashMap<>(); | 251 | Map<String, Object> param = new HashMap<>(); |
| 255 | param.put("url", flvUrl); | 252 | param.put("url", flvUrl); |
| 256 | param.put("timeout_sec", timeout_sec); | 253 | param.put("timeout_sec", timeout_sec); |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
| @@ -2,10 +2,7 @@ package com.genersoft.iot.vmp.media.zlm; | @@ -2,10 +2,7 @@ package com.genersoft.iot.vmp.media.zlm; | ||
| 2 | 2 | ||
| 3 | import com.alibaba.fastjson.JSONArray; | 3 | import com.alibaba.fastjson.JSONArray; |
| 4 | import com.alibaba.fastjson.JSONObject; | 4 | import com.alibaba.fastjson.JSONObject; |
| 5 | -import com.genersoft.iot.vmp.conf.MediaConfig; | ||
| 6 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | 5 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| 7 | -import com.genersoft.iot.vmp.gb28181.session.SsrcUtil; | ||
| 8 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 9 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 6 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 10 | import org.slf4j.Logger; | 7 | import org.slf4j.Logger; |
| 11 | import org.slf4j.LoggerFactory; | 8 | import org.slf4j.LoggerFactory; |
| @@ -21,28 +18,19 @@ public class ZLMRTPServerFactory { | @@ -21,28 +18,19 @@ public class ZLMRTPServerFactory { | ||
| 21 | private Logger logger = LoggerFactory.getLogger("ZLMRTPServerFactory"); | 18 | private Logger logger = LoggerFactory.getLogger("ZLMRTPServerFactory"); |
| 22 | 19 | ||
| 23 | @Autowired | 20 | @Autowired |
| 24 | - private MediaConfig mediaConfig; | ||
| 25 | - | ||
| 26 | - @Autowired | ||
| 27 | private ZLMRESTfulUtils zlmresTfulUtils; | 21 | private ZLMRESTfulUtils zlmresTfulUtils; |
| 28 | 22 | ||
| 29 | private int[] portRangeArray = new int[2]; | 23 | private int[] portRangeArray = new int[2]; |
| 30 | 24 | ||
| 31 | - private int currentPort = 0; | ||
| 32 | - | ||
| 33 | - private Map<String, Integer> currentStreams = null; | ||
| 34 | - | ||
| 35 | - public int createRTPServer(IMediaServerItem mediaServerItem, String streamId) { | ||
| 36 | - if (currentStreams == null) { | ||
| 37 | - currentStreams = new HashMap<>(); | ||
| 38 | - JSONObject jsonObject = zlmresTfulUtils.listRtpServer(mediaServerItem); | ||
| 39 | - if (jsonObject != null) { | ||
| 40 | - JSONArray data = jsonObject.getJSONArray("data"); | ||
| 41 | - if (data != null) { | ||
| 42 | - for (int i = 0; i < data.size(); i++) { | ||
| 43 | - JSONObject dataItem = data.getJSONObject(i); | ||
| 44 | - currentStreams.put(dataItem.getString("stream_id"), dataItem.getInteger("port")); | ||
| 45 | - } | 25 | + public int createRTPServer(MediaServerItem mediaServerItem, String streamId) { |
| 26 | + Map<String, Integer> currentStreams = new HashMap<>(); | ||
| 27 | + JSONObject listRtpServerJsonResult = zlmresTfulUtils.listRtpServer(mediaServerItem); | ||
| 28 | + if (listRtpServerJsonResult != null) { | ||
| 29 | + JSONArray data = listRtpServerJsonResult.getJSONArray("data"); | ||
| 30 | + if (data != null) { | ||
| 31 | + for (int i = 0; i < data.size(); i++) { | ||
| 32 | + JSONObject dataItem = data.getJSONObject(i); | ||
| 33 | + currentStreams.put(dataItem.getString("stream_id"), dataItem.getInteger("port")); | ||
| 46 | } | 34 | } |
| 47 | } | 35 | } |
| 48 | } | 36 | } |
| @@ -56,18 +44,18 @@ public class ZLMRTPServerFactory { | @@ -56,18 +44,18 @@ public class ZLMRTPServerFactory { | ||
| 56 | 44 | ||
| 57 | Map<String, Object> param = new HashMap<>(); | 45 | Map<String, Object> param = new HashMap<>(); |
| 58 | int result = -1; | 46 | int result = -1; |
| 59 | - int newPort = getPortFromportRange(); | 47 | + int newPort = getPortFromportRange(mediaServerItem); |
| 60 | param.put("port", newPort); | 48 | param.put("port", newPort); |
| 61 | param.put("enable_tcp", 1); | 49 | param.put("enable_tcp", 1); |
| 62 | param.put("stream_id", streamId); | 50 | param.put("stream_id", streamId); |
| 63 | - JSONObject jsonObject = zlmresTfulUtils.openRtpServer(mediaServerItem, param); | 51 | + JSONObject openRtpServerResultJson = zlmresTfulUtils.openRtpServer(mediaServerItem, param); |
| 64 | 52 | ||
| 65 | - if (jsonObject != null) { | ||
| 66 | - switch (jsonObject.getInteger("code")){ | 53 | + if (openRtpServerResultJson != null) { |
| 54 | + switch (openRtpServerResultJson.getInteger("code")){ | ||
| 67 | case 0: | 55 | case 0: |
| 68 | result= newPort; | 56 | result= newPort; |
| 69 | break; | 57 | break; |
| 70 | - case -300: // id已经存在, 可能已经在其他端口推流 | 58 | + case -300: // id已经存在, 可能已经在其他端口推流, TODO 也可能是设备不等ack就直接推流了, 需要查询与设置的推流ip端口是否一致 |
| 71 | Map<String, Object> closeRtpServerParam = new HashMap<>(); | 59 | Map<String, Object> closeRtpServerParam = new HashMap<>(); |
| 72 | closeRtpServerParam.put("stream_id", streamId); | 60 | closeRtpServerParam.put("stream_id", streamId); |
| 73 | zlmresTfulUtils.closeRtpServer(mediaServerItem, closeRtpServerParam); | 61 | zlmresTfulUtils.closeRtpServer(mediaServerItem, closeRtpServerParam); |
| @@ -77,7 +65,7 @@ public class ZLMRTPServerFactory { | @@ -77,7 +65,7 @@ public class ZLMRTPServerFactory { | ||
| 77 | result= createRTPServer(mediaServerItem, streamId); | 65 | result= createRTPServer(mediaServerItem, streamId); |
| 78 | break; | 66 | break; |
| 79 | default: | 67 | default: |
| 80 | - logger.error("创建RTP Server 失败 {}: " + jsonObject.getString("msg"), newPort); | 68 | + logger.error("创建RTP Server 失败 {}: " + openRtpServerResultJson.getString("msg"), newPort); |
| 81 | break; | 69 | break; |
| 82 | } | 70 | } |
| 83 | }else { | 71 | }else { |
| @@ -87,7 +75,7 @@ public class ZLMRTPServerFactory { | @@ -87,7 +75,7 @@ public class ZLMRTPServerFactory { | ||
| 87 | return result; | 75 | return result; |
| 88 | } | 76 | } |
| 89 | 77 | ||
| 90 | - public boolean closeRTPServer(IMediaServerItem serverItem, String streamId) { | 78 | + public boolean closeRTPServer(MediaServerItem serverItem, String streamId) { |
| 91 | boolean result = false; | 79 | boolean result = false; |
| 92 | if (serverItem !=null){ | 80 | if (serverItem !=null){ |
| 93 | Map<String, Object> param = new HashMap<>(); | 81 | Map<String, Object> param = new HashMap<>(); |
| @@ -107,21 +95,25 @@ public class ZLMRTPServerFactory { | @@ -107,21 +95,25 @@ public class ZLMRTPServerFactory { | ||
| 107 | return result; | 95 | return result; |
| 108 | } | 96 | } |
| 109 | 97 | ||
| 110 | - private int getPortFromportRange() { | 98 | + private int getPortFromportRange(MediaServerItem mediaServerItem) { |
| 99 | + int currentPort = mediaServerItem.getCurrentPort(); | ||
| 111 | if (currentPort == 0) { | 100 | if (currentPort == 0) { |
| 112 | - String[] portRangeStrArray = mediaConfig.getRtpPortRange().split(","); | 101 | + String[] portRangeStrArray = mediaServerItem.getRtpPortRange().split(","); |
| 113 | portRangeArray[0] = Integer.parseInt(portRangeStrArray[0]); | 102 | portRangeArray[0] = Integer.parseInt(portRangeStrArray[0]); |
| 114 | portRangeArray[1] = Integer.parseInt(portRangeStrArray[1]); | 103 | portRangeArray[1] = Integer.parseInt(portRangeStrArray[1]); |
| 115 | } | 104 | } |
| 116 | 105 | ||
| 117 | if (currentPort == 0 || currentPort++ > portRangeArray[1]) { | 106 | if (currentPort == 0 || currentPort++ > portRangeArray[1]) { |
| 118 | currentPort = portRangeArray[0]; | 107 | currentPort = portRangeArray[0]; |
| 108 | + mediaServerItem.setCurrentPort(currentPort); | ||
| 119 | return portRangeArray[0]; | 109 | return portRangeArray[0]; |
| 120 | } else { | 110 | } else { |
| 121 | if (currentPort % 2 == 1) { | 111 | if (currentPort % 2 == 1) { |
| 122 | currentPort++; | 112 | currentPort++; |
| 123 | } | 113 | } |
| 124 | - return currentPort++; | 114 | + currentPort++; |
| 115 | + mediaServerItem.setCurrentPort(currentPort); | ||
| 116 | + return currentPort; | ||
| 125 | } | 117 | } |
| 126 | } | 118 | } |
| 127 | 119 | ||
| @@ -135,10 +127,14 @@ public class ZLMRTPServerFactory { | @@ -135,10 +127,14 @@ public class ZLMRTPServerFactory { | ||
| 135 | * @param tcp 是否为tcp | 127 | * @param tcp 是否为tcp |
| 136 | * @return SendRtpItem | 128 | * @return SendRtpItem |
| 137 | */ | 129 | */ |
| 138 | - public SendRtpItem createSendRtpItem(IMediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp){ | ||
| 139 | - String playSsrc = SsrcUtil.getPlaySsrc(); | ||
| 140 | - int localPort = createRTPServer(serverItem, SsrcUtil.getPlaySsrc()); | 130 | + public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp){ |
| 131 | + | ||
| 132 | + // 使用RTPServer 功能找一个可用的端口 | ||
| 133 | + String playSsrc = serverItem.getSsrcConfig().getPlaySsrc(); | ||
| 134 | + int localPort = createRTPServer(serverItem, playSsrc); | ||
| 141 | if (localPort != -1) { | 135 | if (localPort != -1) { |
| 136 | + // TODO 高并发时可能因为未放入缓存而ssrc冲突 | ||
| 137 | + serverItem.getSsrcConfig().releaseSsrc(playSsrc); | ||
| 142 | closeRTPServer(serverItem, playSsrc); | 138 | closeRTPServer(serverItem, playSsrc); |
| 143 | }else { | 139 | }else { |
| 144 | logger.error("没有可用的端口"); | 140 | logger.error("没有可用的端口"); |
| @@ -168,10 +164,12 @@ public class ZLMRTPServerFactory { | @@ -168,10 +164,12 @@ public class ZLMRTPServerFactory { | ||
| 168 | * @param tcp 是否为tcp | 164 | * @param tcp 是否为tcp |
| 169 | * @return SendRtpItem | 165 | * @return SendRtpItem |
| 170 | */ | 166 | */ |
| 171 | - public SendRtpItem createSendRtpItem(IMediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp){ | ||
| 172 | - String playSsrc = SsrcUtil.getPlaySsrc(); | ||
| 173 | - int localPort = createRTPServer(serverItem, SsrcUtil.getPlaySsrc()); | 167 | + public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp){ |
| 168 | + String playSsrc = serverItem.getSsrcConfig().getPlaySsrc(); | ||
| 169 | + int localPort = createRTPServer(serverItem, playSsrc); | ||
| 174 | if (localPort != -1) { | 170 | if (localPort != -1) { |
| 171 | + // TODO 高并发时可能因为未放入缓存而ssrc冲突 | ||
| 172 | + serverItem.getSsrcConfig().releaseSsrc(ssrc); | ||
| 175 | closeRTPServer(serverItem, playSsrc); | 173 | closeRTPServer(serverItem, playSsrc); |
| 176 | }else { | 174 | }else { |
| 177 | logger.error("没有可用的端口"); | 175 | logger.error("没有可用的端口"); |
| @@ -194,7 +192,7 @@ public class ZLMRTPServerFactory { | @@ -194,7 +192,7 @@ public class ZLMRTPServerFactory { | ||
| 194 | /** | 192 | /** |
| 195 | * 调用zlm RESTful API —— startSendRtp | 193 | * 调用zlm RESTful API —— startSendRtp |
| 196 | */ | 194 | */ |
| 197 | - public Boolean startSendRtpStream(IMediaServerItem mediaServerItem, Map<String, Object>param) { | 195 | + public Boolean startSendRtpStream(MediaServerItem mediaServerItem, Map<String, Object>param) { |
| 198 | Boolean result = false; | 196 | Boolean result = false; |
| 199 | JSONObject jsonObject = zlmresTfulUtils.startSendRtp(mediaServerItem, param); | 197 | JSONObject jsonObject = zlmresTfulUtils.startSendRtp(mediaServerItem, param); |
| 200 | if (jsonObject == null) { | 198 | if (jsonObject == null) { |
| @@ -219,7 +217,7 @@ public class ZLMRTPServerFactory { | @@ -219,7 +217,7 @@ public class ZLMRTPServerFactory { | ||
| 219 | /** | 217 | /** |
| 220 | * 查询待转推的流是否就绪 | 218 | * 查询待转推的流是否就绪 |
| 221 | */ | 219 | */ |
| 222 | - public Boolean isStreamReady(IMediaServerItem mediaServerItem, String app, String streamId) { | 220 | + public Boolean isStreamReady(MediaServerItem mediaServerItem, String app, String streamId) { |
| 223 | JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId); | 221 | JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId); |
| 224 | return (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online")); | 222 | return (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online")); |
| 225 | } | 223 | } |
| @@ -229,7 +227,7 @@ public class ZLMRTPServerFactory { | @@ -229,7 +227,7 @@ public class ZLMRTPServerFactory { | ||
| 229 | * @param streamId | 227 | * @param streamId |
| 230 | * @return | 228 | * @return |
| 231 | */ | 229 | */ |
| 232 | - public int totalReaderCount(IMediaServerItem mediaServerItem, String app, String streamId) { | 230 | + public int totalReaderCount(MediaServerItem mediaServerItem, String app, String streamId) { |
| 233 | JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId); | 231 | JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId); |
| 234 | return mediaInfo.getInteger("totalReaderCount"); | 232 | return mediaInfo.getInteger("totalReaderCount"); |
| 235 | } | 233 | } |
| @@ -237,7 +235,7 @@ public class ZLMRTPServerFactory { | @@ -237,7 +235,7 @@ public class ZLMRTPServerFactory { | ||
| 237 | /** | 235 | /** |
| 238 | * 调用zlm RESTful API —— stopSendRtp | 236 | * 调用zlm RESTful API —— stopSendRtp |
| 239 | */ | 237 | */ |
| 240 | - public Boolean stopSendRtpStream(IMediaServerItem mediaServerItem,Map<String, Object>param) { | 238 | + public Boolean stopSendRtpStream(MediaServerItem mediaServerItem, Map<String, Object>param) { |
| 241 | Boolean result = false; | 239 | Boolean result = false; |
| 242 | JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(mediaServerItem, param); | 240 | JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(mediaServerItem, param); |
| 243 | if (jsonObject == null) { | 241 | if (jsonObject == null) { |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
| @@ -4,22 +4,16 @@ import com.alibaba.fastjson.JSON; | @@ -4,22 +4,16 @@ import com.alibaba.fastjson.JSON; | ||
| 4 | import com.alibaba.fastjson.JSONArray; | 4 | import com.alibaba.fastjson.JSONArray; |
| 5 | import com.alibaba.fastjson.JSONObject; | 5 | import com.alibaba.fastjson.JSONObject; |
| 6 | import com.genersoft.iot.vmp.conf.MediaConfig; | 6 | import com.genersoft.iot.vmp.conf.MediaConfig; |
| 7 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 8 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 7 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 9 | -import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; | ||
| 10 | import com.genersoft.iot.vmp.service.IMediaServerService; | 8 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 11 | -import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | ||
| 12 | import com.genersoft.iot.vmp.service.IStreamProxyService; | 9 | import com.genersoft.iot.vmp.service.IStreamProxyService; |
| 13 | import org.slf4j.Logger; | 10 | import org.slf4j.Logger; |
| 14 | import org.slf4j.LoggerFactory; | 11 | import org.slf4j.LoggerFactory; |
| 15 | import org.springframework.beans.factory.annotation.Autowired; | 12 | import org.springframework.beans.factory.annotation.Autowired; |
| 16 | -import org.springframework.beans.factory.annotation.Value; | ||
| 17 | import org.springframework.boot.CommandLineRunner; | 13 | import org.springframework.boot.CommandLineRunner; |
| 18 | import org.springframework.core.annotation.Order; | 14 | import org.springframework.core.annotation.Order; |
| 19 | import org.springframework.stereotype.Component; | 15 | import org.springframework.stereotype.Component; |
| 20 | -import org.springframework.util.StringUtils; | ||
| 21 | 16 | ||
| 22 | -import javax.print.attribute.standard.Media; | ||
| 23 | import java.util.*; | 17 | import java.util.*; |
| 24 | 18 | ||
| 25 | @Component | 19 | @Component |
| @@ -47,16 +41,26 @@ public class ZLMRunner implements CommandLineRunner { | @@ -47,16 +41,26 @@ public class ZLMRunner implements CommandLineRunner { | ||
| 47 | 41 | ||
| 48 | @Override | 42 | @Override |
| 49 | public void run(String... strings) throws Exception { | 43 | public void run(String... strings) throws Exception { |
| 50 | - IMediaServerItem presetMediaServer = mediaServerService.getOneByHostAndPort( | 44 | + // 清楚redis缓存的在线zlm信息 |
| 45 | + mediaServerService.clearMediaServerForOnline(); | ||
| 46 | + | ||
| 47 | + // 将配置文件的meida配置写入数据库 | ||
| 48 | + MediaServerItem presetMediaServer = mediaServerService.getOneByHostAndPort( | ||
| 51 | mediaConfig.getIp(), mediaConfig.getHttpPort()); | 49 | mediaConfig.getIp(), mediaConfig.getHttpPort()); |
| 52 | if (presetMediaServer != null) { | 50 | if (presetMediaServer != null) { |
| 53 | - mediaConfig.setId(presetMediaServer.getId()); | ||
| 54 | - mediaServerService.update(mediaConfig); | 51 | + MediaServerItem mediaSerItem = mediaConfig.getMediaSerItem(); |
| 52 | + mediaSerItem.setId(presetMediaServer.getId()); | ||
| 53 | + mediaServerService.update(mediaSerItem); | ||
| 54 | + }else { | ||
| 55 | + if (mediaConfig.getId() != null) { | ||
| 56 | + MediaServerItem mediaSerItem = mediaConfig.getMediaSerItem(); | ||
| 57 | + mediaServerService.add(mediaSerItem); | ||
| 58 | + } | ||
| 55 | } | 59 | } |
| 56 | 60 | ||
| 57 | // 订阅 zlm启动事件, 新的zlm也会从这里进入系统 | 61 | // 订阅 zlm启动事件, 新的zlm也会从这里进入系统 |
| 58 | hookSubscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_server_started,null, | 62 | hookSubscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_server_started,null, |
| 59 | - (IMediaServerItem mediaServerItem, JSONObject response)->{ | 63 | + (MediaServerItem mediaServerItem, JSONObject response)->{ |
| 60 | ZLMServerConfig zlmServerConfig = JSONObject.toJavaObject(response, ZLMServerConfig.class); | 64 | ZLMServerConfig zlmServerConfig = JSONObject.toJavaObject(response, ZLMServerConfig.class); |
| 61 | if (zlmServerConfig !=null ) { | 65 | if (zlmServerConfig !=null ) { |
| 62 | startGetMedia.remove(zlmServerConfig.getGeneralMediaServerId()); | 66 | startGetMedia.remove(zlmServerConfig.getGeneralMediaServerId()); |
| @@ -69,23 +73,25 @@ public class ZLMRunner implements CommandLineRunner { | @@ -69,23 +73,25 @@ public class ZLMRunner implements CommandLineRunner { | ||
| 69 | logger.info("等待默认zlm接入..."); | 73 | logger.info("等待默认zlm接入..."); |
| 70 | 74 | ||
| 71 | // 获取所有的zlm, 并开启主动连接 | 75 | // 获取所有的zlm, 并开启主动连接 |
| 72 | - List<IMediaServerItem> all = mediaServerService.getAll(); | 76 | + List<MediaServerItem> all = mediaServerService.getAll(); |
| 73 | if (presetMediaServer == null) { | 77 | if (presetMediaServer == null) { |
| 74 | all.add(mediaConfig.getMediaSerItem()); | 78 | all.add(mediaConfig.getMediaSerItem()); |
| 75 | } | 79 | } |
| 76 | - for (IMediaServerItem mediaServerItem : all) { | 80 | + for (MediaServerItem mediaServerItem : all) { |
| 77 | if (startGetMedia == null) startGetMedia = new HashMap<>(); | 81 | if (startGetMedia == null) startGetMedia = new HashMap<>(); |
| 78 | startGetMedia.put(mediaServerItem.getId(), true); | 82 | startGetMedia.put(mediaServerItem.getId(), true); |
| 79 | new Thread(() -> { | 83 | new Thread(() -> { |
| 80 | ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem); | 84 | ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem); |
| 81 | if (zlmServerConfig != null) { | 85 | if (zlmServerConfig != null) { |
| 86 | + zlmServerConfig.setIp(mediaServerItem.getIp()); | ||
| 87 | + zlmServerConfig.setHttpPort(mediaServerItem.getHttpPort()); | ||
| 82 | startGetMedia.remove(mediaServerItem.getId()); | 88 | startGetMedia.remove(mediaServerItem.getId()); |
| 83 | mediaServerService.handLeZLMServerConfig(zlmServerConfig); | 89 | mediaServerService.handLeZLMServerConfig(zlmServerConfig); |
| 84 | } | 90 | } |
| 85 | }).start(); | 91 | }).start(); |
| 86 | } | 92 | } |
| 87 | Timer timer = new Timer(); | 93 | Timer timer = new Timer(); |
| 88 | - // 1分钟后未连接到则不再去主动连接 | 94 | + // 2分钟后未连接到则不再去主动连接, TODO 并对重启前使用此在zlm的通道发送bye |
| 89 | timer.schedule(new TimerTask() { | 95 | timer.schedule(new TimerTask() { |
| 90 | @Override | 96 | @Override |
| 91 | public void run() { | 97 | public void run() { |
| @@ -100,7 +106,7 @@ public class ZLMRunner implements CommandLineRunner { | @@ -100,7 +106,7 @@ public class ZLMRunner implements CommandLineRunner { | ||
| 100 | }, 60 * 1000 * 2); | 106 | }, 60 * 1000 * 2); |
| 101 | } | 107 | } |
| 102 | 108 | ||
| 103 | - public ZLMServerConfig getMediaServerConfig(IMediaServerItem mediaServerItem) { | 109 | + public ZLMServerConfig getMediaServerConfig(MediaServerItem mediaServerItem) { |
| 104 | if ( startGetMedia.get(mediaServerItem.getId()) == null || !startGetMedia.get(mediaServerItem.getId())) return null; | 110 | if ( startGetMedia.get(mediaServerItem.getId()) == null || !startGetMedia.get(mediaServerItem.getId())) return null; |
| 105 | JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); | 111 | JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); |
| 106 | ZLMServerConfig ZLMServerConfig = null; | 112 | ZLMServerConfig ZLMServerConfig = null; |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/IMediaServerItem.java deleted
100644 → 0
| 1 | -package com.genersoft.iot.vmp.media.zlm.dto; | ||
| 2 | - | ||
| 3 | -public interface IMediaServerItem { | ||
| 4 | - | ||
| 5 | - String getId(); | ||
| 6 | - | ||
| 7 | - void setId(String id); | ||
| 8 | - | ||
| 9 | - String getIp(); | ||
| 10 | - | ||
| 11 | - void setIp(String ip); | ||
| 12 | - | ||
| 13 | - String getHookIp(); | ||
| 14 | - | ||
| 15 | - void setHookIp(String hookIp); | ||
| 16 | - | ||
| 17 | - String getSdpIp(); | ||
| 18 | - | ||
| 19 | - void setSdpIp(String sdpIp); | ||
| 20 | - | ||
| 21 | - String getStreamIp(); | ||
| 22 | - | ||
| 23 | - void setStreamIp(String streamIp); | ||
| 24 | - | ||
| 25 | - int getHttpPort(); | ||
| 26 | - | ||
| 27 | - void setHttpPort(int httpPort); | ||
| 28 | - | ||
| 29 | - int getHttpSSlPort(); | ||
| 30 | - | ||
| 31 | - void setHttpSSlPort(int httpSSlPort); | ||
| 32 | - | ||
| 33 | - int getRtmpPort(); | ||
| 34 | - | ||
| 35 | - void setRtmpPort(int rtmpPort); | ||
| 36 | - | ||
| 37 | - int getRtmpSSlPort(); | ||
| 38 | - | ||
| 39 | - void setRtmpSSlPort(int rtmpSSlPort); | ||
| 40 | - | ||
| 41 | - int getRtpProxyPort(); | ||
| 42 | - | ||
| 43 | - void setRtpProxyPort(int rtpProxyPort); | ||
| 44 | - | ||
| 45 | - int getRtspPort(); | ||
| 46 | - | ||
| 47 | - void setRtspPort(int rtspPort); | ||
| 48 | - | ||
| 49 | - int getRtspSSLPort(); | ||
| 50 | - | ||
| 51 | - void setRtspSSLPort(int rtspSSLPort); | ||
| 52 | - | ||
| 53 | - boolean isAutoConfig(); | ||
| 54 | - | ||
| 55 | - void setAutoConfig(boolean autoConfig); | ||
| 56 | - | ||
| 57 | - String getSecret(); | ||
| 58 | - | ||
| 59 | - void setSecret(String secret); | ||
| 60 | - | ||
| 61 | - String getStreamNoneReaderDelayMS(); | ||
| 62 | - | ||
| 63 | - void setStreamNoneReaderDelayMS(String streamNoneReaderDelayMS); | ||
| 64 | - | ||
| 65 | - boolean isRtpEnable(); | ||
| 66 | - | ||
| 67 | - void setRtpEnable(boolean rtpEnable); | ||
| 68 | - | ||
| 69 | - String getRtpPortRange(); | ||
| 70 | - | ||
| 71 | - void setRtpPortRange(String rtpPortRange); | ||
| 72 | - | ||
| 73 | - int getRecordAssistPort(); | ||
| 74 | - | ||
| 75 | - void setRecordAssistPort(int recordAssistPort); | ||
| 76 | - | ||
| 77 | - boolean isDocker(); | ||
| 78 | - | ||
| 79 | - void setDocker(boolean docker); | ||
| 80 | - | ||
| 81 | - String getUpdateTime(); | ||
| 82 | - | ||
| 83 | - void setUpdateTime(String updateTime); | ||
| 84 | - | ||
| 85 | - String getCreateTime(); | ||
| 86 | - | ||
| 87 | - void setCreateTime(String createTime); | ||
| 88 | - | ||
| 89 | - int getCount(); | ||
| 90 | - | ||
| 91 | - void setCount(int count); | ||
| 92 | -} |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java
| 1 | package com.genersoft.iot.vmp.media.zlm.dto; | 1 | package com.genersoft.iot.vmp.media.zlm.dto; |
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | +import com.genersoft.iot.vmp.gb28181.session.SsrcConfig; | ||
| 4 | import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; | 5 | import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; |
| 5 | import org.springframework.util.StringUtils; | 6 | import org.springframework.util.StringUtils; |
| 6 | 7 | ||
| 7 | -public class MediaServerItem implements IMediaServerItem{ | 8 | +import java.util.HashMap; |
| 9 | + | ||
| 10 | +public class MediaServerItem{ | ||
| 8 | 11 | ||
| 9 | private String id; | 12 | private String id; |
| 10 | 13 | ||
| @@ -46,9 +49,18 @@ public class MediaServerItem implements IMediaServerItem{ | @@ -46,9 +49,18 @@ public class MediaServerItem implements IMediaServerItem{ | ||
| 46 | 49 | ||
| 47 | private String updateTime; | 50 | private String updateTime; |
| 48 | 51 | ||
| 49 | - private boolean docker; | 52 | + private boolean defaultServer; |
| 53 | + | ||
| 54 | + private SsrcConfig ssrcConfig; | ||
| 55 | + | ||
| 56 | + private int currentPort; | ||
| 57 | + | ||
| 50 | 58 | ||
| 51 | - private int count; | 59 | + /** |
| 60 | + * 每一台ZLM都有一套独立的SSRC列表 | ||
| 61 | + * 在ApplicationCheckRunner里对mediaServerSsrcMap进行初始化 | ||
| 62 | + */ | ||
| 63 | + private HashMap<String, SsrcConfig> mediaServerSsrcMap; | ||
| 52 | 64 | ||
| 53 | public MediaServerItem() { | 65 | public MediaServerItem() { |
| 54 | } | 66 | } |
| @@ -218,14 +230,12 @@ public class MediaServerItem implements IMediaServerItem{ | @@ -218,14 +230,12 @@ public class MediaServerItem implements IMediaServerItem{ | ||
| 218 | this.recordAssistPort = recordAssistPort; | 230 | this.recordAssistPort = recordAssistPort; |
| 219 | } | 231 | } |
| 220 | 232 | ||
| 221 | - @Override | ||
| 222 | - public boolean isDocker() { | ||
| 223 | - return docker; | 233 | + public boolean isDefaultServer() { |
| 234 | + return defaultServer; | ||
| 224 | } | 235 | } |
| 225 | 236 | ||
| 226 | - @Override | ||
| 227 | - public void setDocker(boolean docker) { | ||
| 228 | - this.docker = docker; | 237 | + public void setDefaultServer(boolean defaultServer) { |
| 238 | + this.defaultServer = defaultServer; | ||
| 229 | } | 239 | } |
| 230 | 240 | ||
| 231 | public String getCreateTime() { | 241 | public String getCreateTime() { |
| @@ -244,11 +254,29 @@ public class MediaServerItem implements IMediaServerItem{ | @@ -244,11 +254,29 @@ public class MediaServerItem implements IMediaServerItem{ | ||
| 244 | this.updateTime = updateTime; | 254 | this.updateTime = updateTime; |
| 245 | } | 255 | } |
| 246 | 256 | ||
| 247 | - public int getCount() { | ||
| 248 | - return count; | 257 | + public HashMap<String, SsrcConfig> getMediaServerSsrcMap() { |
| 258 | + return mediaServerSsrcMap; | ||
| 259 | + } | ||
| 260 | + | ||
| 261 | + public void setMediaServerSsrcMap(HashMap<String, SsrcConfig> mediaServerSsrcMap) { | ||
| 262 | + this.mediaServerSsrcMap = mediaServerSsrcMap; | ||
| 263 | + } | ||
| 264 | + | ||
| 265 | + public SsrcConfig getSsrcConfig() { | ||
| 266 | + return ssrcConfig; | ||
| 267 | + } | ||
| 268 | + | ||
| 269 | + public void setSsrcConfig(SsrcConfig ssrcConfig) { | ||
| 270 | + this.ssrcConfig = ssrcConfig; | ||
| 249 | } | 271 | } |
| 250 | 272 | ||
| 251 | - public void setCount(int count) { | ||
| 252 | - this.count = count; | 273 | + public int getCurrentPort() { |
| 274 | + return currentPort; | ||
| 253 | } | 275 | } |
| 276 | + | ||
| 277 | + public void setCurrentPort(int currentPort) { | ||
| 278 | + this.currentPort = currentPort; | ||
| 279 | + } | ||
| 280 | + | ||
| 281 | + | ||
| 254 | } | 282 | } |
src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
| @@ -3,8 +3,8 @@ package com.genersoft.iot.vmp.service; | @@ -3,8 +3,8 @@ package com.genersoft.iot.vmp.service; | ||
| 3 | import com.genersoft.iot.vmp.conf.MediaConfig; | 3 | import com.genersoft.iot.vmp.conf.MediaConfig; |
| 4 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 4 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 5 | import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; | 5 | import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; |
| 6 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 7 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 6 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 7 | +import com.genersoft.iot.vmp.service.bean.SSRCInfo; | ||
| 8 | 8 | ||
| 9 | import java.util.List; | 9 | import java.util.List; |
| 10 | 10 | ||
| @@ -13,11 +13,13 @@ import java.util.List; | @@ -13,11 +13,13 @@ import java.util.List; | ||
| 13 | */ | 13 | */ |
| 14 | public interface IMediaServerService { | 14 | public interface IMediaServerService { |
| 15 | 15 | ||
| 16 | - List<IMediaServerItem> getAll(); | 16 | + List<MediaServerItem> getAll(); |
| 17 | 17 | ||
| 18 | - IMediaServerItem getOne(String generalMediaServerId); | 18 | + List<MediaServerItem> getAllOnline(); |
| 19 | 19 | ||
| 20 | - IMediaServerItem getOneByHostAndPort(String host, int port); | 20 | + MediaServerItem getOne(String generalMediaServerId); |
| 21 | + | ||
| 22 | + MediaServerItem getOneByHostAndPort(String host, int port); | ||
| 21 | 23 | ||
| 22 | /** | 24 | /** |
| 23 | * 新的节点加入 | 25 | * 新的节点加入 |
| @@ -26,19 +28,27 @@ public interface IMediaServerService { | @@ -26,19 +28,27 @@ public interface IMediaServerService { | ||
| 26 | */ | 28 | */ |
| 27 | void handLeZLMServerConfig(ZLMServerConfig zlmServerConfig); | 29 | void handLeZLMServerConfig(ZLMServerConfig zlmServerConfig); |
| 28 | 30 | ||
| 29 | - void updateServerCatch(IMediaServerItem mediaServerItem, Integer count, Boolean b); | ||
| 30 | - | ||
| 31 | - IMediaServerItem getMediaServerForMinimumLoad(); | 31 | + MediaServerItem getMediaServerForMinimumLoad(); |
| 32 | 32 | ||
| 33 | - void setZLMConfig(IMediaServerItem mediaServerItem); | 33 | + void setZLMConfig(MediaServerItem mediaServerItem); |
| 34 | 34 | ||
| 35 | - void init(); | 35 | + SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId); |
| 36 | 36 | ||
| 37 | void closeRTPServer(Device device, String channelId); | 37 | void closeRTPServer(Device device, String channelId); |
| 38 | 38 | ||
| 39 | - void update(MediaConfig mediaConfig); | 39 | + void clearRTPServer(MediaServerItem mediaServerItem); |
| 40 | + | ||
| 41 | + void update(MediaServerItem mediaSerItem); | ||
| 40 | 42 | ||
| 41 | void addCount(String mediaServerId); | 43 | void addCount(String mediaServerId); |
| 42 | 44 | ||
| 43 | void removeCount(String mediaServerId); | 45 | void removeCount(String mediaServerId); |
| 46 | + | ||
| 47 | + void releaseSsrc(MediaServerItem mediaServerItem, String ssrc); | ||
| 48 | + | ||
| 49 | + void clearMediaServerForOnline(); | ||
| 50 | + | ||
| 51 | + void add(MediaServerItem mediaSerItem); | ||
| 52 | + | ||
| 53 | + void resetOnlineServerItem(MediaServerItem serverItem); | ||
| 44 | } | 54 | } |
src/main/java/com/genersoft/iot/vmp/service/IMediaService.java
| @@ -2,7 +2,6 @@ package com.genersoft.iot.vmp.service; | @@ -2,7 +2,6 @@ package com.genersoft.iot.vmp.service; | ||
| 2 | 2 | ||
| 3 | import com.alibaba.fastjson.JSONArray; | 3 | import com.alibaba.fastjson.JSONArray; |
| 4 | import com.genersoft.iot.vmp.common.StreamInfo; | 4 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 5 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 6 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 5 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 7 | 6 | ||
| 8 | /** | 7 | /** |
| @@ -33,7 +32,7 @@ public interface IMediaService { | @@ -33,7 +32,7 @@ public interface IMediaService { | ||
| 33 | * @param stream | 32 | * @param stream |
| 34 | * @return | 33 | * @return |
| 35 | */ | 34 | */ |
| 36 | - StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaServerItem, String app, String stream, JSONArray tracks); | 35 | + StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaServerItem, String app, String stream, JSONArray tracks); |
| 37 | 36 | ||
| 38 | /** | 37 | /** |
| 39 | * 根据应用名和流ID获取播放地址, 只是地址拼接,返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况 | 38 | * 根据应用名和流ID获取播放地址, 只是地址拼接,返回的ip使用远程访问ip,适用与zlm与wvp在一台主机的情况 |
| @@ -41,5 +40,5 @@ public interface IMediaService { | @@ -41,5 +40,5 @@ public interface IMediaService { | ||
| 41 | * @param stream | 40 | * @param stream |
| 42 | * @return | 41 | * @return |
| 43 | */ | 42 | */ |
| 44 | - StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaInfo, String app, String stream, JSONArray tracks, String addr); | 43 | + StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, JSONArray tracks, String addr); |
| 45 | } | 44 | } |
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
| @@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSONObject; | @@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSONObject; | ||
| 4 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 4 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 5 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | 5 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| 6 | import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; | 6 | import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; |
| 7 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 8 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 7 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 9 | import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; | 8 | import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; |
| 10 | 9 | ||
| @@ -13,10 +12,10 @@ import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; | @@ -13,10 +12,10 @@ import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; | ||
| 13 | */ | 12 | */ |
| 14 | public interface IPlayService { | 13 | public interface IPlayService { |
| 15 | 14 | ||
| 16 | - void onPublishHandlerForPlayBack(IMediaServerItem mediaServerItem,JSONObject resonse, String deviceId, String channelId, String uuid); | ||
| 17 | - void onPublishHandlerForPlay(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid); | 15 | + void onPublishHandlerForPlayBack(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid); |
| 16 | + void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid); | ||
| 18 | 17 | ||
| 19 | - PlayResult play(IMediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); | 18 | + PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); |
| 20 | 19 | ||
| 21 | - IMediaServerItem getNewMediaServerItem(Device device); | 20 | + MediaServerItem getNewMediaServerItem(Device device); |
| 22 | } | 21 | } |
src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java
| 1 | package com.genersoft.iot.vmp.service; | 1 | package com.genersoft.iot.vmp.service; |
| 2 | 2 | ||
| 3 | import com.alibaba.fastjson.JSONObject; | 3 | import com.alibaba.fastjson.JSONObject; |
| 4 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 5 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 4 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 6 | import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; | 5 | import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; |
| 7 | import com.github.pagehelper.PageInfo; | 6 | import com.github.pagehelper.PageInfo; |
| @@ -63,5 +62,5 @@ public interface IStreamProxyService { | @@ -63,5 +62,5 @@ public interface IStreamProxyService { | ||
| 63 | * 获取ffmpeg.cmd模板 | 62 | * 获取ffmpeg.cmd模板 |
| 64 | * @return | 63 | * @return |
| 65 | */ | 64 | */ |
| 66 | - JSONObject getFFmpegCMDs(IMediaServerItem mediaServerItem); | 65 | + JSONObject getFFmpegCMDs(MediaServerItem mediaServerItem); |
| 67 | } | 66 | } |
src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
| 1 | package com.genersoft.iot.vmp.service; | 1 | package com.genersoft.iot.vmp.service; |
| 2 | 2 | ||
| 3 | import com.genersoft.iot.vmp.gb28181.bean.GbStream; | 3 | import com.genersoft.iot.vmp.gb28181.bean.GbStream; |
| 4 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | 4 | +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 5 | import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; | 5 | import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; |
| 6 | import com.github.pagehelper.PageInfo; | 6 | import com.github.pagehelper.PageInfo; |
| 7 | 7 | ||
| @@ -9,7 +9,7 @@ import java.util.List; | @@ -9,7 +9,7 @@ import java.util.List; | ||
| 9 | 9 | ||
| 10 | public interface IStreamPushService { | 10 | public interface IStreamPushService { |
| 11 | 11 | ||
| 12 | - List<StreamPushItem> handleJSON(String json, IMediaServerItem mediaServerItem); | 12 | + List<StreamPushItem> handleJSON(String json, MediaServerItem mediaServerItem); |
| 13 | 13 | ||
| 14 | /** | 14 | /** |
| 15 | * 将应用名和流ID加入国标关联 | 15 | * 将应用名和流ID加入国标关联 |
src/main/java/com/genersoft/iot/vmp/service/bean/SSRCInfo.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.service.bean; | ||
| 2 | + | ||
| 3 | +public class SSRCInfo { | ||
| 4 | + | ||
| 5 | + private int port; | ||
| 6 | + private String ssrc; | ||
| 7 | + private String StreamId; | ||
| 8 | + | ||
| 9 | + public SSRCInfo(int port, String ssrc, String streamId) { | ||
| 10 | + this.port = port; | ||
| 11 | + this.ssrc = ssrc; | ||
| 12 | + StreamId = streamId; | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + public int getPort() { | ||
| 16 | + return port; | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + public void setPort(int port) { | ||
| 20 | + this.port = port; | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + public String getSsrc() { | ||
| 24 | + return ssrc; | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + public void setSsrc(String ssrc) { | ||
| 28 | + this.ssrc = ssrc; | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + public String getStreamId() { | ||
| 32 | + return StreamId; | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + public void setStreamId(String streamId) { | ||
| 36 | + StreamId = streamId; | ||
| 37 | + } | ||
| 38 | +} |
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
| 1 | package com.genersoft.iot.vmp.service.impl; | 1 | package com.genersoft.iot.vmp.service.impl; |
| 2 | 2 | ||
| 3 | -import com.alibaba.fastjson.JSON; | ||
| 4 | import com.alibaba.fastjson.JSONArray; | 3 | import com.alibaba.fastjson.JSONArray; |
| 5 | import com.alibaba.fastjson.JSONObject; | 4 | import com.alibaba.fastjson.JSONObject; |
| 6 | -import com.genersoft.iot.vmp.common.StreamInfo; | 5 | +import com.genersoft.iot.vmp.common.VideoManagerConstants; |
| 7 | import com.genersoft.iot.vmp.conf.MediaConfig; | 6 | import com.genersoft.iot.vmp.conf.MediaConfig; |
| 8 | -import com.genersoft.iot.vmp.conf.ProxyServletConfig; | 7 | +import com.genersoft.iot.vmp.conf.SipConfig; |
| 9 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 8 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 9 | +import com.genersoft.iot.vmp.gb28181.session.SsrcConfig; | ||
| 10 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | 10 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 11 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; | 11 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| 12 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | 12 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 13 | import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; | 13 | import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; |
| 14 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 15 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 14 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 16 | -import com.genersoft.iot.vmp.media.zlm.dto.ZLMRunInfo; | ||
| 17 | import com.genersoft.iot.vmp.service.IMediaServerService; | 15 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 16 | +import com.genersoft.iot.vmp.service.bean.SSRCInfo; | ||
| 18 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 17 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 19 | import com.genersoft.iot.vmp.storager.dao.MediaServerMapper; | 18 | import com.genersoft.iot.vmp.storager.dao.MediaServerMapper; |
| 20 | -import org.mitre.dsmiley.httpproxy.ProxyServlet; | 19 | +import com.genersoft.iot.vmp.utils.redis.JedisUtil; |
| 20 | +import com.genersoft.iot.vmp.utils.redis.RedisUtil; | ||
| 21 | import org.slf4j.Logger; | 21 | import org.slf4j.Logger; |
| 22 | import org.slf4j.LoggerFactory; | 22 | import org.slf4j.LoggerFactory; |
| 23 | import org.springframework.beans.factory.annotation.Autowired; | 23 | import org.springframework.beans.factory.annotation.Autowired; |
| 24 | import org.springframework.beans.factory.annotation.Value; | 24 | import org.springframework.beans.factory.annotation.Value; |
| 25 | +import org.springframework.boot.CommandLineRunner; | ||
| 26 | +import org.springframework.core.annotation.Order; | ||
| 25 | import org.springframework.stereotype.Service; | 27 | import org.springframework.stereotype.Service; |
| 26 | 28 | ||
| 29 | +import java.sql.Array; | ||
| 27 | import java.text.SimpleDateFormat; | 30 | import java.text.SimpleDateFormat; |
| 28 | import java.util.*; | 31 | import java.util.*; |
| 29 | 32 | ||
| @@ -31,15 +34,13 @@ import java.util.*; | @@ -31,15 +34,13 @@ import java.util.*; | ||
| 31 | * 媒体服务器节点管理 | 34 | * 媒体服务器节点管理 |
| 32 | */ | 35 | */ |
| 33 | @Service | 36 | @Service |
| 34 | -public class MediaServerServiceImpl implements IMediaServerService { | 37 | +@Order(value=2) |
| 38 | +public class MediaServerServiceImpl implements IMediaServerService, CommandLineRunner { | ||
| 35 | 39 | ||
| 36 | private final static Logger logger = LoggerFactory.getLogger(MediaServerServiceImpl.class); | 40 | private final static Logger logger = LoggerFactory.getLogger(MediaServerServiceImpl.class); |
| 37 | 41 | ||
| 38 | - private Map<String, IMediaServerItem> zlmServers = new HashMap<>(); // 所有数据库的zlm的缓存 | ||
| 39 | - private Map<String, Integer> zlmServerStatus = new LinkedHashMap<>(); // 所有上线的zlm的缓存以及负载 | ||
| 40 | - | ||
| 41 | - @Value("${sip.ip}") | ||
| 42 | - private String sipIp; | 42 | + @Autowired |
| 43 | + private SipConfig sipConfig; | ||
| 43 | 44 | ||
| 44 | @Value("${server.ssl.enabled:false}") | 45 | @Value("${server.ssl.enabled:false}") |
| 45 | private boolean sslEnabled; | 46 | private boolean sslEnabled; |
| @@ -56,7 +57,6 @@ public class MediaServerServiceImpl implements IMediaServerService { | @@ -56,7 +57,6 @@ public class MediaServerServiceImpl implements IMediaServerService { | ||
| 56 | @Autowired | 57 | @Autowired |
| 57 | private MediaServerMapper mediaServerMapper; | 58 | private MediaServerMapper mediaServerMapper; |
| 58 | 59 | ||
| 59 | - | ||
| 60 | @Autowired | 60 | @Autowired |
| 61 | private IRedisCatchStorage redisCatchStorage; | 61 | private IRedisCatchStorage redisCatchStorage; |
| 62 | 62 | ||
| @@ -66,53 +66,134 @@ public class MediaServerServiceImpl implements IMediaServerService { | @@ -66,53 +66,134 @@ public class MediaServerServiceImpl implements IMediaServerService { | ||
| 66 | @Autowired | 66 | @Autowired |
| 67 | private ZLMRTPServerFactory zlmrtpServerFactory; | 67 | private ZLMRTPServerFactory zlmrtpServerFactory; |
| 68 | 68 | ||
| 69 | - private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | 69 | + @Autowired |
| 70 | + private RedisUtil redisUtil; | ||
| 71 | + | ||
| 72 | + @Autowired | ||
| 73 | + JedisUtil jedisUtil; | ||
| 74 | + | ||
| 75 | + private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||
| 70 | 76 | ||
| 71 | /** | 77 | /** |
| 72 | * 初始化 | 78 | * 初始化 |
| 73 | */ | 79 | */ |
| 74 | @Override | 80 | @Override |
| 75 | - public void init() { | ||
| 76 | - zlmServers.clear(); | ||
| 77 | - zlmServerStatus.clear(); | 81 | + public void run(String... args) throws Exception { |
| 82 | + logger.info("Media Server 缓存初始化"); | ||
| 78 | List<MediaServerItem> mediaServerItemList = mediaServerMapper.queryAll(); | 83 | List<MediaServerItem> mediaServerItemList = mediaServerMapper.queryAll(); |
| 79 | - for (IMediaServerItem mediaServerItem : mediaServerItemList) { | ||
| 80 | - zlmServers.put(mediaServerItem.getId(), mediaServerItem); | 84 | + for (MediaServerItem mediaServerItem : mediaServerItemList) { |
| 85 | + // 更新 | ||
| 86 | + if (mediaServerItem.getSsrcConfig() == null) { | ||
| 87 | + SsrcConfig ssrcConfig = new SsrcConfig(mediaServerItem.getId(), null, sipConfig.getSipDomain()); | ||
| 88 | + mediaServerItem.setSsrcConfig(ssrcConfig); | ||
| 89 | + redisUtil.set(VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerItem.getId(), mediaServerItem); | ||
| 90 | + } | ||
| 91 | + // 查询redis是否存在此mediaServer | ||
| 92 | + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerItem.getId(); | ||
| 93 | + if (!redisUtil.hasKey(key)) { | ||
| 94 | + redisUtil.set(key, mediaServerItem); | ||
| 95 | + } | ||
| 96 | + } | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + @Override | ||
| 100 | + public SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId) { | ||
| 101 | + if (mediaServerItem == null || mediaServerItem.getId() == null) return null; | ||
| 102 | + // 获取mediaServer可用的ssrc | ||
| 103 | + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerItem.getId(); | ||
| 104 | + | ||
| 105 | + SsrcConfig ssrcConfig = mediaServerItem.getSsrcConfig(); | ||
| 106 | + if (ssrcConfig == null) { | ||
| 107 | + logger.info("media server [ {} ] ssrcConfig is null", mediaServerItem.getId()); | ||
| 108 | + return null; | ||
| 109 | + }else { | ||
| 110 | + String ssrc = ssrcConfig.getPlaySsrc(); | ||
| 111 | + if (streamId == null) streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); | ||
| 112 | + int rtpServerPort = mediaServerItem.getRtpProxyPort(); | ||
| 113 | + if (mediaServerItem.isRtpEnable()) { | ||
| 114 | + rtpServerPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId); | ||
| 115 | + } | ||
| 116 | + redisUtil.set(key, mediaServerItem); | ||
| 117 | + return new SSRCInfo(rtpServerPort, ssrc, streamId); | ||
| 81 | } | 118 | } |
| 82 | } | 119 | } |
| 83 | 120 | ||
| 84 | @Override | 121 | @Override |
| 85 | public void closeRTPServer(Device device, String channelId) { | 122 | public void closeRTPServer(Device device, String channelId) { |
| 86 | - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId); | ||
| 87 | - IMediaServerItem mediaServerItem = null; | ||
| 88 | - if (streamInfo != null) { | ||
| 89 | - mediaServerItem = this.getOne (streamInfo.getMediaServerId()); | 123 | + String mediaServerId = streamSession.getMediaServerId(device.getDeviceId(), channelId); |
| 124 | + MediaServerItem mediaServerItem = this.getOne(mediaServerId); | ||
| 125 | + if (mediaServerItem != null) { | ||
| 126 | + String streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); | ||
| 127 | + zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId); | ||
| 128 | + releaseSsrc(mediaServerItem, streamSession.getSSRC(device.getDeviceId(), channelId)); | ||
| 90 | } | 129 | } |
| 91 | - String streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); | ||
| 92 | - zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId); | ||
| 93 | streamSession.remove(device.getDeviceId(), channelId); | 130 | streamSession.remove(device.getDeviceId(), channelId); |
| 94 | } | 131 | } |
| 95 | 132 | ||
| 96 | @Override | 133 | @Override |
| 97 | - public void update(MediaConfig mediaConfig) { | 134 | + public void releaseSsrc(MediaServerItem mediaServerItem, String ssrc) { |
| 135 | + if (mediaServerItem == null || ssrc == null) return; | ||
| 136 | + SsrcConfig ssrcConfig = mediaServerItem.getSsrcConfig(); | ||
| 137 | + ssrcConfig.releaseSsrc(ssrc); | ||
| 138 | + mediaServerItem.setSsrcConfig(ssrcConfig); | ||
| 139 | + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerItem.getId(); | ||
| 140 | + redisUtil.set(key, mediaServerItem); | ||
| 141 | + } | ||
| 98 | 142 | ||
| 143 | + /** | ||
| 144 | + * zlm 重启后重置他的推流信息, TODO 给正在使用的设备发送停止命令 | ||
| 145 | + * @param mediaServerItem | ||
| 146 | + */ | ||
| 147 | + @Override | ||
| 148 | + public void clearRTPServer(MediaServerItem mediaServerItem) { | ||
| 149 | + mediaServerItem.setSsrcConfig(new SsrcConfig(mediaServerItem.getId(), null, sipConfig.getSipDomain())); | ||
| 150 | + redisUtil.zAdd(VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX, mediaServerItem.getId(), 0); | ||
| 99 | } | 151 | } |
| 100 | 152 | ||
| 153 | + | ||
| 101 | @Override | 154 | @Override |
| 102 | - public List<IMediaServerItem> getAll() { | ||
| 103 | - if (zlmServers.size() == 0) { | ||
| 104 | - init(); | 155 | + public void update(MediaServerItem mediaSerItem) { |
| 156 | + mediaServerMapper.update(mediaSerItem); | ||
| 157 | + MediaServerItem mediaServerItemInRedis = getOne(mediaSerItem.getId()); | ||
| 158 | + MediaServerItem mediaServerItemInDataBase = mediaServerMapper.queryOne(mediaSerItem.getId()); | ||
| 159 | + if (mediaServerItemInRedis != null && mediaServerItemInRedis.getSsrcConfig() != null) { | ||
| 160 | + mediaServerItemInDataBase.setSsrcConfig(mediaServerItemInRedis.getSsrcConfig()); | ||
| 161 | + }else { | ||
| 162 | + mediaServerItemInDataBase.setSsrcConfig( | ||
| 163 | + new SsrcConfig( | ||
| 164 | + mediaServerItemInDataBase.getId(), | ||
| 165 | + null, | ||
| 166 | + sipConfig.getSipDomain() | ||
| 167 | + ) | ||
| 168 | + ); | ||
| 105 | } | 169 | } |
| 106 | - List<IMediaServerItem> result = new ArrayList<>(); | ||
| 107 | - for (String id : zlmServers.keySet()) { | ||
| 108 | - IMediaServerItem mediaServerItem = zlmServers.get(id); | ||
| 109 | - mediaServerItem.setCount(zlmServerStatus.get(id) == null ? 0 : zlmServerStatus.get(id)); | ||
| 110 | - result.add(mediaServerItem); | 170 | + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerItemInDataBase.getId(); |
| 171 | + redisUtil.set(key, mediaServerItemInDataBase); | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + @Override | ||
| 175 | + public List<MediaServerItem> getAll() { | ||
| 176 | + List<MediaServerItem> result = new ArrayList<>(); | ||
| 177 | + List<Object> mediaServerKeys = redisUtil.scan(String.format("%S*", VideoManagerConstants.MEDIA_SERVER_PREFIX)); | ||
| 178 | + for (int i = 0; i < mediaServerKeys.size(); i++) { | ||
| 179 | + String key = (String) mediaServerKeys.get(i); | ||
| 180 | + result.add((MediaServerItem)redisUtil.get(key)); | ||
| 111 | } | 181 | } |
| 112 | return result; | 182 | return result; |
| 183 | + } | ||
| 113 | 184 | ||
| 114 | - | ||
| 115 | -// return mediaServerMapper.queryAll(); | 185 | + @Override |
| 186 | + public List<MediaServerItem> getAllOnline() { | ||
| 187 | + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX; | ||
| 188 | + Set<String> mediaServerIdSet = redisUtil.zRevRange(key, 0, -1); | ||
| 189 | + List<MediaServerItem> result = new ArrayList<>(); | ||
| 190 | + if (mediaServerIdSet != null && mediaServerIdSet.size() > 0) { | ||
| 191 | + for (String mediaServerId : mediaServerIdSet) { | ||
| 192 | + String serverKey = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerId; | ||
| 193 | + result.add((MediaServerItem) redisUtil.get(serverKey)); | ||
| 194 | + } | ||
| 195 | + } | ||
| 196 | + return result; | ||
| 116 | } | 197 | } |
| 117 | 198 | ||
| 118 | /** | 199 | /** |
| @@ -121,26 +202,28 @@ public class MediaServerServiceImpl implements IMediaServerService { | @@ -121,26 +202,28 @@ public class MediaServerServiceImpl implements IMediaServerService { | ||
| 121 | * @return MediaServerItem | 202 | * @return MediaServerItem |
| 122 | */ | 203 | */ |
| 123 | @Override | 204 | @Override |
| 124 | - public IMediaServerItem getOne(String mediaServerId) { | ||
| 125 | - if (mediaServerId ==null) return null; | ||
| 126 | - IMediaServerItem mediaServerItem = zlmServers.get(mediaServerId); | ||
| 127 | - if (mediaServerItem != null) { | ||
| 128 | - mediaServerItem.setCount(zlmServerStatus.get(mediaServerId) == null ? 0 : zlmServerStatus.get(mediaServerId)); | ||
| 129 | - return mediaServerItem; | ||
| 130 | - }else { | ||
| 131 | - IMediaServerItem item = mediaServerMapper.queryOne(mediaServerId); | ||
| 132 | - if (item != null) { | ||
| 133 | - zlmServers.put(item.getId(), item); | ||
| 134 | - } | ||
| 135 | - return item; | ||
| 136 | - } | 205 | + public MediaServerItem getOne(String mediaServerId) { |
| 206 | + if (mediaServerId == null) return null; | ||
| 207 | + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerId; | ||
| 208 | + return (MediaServerItem)redisUtil.get(key); | ||
| 137 | } | 209 | } |
| 138 | 210 | ||
| 139 | @Override | 211 | @Override |
| 140 | - public IMediaServerItem getOneByHostAndPort(String host, int port) { | 212 | + public MediaServerItem getOneByHostAndPort(String host, int port) { |
| 141 | return mediaServerMapper.queryOneByHostAndPort(host, port); | 213 | return mediaServerMapper.queryOneByHostAndPort(host, port); |
| 142 | } | 214 | } |
| 143 | 215 | ||
| 216 | + @Override | ||
| 217 | + public void clearMediaServerForOnline() { | ||
| 218 | + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX; | ||
| 219 | + redisUtil.del(key); | ||
| 220 | + } | ||
| 221 | + | ||
| 222 | + @Override | ||
| 223 | + public void add(MediaServerItem mediaSerItem) { | ||
| 224 | + mediaServerMapper.add(mediaSerItem); | ||
| 225 | + } | ||
| 226 | + | ||
| 144 | /** | 227 | /** |
| 145 | * 处理zlm上线 | 228 | * 处理zlm上线 |
| 146 | * @param zlmServerConfig zlm上线携带的参数 | 229 | * @param zlmServerConfig zlm上线携带的参数 |
| @@ -150,111 +233,100 @@ public class MediaServerServiceImpl implements IMediaServerService { | @@ -150,111 +233,100 @@ public class MediaServerServiceImpl implements IMediaServerService { | ||
| 150 | logger.info("[ {} ]-[ {}:{} ]已连接", | 233 | logger.info("[ {} ]-[ {}:{} ]已连接", |
| 151 | zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); | 234 | zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); |
| 152 | 235 | ||
| 153 | - IMediaServerItem serverItem = getOne(zlmServerConfig.getGeneralMediaServerId()); | ||
| 154 | - String now = this.format.format(new Date(System.currentTimeMillis())); | ||
| 155 | - if (serverItem != null) { | ||
| 156 | - serverItem.setSecret(zlmServerConfig.getApiSecret()); | ||
| 157 | - serverItem.setIp(zlmServerConfig.getIp()); | 236 | + MediaServerItem serverItem = mediaServerMapper.queryOne(zlmServerConfig.getGeneralMediaServerId()); |
| 237 | + if (serverItem == null) { | ||
| 238 | + serverItem = mediaServerMapper.queryOneByHostAndPort(zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); | ||
| 239 | + } | ||
| 240 | + if (zlmServerConfig.getGeneralMediaServerId().equals(mediaConfig.getId()) | ||
| 241 | + || (zlmServerConfig.getIp().equals(mediaConfig.getIp()) && zlmServerConfig.getHttpPort() == mediaConfig.getHttpPort())) { | ||
| 242 | + // 配置文件的zlm | ||
| 158 | // 如果是配置文件中的zlm。 也就是默认zlm。 一切以配置文件内容为准 | 243 | // 如果是配置文件中的zlm。 也就是默认zlm。 一切以配置文件内容为准 |
| 159 | - // docker部署不会使用zlm配置的端口号; | ||
| 160 | - // 直接编译部署的使用配置文件的端口号,如果zlm修改配改了配置,wvp自动修改 | ||
| 161 | - | ||
| 162 | - if (serverItem.getId().equals(mediaConfig.getId()) | ||
| 163 | - || (serverItem.getIp().equals(mediaConfig.getIp()) && serverItem.getHttpPort() == mediaConfig.getHttpPort())) { | ||
| 164 | - // 配置文件的zlm | ||
| 165 | - mediaConfig.setId(zlmServerConfig.getGeneralMediaServerId()); | ||
| 166 | - mediaConfig.setUpdateTime(now); | ||
| 167 | - if (mediaConfig.getHttpPort() == 0) mediaConfig.setHttpPort(zlmServerConfig.getHttpPort()); | ||
| 168 | - if (mediaConfig.getHttpSSlPort() == 0) mediaConfig.setHttpSSlPort(zlmServerConfig.getHttpSSLport()); | ||
| 169 | - if (mediaConfig.getRtmpPort() == 0) mediaConfig.setRtmpPort(zlmServerConfig.getRtmpPort()); | ||
| 170 | - if (mediaConfig.getRtmpSSlPort() == 0) mediaConfig.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); | ||
| 171 | - if (mediaConfig.getRtspPort() == 0) mediaConfig.setRtspPort(zlmServerConfig.getRtspPort()); | ||
| 172 | - if (mediaConfig.getRtspSSLPort() == 0) mediaConfig.setRtspSSLPort(zlmServerConfig.getRtspSSlport()); | ||
| 173 | - if (mediaConfig.getRtpProxyPort() == 0) mediaConfig.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); | ||
| 174 | - mediaServerMapper.update(mediaConfig); | ||
| 175 | - serverItem = mediaConfig.getMediaSerItem(); | ||
| 176 | - setZLMConfig(mediaConfig); | ||
| 177 | - }else { | ||
| 178 | - if (!serverItem.isDocker()) { | ||
| 179 | - serverItem.setHttpPort(zlmServerConfig.getHttpPort()); | ||
| 180 | - serverItem.setHttpSSlPort(zlmServerConfig.getHttpSSLport()); | ||
| 181 | - serverItem.setRtmpPort(zlmServerConfig.getRtmpPort()); | ||
| 182 | - serverItem.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); | ||
| 183 | - serverItem.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); | ||
| 184 | - serverItem.setRtspPort(zlmServerConfig.getRtspPort()); | ||
| 185 | - | 244 | + // docker部署不会使用zlm配置的端口号不是默认的则不做更新, 配置修改需要自行修改server配置; |
| 245 | + MediaServerItem serverItemFromConfig = mediaConfig.getMediaSerItem(); | ||
| 246 | + serverItemFromConfig.setId(zlmServerConfig.getGeneralMediaServerId()); | ||
| 247 | + if (mediaConfig.getHttpPort() == 0) serverItemFromConfig.setHttpPort(zlmServerConfig.getHttpPort()); | ||
| 248 | + if (mediaConfig.getHttpSSlPort() == 0) serverItemFromConfig.setHttpSSlPort(zlmServerConfig.getHttpSSLport()); | ||
| 249 | + if (mediaConfig.getRtmpPort() == 0) serverItemFromConfig.setRtmpPort(zlmServerConfig.getRtmpPort()); | ||
| 250 | + if (mediaConfig.getRtmpSSlPort() == 0) serverItemFromConfig.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); | ||
| 251 | + if (mediaConfig.getRtspPort() == 0) serverItemFromConfig.setRtspPort(zlmServerConfig.getRtspPort()); | ||
| 252 | + if (mediaConfig.getRtspSSLPort() == 0) serverItemFromConfig.setRtspSSLPort(zlmServerConfig.getRtspSSlport()); | ||
| 253 | + if (mediaConfig.getRtpProxyPort() == 0) serverItemFromConfig.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); | ||
| 254 | + if (serverItem != null){ | ||
| 255 | + // 可能是同一个zlm但id发生了变化 | ||
| 256 | + if (!serverItem.getId().equals(zlmServerConfig.getGeneralMediaServerId())) { | ||
| 257 | + mediaServerMapper.delOne(serverItem.getId()); | ||
| 258 | + redisUtil.del(VideoManagerConstants.MEDIA_SERVER_PREFIX + serverItem.getId()); | ||
| 259 | + | ||
| 260 | + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + serverItemFromConfig.getId(); | ||
| 261 | + serverItemFromConfig.setSsrcConfig(new SsrcConfig(serverItemFromConfig.getId(), null, sipConfig.getSipDomain())); | ||
| 262 | + redisUtil.set(key, serverItemFromConfig); | ||
| 263 | + mediaServerMapper.add(serverItemFromConfig); | ||
| 264 | + }else { | ||
| 265 | + mediaServerMapper.update(serverItemFromConfig); | ||
| 186 | } | 266 | } |
| 187 | - serverItem.setUpdateTime(now); | ||
| 188 | - mediaServerMapper.update(serverItem); | ||
| 189 | - setZLMConfig(serverItem); | 267 | + }else { |
| 268 | + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + serverItemFromConfig.getId(); | ||
| 269 | + serverItemFromConfig.setSsrcConfig(new SsrcConfig(serverItemFromConfig.getId(), null, sipConfig.getSipDomain())); | ||
| 270 | + redisUtil.set(key, serverItemFromConfig); | ||
| 271 | + mediaServerMapper.add(serverItemFromConfig); | ||
| 190 | } | 272 | } |
| 273 | + resetOnlineServerItem(serverItemFromConfig); | ||
| 274 | + setZLMConfig(serverItemFromConfig); | ||
| 191 | }else { | 275 | }else { |
| 192 | - if (zlmServerConfig.getGeneralMediaServerId().equals(mediaConfig.getId()) | ||
| 193 | - || (zlmServerConfig.getIp().equals(mediaConfig.getIp()) && zlmServerConfig.getHttpPort() == mediaConfig.getHttpPort())) { | ||
| 194 | - mediaConfig.setId(zlmServerConfig.getGeneralMediaServerId()); | ||
| 195 | - mediaConfig.setCreateTime(now); | ||
| 196 | - mediaConfig.setUpdateTime(now); | ||
| 197 | - serverItem = mediaConfig.getMediaSerItem(); | ||
| 198 | - mediaServerMapper.add(mediaConfig); | ||
| 199 | - }else { | ||
| 200 | - // 一个新的zlm接入wvp | ||
| 201 | - serverItem = new MediaServerItem(zlmServerConfig, sipIp); | ||
| 202 | - serverItem.setCreateTime(now); | ||
| 203 | - serverItem.setUpdateTime(now); | 276 | + String now = this.format.format(new Date(System.currentTimeMillis())); |
| 277 | + if (serverItem == null){ | ||
| 278 | + // 一个新的zlm接入wvp | ||
| 279 | + serverItem = new MediaServerItem(zlmServerConfig, sipConfig.getSipIp()); | ||
| 280 | + serverItem.setCreateTime(now); | ||
| 281 | + serverItem.setUpdateTime(now); | ||
| 282 | + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + serverItem.getId(); | ||
| 283 | + serverItem.setSsrcConfig(new SsrcConfig(serverItem.getId(), null, sipConfig.getSipDomain())); | ||
| 284 | + redisUtil.set(key, serverItem); | ||
| 285 | + // 存入数据库 | ||
| 204 | mediaServerMapper.add(serverItem); | 286 | mediaServerMapper.add(serverItem); |
| 287 | + setZLMConfig(serverItem); | ||
| 205 | } | 288 | } |
| 289 | + resetOnlineServerItem(serverItem); | ||
| 206 | } | 290 | } |
| 207 | - // 更新缓存 | ||
| 208 | - if (zlmServerStatus.get(serverItem.getId()) == null) { | ||
| 209 | - zlmServers.put(serverItem.getId(), serverItem); | ||
| 210 | - zlmServerStatus.put(serverItem.getId(),0); | ||
| 211 | - } | ||
| 212 | - // 查询服务流数量 | ||
| 213 | - IMediaServerItem finalServerItem = serverItem; | ||
| 214 | - zlmresTfulUtils.getMediaList(serverItem, null, null, "rtmp",(mediaList ->{ | ||
| 215 | - Integer code = mediaList.getInteger("code"); | ||
| 216 | - if (code == 0) { | ||
| 217 | - JSONArray data = mediaList.getJSONArray("data"); | ||
| 218 | - if (data != null) { | ||
| 219 | - zlmServerStatus.put(finalServerItem.getId(),data.size()); | ||
| 220 | - }else { | ||
| 221 | - zlmServerStatus.put(finalServerItem.getId(),0); | ||
| 222 | - } | ||
| 223 | - | ||
| 224 | - } | ||
| 225 | - })); | ||
| 226 | - | ||
| 227 | } | 291 | } |
| 228 | 292 | ||
| 229 | - /** | ||
| 230 | - * 更新缓存 | ||
| 231 | - * @param mediaServerItem zlm服务 | ||
| 232 | - * @param count 在线数 | ||
| 233 | - * @param online 在线状态 | ||
| 234 | - */ | ||
| 235 | @Override | 293 | @Override |
| 236 | - public void updateServerCatch(IMediaServerItem mediaServerItem, Integer count, Boolean online) { | ||
| 237 | - if (mediaServerItem != null) { | ||
| 238 | - zlmServers.put(mediaServerItem.getId(), mediaServerItem); | ||
| 239 | - Collection<Integer> values = zlmServerStatus.values(); | ||
| 240 | - if (online != null && count != null) { | ||
| 241 | - zlmServerStatus.put(mediaServerItem.getId(), count); | ||
| 242 | - } | 294 | + public void resetOnlineServerItem(MediaServerItem serverItem) { |
| 295 | + // 更新缓存 | ||
| 296 | + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX; | ||
| 297 | + // 使用zset的分数作为当前并发量, 默认值设置为0 | ||
| 298 | + if (redisUtil.zScore(key, serverItem.getId()) == null) { // 不存在则设置默认值 已存在则重置 | ||
| 299 | + redisUtil.zAdd(key, serverItem.getId(), 0L); | ||
| 300 | + // 查询服务流数量 | ||
| 301 | + zlmresTfulUtils.getMediaList(serverItem, null, null, "rtmp",(mediaList ->{ | ||
| 302 | + Integer code = mediaList.getInteger("code"); | ||
| 303 | + if (code == 0) { | ||
| 304 | + JSONArray data = mediaList.getJSONArray("data"); | ||
| 305 | + if (data != null) { | ||
| 306 | + redisUtil.zAdd(key, serverItem.getId(), data.size()); | ||
| 307 | + } | ||
| 308 | + } | ||
| 309 | + })); | ||
| 310 | + }else { | ||
| 311 | + clearRTPServer(serverItem); | ||
| 243 | } | 312 | } |
| 313 | + | ||
| 244 | } | 314 | } |
| 245 | 315 | ||
| 316 | + | ||
| 246 | @Override | 317 | @Override |
| 247 | public void addCount(String mediaServerId) { | 318 | public void addCount(String mediaServerId) { |
| 248 | - if (zlmServerStatus.get(mediaServerId) != null) { | ||
| 249 | - zlmServerStatus.put(mediaServerId, zlmServerStatus.get(mediaServerId) + 1); | ||
| 250 | - } | 319 | + if (mediaServerId == null) return; |
| 320 | + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX; | ||
| 321 | + Double aDouble = redisUtil.zScore(key, mediaServerId); | ||
| 322 | + redisUtil.zIncrScore(key, mediaServerId, 1); | ||
| 323 | + | ||
| 251 | } | 324 | } |
| 252 | 325 | ||
| 253 | @Override | 326 | @Override |
| 254 | public void removeCount(String mediaServerId) { | 327 | public void removeCount(String mediaServerId) { |
| 255 | - if (zlmServerStatus.get(mediaServerId) != null) { | ||
| 256 | - zlmServerStatus.put(mediaServerId, zlmServerStatus.get(mediaServerId) - 1); | ||
| 257 | - } | 328 | + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX; |
| 329 | + redisUtil.zIncrScore(key, mediaServerId, - 1); | ||
| 258 | } | 330 | } |
| 259 | 331 | ||
| 260 | /** | 332 | /** |
| @@ -262,35 +334,18 @@ public class MediaServerServiceImpl implements IMediaServerService { | @@ -262,35 +334,18 @@ public class MediaServerServiceImpl implements IMediaServerService { | ||
| 262 | * @return MediaServerItem | 334 | * @return MediaServerItem |
| 263 | */ | 335 | */ |
| 264 | @Override | 336 | @Override |
| 265 | - public IMediaServerItem getMediaServerForMinimumLoad() { | ||
| 266 | - int mediaCount = -1; | ||
| 267 | - String key = null; | ||
| 268 | - System.out.println(JSON.toJSONString(zlmServerStatus)); | ||
| 269 | - if (zlmServerStatus.size() == 1) { | ||
| 270 | - Map.Entry entry = zlmServerStatus.entrySet().iterator().next(); | ||
| 271 | - key= (String) entry.getKey(); | ||
| 272 | - }else { | ||
| 273 | - for (String id : zlmServerStatus.keySet()) { | ||
| 274 | - if (key == null) { | ||
| 275 | - key = id; | ||
| 276 | - mediaCount = zlmServerStatus.get(id); | ||
| 277 | - } | ||
| 278 | - if (zlmServerStatus.get(id) == 0) { | ||
| 279 | - key = id; | ||
| 280 | - break; | ||
| 281 | - }else if (mediaCount >= zlmServerStatus.get(id)){ | ||
| 282 | - mediaCount = zlmServerStatus.get(id); | ||
| 283 | - key = id; | ||
| 284 | - } | ||
| 285 | - } | ||
| 286 | - } | 337 | + public MediaServerItem getMediaServerForMinimumLoad() { |
| 338 | + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX; | ||
| 287 | 339 | ||
| 288 | - if (key == null) { | 340 | + if (redisUtil.zSize(key) == null || redisUtil.zSize(key) == 0) { |
| 289 | logger.info("获取负载最低的节点时无在线节点"); | 341 | logger.info("获取负载最低的节点时无在线节点"); |
| 290 | - return null; | ||
| 291 | - }else{ | ||
| 292 | - return zlmServers.get(key); | ||
| 293 | } | 342 | } |
| 343 | + | ||
| 344 | + // 获取分数最低的,及并发最低的 | ||
| 345 | + Set<Object> objects = redisUtil.ZRange(key, 0, -1); | ||
| 346 | + ArrayList<Object> MediaServerObjectS = new ArrayList<>(objects); | ||
| 347 | + String mediaServerId = (String)MediaServerObjectS.get(0); | ||
| 348 | + return getOne(mediaServerId); | ||
| 294 | } | 349 | } |
| 295 | 350 | ||
| 296 | /** | 351 | /** |
| @@ -298,7 +353,7 @@ public class MediaServerServiceImpl implements IMediaServerService { | @@ -298,7 +353,7 @@ public class MediaServerServiceImpl implements IMediaServerService { | ||
| 298 | * @param mediaServerItem 服务ID | 353 | * @param mediaServerItem 服务ID |
| 299 | */ | 354 | */ |
| 300 | @Override | 355 | @Override |
| 301 | - public void setZLMConfig(IMediaServerItem mediaServerItem) { | 356 | + public void setZLMConfig(MediaServerItem mediaServerItem) { |
| 302 | logger.info("[ {} ]-[ {}:{} ]设置zlm", | 357 | logger.info("[ {} ]-[ {}:{} ]设置zlm", |
| 303 | mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); | 358 | mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); |
| 304 | String protocol = sslEnabled ? "https" : "http"; | 359 | String protocol = sslEnabled ? "https" : "http"; |
| @@ -333,8 +388,10 @@ public class MediaServerServiceImpl implements IMediaServerService { | @@ -333,8 +388,10 @@ public class MediaServerServiceImpl implements IMediaServerService { | ||
| 333 | logger.info("[ {} ]-[ {}:{} ]设置zlm成功", | 388 | logger.info("[ {} ]-[ {}:{} ]设置zlm成功", |
| 334 | mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); | 389 | mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); |
| 335 | }else { | 390 | }else { |
| 336 | - logger.info("[ {} ]-[ {}:{} ]设置zlm失败" + responseJSON.getString("msg"), | 391 | + logger.info("[ {} ]-[ {}:{} ]设置zlm失败", |
| 337 | mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); | 392 | mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); |
| 338 | } | 393 | } |
| 339 | } | 394 | } |
| 395 | + | ||
| 396 | + | ||
| 340 | } | 397 | } |
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
| @@ -4,9 +4,7 @@ import com.alibaba.fastjson.JSON; | @@ -4,9 +4,7 @@ import com.alibaba.fastjson.JSON; | ||
| 4 | import com.alibaba.fastjson.JSONArray; | 4 | import com.alibaba.fastjson.JSONArray; |
| 5 | import com.alibaba.fastjson.JSONObject; | 5 | import com.alibaba.fastjson.JSONObject; |
| 6 | import com.genersoft.iot.vmp.common.StreamInfo; | 6 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 7 | -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; | ||
| 8 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; | 7 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| 9 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 10 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 8 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 11 | import com.genersoft.iot.vmp.service.IMediaServerService; | 9 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 12 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 10 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| @@ -33,14 +31,14 @@ public class MediaServiceImpl implements IMediaService { | @@ -33,14 +31,14 @@ public class MediaServiceImpl implements IMediaService { | ||
| 33 | 31 | ||
| 34 | 32 | ||
| 35 | @Override | 33 | @Override |
| 36 | - public StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaInfo, String app, String stream, JSONArray tracks) { | 34 | + public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, JSONArray tracks) { |
| 37 | return getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, null); | 35 | return getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, null); |
| 38 | } | 36 | } |
| 39 | 37 | ||
| 40 | @Override | 38 | @Override |
| 41 | public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, String addr) { | 39 | public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, String addr) { |
| 42 | StreamInfo streamInfo = null; | 40 | StreamInfo streamInfo = null; |
| 43 | - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); | 41 | + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); |
| 44 | if (mediaInfo == null) { | 42 | if (mediaInfo == null) { |
| 45 | return streamInfo; | 43 | return streamInfo; |
| 46 | } | 44 | } |
| @@ -63,7 +61,7 @@ public class MediaServiceImpl implements IMediaService { | @@ -63,7 +61,7 @@ public class MediaServiceImpl implements IMediaService { | ||
| 63 | } | 61 | } |
| 64 | 62 | ||
| 65 | @Override | 63 | @Override |
| 66 | - public StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaInfo, String app, String stream, JSONArray tracks, String addr) { | 64 | + public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, JSONArray tracks, String addr) { |
| 67 | StreamInfo streamInfoResult = new StreamInfo(); | 65 | StreamInfo streamInfoResult = new StreamInfo(); |
| 68 | streamInfoResult.setStreamId(stream); | 66 | streamInfoResult.setStreamId(stream); |
| 69 | streamInfoResult.setApp(app); | 67 | streamInfoResult.setApp(app); |
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
| @@ -14,11 +14,12 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | @@ -14,11 +14,12 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | ||
| 14 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | 14 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
| 15 | import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; | 15 | import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; |
| 16 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; | 16 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| 17 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 18 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 17 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 19 | import com.genersoft.iot.vmp.service.IMediaServerService; | 18 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 19 | +import com.genersoft.iot.vmp.service.bean.SSRCInfo; | ||
| 20 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 20 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 21 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | 21 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 22 | +import com.genersoft.iot.vmp.utils.redis.RedisUtil; | ||
| 22 | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; | 23 | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; |
| 23 | import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; | 24 | import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; |
| 24 | import com.genersoft.iot.vmp.service.IMediaService; | 25 | import com.genersoft.iot.vmp.service.IMediaService; |
| @@ -54,6 +55,9 @@ public class PlayServiceImpl implements IPlayService { | @@ -54,6 +55,9 @@ public class PlayServiceImpl implements IPlayService { | ||
| 54 | private IRedisCatchStorage redisCatchStorage; | 55 | private IRedisCatchStorage redisCatchStorage; |
| 55 | 56 | ||
| 56 | @Autowired | 57 | @Autowired |
| 58 | + private RedisUtil redis; | ||
| 59 | + | ||
| 60 | + @Autowired | ||
| 57 | private DeferredResultHolder resultHolder; | 61 | private DeferredResultHolder resultHolder; |
| 58 | 62 | ||
| 59 | @Autowired | 63 | @Autowired |
| @@ -73,7 +77,7 @@ public class PlayServiceImpl implements IPlayService { | @@ -73,7 +77,7 @@ public class PlayServiceImpl implements IPlayService { | ||
| 73 | 77 | ||
| 74 | 78 | ||
| 75 | @Override | 79 | @Override |
| 76 | - public PlayResult play(IMediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent) { | 80 | + public PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent) { |
| 77 | PlayResult playResult = new PlayResult(); | 81 | PlayResult playResult = new PlayResult(); |
| 78 | if (mediaServerItem == null) { | 82 | if (mediaServerItem == null) { |
| 79 | RequestMessage msg = new RequestMessage(); | 83 | RequestMessage msg = new RequestMessage(); |
| @@ -97,14 +101,21 @@ public class PlayServiceImpl implements IPlayService { | @@ -97,14 +101,21 @@ public class PlayServiceImpl implements IPlayService { | ||
| 97 | // 超时处理 | 101 | // 超时处理 |
| 98 | result.onTimeout(()->{ | 102 | result.onTimeout(()->{ |
| 99 | logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId)); | 103 | logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId)); |
| 100 | - // 释放rtpserver | ||
| 101 | - mediaServerService.closeRTPServer(playResult.getDevice(), channelId); | ||
| 102 | RequestMessage msg = new RequestMessage(); | 104 | RequestMessage msg = new RequestMessage(); |
| 103 | msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + playResult.getUuid()); | 105 | msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + playResult.getUuid()); |
| 104 | WVPResult wvpResult = new WVPResult(); | 106 | WVPResult wvpResult = new WVPResult(); |
| 105 | wvpResult.setCode(-1); | 107 | wvpResult.setCode(-1); |
| 106 | - wvpResult.setMsg("Timeout"); | 108 | + SIPDialog dialog = streamSession.getDialog(deviceId, channelId); |
| 109 | + if (dialog != null) { | ||
| 110 | + wvpResult.setMsg("收流超时,请稍候重试"); | ||
| 111 | + }else { | ||
| 112 | + wvpResult.setMsg("点播超时,请稍候重试"); | ||
| 113 | + } | ||
| 107 | msg.setData(wvpResult); | 114 | msg.setData(wvpResult); |
| 115 | + // 点播超时回复BYE | ||
| 116 | + cmder.streamByeCmd(device.getDeviceId(), channelId); | ||
| 117 | + // 释放rtpserver | ||
| 118 | + mediaServerService.closeRTPServer(playResult.getDevice(), channelId); | ||
| 108 | resultHolder.invokeResult(msg); | 119 | resultHolder.invokeResult(msg); |
| 109 | }); | 120 | }); |
| 110 | result.onCompletion(()->{ | 121 | result.onCompletion(()->{ |
| @@ -131,7 +142,7 @@ public class PlayServiceImpl implements IPlayService { | @@ -131,7 +142,7 @@ public class PlayServiceImpl implements IPlayService { | ||
| 131 | WVPResult wvpResult = (WVPResult)responseEntity.getBody(); | 142 | WVPResult wvpResult = (WVPResult)responseEntity.getBody(); |
| 132 | if (wvpResult.getCode() == 0) { | 143 | if (wvpResult.getCode() == 0) { |
| 133 | StreamInfo streamInfoForSuccess = (StreamInfo)wvpResult.getData(); | 144 | StreamInfo streamInfoForSuccess = (StreamInfo)wvpResult.getData(); |
| 134 | - IMediaServerItem mediaInfo = mediaServerService.getOne(streamInfoForSuccess.getMediaServerId()); | 145 | + MediaServerItem mediaInfo = mediaServerService.getOne(streamInfoForSuccess.getMediaServerId()); |
| 135 | String streamUrl = streamInfoForSuccess.getFmp4(); | 146 | String streamUrl = streamInfoForSuccess.getFmp4(); |
| 136 | // 请求截图 | 147 | // 请求截图 |
| 137 | zlmresTfulUtils.getSnap(mediaInfo, streamUrl, 15, 1, path, fileName); | 148 | zlmresTfulUtils.getSnap(mediaInfo, streamUrl, 15, 1, path, fileName); |
| @@ -142,14 +153,23 @@ public class PlayServiceImpl implements IPlayService { | @@ -142,14 +153,23 @@ public class PlayServiceImpl implements IPlayService { | ||
| 142 | } | 153 | } |
| 143 | }); | 154 | }); |
| 144 | if (streamInfo == null) { | 155 | if (streamInfo == null) { |
| 156 | + SSRCInfo ssrcInfo; | ||
| 157 | + String streamId = null; | ||
| 158 | + if (mediaServerItem.isRtpEnable()) { | ||
| 159 | + streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); | ||
| 160 | + } | ||
| 161 | + | ||
| 162 | + ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId); | ||
| 163 | + | ||
| 145 | // 发送点播消息 | 164 | // 发送点播消息 |
| 146 | - cmder.playStreamCmd(mediaServerItem, device, channelId, (IMediaServerItem mediaServerItemInUse, JSONObject response) -> { | 165 | + cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInUse, JSONObject response) -> { |
| 147 | logger.info("收到订阅消息: " + response.toJSONString()); | 166 | logger.info("收到订阅消息: " + response.toJSONString()); |
| 148 | onPublishHandlerForPlay(mediaServerItemInUse, response, deviceId, channelId, uuid.toString()); | 167 | onPublishHandlerForPlay(mediaServerItemInUse, response, deviceId, channelId, uuid.toString()); |
| 149 | if (hookEvent != null) { | 168 | if (hookEvent != null) { |
| 150 | hookEvent.response(mediaServerItem, response); | 169 | hookEvent.response(mediaServerItem, response); |
| 151 | } | 170 | } |
| 152 | }, (event) -> { | 171 | }, (event) -> { |
| 172 | + // 点播返回sip错误 | ||
| 153 | RequestMessage msg = new RequestMessage(); | 173 | RequestMessage msg = new RequestMessage(); |
| 154 | msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); | 174 | msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); |
| 155 | Response response = event.getResponse(); | 175 | Response response = event.getResponse(); |
| @@ -162,6 +182,7 @@ public class PlayServiceImpl implements IPlayService { | @@ -162,6 +182,7 @@ public class PlayServiceImpl implements IPlayService { | ||
| 162 | if (errorEvent != null) { | 182 | if (errorEvent != null) { |
| 163 | errorEvent.response(event); | 183 | errorEvent.response(event); |
| 164 | } | 184 | } |
| 185 | + | ||
| 165 | }); | 186 | }); |
| 166 | } else { | 187 | } else { |
| 167 | String streamId = streamInfo.getStreamId(); | 188 | String streamId = streamInfo.getStreamId(); |
| @@ -176,7 +197,7 @@ public class PlayServiceImpl implements IPlayService { | @@ -176,7 +197,7 @@ public class PlayServiceImpl implements IPlayService { | ||
| 176 | return playResult; | 197 | return playResult; |
| 177 | } | 198 | } |
| 178 | String mediaServerId = streamInfo.getMediaServerId(); | 199 | String mediaServerId = streamInfo.getMediaServerId(); |
| 179 | - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); | 200 | + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); |
| 180 | 201 | ||
| 181 | JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId); | 202 | JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId); |
| 182 | if (rtpInfo != null && rtpInfo.getBoolean("exist")) { | 203 | if (rtpInfo != null && rtpInfo.getBoolean("exist")) { |
| @@ -194,9 +215,17 @@ public class PlayServiceImpl implements IPlayService { | @@ -194,9 +215,17 @@ public class PlayServiceImpl implements IPlayService { | ||
| 194 | hookEvent.response(mediaServerItem, JSONObject.parseObject(JSON.toJSONString(streamInfo))); | 215 | hookEvent.response(mediaServerItem, JSONObject.parseObject(JSON.toJSONString(streamInfo))); |
| 195 | } | 216 | } |
| 196 | } else { | 217 | } else { |
| 218 | + // TODO 点播前是否重置状态 | ||
| 197 | redisCatchStorage.stopPlay(streamInfo); | 219 | redisCatchStorage.stopPlay(streamInfo); |
| 198 | storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); | 220 | storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); |
| 199 | - cmder.playStreamCmd(mediaServerItem, device, channelId, (IMediaServerItem mediaServerItemInuse, JSONObject response) -> { | 221 | + SSRCInfo ssrcInfo; |
| 222 | + String streamId2 = null; | ||
| 223 | + if (mediaServerItem.isRtpEnable()) { | ||
| 224 | + streamId2 = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); | ||
| 225 | + } | ||
| 226 | + ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId2); | ||
| 227 | + | ||
| 228 | + cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> { | ||
| 200 | logger.info("收到订阅消息: " + response.toJSONString()); | 229 | logger.info("收到订阅消息: " + response.toJSONString()); |
| 201 | onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString()); | 230 | onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString()); |
| 202 | }, (event) -> { | 231 | }, (event) -> { |
| @@ -218,7 +247,7 @@ public class PlayServiceImpl implements IPlayService { | @@ -218,7 +247,7 @@ public class PlayServiceImpl implements IPlayService { | ||
| 218 | } | 247 | } |
| 219 | 248 | ||
| 220 | @Override | 249 | @Override |
| 221 | - public void onPublishHandlerForPlay(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { | 250 | + public void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { |
| 222 | RequestMessage msg = new RequestMessage(); | 251 | RequestMessage msg = new RequestMessage(); |
| 223 | msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); | 252 | msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); |
| 224 | StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid); | 253 | StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid); |
| @@ -228,14 +257,6 @@ public class PlayServiceImpl implements IPlayService { | @@ -228,14 +257,6 @@ public class PlayServiceImpl implements IPlayService { | ||
| 228 | deviceChannel.setStreamId(streamInfo.getStreamId()); | 257 | deviceChannel.setStreamId(streamInfo.getStreamId()); |
| 229 | storager.startPlay(deviceId, channelId, streamInfo.getStreamId()); | 258 | storager.startPlay(deviceId, channelId, streamInfo.getStreamId()); |
| 230 | } | 259 | } |
| 231 | - ClientTransaction transaction = streamSession.getTransaction(deviceId, channelId); | ||
| 232 | - SIPDialog dialog = (SIPDialog)transaction.getDialog(); | ||
| 233 | - StreamInfo.TransactionInfo transactionInfo = new StreamInfo.TransactionInfo(); | ||
| 234 | - transactionInfo.callId = dialog.getCallId().getCallId(); | ||
| 235 | - transactionInfo.localTag = dialog.getLocalTag(); | ||
| 236 | - transactionInfo.remoteTag = dialog.getRemoteTag(); | ||
| 237 | - transactionInfo.branch = dialog.getFirstTransactionInt().getBranchId(); | ||
| 238 | - streamInfo.setTransactionInfo(transactionInfo); | ||
| 239 | redisCatchStorage.startPlay(streamInfo); | 260 | redisCatchStorage.startPlay(streamInfo); |
| 240 | msg.setData(JSON.toJSONString(streamInfo)); | 261 | msg.setData(JSON.toJSONString(streamInfo)); |
| 241 | 262 | ||
| @@ -254,10 +275,10 @@ public class PlayServiceImpl implements IPlayService { | @@ -254,10 +275,10 @@ public class PlayServiceImpl implements IPlayService { | ||
| 254 | } | 275 | } |
| 255 | 276 | ||
| 256 | @Override | 277 | @Override |
| 257 | - public IMediaServerItem getNewMediaServerItem(Device device) { | 278 | + public MediaServerItem getNewMediaServerItem(Device device) { |
| 258 | if (device == null) return null; | 279 | if (device == null) return null; |
| 259 | String mediaServerId = device.getMediaServerId(); | 280 | String mediaServerId = device.getMediaServerId(); |
| 260 | - IMediaServerItem mediaServerItem = null; | 281 | + MediaServerItem mediaServerItem = null; |
| 261 | if (mediaServerId == null) { | 282 | if (mediaServerId == null) { |
| 262 | mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(); | 283 | mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(); |
| 263 | }else { | 284 | }else { |
| @@ -270,7 +291,7 @@ public class PlayServiceImpl implements IPlayService { | @@ -270,7 +291,7 @@ public class PlayServiceImpl implements IPlayService { | ||
| 270 | } | 291 | } |
| 271 | 292 | ||
| 272 | @Override | 293 | @Override |
| 273 | - public void onPublishHandlerForPlayBack(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { | 294 | + public void onPublishHandlerForPlayBack(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { |
| 274 | RequestMessage msg = new RequestMessage(); | 295 | RequestMessage msg = new RequestMessage(); |
| 275 | msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); | 296 | msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); |
| 276 | StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid); | 297 | StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid); |
| @@ -285,7 +306,7 @@ public class PlayServiceImpl implements IPlayService { | @@ -285,7 +306,7 @@ public class PlayServiceImpl implements IPlayService { | ||
| 285 | } | 306 | } |
| 286 | } | 307 | } |
| 287 | 308 | ||
| 288 | - public StreamInfo onPublishHandler(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { | 309 | + public StreamInfo onPublishHandler(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { |
| 289 | String streamId = resonse.getString("stream"); | 310 | String streamId = resonse.getString("stream"); |
| 290 | JSONArray tracks = resonse.getJSONArray("tracks"); | 311 | JSONArray tracks = resonse.getJSONArray("tracks"); |
| 291 | StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem,"rtp", streamId, tracks); | 312 | StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem,"rtp", streamId, tracks); |
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
| @@ -3,7 +3,6 @@ package com.genersoft.iot.vmp.service.impl; | @@ -3,7 +3,6 @@ package com.genersoft.iot.vmp.service.impl; | ||
| 3 | import com.alibaba.fastjson.JSONObject; | 3 | import com.alibaba.fastjson.JSONObject; |
| 4 | import com.genersoft.iot.vmp.gb28181.bean.GbStream; | 4 | import com.genersoft.iot.vmp.gb28181.bean.GbStream; |
| 5 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; | 5 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| 6 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 7 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 6 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 8 | import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; | 7 | import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; |
| 9 | import com.genersoft.iot.vmp.service.IGbStreamService; | 8 | import com.genersoft.iot.vmp.service.IGbStreamService; |
| @@ -58,7 +57,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { | @@ -58,7 +57,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { | ||
| 58 | 57 | ||
| 59 | @Override | 58 | @Override |
| 60 | public String save(StreamProxyItem param) { | 59 | public String save(StreamProxyItem param) { |
| 61 | - IMediaServerItem mediaInfo; | 60 | + MediaServerItem mediaInfo; |
| 62 | if ("auto".equals(param.getMediaServerId())){ | 61 | if ("auto".equals(param.getMediaServerId())){ |
| 63 | mediaInfo = mediaServerService.getMediaServerForMinimumLoad(); | 62 | mediaInfo = mediaServerService.getMediaServerForMinimumLoad(); |
| 64 | }else { | 63 | }else { |
| @@ -120,7 +119,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { | @@ -120,7 +119,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { | ||
| 120 | @Override | 119 | @Override |
| 121 | public JSONObject addStreamProxyToZlm(StreamProxyItem param) { | 120 | public JSONObject addStreamProxyToZlm(StreamProxyItem param) { |
| 122 | JSONObject result = null; | 121 | JSONObject result = null; |
| 123 | - IMediaServerItem mediaServerItem = null; | 122 | + MediaServerItem mediaServerItem = null; |
| 124 | if (param.getMediaServerId() == null) { | 123 | if (param.getMediaServerId() == null) { |
| 125 | logger.warn("添加代理时MediaServerId 为null"); | 124 | logger.warn("添加代理时MediaServerId 为null"); |
| 126 | return null; | 125 | return null; |
| @@ -141,7 +140,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { | @@ -141,7 +140,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { | ||
| 141 | @Override | 140 | @Override |
| 142 | public JSONObject removeStreamProxyFromZlm(StreamProxyItem param) { | 141 | public JSONObject removeStreamProxyFromZlm(StreamProxyItem param) { |
| 143 | if (param ==null) return null; | 142 | if (param ==null) return null; |
| 144 | - IMediaServerItem mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); | 143 | + MediaServerItem mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); |
| 145 | JSONObject result = zlmresTfulUtils.closeStreams(mediaServerItem, param.getApp(), param.getStream()); | 144 | JSONObject result = zlmresTfulUtils.closeStreams(mediaServerItem, param.getApp(), param.getStream()); |
| 146 | return result; | 145 | return result; |
| 147 | } | 146 | } |
| @@ -198,7 +197,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { | @@ -198,7 +197,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { | ||
| 198 | } | 197 | } |
| 199 | 198 | ||
| 200 | @Override | 199 | @Override |
| 201 | - public JSONObject getFFmpegCMDs(IMediaServerItem mediaServerItem) { | 200 | + public JSONObject getFFmpegCMDs(MediaServerItem mediaServerItem) { |
| 202 | JSONObject result = new JSONObject(); | 201 | JSONObject result = new JSONObject(); |
| 203 | JSONObject mediaServerConfigResuly = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); | 202 | JSONObject mediaServerConfigResuly = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); |
| 204 | if (mediaServerConfigResuly != null && mediaServerConfigResuly.getInteger("code") == 0 | 203 | if (mediaServerConfigResuly != null && mediaServerConfigResuly.getInteger("code") == 0 |
src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
| @@ -5,7 +5,6 @@ import com.alibaba.fastjson.JSONObject; | @@ -5,7 +5,6 @@ import com.alibaba.fastjson.JSONObject; | ||
| 5 | import com.alibaba.fastjson.TypeReference; | 5 | import com.alibaba.fastjson.TypeReference; |
| 6 | import com.genersoft.iot.vmp.gb28181.bean.GbStream; | 6 | import com.genersoft.iot.vmp.gb28181.bean.GbStream; |
| 7 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; | 7 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| 8 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 9 | import com.genersoft.iot.vmp.media.zlm.dto.MediaItem; | 8 | import com.genersoft.iot.vmp.media.zlm.dto.MediaItem; |
| 10 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 9 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 11 | import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; | 10 | import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; |
| @@ -43,7 +42,7 @@ public class StreamPushServiceImpl implements IStreamPushService { | @@ -43,7 +42,7 @@ public class StreamPushServiceImpl implements IStreamPushService { | ||
| 43 | private IMediaServerService mediaServerService; | 42 | private IMediaServerService mediaServerService; |
| 44 | 43 | ||
| 45 | @Override | 44 | @Override |
| 46 | - public List<StreamPushItem> handleJSON(String jsonData, IMediaServerItem mediaServerItem) { | 45 | + public List<StreamPushItem> handleJSON(String jsonData, MediaServerItem mediaServerItem) { |
| 47 | if (jsonData == null) return null; | 46 | if (jsonData == null) return null; |
| 48 | 47 | ||
| 49 | Map<String, StreamPushItem> result = new HashMap<>(); | 48 | Map<String, StreamPushItem> result = new HashMap<>(); |
| @@ -98,7 +97,7 @@ public class StreamPushServiceImpl implements IStreamPushService { | @@ -98,7 +97,7 @@ public class StreamPushServiceImpl implements IStreamPushService { | ||
| 98 | @Override | 97 | @Override |
| 99 | public boolean removeFromGB(GbStream stream) { | 98 | public boolean removeFromGB(GbStream stream) { |
| 100 | int del = gbStreamMapper.del(stream.getApp(), stream.getStream()); | 99 | int del = gbStreamMapper.del(stream.getApp(), stream.getStream()); |
| 101 | - IMediaServerItem mediaInfo = mediaServerService.getOne(stream.getMediaServerId()); | 100 | + MediaServerItem mediaInfo = mediaServerService.getOne(stream.getMediaServerId()); |
| 102 | JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaInfo, stream.getApp(), stream.getStream()); | 101 | JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaInfo, stream.getApp(), stream.getStream()); |
| 103 | if (mediaList == null) { | 102 | if (mediaList == null) { |
| 104 | streamPushMapper.del(stream.getApp(), stream.getStream()); | 103 | streamPushMapper.del(stream.getApp(), stream.getStream()); |
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
| @@ -5,8 +5,6 @@ import com.genersoft.iot.vmp.common.StreamInfo; | @@ -5,8 +5,6 @@ import com.genersoft.iot.vmp.common.StreamInfo; | ||
| 5 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | 5 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 6 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; | 6 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; |
| 7 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | 7 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| 8 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 9 | -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | ||
| 10 | 8 | ||
| 11 | import java.util.List; | 9 | import java.util.List; |
| 12 | import java.util.Map; | 10 | import java.util.Map; |
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
| @@ -3,7 +3,6 @@ package com.genersoft.iot.vmp.storager; | @@ -3,7 +3,6 @@ package com.genersoft.iot.vmp.storager; | ||
| 3 | import java.util.List; | 3 | import java.util.List; |
| 4 | 4 | ||
| 5 | import com.genersoft.iot.vmp.gb28181.bean.*; | 5 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 6 | -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; | ||
| 7 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 6 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 8 | import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; | 7 | import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; |
| 9 | import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; | 8 | import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; |
src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java
| 1 | package com.genersoft.iot.vmp.storager.dao; | 1 | package com.genersoft.iot.vmp.storager.dao; |
| 2 | 2 | ||
| 3 | -import com.genersoft.iot.vmp.conf.MediaConfig; | ||
| 4 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 5 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 3 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 6 | import org.apache.ibatis.annotations.Insert; | 4 | import org.apache.ibatis.annotations.Insert; |
| 7 | import org.apache.ibatis.annotations.Mapper; | 5 | import org.apache.ibatis.annotations.Mapper; |
| @@ -35,6 +33,7 @@ public interface MediaServerMapper { | @@ -35,6 +33,7 @@ public interface MediaServerMapper { | ||
| 35 | "rtpEnable, " + | 33 | "rtpEnable, " + |
| 36 | "rtpPortRange, " + | 34 | "rtpPortRange, " + |
| 37 | "recordAssistPort, " + | 35 | "recordAssistPort, " + |
| 36 | + "defaultServer, " + | ||
| 38 | "createTime, " + | 37 | "createTime, " + |
| 39 | "updateTime" + | 38 | "updateTime" + |
| 40 | ") VALUES " + | 39 | ") VALUES " + |
| @@ -57,9 +56,10 @@ public interface MediaServerMapper { | @@ -57,9 +56,10 @@ public interface MediaServerMapper { | ||
| 57 | "${rtpEnable}, " + | 56 | "${rtpEnable}, " + |
| 58 | "'${rtpPortRange}', " + | 57 | "'${rtpPortRange}', " + |
| 59 | "${recordAssistPort}, " + | 58 | "${recordAssistPort}, " + |
| 59 | + "${defaultServer}, " + | ||
| 60 | "'${createTime}', " + | 60 | "'${createTime}', " + |
| 61 | "'${updateTime}')") | 61 | "'${updateTime}')") |
| 62 | - int add(IMediaServerItem mediaServerItem); | 62 | + int add(MediaServerItem mediaServerItem); |
| 63 | 63 | ||
| 64 | @Update(value = {" <script>" + | 64 | @Update(value = {" <script>" + |
| 65 | "UPDATE media_server " + | 65 | "UPDATE media_server " + |
| @@ -83,7 +83,7 @@ public interface MediaServerMapper { | @@ -83,7 +83,7 @@ public interface MediaServerMapper { | ||
| 83 | "<if test=\"recordAssistPort != null\">, recordAssistPort=${recordAssistPort}</if>" + | 83 | "<if test=\"recordAssistPort != null\">, recordAssistPort=${recordAssistPort}</if>" + |
| 84 | "WHERE id='${id}'"+ | 84 | "WHERE id='${id}'"+ |
| 85 | " </script>"}) | 85 | " </script>"}) |
| 86 | - int update(IMediaServerItem mediaServerItem); | 86 | + int update(MediaServerItem mediaServerItem); |
| 87 | 87 | ||
| 88 | @Select("SELECT * FROM media_server WHERE id='${id}'") | 88 | @Select("SELECT * FROM media_server WHERE id='${id}'") |
| 89 | MediaServerItem queryOne(String id); | 89 | MediaServerItem queryOne(String id); |
| @@ -92,7 +92,7 @@ public interface MediaServerMapper { | @@ -92,7 +92,7 @@ public interface MediaServerMapper { | ||
| 92 | List<MediaServerItem> queryAll(); | 92 | List<MediaServerItem> queryAll(); |
| 93 | 93 | ||
| 94 | @Select("DELETE FROM media_server WHERE id='${id}'") | 94 | @Select("DELETE FROM media_server WHERE id='${id}'") |
| 95 | - int delOne(String secret); | 95 | + void delOne(String id); |
| 96 | 96 | ||
| 97 | @Select("SELECT * FROM media_server WHERE ip='${host}' and httpPort=${port}") | 97 | @Select("SELECT * FROM media_server WHERE ip='${host}' and httpPort=${port}") |
| 98 | MediaServerItem queryOneByHostAndPort(String host, int port); | 98 | MediaServerItem queryOneByHostAndPort(String host, int port); |
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
| @@ -3,10 +3,7 @@ package com.genersoft.iot.vmp.storager.impl; | @@ -3,10 +3,7 @@ package com.genersoft.iot.vmp.storager.impl; | ||
| 3 | import com.alibaba.fastjson.JSONObject; | 3 | import com.alibaba.fastjson.JSONObject; |
| 4 | import com.genersoft.iot.vmp.common.StreamInfo; | 4 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 5 | import com.genersoft.iot.vmp.common.VideoManagerConstants; | 5 | import com.genersoft.iot.vmp.common.VideoManagerConstants; |
| 6 | -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; | ||
| 7 | import com.genersoft.iot.vmp.gb28181.bean.*; | 6 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 8 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 9 | -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | ||
| 10 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 7 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 11 | import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; | 8 | import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; |
| 12 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; | 9 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
src/main/java/com/genersoft/iot/vmp/utils/ConfigConst.java
0 → 100644
src/main/java/com/genersoft/iot/vmp/utils/SerializeUtils.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.utils; | ||
| 2 | + | ||
| 3 | +import java.io.*; | ||
| 4 | + | ||
| 5 | +public class SerializeUtils { | ||
| 6 | + public static byte[] serialize(Object obj){ | ||
| 7 | + byte[] bytes = null; | ||
| 8 | + try { | ||
| 9 | + ByteArrayOutputStream baos=new ByteArrayOutputStream();; | ||
| 10 | + ObjectOutputStream oos=new ObjectOutputStream(baos); | ||
| 11 | + oos.writeObject(obj); | ||
| 12 | + bytes=baos.toByteArray(); | ||
| 13 | + baos.close(); | ||
| 14 | + oos.close(); | ||
| 15 | + } catch (IOException e) { | ||
| 16 | + e.printStackTrace(); | ||
| 17 | + } | ||
| 18 | + return bytes; | ||
| 19 | + } | ||
| 20 | + public static Object deSerialize(byte[] bytes){ | ||
| 21 | + Object obj=null; | ||
| 22 | + try { | ||
| 23 | + ByteArrayInputStream bais=new ByteArrayInputStream(bytes); | ||
| 24 | + ObjectInputStream ois=new ObjectInputStream(bais); | ||
| 25 | + obj=ois.readObject(); | ||
| 26 | + } catch (Exception e) { | ||
| 27 | + e.printStackTrace(); | ||
| 28 | + } | ||
| 29 | + return obj; | ||
| 30 | + } | ||
| 31 | +} |
src/main/java/com/genersoft/iot/vmp/utils/redis/JedisUtil.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.utils.redis; | ||
| 2 | + | ||
| 3 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 4 | +import org.springframework.stereotype.Component; | ||
| 5 | +import redis.clients.jedis.Jedis; | ||
| 6 | +import redis.clients.jedis.JedisPool; | ||
| 7 | + | ||
| 8 | +import java.util.Set; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * @Description:Jedis工具类 | ||
| 12 | + * @author: wangshaopeng@sunnybs.com | ||
| 13 | + * @date: 2021年03月22日 下午8:27:29 | ||
| 14 | + */ | ||
| 15 | +@Component | ||
| 16 | +public class JedisUtil { | ||
| 17 | + | ||
| 18 | + @Autowired | ||
| 19 | + private JedisPool jedisPool; | ||
| 20 | + | ||
| 21 | + // ============================== Key ============================== | ||
| 22 | + | ||
| 23 | + /** | ||
| 24 | + * 检查给定 key 是否存在。 | ||
| 25 | + * | ||
| 26 | + * @param key | ||
| 27 | + * @return | ||
| 28 | + */ | ||
| 29 | + public Boolean exists(String key) { | ||
| 30 | + Jedis jedis = null; | ||
| 31 | + try { | ||
| 32 | + jedis = jedisPool.getResource(); | ||
| 33 | + Boolean exists = jedis.exists(key); | ||
| 34 | + return exists; | ||
| 35 | + } finally { | ||
| 36 | + returnToPool(jedis); | ||
| 37 | + } | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + | ||
| 41 | + // ============================== Set ============================== | ||
| 42 | + | ||
| 43 | + /** | ||
| 44 | + * SADD key member [member ...] | ||
| 45 | + * 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。 | ||
| 46 | + * 假如 key 不存在,则创建一个只包含 member 元素作成员的集合。 | ||
| 47 | + * 当 key 不是集合类型时,返回一个错误。 | ||
| 48 | + */ | ||
| 49 | + public Long sadd(String key, String... members) { | ||
| 50 | + Jedis jedis = null; | ||
| 51 | + try { | ||
| 52 | + jedis = jedisPool.getResource(); | ||
| 53 | + Long smove = jedis.sadd(key, members); | ||
| 54 | + return smove; | ||
| 55 | + } finally { | ||
| 56 | + returnToPool(jedis); | ||
| 57 | + } | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * SMEMBERS key | ||
| 62 | + * 返回集合 key 中的所有成员。 | ||
| 63 | + * 不存在的 key 被视为空集合。 | ||
| 64 | + */ | ||
| 65 | + public Set<String> smembers(String key) { | ||
| 66 | + Jedis jedis = null; | ||
| 67 | + try { | ||
| 68 | + jedis = jedisPool.getResource(); | ||
| 69 | + Set<String> smembers = jedis.smembers(key); | ||
| 70 | + return smembers; | ||
| 71 | + } finally { | ||
| 72 | + returnToPool(jedis); | ||
| 73 | + } | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + | ||
| 77 | + /** | ||
| 78 | + * SREM key member1 [member2] | ||
| 79 | + * 移除集合中一个或多个成员 | ||
| 80 | + */ | ||
| 81 | + public Long srem(String key, String... member) { | ||
| 82 | + Jedis jedis = null; | ||
| 83 | + try { | ||
| 84 | + jedis = jedisPool.getResource(); | ||
| 85 | + Long srem = jedis.srem(key, member); | ||
| 86 | + return srem; | ||
| 87 | + } finally { | ||
| 88 | + returnToPool(jedis); | ||
| 89 | + } | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + private void returnToPool(Jedis jedis) { | ||
| 93 | + if (jedis != null) { | ||
| 94 | + jedis.close(); | ||
| 95 | + } | ||
| 96 | + } | ||
| 97 | +} | ||
| 0 | \ No newline at end of file | 98 | \ No newline at end of file |
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
| @@ -415,10 +415,10 @@ public class RedisUtil { | @@ -415,10 +415,10 @@ public class RedisUtil { | ||
| 415 | * | 415 | * |
| 416 | * @param key | 416 | * @param key |
| 417 | * @param value | 417 | * @param value |
| 418 | - * @param score | 418 | + * @param delta -1 表示减 1 表示加1 |
| 419 | */ | 419 | */ |
| 420 | - public Double zIncrScore(Object key, Object value, double score) { | ||
| 421 | - return redisTemplate.opsForZSet().incrementScore(key, value, score); | 420 | + public Double zIncrScore(Object key, Object value, double delta) { |
| 421 | + return redisTemplate.opsForZSet().incrementScore(key, value, delta); | ||
| 422 | } | 422 | } |
| 423 | 423 | ||
| 424 | /** | 424 | /** |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
| @@ -2,13 +2,12 @@ package com.genersoft.iot.vmp.vmanager.gb28181.play; | @@ -2,13 +2,12 @@ package com.genersoft.iot.vmp.vmanager.gb28181.play; | ||
| 2 | 2 | ||
| 3 | import com.alibaba.fastjson.JSONArray; | 3 | import com.alibaba.fastjson.JSONArray; |
| 4 | import com.genersoft.iot.vmp.common.StreamInfo; | 4 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 5 | +import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; | ||
| 5 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | 6 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 6 | -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; | ||
| 7 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 7 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 8 | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | 8 | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
| 9 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | 9 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; |
| 10 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; | 10 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| 11 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 12 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 11 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 13 | import com.genersoft.iot.vmp.service.IMediaServerService; | 12 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 14 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 13 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| @@ -37,7 +36,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | @@ -37,7 +36,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | ||
| 37 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | 36 | import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
| 38 | import org.springframework.web.context.request.async.DeferredResult; | 37 | import org.springframework.web.context.request.async.DeferredResult; |
| 39 | 38 | ||
| 40 | -import java.util.Enumeration; | 39 | +import java.util.List; |
| 41 | import java.util.Map; | 40 | import java.util.Map; |
| 42 | import java.util.UUID; | 41 | import java.util.UUID; |
| 43 | 42 | ||
| @@ -89,7 +88,7 @@ public class PlayController { | @@ -89,7 +88,7 @@ public class PlayController { | ||
| 89 | 88 | ||
| 90 | // 获取可用的zlm | 89 | // 获取可用的zlm |
| 91 | Device device = storager.queryVideoDevice(deviceId); | 90 | Device device = storager.queryVideoDevice(deviceId); |
| 92 | - IMediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); | 91 | + MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); |
| 93 | PlayResult playResult = playService.play(newMediaServerItem, deviceId, channelId, null, null); | 92 | PlayResult playResult = playService.play(newMediaServerItem, deviceId, channelId, null, null); |
| 94 | 93 | ||
| 95 | return playResult.getResult(); | 94 | return playResult.getResult(); |
| @@ -174,7 +173,7 @@ public class PlayController { | @@ -174,7 +173,7 @@ public class PlayController { | ||
| 174 | logger.warn("视频转码API调用失败!, 视频流已经停止!"); | 173 | logger.warn("视频转码API调用失败!, 视频流已经停止!"); |
| 175 | return new ResponseEntity<String>("未找到视频流信息, 视频流可能已经停止", HttpStatus.OK); | 174 | return new ResponseEntity<String>("未找到视频流信息, 视频流可能已经停止", HttpStatus.OK); |
| 176 | } | 175 | } |
| 177 | - IMediaServerItem mediaInfo = mediaServerService.getOne(streamInfo.getMediaServerId()); | 176 | + MediaServerItem mediaInfo = mediaServerService.getOne(streamInfo.getMediaServerId()); |
| 178 | JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId); | 177 | JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId); |
| 179 | if (!rtpInfo.getBoolean("exist")) { | 178 | if (!rtpInfo.getBoolean("exist")) { |
| 180 | logger.warn("视频转码API调用失败!, 视频流已停止推流!"); | 179 | logger.warn("视频转码API调用失败!, 视频流已停止推流!"); |
| @@ -219,7 +218,7 @@ public class PlayController { | @@ -219,7 +218,7 @@ public class PlayController { | ||
| 219 | result.put("msg", "mediaServerId is null"); | 218 | result.put("msg", "mediaServerId is null"); |
| 220 | return new ResponseEntity<String>( result.toJSONString(), HttpStatus.BAD_REQUEST); | 219 | return new ResponseEntity<String>( result.toJSONString(), HttpStatus.BAD_REQUEST); |
| 221 | } | 220 | } |
| 222 | - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); | 221 | + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); |
| 223 | if (mediaInfo == null) { | 222 | if (mediaInfo == null) { |
| 224 | result.put("code", 0); | 223 | result.put("code", 0); |
| 225 | result.put("msg", "使用的流媒体已经停止运行"); | 224 | result.put("msg", "使用的流媒体已经停止运行"); |
| @@ -307,16 +306,16 @@ public class PlayController { | @@ -307,16 +306,16 @@ public class PlayController { | ||
| 307 | logger.debug("获取所有的ssrc"); | 306 | logger.debug("获取所有的ssrc"); |
| 308 | } | 307 | } |
| 309 | JSONArray objects = new JSONArray(); | 308 | JSONArray objects = new JSONArray(); |
| 310 | - for(Map.Entry<String, String> entry: streamSession.getSsrcMap().entrySet()) { | ||
| 311 | - System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); | 309 | + List<SsrcTransaction> allSsrc = streamSession.getAllSsrc(); |
| 310 | + for (SsrcTransaction transaction : allSsrc) { | ||
| 312 | JSONObject jsonObject = new JSONObject(); | 311 | JSONObject jsonObject = new JSONObject(); |
| 313 | - String[] keyArray = entry.getKey().split("_"); | ||
| 314 | - jsonObject.put("deviceId", keyArray[0]); | ||
| 315 | - jsonObject.put("channelId", keyArray[1]); | ||
| 316 | - jsonObject.put("ssrc", entry.getValue()); | ||
| 317 | - jsonObject.put("streamId", streamSession.getStreamIdMap().get(entry.getKey())); | 312 | + jsonObject.put("deviceId", transaction.getDeviceId()); |
| 313 | + jsonObject.put("channelId", transaction.getChannelId()); | ||
| 314 | + jsonObject.put("ssrc", transaction.getSsrc()); | ||
| 315 | + jsonObject.put("streamId", transaction.getStreamId()); | ||
| 318 | objects.add(jsonObject); | 316 | objects.add(jsonObject); |
| 319 | } | 317 | } |
| 318 | + | ||
| 320 | WVPResult<JSONObject> result = new WVPResult<>(); | 319 | WVPResult<JSONObject> result = new WVPResult<>(); |
| 321 | result.setCode(0); | 320 | result.setCode(0); |
| 322 | result.setMsg("success"); | 321 | result.setMsg("success"); |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/DownloadController.java
| @@ -3,9 +3,9 @@ package com.genersoft.iot.vmp.vmanager.gb28181.playback; | @@ -3,9 +3,9 @@ package com.genersoft.iot.vmp.vmanager.gb28181.playback; | ||
| 3 | import com.genersoft.iot.vmp.common.StreamInfo; | 3 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 4 | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | 4 | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
| 5 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | 5 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; |
| 6 | -//import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; | ||
| 7 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 8 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 6 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 7 | +import com.genersoft.iot.vmp.service.IMediaServerService; | ||
| 8 | +import com.genersoft.iot.vmp.service.bean.SSRCInfo; | ||
| 9 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 9 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 10 | import com.genersoft.iot.vmp.service.IPlayService; | 10 | import com.genersoft.iot.vmp.service.IPlayService; |
| 11 | import io.swagger.annotations.Api; | 11 | import io.swagger.annotations.Api; |
| @@ -58,6 +58,9 @@ public class DownloadController { | @@ -58,6 +58,9 @@ public class DownloadController { | ||
| 58 | @Autowired | 58 | @Autowired |
| 59 | private DeferredResultHolder resultHolder; | 59 | private DeferredResultHolder resultHolder; |
| 60 | 60 | ||
| 61 | + @Autowired | ||
| 62 | + private IMediaServerService mediaServerService; | ||
| 63 | + | ||
| 61 | @ApiOperation("开始历史媒体下载") | 64 | @ApiOperation("开始历史媒体下载") |
| 62 | @ApiImplicitParams({ | 65 | @ApiImplicitParams({ |
| 63 | @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class), | 66 | @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class), |
| @@ -90,7 +93,7 @@ public class DownloadController { | @@ -90,7 +93,7 @@ public class DownloadController { | ||
| 90 | cmder.streamByeCmd(deviceId, channelId); | 93 | cmder.streamByeCmd(deviceId, channelId); |
| 91 | } | 94 | } |
| 92 | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result); | 95 | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result); |
| 93 | - IMediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); | 96 | + MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); |
| 94 | if (newMediaServerItem == null) { | 97 | if (newMediaServerItem == null) { |
| 95 | logger.warn(String.format("设备下载响应超时,deviceId:%s ,channelId:%s", deviceId, channelId)); | 98 | logger.warn(String.format("设备下载响应超时,deviceId:%s ,channelId:%s", deviceId, channelId)); |
| 96 | RequestMessage msg = new RequestMessage(); | 99 | RequestMessage msg = new RequestMessage(); |
| @@ -99,7 +102,10 @@ public class DownloadController { | @@ -99,7 +102,10 @@ public class DownloadController { | ||
| 99 | resultHolder.invokeResult(msg); | 102 | resultHolder.invokeResult(msg); |
| 100 | return result; | 103 | return result; |
| 101 | } | 104 | } |
| 102 | - cmder.downloadStreamCmd(newMediaServerItem, device, channelId, startTime, endTime, downloadSpeed, (IMediaServerItem mediaServerItem, JSONObject response) -> { | 105 | + |
| 106 | + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null); | ||
| 107 | + | ||
| 108 | + cmder.downloadStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, (MediaServerItem mediaServerItem, JSONObject response) -> { | ||
| 103 | logger.info("收到订阅消息: " + response.toJSONString()); | 109 | logger.info("收到订阅消息: " + response.toJSONString()); |
| 104 | playService.onPublishHandlerForPlayBack(mediaServerItem, response, deviceId, channelId, uuid.toString()); | 110 | playService.onPublishHandlerForPlayBack(mediaServerItem, response, deviceId, channelId, uuid.toString()); |
| 105 | }, event -> { | 111 | }, event -> { |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java
| @@ -4,8 +4,9 @@ import com.genersoft.iot.vmp.common.StreamInfo; | @@ -4,8 +4,9 @@ import com.genersoft.iot.vmp.common.StreamInfo; | ||
| 4 | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | 4 | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
| 5 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | 5 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; |
| 6 | //import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; | 6 | //import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| 7 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 8 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 7 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 8 | +import com.genersoft.iot.vmp.service.IMediaServerService; | ||
| 9 | +import com.genersoft.iot.vmp.service.bean.SSRCInfo; | ||
| 9 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | 10 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 10 | import com.genersoft.iot.vmp.service.IPlayService; | 11 | import com.genersoft.iot.vmp.service.IPlayService; |
| 11 | import io.swagger.annotations.Api; | 12 | import io.swagger.annotations.Api; |
| @@ -58,6 +59,9 @@ public class PlaybackController { | @@ -58,6 +59,9 @@ public class PlaybackController { | ||
| 58 | @Autowired | 59 | @Autowired |
| 59 | private DeferredResultHolder resultHolder; | 60 | private DeferredResultHolder resultHolder; |
| 60 | 61 | ||
| 62 | + @Autowired | ||
| 63 | + private IMediaServerService mediaServerService; | ||
| 64 | + | ||
| 61 | @ApiOperation("开始视频回放") | 65 | @ApiOperation("开始视频回放") |
| 62 | @ApiImplicitParams({ | 66 | @ApiImplicitParams({ |
| 63 | @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class), | 67 | @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class), |
| @@ -74,6 +78,15 @@ public class PlaybackController { | @@ -74,6 +78,15 @@ public class PlaybackController { | ||
| 74 | } | 78 | } |
| 75 | UUID uuid = UUID.randomUUID(); | 79 | UUID uuid = UUID.randomUUID(); |
| 76 | DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(30000L); | 80 | DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(30000L); |
| 81 | + | ||
| 82 | + Device device = storager.queryVideoDevice(deviceId); | ||
| 83 | + if (device == null) { | ||
| 84 | + result.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST)); | ||
| 85 | + return result; | ||
| 86 | + } | ||
| 87 | + MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); | ||
| 88 | + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null); | ||
| 89 | + | ||
| 77 | // 超时处理 | 90 | // 超时处理 |
| 78 | result.onTimeout(()->{ | 91 | result.onTimeout(()->{ |
| 79 | logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId)); | 92 | logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId)); |
| @@ -82,14 +95,14 @@ public class PlaybackController { | @@ -82,14 +95,14 @@ public class PlaybackController { | ||
| 82 | msg.setData("Timeout"); | 95 | msg.setData("Timeout"); |
| 83 | resultHolder.invokeResult(msg); | 96 | resultHolder.invokeResult(msg); |
| 84 | }); | 97 | }); |
| 85 | - Device device = storager.queryVideoDevice(deviceId); | 98 | + |
| 86 | StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId); | 99 | StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId); |
| 87 | if (streamInfo != null) { | 100 | if (streamInfo != null) { |
| 88 | // 停止之前的回放 | 101 | // 停止之前的回放 |
| 89 | cmder.streamByeCmd(deviceId, channelId); | 102 | cmder.streamByeCmd(deviceId, channelId); |
| 90 | } | 103 | } |
| 91 | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result); | 104 | resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result); |
| 92 | - IMediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); | 105 | + |
| 93 | if (newMediaServerItem == null) { | 106 | if (newMediaServerItem == null) { |
| 94 | logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId)); | 107 | logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId)); |
| 95 | RequestMessage msg = new RequestMessage(); | 108 | RequestMessage msg = new RequestMessage(); |
| @@ -98,7 +111,8 @@ public class PlaybackController { | @@ -98,7 +111,8 @@ public class PlaybackController { | ||
| 98 | resultHolder.invokeResult(msg); | 111 | resultHolder.invokeResult(msg); |
| 99 | return result; | 112 | return result; |
| 100 | } | 113 | } |
| 101 | - cmder.playbackStreamCmd(newMediaServerItem, device, channelId, startTime, endTime, (IMediaServerItem mediaServerItem, JSONObject response) -> { | 114 | + |
| 115 | + cmder.playbackStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, (MediaServerItem mediaServerItem, JSONObject response) -> { | ||
| 102 | logger.info("收到订阅消息: " + response.toJSONString()); | 116 | logger.info("收到订阅消息: " + response.toJSONString()); |
| 103 | playService.onPublishHandlerForPlayBack(mediaServerItem, response, deviceId, channelId, uuid.toString()); | 117 | playService.onPublishHandlerForPlayBack(mediaServerItem, response, deviceId, channelId, uuid.toString()); |
| 104 | }, event -> { | 118 | }, event -> { |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/session/PlayTypeEnum.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.vmanager.gb28181.session; | ||
| 2 | + | ||
| 3 | +public enum PlayTypeEnum { | ||
| 4 | + | ||
| 5 | + PLAY("0", "直播"), | ||
| 6 | + PLAY_BACK("1", "回放"); | ||
| 7 | + | ||
| 8 | + private String value; | ||
| 9 | + private String name; | ||
| 10 | + | ||
| 11 | + PlayTypeEnum(String value, String name) { | ||
| 12 | + this.value = value; | ||
| 13 | + this.name = name; | ||
| 14 | + } | ||
| 15 | + | ||
| 16 | + public String getValue() { | ||
| 17 | + return value; | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + public String getName() { | ||
| 21 | + return name; | ||
| 22 | + } | ||
| 23 | +} |
src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java
| 1 | package com.genersoft.iot.vmp.vmanager.server; | 1 | package com.genersoft.iot.vmp.vmanager.server; |
| 2 | 2 | ||
| 3 | import com.genersoft.iot.vmp.VManageBootstrap; | 3 | import com.genersoft.iot.vmp.VManageBootstrap; |
| 4 | -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; | ||
| 5 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | 4 | +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 6 | import com.genersoft.iot.vmp.service.IMediaServerService; | 5 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 7 | -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | ||
| 8 | import com.genersoft.iot.vmp.utils.SpringBeanFactory; | 6 | import com.genersoft.iot.vmp.utils.SpringBeanFactory; |
| 9 | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; | 7 | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; |
| 10 | import gov.nist.javax.sip.SipStackImpl; | 8 | import gov.nist.javax.sip.SipStackImpl; |
| @@ -17,7 +15,6 @@ import org.springframework.web.bind.annotation.*; | @@ -17,7 +15,6 @@ import org.springframework.web.bind.annotation.*; | ||
| 17 | import javax.sip.ListeningPoint; | 15 | import javax.sip.ListeningPoint; |
| 18 | import javax.sip.ObjectInUseException; | 16 | import javax.sip.ObjectInUseException; |
| 19 | import javax.sip.SipProvider; | 17 | import javax.sip.SipProvider; |
| 20 | -import java.util.ArrayList; | ||
| 21 | import java.util.Iterator; | 18 | import java.util.Iterator; |
| 22 | import java.util.List; | 19 | import java.util.List; |
| 23 | 20 | ||
| @@ -38,19 +35,30 @@ public class ServerController { | @@ -38,19 +35,30 @@ public class ServerController { | ||
| 38 | @ApiOperation("流媒体服务列表") | 35 | @ApiOperation("流媒体服务列表") |
| 39 | @GetMapping(value = "/media_server/list") | 36 | @GetMapping(value = "/media_server/list") |
| 40 | @ResponseBody | 37 | @ResponseBody |
| 41 | - public WVPResult<List<IMediaServerItem>> getMediaServerList(){ | ||
| 42 | - WVPResult<List<IMediaServerItem>> result = new WVPResult<>(); | 38 | + public WVPResult<List<MediaServerItem>> getMediaServerList(){ |
| 39 | + WVPResult<List<MediaServerItem>> result = new WVPResult<>(); | ||
| 43 | result.setCode(0); | 40 | result.setCode(0); |
| 44 | result.setMsg("success"); | 41 | result.setMsg("success"); |
| 45 | result.setData(mediaServerService.getAll()); | 42 | result.setData(mediaServerService.getAll()); |
| 46 | return result; | 43 | return result; |
| 47 | } | 44 | } |
| 48 | 45 | ||
| 46 | + @ApiOperation("在线流媒体服务列表") | ||
| 47 | + @GetMapping(value = "/media_server/online/list") | ||
| 48 | + @ResponseBody | ||
| 49 | + public WVPResult<List<MediaServerItem>> getOnlineMediaServerList(){ | ||
| 50 | + WVPResult<List<MediaServerItem>> result = new WVPResult<>(); | ||
| 51 | + result.setCode(0); | ||
| 52 | + result.setMsg("success"); | ||
| 53 | + result.setData(mediaServerService.getAllOnline()); | ||
| 54 | + return result; | ||
| 55 | + } | ||
| 56 | + | ||
| 49 | @ApiOperation("获取流媒体服务") | 57 | @ApiOperation("获取流媒体服务") |
| 50 | @GetMapping(value = "/media_server/one/{id}") | 58 | @GetMapping(value = "/media_server/one/{id}") |
| 51 | @ResponseBody | 59 | @ResponseBody |
| 52 | - public WVPResult<IMediaServerItem> getMediaServer(@PathVariable String id){ | ||
| 53 | - WVPResult<IMediaServerItem> result = new WVPResult<>(); | 60 | + public WVPResult<MediaServerItem> getMediaServer(@PathVariable String id){ |
| 61 | + WVPResult<MediaServerItem> result = new WVPResult<>(); | ||
| 54 | result.setCode(0); | 62 | result.setCode(0); |
| 55 | result.setMsg("success"); | 63 | result.setMsg("success"); |
| 56 | result.setData(mediaServerService.getOne(id)); | 64 | result.setData(mediaServerService.getOne(id)); |
src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java
| 1 | package com.genersoft.iot.vmp.vmanager.streamProxy; | 1 | package com.genersoft.iot.vmp.vmanager.streamProxy; |
| 2 | 2 | ||
| 3 | import com.alibaba.fastjson.JSONObject; | 3 | import com.alibaba.fastjson.JSONObject; |
| 4 | -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; | ||
| 5 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 4 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 6 | import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; | 5 | import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; |
| 7 | import com.genersoft.iot.vmp.service.IMediaServerService; | 6 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| @@ -9,7 +8,6 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | @@ -9,7 +8,6 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | ||
| 9 | import com.genersoft.iot.vmp.service.IStreamProxyService; | 8 | import com.genersoft.iot.vmp.service.IStreamProxyService; |
| 10 | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; | 9 | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; |
| 11 | import com.github.pagehelper.PageInfo; | 10 | import com.github.pagehelper.PageInfo; |
| 12 | -import io.netty.util.internal.StringUtil; | ||
| 13 | import io.swagger.annotations.Api; | 11 | import io.swagger.annotations.Api; |
| 14 | import io.swagger.annotations.ApiImplicitParam; | 12 | import io.swagger.annotations.ApiImplicitParam; |
| 15 | import io.swagger.annotations.ApiImplicitParams; | 13 | import io.swagger.annotations.ApiImplicitParams; |
| @@ -86,7 +84,7 @@ public class StreamProxyController { | @@ -86,7 +84,7 @@ public class StreamProxyController { | ||
| 86 | public WVPResult getFFmpegCMDs(@RequestParam String mediaServerId){ | 84 | public WVPResult getFFmpegCMDs(@RequestParam String mediaServerId){ |
| 87 | logger.debug("获取节点[ {} ]ffmpeg.cmd模板", mediaServerId ); | 85 | logger.debug("获取节点[ {} ]ffmpeg.cmd模板", mediaServerId ); |
| 88 | 86 | ||
| 89 | - IMediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); | 87 | + MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); |
| 90 | JSONObject data = streamProxyService.getFFmpegCMDs(mediaServerItem); | 88 | JSONObject data = streamProxyService.getFFmpegCMDs(mediaServerItem); |
| 91 | WVPResult<JSONObject> result = new WVPResult<>(); | 89 | WVPResult<JSONObject> result = new WVPResult<>(); |
| 92 | result.setCode(0); | 90 | result.setCode(0); |
src/main/resources/all-application.yml
| @@ -17,6 +17,12 @@ spring: | @@ -17,6 +17,12 @@ spring: | ||
| 17 | password: | 17 | password: |
| 18 | # [可选] 超时时间 | 18 | # [可选] 超时时间 |
| 19 | timeout: 10000 | 19 | timeout: 10000 |
| 20 | + # [可选] 一个pool最多可分配多少个jedis实例 | ||
| 21 | + poolMaxTotal: 1000 | ||
| 22 | + # [可选] 一个pool最多有多少个状态为idle(空闲)的jedis实例 | ||
| 23 | + poolMaxIdle: 500 | ||
| 24 | + # [可选] 最大的等待时间(秒) | ||
| 25 | + poolMaxWait: 5 | ||
| 20 | # [可选] jdbc数据库配置, 项目使用sqlite作为数据库,一般不需要配置 | 26 | # [可选] jdbc数据库配置, 项目使用sqlite作为数据库,一般不需要配置 |
| 21 | datasource: | 27 | datasource: |
| 22 | # 使用mysql 打开23-28行注释, 删除29-36行 | 28 | # 使用mysql 打开23-28行注释, 删除29-36行 |
| @@ -124,6 +130,7 @@ logging: | @@ -124,6 +130,7 @@ logging: | ||
| 124 | level: | 130 | level: |
| 125 | com.genersoft.iot: debug | 131 | com.genersoft.iot: debug |
| 126 | com.genersoft.iot.vmp.storager.dao: info | 132 | com.genersoft.iot.vmp.storager.dao: info |
| 133 | + com.genersoft.iot.vmp.gb28181: info | ||
| 127 | # [根据业务需求配置] | 134 | # [根据业务需求配置] |
| 128 | user-settings: | 135 | user-settings: |
| 129 | # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true | 136 | # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true |
src/main/resources/application-dev.yml
| @@ -76,6 +76,8 @@ logging: | @@ -76,6 +76,8 @@ logging: | ||
| 76 | level: | 76 | level: |
| 77 | com.genersoft.iot: debug | 77 | com.genersoft.iot: debug |
| 78 | com.genersoft.iot.vmp.storager.dao: info | 78 | com.genersoft.iot.vmp.storager.dao: info |
| 79 | + com.genersoft.iot.vmp.gb28181: info | ||
| 80 | + | ||
| 79 | # [根据业务需求配置] | 81 | # [根据业务需求配置] |
| 80 | user-settings: | 82 | user-settings: |
| 81 | # 推流直播是否录制 | 83 | # 推流直播是否录制 |
src/main/resources/wvp.sqlite
No preview for this file type
web_src/src/components/service/MediaServer.js
| @@ -9,7 +9,7 @@ class MediaServer{ | @@ -9,7 +9,7 @@ class MediaServer{ | ||
| 9 | getMediaServerList(callback){ | 9 | getMediaServerList(callback){ |
| 10 | this.$axios({ | 10 | this.$axios({ |
| 11 | method: 'get', | 11 | method: 'get', |
| 12 | - url:`/api/server/media_server/list`, | 12 | + url:`/api/server/media_server/online/list`, |
| 13 | }).then(function (res) { | 13 | }).then(function (res) { |
| 14 | if (typeof (callback) == "function") callback(res.data) | 14 | if (typeof (callback) == "function") callback(res.data) |
| 15 | }).catch(function (error) { | 15 | }).catch(function (error) { |