From 3469271ec25c69e4528b085ba3be7d9d85ec519e Mon Sep 17 00:00:00 2001 From: 64850858 <648540858@qq.com> Date: 星期一, 26 七月 2021 11:40:32 +0800 Subject: [PATCH] 优化集群方案, 每个zlm一套ssrc; 优化集群下的docker接入逻辑; 更正sql脚本; 支持重启不设置设备离线。重启SIP事务不丢失 --- src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java | 14 src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/session/PlayTypeEnum.java | 23 web_src/src/components/service/MediaServer.js | 2 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java | 80 +- src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java | 10 src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/DownloadController.java | 14 sql/mysql.sql | 204 ++-- src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java | 2 src/main/java/com/genersoft/iot/vmp/utils/redis/JedisUtil.java | 97 ++ src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java | 391 +++++---- src/main/resources/application-dev.yml | 2 src/main/java/com/genersoft/iot/vmp/service/IPlayService.java | 9 src/main/java/com/genersoft/iot/vmp/service/bean/SSRCInfo.java | 38 + src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java | 65 + src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java | 37 src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java | 3 src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java | 3 src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java | 4 src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java | 6 src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java | 6 src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java | 115 ++ src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java | 5 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java | 2 src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java | 20 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java | 9 src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java | 4 src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java | 5 src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java | 22 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java | 211 ++--- src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java | 45 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java | 3 src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java | 8 src/main/java/com/genersoft/iot/vmp/utils/ConfigConst.java | 8 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java | 54 + pom.xml | 7 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java | 8 src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java | 3 src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java | 190 ---- src/main/java/com/genersoft/iot/vmp/gb28181/bean/SsrcTransaction.java | 70 + src/main/java/com/genersoft/iot/vmp/service/IMediaService.java | 5 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java | 34 src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcConfig.java | 140 +++ src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java | 3 src/main/resources/wvp.sqlite | 0 src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java | 30 src/main/resources/all-application.yml | 7 src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java | 24 src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java | 1 /dev/null | 92 -- src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java | 28 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java | 24 src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java | 10 src/main/java/com/genersoft/iot/vmp/utils/SerializeUtils.java | 31 src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java | 25 src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java | 9 55 files changed, 1,318 insertions(+), 944 deletions(-) diff --git a/pom.xml b/pom.xml index 93b4257..077f8f1 100644 --- a/pom.xml +++ b/pom.xml @@ -46,6 +46,7 @@ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.build.timestamp.format>MMddHHmm</maven.build.timestamp.format> <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version> + <jedis-version>3.1.0</jedis-version> <!-- 渚濊禆鐗堟湰 --> <pagehelper.version>5.2.0</pagehelper.version> @@ -80,6 +81,12 @@ <artifactId>spring-boot-starter-security</artifactId> </dependency> + <dependency> + <groupId>redis.clients</groupId> + <artifactId>jedis</artifactId> + <version>${jedis-version}</version> + </dependency> + <!-- druid鏁版嵁搴撹繛鎺ユ睜 --> <dependency> <groupId>com.alibaba</groupId> diff --git a/sql/mysql.sql b/sql/mysql.sql index 0bb4c03..5d8bbfc 100644 --- a/sql/mysql.sql +++ b/sql/mysql.sql @@ -1,112 +1,145 @@ -- auto-generated definition -create schema wvp collate utf8_bin; + + +CREATE DATABASE `wvp` /*!40100 DEFAULT CHARACTER SET utf8mb3 COLLATE utf8mb3_bin */; + +use wvp; create table device ( - deviceId varchar(50) not null + deviceId varchar(50) not null primary key, - name varchar(255) null, - manufacturer varchar(255) null, - model varchar(255) null, - firmware varchar(255) null, - transport varchar(50) null, - streamMode varchar(50) null, - online varchar(50) null, - registerTime varchar(50) null, - keepaliveTime varchar(50) null, - ip varchar(50) not null, - createTime varchar(50) not null, - updateTime varchar(50) not null, - port int not null, - expires int not null, - hostAddress varchar(50) not null + name varchar(255) null, + manufacturer varchar(255) null, + model varchar(255) null, + firmware varchar(255) null, + transport varchar(50) null, + streamMode varchar(50) null, + online varchar(50) null, + registerTime varchar(50) null, + keepaliveTime varchar(50) null, + ip varchar(50) not null, + createTime varchar(50) not null, + updateTime varchar(50) not null, + port int not null, + expires int not null, + hostAddress varchar(50) not null ); create table device_channel ( - channelId varchar(50) not null, + channelId varchar(50) not null, name varchar(255) null, - manufacture varchar(50) null, - model varchar(50) null, - owner varchar(50) null, - civilCode varchar(50) null, - block varchar(50) null, - address varchar(50) null, - parentId varchar(50) null, + manufacture varchar(50) null, + model varchar(50) null, + owner varchar(50) null, + civilCode varchar(50) null, + block varchar(50) null, + address varchar(50) null, + parentId varchar(50) null, safetyWay int null, registerWay int null, - certNum varchar(50) null, + certNum varchar(50) null, certifiable int null, errCode int null, - endTime varchar(50) null, - secrecy varchar(50) null, - ipAddress varchar(50) null, + endTime varchar(50) null, + secrecy varchar(50) null, + ipAddress varchar(50) null, port int null, password varchar(255) null, PTZType int null, status int null, longitude double null, latitude double null, - streamId varchar(50) null, - deviceId varchar(50) not null, - parental varchar(50) null, - hasAudio bit(1) null, - createTime varchar(50) not null, - updateTime varchar(50) not null, + streamId varchar(50) null, + deviceId varchar(50) not null, + parental varchar(50) null, + hasAudio bit null, + createTime varchar(50) not null, + updateTime varchar(50) not null, primary key (channelId, deviceId) ); create table device_mobile_position ( - deviceId varchar(50) not null, + deviceId varchar(50) not null, deviceName varchar(255) null, - time varchar(50) not null, + time varchar(50) not null, longitude double not null, latitude double not null, altitude double null, speed double null, direction double null, - reportSource varchar(50) null, - geodeticSystem varchar(50) null, - cnLng varchar(50) null, - cnLat varchar(50) null, + reportSource varchar(50) null, + geodeticSystem varchar(50) null, + cnLng varchar(50) null, + cnLat varchar(50) null, primary key (deviceId, time) ); create table gb_stream ( - app varchar(255) not null, - stream varchar(255) not null, - gbId varchar(50) not null, - name varchar(255) null, - longitude double null, - latitude double null, - streamType varchar(50) null, - status int null, + app varchar(255) not null, + stream varchar(255) not null, + gbId varchar(50) not null, + name varchar(255) null, + longitude double null, + latitude double null, + streamType varchar(50) null, + mediaServerId varchar(50) null, + status int null, primary key (app, stream, gbId) +); + +create table media_server +( + id varchar(255) not null + primary key, + ip varchar(50) not null, + hookIp varchar(50) not null, + sdpIp varchar(50) not null, + streamIp varchar(50) not null, + httpPort int not null, + httpSSlPort int not null, + rtmpPort int not null, + rtmpSSlPort int not null, + rtpProxyPort int not null, + rtspPort int not null, + rtspSSLPort int not null, + autoConfig int not null, + secret varchar(50) not null, + streamNoneReaderDelayMS int not null, + rtpEnable int not null, + rtpPortRange varchar(50) not null, + recordAssistPort int not null, + defaultServer int not null, + createTime varchar(50) not null, + updateTime varchar(50) not null, + constraint media_server_i + unique (ip, httpPort) ); create table parent_platform ( - id int auto_increment, + id int auto_increment, enable int null, name varchar(255) null, - serverGBId varchar(50) not null, - serverGBDomain varchar(50) null, - serverIP varchar(50) null, + serverGBId varchar(50) not null, + serverGBDomain varchar(50) null, + serverIP varchar(50) null, serverPort int null, - deviceGBId varchar(50) not null, - deviceIp varchar(50) null, - devicePort varchar(50) null, + deviceGBId varchar(50) not null, + deviceIp varchar(50) null, + devicePort varchar(50) null, username varchar(255) null, - password varchar(50) null, - expires varchar(50) null, - keepTimeout varchar(50) null, - transport varchar(50) null, - characterSet varchar(50) null, + password varchar(50) null, + expires varchar(50) null, + keepTimeout varchar(50) null, + transport varchar(50) null, + characterSet varchar(50) null, ptz int null, rtcp int null, - status bit(1) null, + status bit null, primary key (id, serverGBId) ); @@ -121,7 +154,7 @@ create table platform_gb_stream ( - platformId varchar(50) not null, + platformId varchar(50) not null, app varchar(255) not null, stream varchar(255) not null, primary key (platformId, app, stream) @@ -129,7 +162,7 @@ create table stream_proxy ( - type varchar(50) not null, + type varchar(50) not null, app varchar(255) not null, stream varchar(255) not null, url varchar(255) null, @@ -137,11 +170,12 @@ dst_url varchar(255) null, timeout_ms int null, ffmpeg_cmd_key varchar(255) null, - rtp_type varchar(50) null, - mediaServerId varchar(50) null, - enable_hls bit(1) null, - enable_mp4 bit(1) null, - enable bit(1) not null, + rtp_type varchar(50) null, + mediaServerId varchar(50) null, + enable_hls bit null, + enable_mp4 bit null, + enable bit not null, + createTime varchar(50) not null, primary key (app, stream) ); @@ -149,11 +183,12 @@ ( app varchar(255) not null, stream varchar(255) not null, - totalReaderCount varchar(50) null, + totalReaderCount varchar(50) null, originType int null, - originTypeStr varchar(50) null, + originTypeStr varchar(50) null, createStamp int null, aliveSecond int null, + mediaServerId varchar(50) null, primary key (app, stream) ); @@ -164,31 +199,6 @@ username varchar(255) not null, password varchar(255) not null, roleId int not null, - create_time varchar(50) not null + create_time varchar(50) not null ); -insert into user (username, password, roleId, create_time) values ('admin', '21232f297a57a5a743894a0e4a801fc3', '0', '2021-04-13 14:14:57'); - -create table media_server ( - id varchar(255) - primary key, - ip varchar(50) NOT NULL, - hookIp varchar(50) NOT NULL, - sdpIp varchar(50) NOT NULL, - streamIp varchar(50) NOT NULL, - httpPort int NOT NULL, - httpSSlPort int NOT NULL, - rtmpPort int NOT NULL, - rtmpSSlPort int NOT NULL, - rtpProxyPort int NOT NULL, - rtspPort int NOT NULL, - rtspSSLPort int NOT NULL, - autoConfig int NOT NULL, - secret varchar(50) NOT NULL, - streamNoneReaderDelayMS int NOT NULL, - rtpEnable int NOT NULL, - rtpPortRange varchar(50) NOT NULL, - recordAssistPort int NOT NULL, - createTime varchar(50) not null, - updateTime varchar(50) not null -); \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java index 5749314..cb2b173 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java +++ b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java @@ -12,6 +12,8 @@ public static final String MEDIA_SERVER_PREFIX = "VMP_MEDIA_SERVER_"; + public static final String MEDIA_SERVERS_ONLINE_PREFIX = "VMP_MEDIA_ONLINE_SERVERS"; + public static final String MEDIA_STREAM_PREFIX = "VMP_MEDIA_STREAM"; public static final String DEVICE_PREFIX = "VMP_DEVICE_"; @@ -45,4 +47,8 @@ public static final String EVENT_OUTLINE_UNREGISTER = "1"; public static final String EVENT_OUTLINE_TIMEOUT = "2"; + + public static final String MEDIA_SSRC_USED_PREFIX = "VMP_media_used_ssrc_"; + + public static final String MEDIA_TRANSACTION_USED_PREFIX = "VMP_media_transaction_"; } diff --git a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java index f2a0bcd..744e56f 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java @@ -1,13 +1,16 @@ package com.genersoft.iot.vmp.conf; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; +import com.genersoft.iot.vmp.gb28181.session.SsrcConfig; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; +import java.text.SimpleDateFormat; +import java.util.Date; + @Configuration("mediaConfig") -public class MediaConfig implements IMediaServerItem { +public class MediaConfig{ @Value("${media.id:}") private String id; @@ -20,6 +23,9 @@ @Value("${sip.ip}") private String sipIp; + + @Value("${sip.domain}") + private String sipDomain; @Value("${media.sdp-ip:${media.ip}}") private String sdpIp; @@ -66,29 +72,12 @@ @Value("${media.record-assist-port:0}") private Integer recordAssistPort = 0; - private String updateTime; - - private String createTime; - - private boolean docker = false; - - private int count; - - public String getId() { return id; } - public void setId(String id) { - this.id = id; - } - public String getIp() { return ip; - } - - public void setIp(String ip) { - this.ip = ip; } public String getHookIp() { @@ -100,76 +89,24 @@ } - public void setHookIp(String hookIp) { - this.hookIp = hookIp; - } - public String getSipIp() { return sipIp; - } - - public void setSipIp(String sipIp) { - this.sipIp = sipIp; - } - - public void setSdpIp(String sdpIp) { - this.sdpIp = sdpIp; - } - - public void setStreamIp(String streamIp) { - this.streamIp = streamIp; } public int getHttpPort() { return httpPort; } - @Override - public void setHttpPort(int httpPort) { - - } - - public void setHttpPort(Integer httpPort) { - this.httpPort = httpPort; - } - public int getHttpSSlPort() { return httpSSlPort; - } - - @Override - public void setHttpSSlPort(int httpSSlPort) { - - } - - public void setHttpSSlPort(Integer httpSSlPort) { - this.httpSSlPort = httpSSlPort; } public int getRtmpPort() { return rtmpPort; } - - @Override - public void setRtmpPort(int rtmpPort) { - - } - - public void setRtmpPort(Integer rtmpPort) { - this.rtmpPort = rtmpPort; - } - + public int getRtmpSSlPort() { return rtmpSSlPort; - } - - @Override - public void setRtmpSSlPort(int rtmpSSlPort) { - - } - - public void setRtmpSSlPort(Integer rtmpSSlPort) { - this.rtmpSSlPort = rtmpSSlPort; } public int getRtpProxyPort() { @@ -181,102 +118,36 @@ } - @Override - public void setRtpProxyPort(int rtpProxyPort) { - - } - - public void setRtpProxyPort(Integer rtpProxyPort) { - this.rtpProxyPort = rtpProxyPort; - } - public int getRtspPort() { return rtspPort; - } - - @Override - public void setRtspPort(int rtspPort) { - - } - - public void setRtspPort(Integer rtspPort) { - this.rtspPort = rtspPort; } public int getRtspSSLPort() { return rtspSSLPort; } - @Override - public void setRtspSSLPort(int rtspSSLPort) { - - } - - public void setRtspSSLPort(Integer rtspSSLPort) { - this.rtspSSLPort = rtspSSLPort; - } - public boolean isAutoConfig() { return autoConfig; - } - - public void setAutoConfig(boolean autoConfig) { - this.autoConfig = autoConfig; } public String getSecret() { return secret; } - public void setSecret(String secret) { - this.secret = secret; - } - public String getStreamNoneReaderDelayMS() { return streamNoneReaderDelayMS; - } - - public void setStreamNoneReaderDelayMS(String streamNoneReaderDelayMS) { - this.streamNoneReaderDelayMS = streamNoneReaderDelayMS; } public boolean isRtpEnable() { return rtpEnable; } - public void setRtpEnable(boolean rtpEnable) { - this.rtpEnable = rtpEnable; - } - public String getRtpPortRange() { return rtpPortRange; } - - public void setRtpPortRange(String rtpPortRange) { - this.rtpPortRange = rtpPortRange; - } - + public int getRecordAssistPort() { return recordAssistPort; - } - - @Override - public void setRecordAssistPort(int recordAssistPort) { - - } - - public void setRecordAssistPort(Integer recordAssistPort) { - this.recordAssistPort = recordAssistPort; - } - - @Override - public boolean isDocker() { - return docker; - } - - @Override - public void setDocker(boolean docker) { - this.docker = docker; } public String getSdpIp() { @@ -295,13 +166,11 @@ } } - - public MediaServerItem getMediaSerItem(){ MediaServerItem mediaServerItem = new MediaServerItem(); mediaServerItem.setId(id); mediaServerItem.setIp(ip); - mediaServerItem.setDocker(true); + mediaServerItem.setDefaultServer(true); mediaServerItem.setHookIp(hookIp); mediaServerItem.setSdpIp(sdpIp); mediaServerItem.setStreamIp(streamIp); @@ -318,39 +187,12 @@ mediaServerItem.setRtpEnable(rtpEnable); mediaServerItem.setRtpPortRange(rtpPortRange); mediaServerItem.setRecordAssistPort(recordAssistPort); - mediaServerItem.setCreateTime(createTime); - mediaServerItem.setUpdateTime(updateTime); - mediaServerItem.setCount(count); + + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + mediaServerItem.setCreateTime(format.format(new Date(System.currentTimeMillis()))); + mediaServerItem.setUpdateTime(format.format(new Date(System.currentTimeMillis()))); + return mediaServerItem; } - @Override - public String getUpdateTime() { - return updateTime; - } - - @Override - public void setUpdateTime(String updateTime) { - this.updateTime = updateTime; - } - - @Override - public String getCreateTime() { - return createTime; - } - - @Override - public void setCreateTime(String createTime) { - this.createTime = createTime; - } - - @Override - public int getCount() { - return count; - } - - @Override - public void setCount(int count) { - this.count = count; - } } diff --git a/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java index c2fb326..ab327b0 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.conf; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; import org.apache.catalina.connector.ClientAbortException; import org.apache.http.HttpHost; @@ -49,7 +49,7 @@ @Override protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) { String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString); - IMediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI()); + MediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI()); if (mediaInfo != null) { if (!StringUtils.isEmpty(queryStr)) { queryStr += "&secret=" + mediaInfo.getSecret(); @@ -88,7 +88,7 @@ @Override protected String getTargetUri(HttpServletRequest servletRequest) { String requestURI = servletRequest.getRequestURI(); - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); String uri = null; if (mediaInfo != null) { @@ -106,7 +106,7 @@ @Override protected HttpHost getTargetHost(HttpServletRequest servletRequest) { String requestURI = servletRequest.getRequestURI(); - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); HttpHost host; if (mediaInfo != null) { host = new HttpHost(mediaInfo.getIp(), mediaInfo.getHttpPort()); @@ -120,7 +120,7 @@ /** * 鏍规嵁uri鑾峰彇娴佸獟浣撲俊鎭� */ - IMediaServerItem getMediaInfoByUri(String uri){ + MediaServerItem getMediaInfoByUri(String uri){ String[] split = uri.split("/"); String mediaServerId = split[2]; return mediaServerService.getOne(mediaServerId); @@ -132,7 +132,7 @@ @Override protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) { String requestURI = servletRequest.getRequestURI(); - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); String url = super.rewriteUrlFromRequest(servletRequest); if (mediaInfo == null) { return url; @@ -186,7 +186,7 @@ @Override protected String getTargetUri(HttpServletRequest servletRequest) { String requestURI = servletRequest.getRequestURI(); - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); String uri = null; if (mediaInfo != null) { @@ -204,7 +204,7 @@ @Override protected HttpHost getTargetHost(HttpServletRequest servletRequest) { String requestURI = servletRequest.getRequestURI(); - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); HttpHost host; if (mediaInfo != null) { host = new HttpHost(mediaInfo.getIp(), mediaInfo.getRecordAssistPort()); @@ -218,7 +218,7 @@ /** * 鏍规嵁uri鑾峰彇娴佸獟浣撲俊鎭� */ - IMediaServerItem getMediaInfoByUri(String uri){ + MediaServerItem getMediaInfoByUri(String uri){ String[] split = uri.split("/"); String mediaServerId = split[2]; return mediaServerService.getOne(mediaServerId); @@ -230,7 +230,7 @@ @Override protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) { String requestURI = servletRequest.getRequestURI(); - IMediaServerItem mediaInfo = getMediaInfoByUri(requestURI); + MediaServerItem mediaInfo = getMediaInfoByUri(requestURI); String url = super.rewriteUrlFromRequest(servletRequest); if (mediaInfo == null) { return url; diff --git a/src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java index 0b3e23b..ee90788 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java @@ -1,5 +1,7 @@ package com.genersoft.iot.vmp.conf; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -10,6 +12,8 @@ import com.alibaba.fastjson.parser.ParserConfig; import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; /** * @Description:Redis涓棿浠堕厤缃被锛屼娇鐢╯pring-data-redis闆嗘垚锛岃嚜鍔ㄤ粠application.yml涓姞杞絩edis閰嶇疆 @@ -19,6 +23,37 @@ */ @Configuration public class RedisConfig extends CachingConfigurerSupport { + + @Value("${spring.redis.host}") + private String host; + @Value("${spring.redis.port}") + private int port; + @Value("${spring.redis.database}") + private int database; + @Value("${spring.redis.password}") + private String password; + @Value("${spring.redis.timeout}") + private int timeout; + @Value("${spring.redis.poolMaxTotal:1000}") + private int poolMaxTotal; + @Value("${spring.redis.poolMaxIdle:500}") + private int poolMaxIdle; + @Value("${spring.redis.poolMaxWait:5}") + private int poolMaxWait; + + @Bean + public JedisPool jedisPool() { + if (StringUtils.isBlank(password)) { + password = null; + } + JedisPoolConfig poolConfig = new JedisPoolConfig(); + poolConfig.setMaxIdle(poolMaxIdle); + poolConfig.setMaxTotal(poolMaxTotal); + // 绉掕浆姣 + poolConfig.setMaxWaitMillis(poolMaxWait * 1000L); + JedisPool jp = new JedisPool(poolConfig, host, port, timeout * 1000, password, database); + return jp; + } @Bean("redisTemplate") public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { @@ -34,7 +69,7 @@ template.setHashKeySerializer(new StringRedisSerializer()); template.setConnectionFactory(redisConnectionFactory); // 浣跨敤fastjson鏃堕渶璁剧疆姝ら」锛屽惁鍒欎細鎶ュ紓甯竛ot support type - ParserConfig.getGlobalInstance().setAutoTypeSupport(true); + ParserConfig.getGlobalInstance().setAutoTypeSupport(true); return template; } diff --git a/src/main/java/com/genersoft/iot/vmp/conf/SipDeviceRunner.java b/src/main/java/com/genersoft/iot/vmp/conf/SipDeviceRunner.java deleted file mode 100644 index 2b7ab1a..0000000 --- a/src/main/java/com/genersoft/iot/vmp/conf/SipDeviceRunner.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.genersoft.iot.vmp.conf; - -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; -import com.genersoft.iot.vmp.storager.IVideoManagerStorager; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; - - -/** - * 绯荤粺鍚姩鏃舵帶鍒惰澶囩绾� - */ -@Component -@Order(value=4) -public class SipDeviceRunner implements CommandLineRunner { - - @Autowired - private IVideoManagerStorager storager; - - @Autowired - private IRedisCatchStorage redisCatchStorage; - - @Override - public void run(String... args) throws Exception { - // 璁剧疆鎵�鏈夎澶囩绾� - storager.outlineForAll(); - // 璁剧疆鎵�鏈夎澶囩绾� - redisCatchStorage.outlineForAll(); - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java index 0a76f69..e71ac05 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java @@ -12,6 +12,7 @@ import javax.sip.message.Response; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; +import gov.nist.javax.sip.SipProviderImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -39,7 +40,7 @@ @Autowired private SipSubscribe sipSubscribe; - private SipStack sipStack; + private SipStackImpl sipStack; private SipFactory sipFactory; @@ -52,7 +53,7 @@ private ThreadPoolExecutor initSipServer() { int processThreadNum = Runtime.getRuntime().availableProcessors() * 10; - LinkedBlockingQueue<Runnable> processQueue = new LinkedBlockingQueue<Runnable>(10000); + LinkedBlockingQueue<Runnable> processQueue = new LinkedBlockingQueue<>(10000); processThreadPool = new ThreadPoolExecutor(processThreadNum,processThreadNum, 0L,TimeUnit.MILLISECONDS,processQueue, new ThreadPoolExecutor.CallerRunsPolicy()); @@ -88,17 +89,14 @@ @Bean("tcpSipProvider") @DependsOn("sipStack") - private SipProvider startTcpListener() { + private SipProviderImpl startTcpListener() { ListeningPoint tcpListeningPoint = null; - SipProvider tcpSipProvider = null; + SipProviderImpl tcpSipProvider = null; try { tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getSipPort(), "TCP"); - tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint); + tcpSipProvider = (SipProviderImpl)sipStack.createSipProvider(tcpListeningPoint); tcpSipProvider.addSipListener(this); logger.info("Sip Server TCP 鍚姩鎴愬姛 port {" + sipConfig.getMonitorIp() + ":" + sipConfig.getSipPort() + "}"); -// } catch (TransportNotSupportedException | InvalidArgumentException | TooManyListenersException | ObjectInUseException e) { -// logger.error(String.format("鍒涘缓SIP鏈嶅姟澶辫触: %s", e.getMessage())); -// } } catch (TransportNotSupportedException e) { e.printStackTrace(); } catch (InvalidArgumentException e) { @@ -114,13 +112,14 @@ @Bean("udpSipProvider") @DependsOn("sipStack") - private SipProvider startUdpListener() { + private SipProviderImpl startUdpListener() { ListeningPoint udpListeningPoint = null; - SipProvider udpSipProvider = null; + SipProviderImpl udpSipProvider = null; try { udpListeningPoint = sipStack.createListeningPoint(sipConfig.getMonitorIp(), sipConfig.getSipPort(), "UDP"); - udpSipProvider = sipStack.createSipProvider(udpListeningPoint); + udpSipProvider = (SipProviderImpl)sipStack.createSipProvider(udpListeningPoint); udpSipProvider.addSipListener(this); +// udpSipProvider.setAutomaticDialogSupportEnabled(false); } catch (TransportNotSupportedException e) { e.printStackTrace(); } catch (InvalidArgumentException e) { @@ -141,7 +140,7 @@ */ @Override public void processRequest(RequestEvent evt) { -// logger.debug(evt.getRequest().toString()); + logger.debug(evt.getRequest().toString()); // 鐢变簬jainsip鏄崟绾跨▼绋嬪簭锛屼负鎻愰珮鎬ц兘骞跺彂澶勭悊 processThreadPool.execute(() -> { if (processorFactory != null) { @@ -153,7 +152,7 @@ @Override public void processResponse(ResponseEvent evt) { Response response = evt.getResponse(); -// logger.debug(evt.getResponse().toString()); + logger.debug(evt.getResponse().toString()); int status = response.getStatusCode(); if (((status >= 200) && (status < 300)) || status == 401) { // Success! ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt); @@ -163,6 +162,7 @@ // TODO Auto-generated catch block e.printStackTrace(); } + if (evt.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) { CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME); if (callIdHeader != null) { @@ -220,7 +220,6 @@ @Override public void processIOException(IOExceptionEvent exceptionEvent) { // TODO Auto-generated method stub - } /** @@ -236,7 +235,6 @@ @Override public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) { // TODO Auto-generated method stub - } /** diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SsrcTransaction.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SsrcTransaction.java new file mode 100644 index 0000000..47d4d8a --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SsrcTransaction.java @@ -0,0 +1,70 @@ +package com.genersoft.iot.vmp.gb28181.bean; + +import javax.sip.message.Request; + +public class SsrcTransaction { + + private String deviceId; + private String channelId; + private String ssrc; + private String streamId; + private byte[] transaction; + private byte[] dialog; + private String mediaServerId; + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getChannelId() { + return channelId; + } + + public void setChannelId(String channelId) { + this.channelId = channelId; + } + + public String getSsrc() { + return ssrc; + } + + public void setSsrc(String ssrc) { + this.ssrc = ssrc; + } + + public String getStreamId() { + return streamId; + } + + public void setStreamId(String streamId) { + this.streamId = streamId; + } + + public byte[] getTransaction() { + return transaction; + } + + public void setTransaction(byte[] transaction) { + this.transaction = transaction; + } + + public byte[] getDialog() { + return dialog; + } + + public void setDialog(byte[] dialog) { + this.dialog = dialog; + } + + public String getMediaServerId() { + return mediaServerId; + } + + public void setMediaServerId(String mediaServerId) { + this.mediaServerId = mediaServerId; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java index aed2100..0b4bc88 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/platformNotRegister/PlatformNotRegisterEventLister.java @@ -6,7 +6,6 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -77,7 +76,7 @@ } stream.append(sendRtpItem.getStreamId()); redisCatchStorage.deleteSendRTPServer(event.getPlatformGbID(), sendRtpItem.getChannelId()); - IMediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); Map<String, Object> param = new HashMap<>(); param.put("vhost", "__defaultVhost__"); param.put("app", app.toString()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcConfig.java b/src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcConfig.java new file mode 100644 index 0000000..e96e6a5 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcConfig.java @@ -0,0 +1,140 @@ +package com.genersoft.iot.vmp.gb28181.session; + +import com.genersoft.iot.vmp.utils.ConfigConst; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.Set; + +public class SsrcConfig { + + /** + * zlm娴佸獟浣撴湇鍔″櫒Id + */ + private String mediaServerId; + + private String ssrcPrefix; + /** + * zlm娴佸獟浣撴湇鍔″櫒宸茬敤浼氳瘽鍙ユ焺 + */ + private List<String> isUsed; + /** + * zlm娴佸獟浣撴湇鍔″櫒鍙敤浼氳瘽鍙ユ焺 + */ + private List<String> notUsed; + + public SsrcConfig() { + } + + public SsrcConfig(String mediaServerId, Set<String> usedSet, String sipDomain) { + this.mediaServerId = mediaServerId; + this.isUsed = new ArrayList<>(); + this.ssrcPrefix = sipDomain.substring(3, 8); + this.notUsed = new ArrayList<>(); + for (int i = 1; i < ConfigConst.MAX_STRTEAM_COUNT; i++) { + String ssrc; + if (i < 10) { + ssrc = "000" + i; + } else if (i < 100) { + ssrc = "00" + i; + } else if (i < 1000) { + ssrc = "0" + i; + } else { + ssrc = String.valueOf(i); + } + if (null == usedSet || !usedSet.contains(ssrc)) { + this.notUsed.add(ssrc); + } else { + this.isUsed.add(ssrc); + } + } + } + + + /** + * 鑾峰彇瑙嗛棰勮鐨凷SRC鍊�,绗竴浣嶅浐瀹氫负0 + * @return ssrc + */ + public String getPlaySsrc() { + return "0" + getSsrcPrefix() + getSN(); + } + + /** + * 鑾峰彇褰曞儚鍥炴斁鐨凷SRC鍊�,绗竴浣嶅浐瀹氫负1 + * + */ + public String getPlayBackSsrc() { + return "1" + getSsrcPrefix() + getSN(); + } + + /** + * 閲婃斁ssrc锛屼富瑕佺敤瀹岀殑ssrc涓�瀹氳閲婃斁锛屽惁鍒欎細鑰楀敖 + * @param ssrc 闇�瑕侀噸缃殑ssrc + */ + public void releaseSsrc(String ssrc) { + if (ssrc == null) { + return; + } + String sn = ssrc.substring(6); + try { + isUsed.remove(sn); + notUsed.add(sn); + }catch (NullPointerException e){ + System.out.printf("11111"); + } + } + + /** + * 鑾峰彇鍚庡洓浣嶆暟SN,闅忔満鏁� + * + */ + private String getSN() { + String sn = null; + int index = 0; + if (notUsed.size() == 0) { + throw new RuntimeException("ssrc宸茬粡鐢ㄥ畬"); + } else if (notUsed.size() == 1) { + sn = notUsed.get(0); + } else { + index = new Random().nextInt(notUsed.size() - 1); + sn = notUsed.get(index); + } + notUsed.remove(index); + isUsed.add(sn); + return sn; + } + + public String getSsrcPrefix() { + return ssrcPrefix; + } + + public String getMediaServerId() { + return mediaServerId; + } + + public void setMediaServerId(String mediaServerId) { + this.mediaServerId = mediaServerId; + } + + public void setSsrcPrefix(String ssrcPrefix) { + this.ssrcPrefix = ssrcPrefix; + } + + public List<String> getIsUsed() { + return isUsed; + } + + public void setIsUsed(List<String> isUsed) { + this.isUsed = isUsed; + } + + public List<String> getNotUsed() { + return notUsed; + } + + public void setNotUsed(List<String> notUsed) { + this.notUsed = notUsed; + } + +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcUtil.java b/src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcUtil.java deleted file mode 100644 index 7377997..0000000 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcUtil.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.genersoft.iot.vmp.gb28181.session; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import com.genersoft.iot.vmp.conf.SipConfig; -import com.genersoft.iot.vmp.utils.SpringBeanFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * @Description:SIP淇′护涓殑SSRC宸ュ叿绫汇�係SRC鍊肩敱10浣嶅崄杩涘埗鏁存暟缁勬垚鐨勫瓧绗︿覆锛岀涓�浣嶄负0浠h〃瀹炲喌锛屼负1鍒欎唬琛ㄥ洖鏀撅紱绗簩浣嶈嚦绗叚浣嶇敱鐩戞帶鍩烮D鐨勭4浣嶅埌绗�8浣嶇粍鎴愶紱鏈�鍚�4浣嶄负涓嶉噸澶嶇殑4涓暣鏁� - * @author: swwheihei - * @date: 2020骞�5鏈�10鏃� 涓婂崍11:57:57 - */ -public class SsrcUtil { - - private final static Logger logger = LoggerFactory.getLogger(SsrcUtil.class); - - private static String ssrcPrefix; - - private static List<String> isUsed; - - private static List<String> notUsed; - - private static void init() { - SipConfig sipConfig = (SipConfig) SpringBeanFactory.getBean("sipConfig"); - ssrcPrefix = sipConfig.getSipDomain().substring(3, 8); - isUsed = new ArrayList<String>(); - notUsed = new ArrayList<String>(); - for (int i = 1; i < 10000; i++) { - if (i < 10) { - notUsed.add("000" + i); - } else if (i < 100) { - notUsed.add("00" + i); - } else if (i < 1000) { - notUsed.add("0" + i); - } else { - notUsed.add(String.valueOf(i)); - } - } - } - - /** - * 鑾峰彇瑙嗛棰勮鐨凷SRC鍊�,绗竴浣嶅浐瀹氫负0 - * - */ - public static String getPlaySsrc() { - return "0" + getSsrcPrefix() + getSN(); - } - - /** - * 鑾峰彇褰曞儚鍥炴斁鐨凷SRC鍊�,绗竴浣嶅浐瀹氫负1 - * - */ - public static String getPlayBackSsrc() { - return "1" + getSsrcPrefix() + getSN(); - } - - /** - * 閲婃斁ssrc锛屼富瑕佺敤瀹岀殑ssrc涓�瀹氳閲婃斁锛屽惁鍒欎細鑰楀敖 - * - */ - public static void releaseSsrc(String ssrc) { - if (ssrc == null) { - logger.error("瑕侀噴鏀緎src涓簄ull"); - return; - } - String sn = ssrc.substring(6); - isUsed.remove(sn); - notUsed.add(sn); - } - - /** - * 鑾峰彇鍚庡洓浣嶆暟SN,闅忔満鏁� - * - */ - private static String getSN() { - String sn = null; - int index = 0; - if (notUsed.size() == 0) { - throw new RuntimeException("ssrc宸茬粡鐢ㄥ畬"); - } else if (notUsed.size() == 1) { - sn = notUsed.get(0); - } else { - index = new Random().nextInt(notUsed.size() - 1); - sn = notUsed.get(index); - } - notUsed.remove(index); - isUsed.add(sn); - return sn; - } - - private static String getSsrcPrefix() { - if (ssrcPrefix == null) { - init(); - } - return ssrcPrefix; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java b/src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java index 9e402e1..f9d3a69 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java @@ -1,9 +1,23 @@ package com.genersoft.iot.vmp.gb28181.session; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import javax.sip.ClientTransaction; +import javax.sip.Dialog; +import javax.sip.message.Request; +import com.genersoft.iot.vmp.common.VideoManagerConstants; +import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; +import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.utils.SerializeUtils; +import com.genersoft.iot.vmp.utils.redis.JedisUtil; +import com.genersoft.iot.vmp.utils.redis.RedisUtil; +import gov.nist.javax.sip.stack.SIPDialog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; /** @@ -14,50 +28,85 @@ @Component public class VideoStreamSessionManager { - private ConcurrentHashMap<String, ClientTransaction> sessionMap = new ConcurrentHashMap<>(); - private ConcurrentHashMap<String, String> ssrcMap = new ConcurrentHashMap<>(); - private ConcurrentHashMap<String, String> streamIdMap = new ConcurrentHashMap<>(); + @Autowired + private RedisUtil redisUtil; - public String createPlaySsrc(){ - return SsrcUtil.getPlaySsrc(); + public void put(String deviceId, String channelId ,String ssrc, String streamId, String mediaServerId, ClientTransaction transaction){ + SsrcTransaction ssrcTransaction = new SsrcTransaction(); + ssrcTransaction.setDeviceId(deviceId); + ssrcTransaction.setChannelId(channelId); + ssrcTransaction.setStreamId(streamId); + byte[] transactionByteArray = SerializeUtils.serialize(transaction); + ssrcTransaction.setTransaction(transactionByteArray); + ssrcTransaction.setSsrc(ssrc); + ssrcTransaction.setMediaServerId(mediaServerId); + + redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + deviceId + "_" + channelId, ssrcTransaction); } - - public String createPlayBackSsrc(){ - return SsrcUtil.getPlayBackSsrc(); + + public void put(String deviceId, String channelId , Dialog dialog){ + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); + if (ssrcTransaction != null) { + byte[] dialogByteArray = SerializeUtils.serialize(dialog); + ssrcTransaction.setDialog(dialogByteArray); + } + redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + deviceId + "_" + channelId, ssrcTransaction); } - - public void put(String deviceId, String channelId ,String ssrc, String streamId, ClientTransaction transaction){ - sessionMap.put(deviceId + "_" + channelId, transaction); - ssrcMap.put(deviceId + "_" + channelId, ssrc); - streamIdMap.put(deviceId + "_" + channelId, streamId); - } + public ClientTransaction getTransaction(String deviceId, String channelId){ - return sessionMap.get(deviceId + "_" + channelId); + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); + if (ssrcTransaction == null) return null; + byte[] transactionByteArray = ssrcTransaction.getTransaction(); + ClientTransaction clientTransaction = (ClientTransaction)SerializeUtils.deSerialize(transactionByteArray); + return clientTransaction; + } + + public SIPDialog getDialog(String deviceId, String channelId){ + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); + if (ssrcTransaction == null) return null; + byte[] dialogByteArray = ssrcTransaction.getDialog(); + if (dialogByteArray == null) return null; + SIPDialog dialog = (SIPDialog)SerializeUtils.deSerialize(dialogByteArray); + return dialog; + } + + public SsrcTransaction getSsrcTransaction(String deviceId, String channelId){ + SsrcTransaction ssrcTransaction = (SsrcTransaction)redisUtil.get(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + deviceId + "_" + channelId); + return ssrcTransaction; } public String getStreamId(String deviceId, String channelId){ - return streamIdMap.get(deviceId + "_" + channelId); + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); + if (ssrcTransaction == null) return null; + return ssrcTransaction.getStreamId(); + } + public String getMediaServerId(String deviceId, String channelId){ + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); + if (ssrcTransaction == null) return null; + return ssrcTransaction.getMediaServerId(); + } + + public String getSSRC(String deviceId, String channelId){ + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); + if (ssrcTransaction == null) return null; + return ssrcTransaction.getSsrc(); } public void remove(String deviceId, String channelId) { - sessionMap.remove(deviceId + "_" + channelId); - if (ssrcMap.get(deviceId + "_" + channelId) != null) { - SsrcUtil.releaseSsrc(ssrcMap.get(deviceId + "_" + channelId)); + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); + if (ssrcTransaction == null) return; + redisUtil.del(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + deviceId + "_" + channelId); + } + + public List<SsrcTransaction> getAllSsrc() { + List<Object> ssrcTransactionKeys = redisUtil.scan(String.format("%s_*_*", VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX)); + List<SsrcTransaction> result= new ArrayList<>(); + for (int i = 0; i < ssrcTransactionKeys.size(); i++) { + String key = (String)ssrcTransactionKeys.get(i); + SsrcTransaction ssrcTransaction = (SsrcTransaction)redisUtil.get(key); + result.add(ssrcTransaction); } - ssrcMap.remove(deviceId + "_" + channelId); - streamIdMap.remove(deviceId + "_" + channelId); - } - - public ConcurrentHashMap<String, ClientTransaction> getSessionMap() { - return sessionMap; - } - - public ConcurrentHashMap<String, String> getSsrcMap() { - return ssrcMap; - } - - public ConcurrentHashMap<String, String> getStreamIdMap() { - return streamIdMap; + return result; } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java index e2ff0f4..30c9e95 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java @@ -7,6 +7,7 @@ import javax.sip.message.Request; import javax.sip.message.Response; +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; import com.genersoft.iot.vmp.service.IMediaServerService; @@ -107,7 +108,6 @@ @Autowired private IMediaServerService mediaServerService; - // 娉細杩欓噷浣跨敤娉ㄨВ浼氬鑷村惊鐜緷璧栨敞鍏ワ紝鏆傜敤springBean private SipProvider tcpSipProvider; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java index 99da23d..10611dc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java @@ -3,8 +3,8 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.service.bean.SSRCInfo; /** * @Description:璁惧鑳藉姏鎺ュ彛锛岀敤浜庡畾涔夎澶囩殑鎺у埗銆佹煡璇㈣兘鍔� @@ -92,7 +92,7 @@ * @param device 瑙嗛璁惧 * @param channelId 棰勮閫氶亾 */ - void playStreamCmd(IMediaServerItem mediaServerItem, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); + void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); /** * 璇锋眰鍥炴斁瑙嗛娴� @@ -102,7 +102,7 @@ * @param startTime 寮�濮嬫椂闂�,鏍煎紡瑕佹眰锛歽yyy-MM-dd HH:mm:ss * @param endTime 缁撴潫鏃堕棿,鏍煎紡瑕佹眰锛歽yyy-MM-dd HH:mm:ss */ - void playbackStreamCmd(IMediaServerItem mediaServerItem,Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); + void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInf, Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); /** * 璇锋眰鍘嗗彶濯掍綋涓嬭浇 @@ -113,12 +113,10 @@ * @param endTime 缁撴潫鏃堕棿,鏍煎紡瑕佹眰锛歽yyy-MM-dd HH:mm:ss * @param downloadSpeed 涓嬭浇鍊嶉�熷弬鏁� */ - void downloadStreamCmd(IMediaServerItem mediaServerItem,Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); + void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); /** * 瑙嗛娴佸仠姝� - * - * @param ssrc ssrc */ void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent); void streamByeCmd(String deviceId, String channelId); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index d2318dc..f1223d5 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -1,6 +1,8 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; +import java.lang.reflect.Field; import java.text.ParseException; +import java.util.HashSet; import javax.sip.*; import javax.sip.address.SipURI; @@ -8,18 +10,21 @@ import javax.sip.header.ViaHeader; import javax.sip.message.Request; -import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.genersoft.iot.vmp.common.StreamInfo; -import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.conf.UserSetup; +import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; import com.genersoft.iot.vmp.media.zlm.*; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; +import gov.nist.javax.sip.SipProviderImpl; +import gov.nist.javax.sip.SipStackImpl; import gov.nist.javax.sip.message.SIPRequest; +import gov.nist.javax.sip.stack.SIPDialog; +import gov.nist.javax.sip.stack.SIPTransaction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -35,7 +40,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; import com.genersoft.iot.vmp.gb28181.utils.DateUtil; import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; -import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; import org.springframework.util.StringUtils; /** @@ -55,12 +59,12 @@ @Lazy @Autowired @Qualifier(value="tcpSipProvider") - private SipProvider tcpSipProvider; + private SipProviderImpl tcpSipProvider; @Lazy @Autowired @Qualifier(value="udpSipProvider") - private SipProvider udpSipProvider; + private SipProviderImpl udpSipProvider; @Autowired private SIPRequestHeaderProvider headerProvider; @@ -75,9 +79,6 @@ private IRedisCatchStorage redisCatchStorage; @Autowired - private ZLMRTPServerFactory zlmrtpServerFactory; - - @Autowired private UserSetup userSetup; @Autowired @@ -85,6 +86,11 @@ @Autowired private SipSubscribe sipSubscribe; + + @Autowired + private IMediaServerService mediaServerService; + + private SIPDialog dialog; public SipConfig getSipConfig() { return sipConfig; @@ -334,26 +340,13 @@ * @param errorEvent sip閿欒璁㈤槄 */ @Override - public void playStreamCmd(IMediaServerItem mediaServerItem, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) { - String streamId = null; + public void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) { + String streamId = ssrcInfo.getStreamId(); try { if (device == null) return; String streamMode = device.getStreamMode().toUpperCase(); - String ssrc = streamSession.createPlaySsrc(); - if (mediaServerItem.isRtpEnable()) { - streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); - }else { - streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); - } - Integer mediaPort = null; - // 浣跨敤鍔ㄦ�乽dp绔彛 - if (mediaServerItem.isRtpEnable()) { - mediaPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId); - }else { - mediaPort = mediaServerItem.getRtpProxyPort(); - } - logger.info("{} 鍒嗛厤鐨刏LM涓�: {} [{}:{}]", streamId, mediaServerItem.getId(), mediaServerItem.getIp(), mediaPort); + logger.info("{} 鍒嗛厤鐨刏LM涓�: {} [{}:{}]", streamId, mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); // 娣诲姞璁㈤槄 JSONObject subscribeKey = new JSONObject(); subscribeKey.put("app", "rtp"); @@ -361,7 +354,7 @@ subscribeKey.put("regist", true); subscribeKey.put("mediaServerId", mediaServerItem.getId()); subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, - (IMediaServerItem mediaServerItemInUse, JSONObject json)->{ + (MediaServerItem mediaServerItemInUse, JSONObject json)->{ if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return; event.response(mediaServerItemInUse, json); subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey); @@ -369,7 +362,6 @@ // StringBuffer content = new StringBuffer(200); content.append("v=0\r\n"); -// content.append("o=" + sipConfig.getSipId() + " 0 0 IN IP4 "+mediaInfo.getWanIp()+"\r\n"); content.append("o="+"00000"+" 0 0 IN IP4 "+ mediaServerItem.getSdpIp() +"\r\n"); content.append("s=Play\r\n"); content.append("c=IN IP4 "+ mediaServerItem.getSdpIp() +"\r\n"); @@ -377,11 +369,11 @@ if (userSetup.isSeniorSdp()) { if("TCP-PASSIVE".equals(streamMode)) { - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); }else if ("TCP-ACTIVE".equals(streamMode)) { - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); }else if("UDP".equals(streamMode)) { - content.append("m=video "+ mediaPort +" RTP/AVP 96 126 125 99 34 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 126 125 99 34 98 97\r\n"); } content.append("a=recvonly\r\n"); content.append("a=rtpmap:96 PS/90000\r\n"); @@ -402,11 +394,11 @@ } }else { if("TCP-PASSIVE".equals(streamMode)) { - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n"); }else if ("TCP-ACTIVE".equals(streamMode)) { - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n"); }else if("UDP".equals(streamMode)) { - content.append("m=video "+ mediaPort +" RTP/AVP 96 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 98 97\r\n"); } content.append("a=recvonly\r\n"); content.append("a=rtpmap:96 PS/90000\r\n"); @@ -421,20 +413,25 @@ } } - content.append("y="+ssrc+"\r\n");//ssrc + content.append("y="+ssrcInfo.getSsrc()+"\r\n");//ssrc String tm = Long.toString(System.currentTimeMillis()); CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId() : udpSipProvider.getNewCallId(); - Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "FromInvt" + tm, null, ssrc, callIdHeader); + Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "FromInvt" + tm, null, ssrcInfo.getSsrc(), callIdHeader); - ClientTransaction transaction = transmitRequest(device, request, (e -> { + String finalStreamId = streamId; + transmitRequest(device, request, (e -> { streamSession.remove(device.getDeviceId(), channelId); + mediaServerService.releaseSsrc(mediaServerItem, ssrcInfo.getSsrc()); errorEvent.response(e); - })); - streamSession.put(device.getDeviceId(), channelId ,ssrc,streamId, transaction); + }), e ->{ + streamSession.put(device.getDeviceId(), channelId ,ssrcInfo.getSsrc(), finalStreamId, mediaServerItem.getId(),e.getClientTransaction()); + streamSession.put(device.getDeviceId(), channelId , e.getDialog()); + }); + } catch ( SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); @@ -450,30 +447,21 @@ * @param endTime 缁撴潫鏃堕棿,鏍煎紡瑕佹眰锛歽yyy-MM-dd HH:mm:ss */ @Override - public void playbackStreamCmd(IMediaServerItem mediaServerItem,Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event + public void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, ZLMHttpHookSubscribe.Event event , SipSubscribe.Event errorEvent) { try { - String ssrc = streamSession.createPlayBackSsrc(); - String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); - Integer mediaPort = null; - // 浣跨敤鍔ㄦ�乽dp绔彛 - if (mediaServerItem.isRtpEnable()) { - mediaPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId); - }else { - mediaPort = mediaServerItem.getRtpProxyPort(); - } - logger.info("{} 鍒嗛厤鐨刏LM涓�: {} [{}:{}]", streamId, mediaServerItem.getId(), mediaServerItem.getIp(), mediaPort); + logger.info("{} 鍒嗛厤鐨刏LM涓�: {} [{}:{}]", ssrcInfo.getStreamId(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); // 娣诲姞璁㈤槄 JSONObject subscribeKey = new JSONObject(); subscribeKey.put("app", "rtp"); - subscribeKey.put("stream", streamId); + subscribeKey.put("stream", ssrcInfo.getStreamId()); subscribeKey.put("regist", true); subscribeKey.put("mediaServerId", mediaServerItem.getId()); logger.debug("褰曞儚鍥炴斁娣诲姞璁㈤槄锛岃闃呭唴瀹癸細" + subscribeKey.toString()); subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, - (IMediaServerItem mediaServerItemInUse, JSONObject json)->{ + (MediaServerItem mediaServerItemInUse, JSONObject json)->{ if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return; event.response(mediaServerItemInUse, json); subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey); @@ -494,11 +482,11 @@ if (userSetup.isSeniorSdp()) { if("TCP-PASSIVE".equals(streamMode)) { - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); }else if ("TCP-ACTIVE".equals(streamMode)) { - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); }else if("UDP".equals(streamMode)) { - content.append("m=video "+ mediaPort +" RTP/AVP 96 126 125 99 34 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 126 125 99 34 98 97\r\n"); } content.append("a=recvonly\r\n"); content.append("a=rtpmap:96 PS/90000\r\n"); @@ -519,11 +507,11 @@ } }else { if("TCP-PASSIVE".equals(streamMode)) { - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n"); }else if ("TCP-ACTIVE".equals(streamMode)) { - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n"); }else if("UDP".equals(streamMode)) { - content.append("m=video "+ mediaPort +" RTP/AVP 96 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 98 97\r\n"); } content.append("a=recvonly\r\n"); content.append("a=rtpmap:96 PS/90000\r\n"); @@ -538,7 +526,7 @@ } } - content.append("y="+ssrc+"\r\n");//ssrc + content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc String tm = Long.toString(System.currentTimeMillis()); @@ -547,9 +535,11 @@ Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader); - ClientTransaction transaction = transmitRequest(device, request, errorEvent); - streamSession.put(device.getDeviceId(), channelId, ssrc, streamId, transaction); - + transmitRequest(device, request, errorEvent, okEvent -> { + Dialog dialog = okEvent.getClientTransaction().getDialog(); + streamSession.put(device.getDeviceId(), channelId, ssrcInfo.getSsrc(), ssrcInfo.getStreamId(), mediaServerItem.getId(), okEvent.getClientTransaction()); + streamSession.put(device.getDeviceId(), channelId, dialog); + }); } catch ( SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); } @@ -565,30 +555,20 @@ * @param downloadSpeed 涓嬭浇鍊嶉�熷弬鏁� */ @Override - public void downloadStreamCmd(IMediaServerItem mediaServerItem,Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event + public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event , SipSubscribe.Event errorEvent) { try { - String ssrc = streamSession.createPlayBackSsrc(); - String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); - - Integer mediaPort = null; - // 浣跨敤鍔ㄦ�乽dp绔彛 - if (mediaServerItem.isRtpEnable()) { - mediaPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId); - }else { - mediaPort = mediaServerItem.getRtpProxyPort(); - } - logger.info("{} 鍒嗛厤鐨刏LM涓�: {} [{}:{}]", streamId, mediaServerItem.getId(), mediaServerItem.getIp(), mediaPort); + logger.info("{} 鍒嗛厤鐨刏LM涓�: {} [{}:{}]", ssrcInfo.getStreamId(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); // 娣诲姞璁㈤槄 JSONObject subscribeKey = new JSONObject(); subscribeKey.put("app", "rtp"); - subscribeKey.put("stream", streamId); + subscribeKey.put("stream", ssrcInfo.getStreamId()); subscribeKey.put("regist", true); subscribeKey.put("mediaServerId", mediaServerItem.getId()); logger.debug("褰曞儚鍥炴斁娣诲姞璁㈤槄锛岃闃呭唴瀹癸細" + subscribeKey.toString()); subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, - (IMediaServerItem mediaServerItemInUse, JSONObject json)->{ + (MediaServerItem mediaServerItemInUse, JSONObject json)->{ if (userSetup.isWaitTrack() && json.getJSONArray("tracks") == null) return; event.response(mediaServerItemInUse, json); subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey); @@ -609,11 +589,11 @@ if (userSetup.isSeniorSdp()) { if("TCP-PASSIVE".equals(streamMode)) { - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); }else if ("TCP-ACTIVE".equals(streamMode)) { - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 126 125 99 34 98 97\r\n"); }else if("UDP".equals(streamMode)) { - content.append("m=video "+ mediaPort +" RTP/AVP 96 126 125 99 34 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 126 125 99 34 98 97\r\n"); } content.append("a=recvonly\r\n"); content.append("a=rtpmap:96 PS/90000\r\n"); @@ -634,11 +614,11 @@ } }else { if("TCP-PASSIVE".equals(streamMode)) { - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n"); }else if ("TCP-ACTIVE".equals(streamMode)) { - content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" TCP/RTP/AVP 96 98 97\r\n"); }else if("UDP".equals(streamMode)) { - content.append("m=video "+ mediaPort +" RTP/AVP 96 98 97\r\n"); + content.append("m=video "+ ssrcInfo.getPort() +" RTP/AVP 96 98 97\r\n"); } content.append("a=recvonly\r\n"); content.append("a=rtpmap:96 PS/90000\r\n"); @@ -654,7 +634,7 @@ } content.append("a=downloadspeed:" + downloadSpeed + "\r\n"); - content.append("y="+ssrc+"\r\n");//ssrc + content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc String tm = Long.toString(System.currentTimeMillis()); @@ -664,7 +644,7 @@ Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader); ClientTransaction transaction = transmitRequest(device, request, errorEvent); - streamSession.put(device.getDeviceId(), channelId, ssrc, streamId, transaction); + streamSession.put(device.getDeviceId(), channelId, ssrcInfo.getSsrc(), ssrcInfo.getStreamId(), mediaServerItem.getId(), transaction); } catch ( SipException | ParseException | InvalidArgumentException e) { e.printStackTrace(); @@ -684,53 +664,35 @@ */ @Override public void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent) { - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); try { ClientTransaction transaction = streamSession.getTransaction(deviceId, channelId); - // 鏈嶅姟閲嶅惎鍚�, 鏃犳硶鐩存帴鍙戦�乥ye锛� 閫氳繃鎵嬪姩鏋勫缓鍙戦�� -// if (transaction == null) { -// -// if (streamInfo != null) { -// MediaServerItem mediaServerItem = redisCatchStorage.getMediaInfo(streamInfo.getMediaServerId()); -// JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaServerItem,streamInfo.getApp(), streamInfo.getStreamId()); -// if (mediaList != null) { // 浠嶅湪鎺ㄦ祦鎵嶅彂閫� -// if (mediaList.getInteger("code") == 0) { -// JSONArray data = mediaList.getJSONArray("data"); -// if (data != null && data.size() > 0) { -// Device device = storager.queryVideoDevice(deviceId); -// if (device != null) { -// StreamInfo.TransactionInfo transactionInfo = streamInfo.getTransactionInfo(); -// try { -// Request byteRequest = headerProvider.createByteRequest(device, channelId, -// transactionInfo.branch, -// transactionInfo.localTag, -// transactionInfo.remoteTag, -// transactionInfo.callId); -// transmitRequest(device, byteRequest); -// } catch (InvalidArgumentException e) { -// e.printStackTrace(); -// } -// } -// } -// } -// } -// redisCatchStorage.stopPlay(streamInfo); -// } -// -// if (okEvent != null) { -// okEvent.response(null); -// } -// return; -// } if (transaction == null) { logger.warn("[ {} -> {}]鍋滄瑙嗛娴佺殑鏃跺�欏彂鐜颁簨鍔″凡涓㈠け", deviceId, channelId); return; } - Dialog dialog = transaction.getDialog(); + SIPDialog dialog = streamSession.getDialog(deviceId, channelId); if (dialog == null) { logger.warn("[ {} -> {}]鍋滄瑙嗛娴佺殑鏃跺�欏彂鐜板璇濆凡涓㈠け", deviceId, channelId); return; } + SipStack sipStack = udpSipProvider.getSipStack(); + SIPDialog sipDialog = ((SipStackImpl) sipStack).putDialog(dialog); + if (dialog != sipDialog) { + dialog = sipDialog; + }else { + dialog.setSipProvider(udpSipProvider); + try { + Field sipStackField = SIPDialog.class.getDeclaredField("sipStack"); + sipStackField.setAccessible(true); + sipStackField.set(dialog, sipStack); + Field eventListenersField = SIPDialog.class.getDeclaredField("eventListeners"); + eventListenersField.setAccessible(true); + eventListenersField.set(dialog, new HashSet<>()); + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + } + Request byeRequest = dialog.createRequest(Request.BYE); SipURI byeURI = (SipURI) byeRequest.getRequestURI(); SIPRequest request = (SIPRequest)transaction.getRequest(); @@ -752,7 +714,12 @@ dialog.sendRequest(clientTransaction); - streamSession.remove(deviceId, channelId); + SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(deviceId, channelId); + if (ssrcTransaction != null) { + MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId()); + mediaServerService.releaseSsrc(mediaServerItem, ssrcTransaction.getSsrc()); + streamSession.remove(deviceId, channelId); + } } catch (SipException | ParseException e) { e.printStackTrace(); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java index 6f80971..7d9e5f7 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java @@ -13,7 +13,6 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -81,7 +80,7 @@ while (!rtpPushed) { try { if (System.currentTimeMillis() - startTime < 30 * 1000) { - IMediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); if (zlmrtpServerFactory.isStreamReady(mediaInfo, streamInfo.getApp(), streamInfo.getStreamId())) { rtpPushed = true; logger.info("宸茶幏鍙栬澶囨帹娴乕{}/{}]锛屽紑濮嬪悜涓婄骇鎺ㄦ祦[{}:{}]", diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java index 50e8c32..ffa5377 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java @@ -15,7 +15,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -65,7 +64,7 @@ param.put("stream",streamId); param.put("ssrc",sendRtpItem.getSsrc()); logger.info("鍋滄鍚戜笂绾ф帹娴侊細" + streamId); - IMediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); redisCatchStorage.deleteSendRTPServer(platformGbId, channelId); if (zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId) == 0) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java index 7219dbb..1aa0079 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java @@ -11,14 +11,11 @@ import javax.sip.message.Request; import javax.sip.message.Response; -import com.genersoft.iot.vmp.common.StreamInfo; -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor; import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -97,7 +94,7 @@ // 鏌ヨ骞冲彴涓嬫槸鍚︽湁璇ラ�氶亾 DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId); GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId); - IMediaServerItem mediaServerItem = null; + MediaServerItem mediaServerItem = null; // 涓嶆槸閫氶亾鍙兘鏄洿鎾祦 if (channel != null && gbStream == null ) { if (channel.getStatus() == 0) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java index 7368c36..bcc7626 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java @@ -3,14 +3,18 @@ import java.text.ParseException; import javax.sip.*; +import javax.sip.address.Address; import javax.sip.address.SipURI; import javax.sip.header.CSeqHeader; import javax.sip.message.Request; import javax.sip.message.Response; +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import gov.nist.javax.sip.ResponseEventExt; +import gov.nist.javax.sip.stack.SIPDialog; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.genersoft.iot.vmp.conf.SipConfig; @@ -27,6 +31,9 @@ public class InviteResponseProcessor implements ISIPResponseProcessor { private final static Logger logger = LoggerFactory.getLogger(InviteResponseProcessor.class); + + @Autowired + private VideoStreamSessionManager streamSession; /** * 澶勭悊invite鍝嶅簲 @@ -46,7 +53,7 @@ // 涓嬪彂ack if (statusCode == Response.OK) { ResponseEventExt event = (ResponseEventExt)evt; - Dialog dialog = evt.getDialog(); + SIPDialog dialog = (SIPDialog)evt.getDialog(); CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); Request reqAck = dialog.createAck(cseq.getSeqNumber()); SipURI requestURI = (SipURI) reqAck.getRequestURI(); @@ -54,7 +61,12 @@ requestURI.setPort(event.getRemotePort()); reqAck.setRequestURI(requestURI); logger.info("鍚� " + event.getRemoteIpAddress() + ":" + event.getRemotePort() + "鍥炲ack"); + SipURI sipURI = (SipURI)dialog.getRemoteParty().getURI(); + String deviceId = requestURI.getUser(); + String channelId = sipURI.getUser(); + dialog.sendAck(reqAck); + } } catch (InvalidArgumentException | SipException e) { e.printStackTrace(); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index b7aebf4..478772a 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -3,15 +3,14 @@ import java.util.List; import java.util.UUID; -import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.conf.UserSetup; import com.genersoft.iot.vmp.gb28181.bean.Device; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.service.IPlayService; @@ -41,7 +40,6 @@ public class ZLMHttpHookListener { private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookListener.class); - @Autowired private SIPCommander cmder; @@ -125,7 +123,7 @@ String mediaServerId = json.getString("mediaServerId"); ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_play, json); if (subscribe != null ) { - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo != null) { subscribe.response(mediaInfo, json); } @@ -150,7 +148,7 @@ String mediaServerId = json.getString("mediaServerId"); ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, json); if (subscribe != null) { - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo != null) { subscribe.response(mediaInfo, json); } @@ -237,7 +235,7 @@ String mediaServerId = json.getString("mediaServerId"); ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_shell_login, json); if (subscribe != null ) { - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo != null) { subscribe.response(mediaInfo, json); } @@ -264,7 +262,7 @@ String mediaServerId = json.getString("mediaServerId"); ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, json); if (subscribe != null ) { - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo != null) { subscribe.response(mediaInfo, json); } @@ -297,7 +295,7 @@ } }else { if (!"rtp".equals(app) ){ - IMediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); + MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); if (regist) { zlmMediaListManager.addMedia(mediaServerItem, app, streamId); }else { @@ -369,7 +367,7 @@ logger.debug("ZLM HOOK on_stream_not_found API璋冪敤锛屽弬鏁帮細" + json.toString()); } String mediaServerId = json.getString("mediaServerId"); - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); if (userSetup.isAutoApplyPlay() && mediaInfo != null) { String app = json.getString("app"); String streamId = json.getString("stream"); @@ -381,7 +379,13 @@ Device device = storager.queryVideoDevice(deviceId); if (device != null) { UUID uuid = UUID.randomUUID(); - cmder.playStreamCmd(mediaInfo, device, channelId, (IMediaServerItem mediaServerItemInuse, JSONObject response) -> { + SSRCInfo ssrcInfo; + String streamId2 = null; + if (mediaInfo.isRtpEnable()) { + streamId2 = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); + } + ssrcInfo = mediaServerService.openRTPServer(mediaInfo, streamId2); + cmder.playStreamCmd(mediaInfo, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> { logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); playService.onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString()); }, null); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java index 62b18f5..be69df1 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java @@ -1,7 +1,6 @@ package com.genersoft.iot.vmp.media.zlm; import com.alibaba.fastjson.JSONObject; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import org.springframework.stereotype.Component; @@ -32,7 +31,7 @@ } public interface Event{ - void response(IMediaServerItem mediaServerItem, JSONObject response); + void response(MediaServerItem mediaServerItem, JSONObject response); } private Map<HookType, Map<JSONObject, ZLMHttpHookSubscribe.Event>> allSubscribes = new ConcurrentHashMap<>(); @@ -58,6 +57,9 @@ if (result == null) { result = key.getString(s).equals(hookResponse.getString(s)); }else { + if (key.getString(s) == null) { + continue; + } result = result && key.getString(s).equals(hookResponse.getString(s)); } @@ -83,9 +85,9 @@ if (result == null) { result = key.getString(s).equals(hookResponse.getString(s)); }else { + if (key.getString(s) == null) continue; result = result && key.getString(s).equals(hookResponse.getString(s)); } - } if (null != result && result){ iterator.remove(); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java index 3876309..7fc0a08 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java @@ -1,12 +1,9 @@ package com.genersoft.iot.vmp.media.zlm; -import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; -import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; @@ -76,7 +73,7 @@ jsonObject.put("stream", streamPushItem.getStream()); jsonObject.put("mediaServerId", mediaServerItem.getId()); subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_play,jsonObject, - (IMediaServerItem mediaServerItemInuse, JSONObject response)->{ + (MediaServerItem mediaServerItemInuse, JSONObject response)->{ updateMedia(mediaServerItem, response.getString("app"), response.getString("stream")); } ); @@ -86,13 +83,13 @@ } - public void addMedia(IMediaServerItem mediaServerItem, String app, String streamId) { + public void addMedia(MediaServerItem mediaServerItem, String app, String streamId) { //浣跨敤寮傛鏇存柊鎺ㄦ祦 updateMedia(mediaServerItem, app, streamId); } - public void updateMedia(IMediaServerItem mediaServerItem, String app, String streamId) { + public void updateMedia(MediaServerItem mediaServerItem, String app, String streamId) { //浣跨敤寮傛鏇存柊鎺ㄦ祦 zlmresTfulUtils.getMediaList(mediaServerItem, app, streamId, "rtmp", json->{ diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java index 8e12e57..af8793a 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java @@ -2,14 +2,11 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; -import com.genersoft.iot.vmp.conf.MediaConfig; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import okhttp3.*; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.io.*; @@ -27,7 +24,7 @@ void run(JSONObject response); } - public JSONObject sendPost(IMediaServerItem mediaServerItem, String api, Map<String, Object> param, RequestCallback callback) { + public JSONObject sendPost(MediaServerItem mediaServerItem, String api, Map<String, Object> param, RequestCallback callback) { OkHttpClient client = new OkHttpClient(); String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api); JSONObject responseJSON = null; @@ -93,7 +90,7 @@ } - public void sendPostForImg(IMediaServerItem mediaServerItem, String api, Map<String, Object> param, String targetPath, String fileName) { + public void sendPostForImg(MediaServerItem mediaServerItem, String api, Map<String, Object> param, String targetPath, String fileName) { OkHttpClient client = new OkHttpClient(); String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api); JSONObject responseJSON = null; @@ -139,7 +136,7 @@ } - public JSONObject getMediaList(IMediaServerItem mediaServerItem,String app, String stream, String schema, RequestCallback callback){ + public JSONObject getMediaList(MediaServerItem mediaServerItem, String app, String stream, String schema, RequestCallback callback){ Map<String, Object> param = new HashMap<>(); if (app != null) param.put("app",app); if (stream != null) param.put("stream",stream); @@ -148,15 +145,15 @@ return sendPost(mediaServerItem, "getMediaList",param, callback); } - public JSONObject getMediaList(IMediaServerItem mediaServerItem,String app, String stream){ + public JSONObject getMediaList(MediaServerItem mediaServerItem, String app, String stream){ return getMediaList(mediaServerItem, app, stream,null, null); } - public JSONObject getMediaList(IMediaServerItem mediaServerItem,RequestCallback callback){ + public JSONObject getMediaList(MediaServerItem mediaServerItem, RequestCallback callback){ return sendPost(mediaServerItem, "getMediaList",null, callback); } - public JSONObject getMediaInfo(IMediaServerItem mediaServerItem,String app, String schema, String stream){ + public JSONObject getMediaInfo(MediaServerItem mediaServerItem, String app, String schema, String stream){ Map<String, Object> param = new HashMap<>(); param.put("app",app); param.put("schema",schema); @@ -165,13 +162,13 @@ return sendPost(mediaServerItem, "getMediaInfo",param, null); } - public JSONObject getRtpInfo(IMediaServerItem mediaServerItem,String stream_id){ + public JSONObject getRtpInfo(MediaServerItem mediaServerItem, String stream_id){ Map<String, Object> param = new HashMap<>(); param.put("stream_id",stream_id); return sendPost(mediaServerItem, "getRtpInfo",param, null); } - public JSONObject addFFmpegSource(IMediaServerItem mediaServerItem,String src_url, String dst_url, String timeout_ms, + public JSONObject addFFmpegSource(MediaServerItem mediaServerItem, String src_url, String dst_url, String timeout_ms, boolean enable_hls, boolean enable_mp4, String ffmpeg_cmd_key){ logger.info(src_url); logger.info(dst_url); @@ -185,41 +182,41 @@ return sendPost(mediaServerItem, "addFFmpegSource",param, null); } - public JSONObject delFFmpegSource(IMediaServerItem mediaServerItem,String key){ + public JSONObject delFFmpegSource(MediaServerItem mediaServerItem, String key){ Map<String, Object> param = new HashMap<>(); param.put("key", key); return sendPost(mediaServerItem, "delFFmpegSource",param, null); } - public JSONObject getMediaServerConfig(IMediaServerItem mediaServerItem){ + public JSONObject getMediaServerConfig(MediaServerItem mediaServerItem){ return sendPost(mediaServerItem, "getServerConfig",null, null); } - public JSONObject setServerConfig(IMediaServerItem mediaServerItem, Map<String, Object> param){ + public JSONObject setServerConfig(MediaServerItem mediaServerItem, Map<String, Object> param){ return sendPost(mediaServerItem,"setServerConfig",param, null); } - public JSONObject openRtpServer(IMediaServerItem mediaServerItem,Map<String, Object> param){ + public JSONObject openRtpServer(MediaServerItem mediaServerItem, Map<String, Object> param){ return sendPost(mediaServerItem, "openRtpServer",param, null); } - public JSONObject closeRtpServer(IMediaServerItem mediaServerItem,Map<String, Object> param) { + public JSONObject closeRtpServer(MediaServerItem mediaServerItem, Map<String, Object> param) { return sendPost(mediaServerItem, "closeRtpServer",param, null); } - public JSONObject listRtpServer(IMediaServerItem mediaServerItem) { + public JSONObject listRtpServer(MediaServerItem mediaServerItem) { return sendPost(mediaServerItem, "listRtpServer",null, null); } - public JSONObject startSendRtp(IMediaServerItem mediaServerItem,Map<String, Object> param) { + public JSONObject startSendRtp(MediaServerItem mediaServerItem, Map<String, Object> param) { return sendPost(mediaServerItem, "startSendRtp",param, null); } - public JSONObject stopSendRtp(IMediaServerItem mediaServerItem,Map<String, Object> param) { + public JSONObject stopSendRtp(MediaServerItem mediaServerItem, Map<String, Object> param) { return sendPost(mediaServerItem, "stopSendRtp",param, null); } - public JSONObject addStreamProxy(IMediaServerItem mediaServerItem,String app, String stream, String url, boolean enable_hls, boolean enable_mp4, String rtp_type) { + public JSONObject addStreamProxy(MediaServerItem mediaServerItem, String app, String stream, String url, boolean enable_hls, boolean enable_mp4, String rtp_type) { Map<String, Object> param = new HashMap<>(); param.put("vhost", "__defaultVhost__"); param.put("app", app); @@ -231,7 +228,7 @@ return sendPost(mediaServerItem, "addStreamProxy",param, null); } - public JSONObject closeStreams(IMediaServerItem mediaServerItem,String app, String stream) { + public JSONObject closeStreams(MediaServerItem mediaServerItem, String app, String stream) { Map<String, Object> param = new HashMap<>(); param.put("vhost", "__defaultVhost__"); param.put("app", app); @@ -240,17 +237,17 @@ return sendPost(mediaServerItem, "close_streams",param, null); } - public JSONObject getAllSession(IMediaServerItem mediaServerItem) { + public JSONObject getAllSession(MediaServerItem mediaServerItem) { return sendPost(mediaServerItem, "getAllSession",null, null); } - public void kickSessions(IMediaServerItem mediaServerItem, String localPortSStr) { + public void kickSessions(MediaServerItem mediaServerItem, String localPortSStr) { Map<String, Object> param = new HashMap<>(); param.put("local_port", localPortSStr); sendPost(mediaServerItem, "kick_sessions",param, null); } - public void getSnap(IMediaServerItem mediaServerItem, String flvUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) { + public void getSnap(MediaServerItem mediaServerItem, String flvUrl, int timeout_sec, int expire_sec, String targetPath, String fileName) { Map<String, Object> param = new HashMap<>(); param.put("url", flvUrl); param.put("timeout_sec", timeout_sec); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java index 5919c9f..0ddd904 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java @@ -2,10 +2,7 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; -import com.genersoft.iot.vmp.gb28181.session.SsrcUtil; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,28 +18,19 @@ private Logger logger = LoggerFactory.getLogger("ZLMRTPServerFactory"); @Autowired - private MediaConfig mediaConfig; - - @Autowired private ZLMRESTfulUtils zlmresTfulUtils; private int[] portRangeArray = new int[2]; - private int currentPort = 0; - - private Map<String, Integer> currentStreams = null; - - public int createRTPServer(IMediaServerItem mediaServerItem, String streamId) { - if (currentStreams == null) { - currentStreams = new HashMap<>(); - JSONObject jsonObject = zlmresTfulUtils.listRtpServer(mediaServerItem); - if (jsonObject != null) { - JSONArray data = jsonObject.getJSONArray("data"); - if (data != null) { - for (int i = 0; i < data.size(); i++) { - JSONObject dataItem = data.getJSONObject(i); - currentStreams.put(dataItem.getString("stream_id"), dataItem.getInteger("port")); - } + public int createRTPServer(MediaServerItem mediaServerItem, String streamId) { + Map<String, Integer> currentStreams = new HashMap<>(); + JSONObject listRtpServerJsonResult = zlmresTfulUtils.listRtpServer(mediaServerItem); + if (listRtpServerJsonResult != null) { + JSONArray data = listRtpServerJsonResult.getJSONArray("data"); + if (data != null) { + for (int i = 0; i < data.size(); i++) { + JSONObject dataItem = data.getJSONObject(i); + currentStreams.put(dataItem.getString("stream_id"), dataItem.getInteger("port")); } } } @@ -56,18 +44,18 @@ Map<String, Object> param = new HashMap<>(); int result = -1; - int newPort = getPortFromportRange(); + int newPort = getPortFromportRange(mediaServerItem); param.put("port", newPort); param.put("enable_tcp", 1); param.put("stream_id", streamId); - JSONObject jsonObject = zlmresTfulUtils.openRtpServer(mediaServerItem, param); + JSONObject openRtpServerResultJson = zlmresTfulUtils.openRtpServer(mediaServerItem, param); - if (jsonObject != null) { - switch (jsonObject.getInteger("code")){ + if (openRtpServerResultJson != null) { + switch (openRtpServerResultJson.getInteger("code")){ case 0: result= newPort; break; - case -300: // id宸茬粡瀛樺湪, 鍙兘宸茬粡鍦ㄥ叾浠栫鍙f帹娴� + case -300: // id宸茬粡瀛樺湪, 鍙兘宸茬粡鍦ㄥ叾浠栫鍙f帹娴�, TODO 涔熷彲鑳芥槸璁惧涓嶇瓑ack灏辩洿鎺ユ帹娴佷簡, 闇�瑕佹煡璇笌璁剧疆鐨勬帹娴乮p绔彛鏄惁涓�鑷� Map<String, Object> closeRtpServerParam = new HashMap<>(); closeRtpServerParam.put("stream_id", streamId); zlmresTfulUtils.closeRtpServer(mediaServerItem, closeRtpServerParam); @@ -77,7 +65,7 @@ result= createRTPServer(mediaServerItem, streamId); break; default: - logger.error("鍒涘缓RTP Server 澶辫触 {}: " + jsonObject.getString("msg"), newPort); + logger.error("鍒涘缓RTP Server 澶辫触 {}: " + openRtpServerResultJson.getString("msg"), newPort); break; } }else { @@ -87,7 +75,7 @@ return result; } - public boolean closeRTPServer(IMediaServerItem serverItem, String streamId) { + public boolean closeRTPServer(MediaServerItem serverItem, String streamId) { boolean result = false; if (serverItem !=null){ Map<String, Object> param = new HashMap<>(); @@ -107,21 +95,25 @@ return result; } - private int getPortFromportRange() { + private int getPortFromportRange(MediaServerItem mediaServerItem) { + int currentPort = mediaServerItem.getCurrentPort(); if (currentPort == 0) { - String[] portRangeStrArray = mediaConfig.getRtpPortRange().split(","); + String[] portRangeStrArray = mediaServerItem.getRtpPortRange().split(","); portRangeArray[0] = Integer.parseInt(portRangeStrArray[0]); portRangeArray[1] = Integer.parseInt(portRangeStrArray[1]); } if (currentPort == 0 || currentPort++ > portRangeArray[1]) { currentPort = portRangeArray[0]; + mediaServerItem.setCurrentPort(currentPort); return portRangeArray[0]; } else { if (currentPort % 2 == 1) { currentPort++; } - return currentPort++; + currentPort++; + mediaServerItem.setCurrentPort(currentPort); + return currentPort; } } @@ -135,10 +127,14 @@ * @param tcp 鏄惁涓簍cp * @return SendRtpItem */ - public SendRtpItem createSendRtpItem(IMediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp){ - String playSsrc = SsrcUtil.getPlaySsrc(); - int localPort = createRTPServer(serverItem, SsrcUtil.getPlaySsrc()); + public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp){ + + // 浣跨敤RTPServer 鍔熻兘鎵句竴涓彲鐢ㄧ殑绔彛 + String playSsrc = serverItem.getSsrcConfig().getPlaySsrc(); + int localPort = createRTPServer(serverItem, playSsrc); if (localPort != -1) { + // TODO 楂樺苟鍙戞椂鍙兘鍥犱负鏈斁鍏ョ紦瀛樿�宻src鍐茬獊 + serverItem.getSsrcConfig().releaseSsrc(playSsrc); closeRTPServer(serverItem, playSsrc); }else { logger.error("娌℃湁鍙敤鐨勭鍙�"); @@ -168,10 +164,12 @@ * @param tcp 鏄惁涓簍cp * @return SendRtpItem */ - public SendRtpItem createSendRtpItem(IMediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp){ - String playSsrc = SsrcUtil.getPlaySsrc(); - int localPort = createRTPServer(serverItem, SsrcUtil.getPlaySsrc()); + public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp){ + String playSsrc = serverItem.getSsrcConfig().getPlaySsrc(); + int localPort = createRTPServer(serverItem, playSsrc); if (localPort != -1) { + // TODO 楂樺苟鍙戞椂鍙兘鍥犱负鏈斁鍏ョ紦瀛樿�宻src鍐茬獊 + serverItem.getSsrcConfig().releaseSsrc(ssrc); closeRTPServer(serverItem, playSsrc); }else { logger.error("娌℃湁鍙敤鐨勭鍙�"); @@ -194,7 +192,7 @@ /** * 璋冪敤zlm RESTful API 鈥斺�� startSendRtp */ - public Boolean startSendRtpStream(IMediaServerItem mediaServerItem, Map<String, Object>param) { + public Boolean startSendRtpStream(MediaServerItem mediaServerItem, Map<String, Object>param) { Boolean result = false; JSONObject jsonObject = zlmresTfulUtils.startSendRtp(mediaServerItem, param); if (jsonObject == null) { @@ -219,7 +217,7 @@ /** * 鏌ヨ寰呰浆鎺ㄧ殑娴佹槸鍚﹀氨缁� */ - public Boolean isStreamReady(IMediaServerItem mediaServerItem, String app, String streamId) { + public Boolean isStreamReady(MediaServerItem mediaServerItem, String app, String streamId) { JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId); return (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online")); } @@ -229,7 +227,7 @@ * @param streamId * @return */ - public int totalReaderCount(IMediaServerItem mediaServerItem, String app, String streamId) { + public int totalReaderCount(MediaServerItem mediaServerItem, String app, String streamId) { JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId); return mediaInfo.getInteger("totalReaderCount"); } @@ -237,7 +235,7 @@ /** * 璋冪敤zlm RESTful API 鈥斺�� stopSendRtp */ - public Boolean stopSendRtpStream(IMediaServerItem mediaServerItem,Map<String, Object>param) { + public Boolean stopSendRtpStream(MediaServerItem mediaServerItem, Map<String, Object>param) { Boolean result = false; JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(mediaServerItem, param); if (jsonObject == null) { diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java index d06c6c3..67b605c 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java @@ -4,22 +4,16 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.conf.MediaConfig; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; -import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.service.IMediaServerService; -import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.service.IStreamProxyService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; -import javax.print.attribute.standard.Media; import java.util.*; @Component @@ -47,16 +41,26 @@ @Override public void run(String... strings) throws Exception { - IMediaServerItem presetMediaServer = mediaServerService.getOneByHostAndPort( + // 娓呮redis缂撳瓨鐨勫湪绾縵lm淇℃伅 + mediaServerService.clearMediaServerForOnline(); + + // 灏嗛厤缃枃浠剁殑meida閰嶇疆鍐欏叆鏁版嵁搴� + MediaServerItem presetMediaServer = mediaServerService.getOneByHostAndPort( mediaConfig.getIp(), mediaConfig.getHttpPort()); if (presetMediaServer != null) { - mediaConfig.setId(presetMediaServer.getId()); - mediaServerService.update(mediaConfig); + MediaServerItem mediaSerItem = mediaConfig.getMediaSerItem(); + mediaSerItem.setId(presetMediaServer.getId()); + mediaServerService.update(mediaSerItem); + }else { + if (mediaConfig.getId() != null) { + MediaServerItem mediaSerItem = mediaConfig.getMediaSerItem(); + mediaServerService.add(mediaSerItem); + } } // 璁㈤槄 zlm鍚姩浜嬩欢, 鏂扮殑zlm涔熶細浠庤繖閲岃繘鍏ョ郴缁� hookSubscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_server_started,null, - (IMediaServerItem mediaServerItem, JSONObject response)->{ + (MediaServerItem mediaServerItem, JSONObject response)->{ ZLMServerConfig zlmServerConfig = JSONObject.toJavaObject(response, ZLMServerConfig.class); if (zlmServerConfig !=null ) { startGetMedia.remove(zlmServerConfig.getGeneralMediaServerId()); @@ -69,23 +73,25 @@ logger.info("绛夊緟榛樿zlm鎺ュ叆..."); // 鑾峰彇鎵�鏈夌殑zlm锛� 骞跺紑鍚富鍔ㄨ繛鎺� - List<IMediaServerItem> all = mediaServerService.getAll(); + List<MediaServerItem> all = mediaServerService.getAll(); if (presetMediaServer == null) { all.add(mediaConfig.getMediaSerItem()); } - for (IMediaServerItem mediaServerItem : all) { + for (MediaServerItem mediaServerItem : all) { if (startGetMedia == null) startGetMedia = new HashMap<>(); startGetMedia.put(mediaServerItem.getId(), true); new Thread(() -> { ZLMServerConfig zlmServerConfig = getMediaServerConfig(mediaServerItem); if (zlmServerConfig != null) { + zlmServerConfig.setIp(mediaServerItem.getIp()); + zlmServerConfig.setHttpPort(mediaServerItem.getHttpPort()); startGetMedia.remove(mediaServerItem.getId()); mediaServerService.handLeZLMServerConfig(zlmServerConfig); } }).start(); } Timer timer = new Timer(); - // 1鍒嗛挓鍚庢湭杩炴帴鍒板垯涓嶅啀鍘讳富鍔ㄨ繛鎺� + // 2鍒嗛挓鍚庢湭杩炴帴鍒板垯涓嶅啀鍘讳富鍔ㄨ繛鎺�, TODO 骞跺閲嶅惎鍓嶄娇鐢ㄦ鍦▃lm鐨勯�氶亾鍙戦�乥ye timer.schedule(new TimerTask() { @Override public void run() { @@ -100,7 +106,7 @@ }, 60 * 1000 * 2); } - public ZLMServerConfig getMediaServerConfig(IMediaServerItem mediaServerItem) { + public ZLMServerConfig getMediaServerConfig(MediaServerItem mediaServerItem) { if ( startGetMedia.get(mediaServerItem.getId()) == null || !startGetMedia.get(mediaServerItem.getId())) return null; JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); ZLMServerConfig ZLMServerConfig = null; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/IMediaServerItem.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/IMediaServerItem.java deleted file mode 100644 index 6497162..0000000 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/IMediaServerItem.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.genersoft.iot.vmp.media.zlm.dto; - -public interface IMediaServerItem { - - String getId(); - - void setId(String id); - - String getIp(); - - void setIp(String ip); - - String getHookIp(); - - void setHookIp(String hookIp); - - String getSdpIp(); - - void setSdpIp(String sdpIp); - - String getStreamIp(); - - void setStreamIp(String streamIp); - - int getHttpPort(); - - void setHttpPort(int httpPort); - - int getHttpSSlPort(); - - void setHttpSSlPort(int httpSSlPort); - - int getRtmpPort(); - - void setRtmpPort(int rtmpPort); - - int getRtmpSSlPort(); - - void setRtmpSSlPort(int rtmpSSlPort); - - int getRtpProxyPort(); - - void setRtpProxyPort(int rtpProxyPort); - - int getRtspPort(); - - void setRtspPort(int rtspPort); - - int getRtspSSLPort(); - - void setRtspSSLPort(int rtspSSLPort); - - boolean isAutoConfig(); - - void setAutoConfig(boolean autoConfig); - - String getSecret(); - - void setSecret(String secret); - - String getStreamNoneReaderDelayMS(); - - void setStreamNoneReaderDelayMS(String streamNoneReaderDelayMS); - - boolean isRtpEnable(); - - void setRtpEnable(boolean rtpEnable); - - String getRtpPortRange(); - - void setRtpPortRange(String rtpPortRange); - - int getRecordAssistPort(); - - void setRecordAssistPort(int recordAssistPort); - - boolean isDocker(); - - void setDocker(boolean docker); - - String getUpdateTime(); - - void setUpdateTime(String updateTime); - - String getCreateTime(); - - void setCreateTime(String createTime); - - int getCount(); - - void setCount(int count); -} diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java index b56881f..d1578d1 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java @@ -1,10 +1,13 @@ package com.genersoft.iot.vmp.media.zlm.dto; +import com.genersoft.iot.vmp.gb28181.session.SsrcConfig; import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; import org.springframework.util.StringUtils; -public class MediaServerItem implements IMediaServerItem{ +import java.util.HashMap; + +public class MediaServerItem{ private String id; @@ -46,9 +49,18 @@ private String updateTime; - private boolean docker; + private boolean defaultServer; - private int count; + private SsrcConfig ssrcConfig; + + private int currentPort; + + + /** + * 姣忎竴鍙癦LM閮芥湁涓�濂楃嫭绔嬬殑SSRC鍒楄〃 + * 鍦ˋpplicationCheckRunner閲屽mediaServerSsrcMap杩涜鍒濆鍖� + */ + private HashMap<String, SsrcConfig> mediaServerSsrcMap; public MediaServerItem() { } @@ -218,14 +230,12 @@ this.recordAssistPort = recordAssistPort; } - @Override - public boolean isDocker() { - return docker; + public boolean isDefaultServer() { + return defaultServer; } - @Override - public void setDocker(boolean docker) { - this.docker = docker; + public void setDefaultServer(boolean defaultServer) { + this.defaultServer = defaultServer; } public String getCreateTime() { @@ -244,11 +254,29 @@ this.updateTime = updateTime; } - public int getCount() { - return count; + public HashMap<String, SsrcConfig> getMediaServerSsrcMap() { + return mediaServerSsrcMap; } - public void setCount(int count) { - this.count = count; + public void setMediaServerSsrcMap(HashMap<String, SsrcConfig> mediaServerSsrcMap) { + this.mediaServerSsrcMap = mediaServerSsrcMap; } + + public SsrcConfig getSsrcConfig() { + return ssrcConfig; + } + + public void setSsrcConfig(SsrcConfig ssrcConfig) { + this.ssrcConfig = ssrcConfig; + } + + public int getCurrentPort() { + return currentPort; + } + + public void setCurrentPort(int currentPort) { + this.currentPort = currentPort; + } + + } diff --git a/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java index 7a57bed..be9959a 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java @@ -3,8 +3,8 @@ import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.service.bean.SSRCInfo; import java.util.List; @@ -13,11 +13,13 @@ */ public interface IMediaServerService { - List<IMediaServerItem> getAll(); + List<MediaServerItem> getAll(); - IMediaServerItem getOne(String generalMediaServerId); + List<MediaServerItem> getAllOnline(); - IMediaServerItem getOneByHostAndPort(String host, int port); + MediaServerItem getOne(String generalMediaServerId); + + MediaServerItem getOneByHostAndPort(String host, int port); /** * 鏂扮殑鑺傜偣鍔犲叆 @@ -26,19 +28,27 @@ */ void handLeZLMServerConfig(ZLMServerConfig zlmServerConfig); - void updateServerCatch(IMediaServerItem mediaServerItem, Integer count, Boolean b); + MediaServerItem getMediaServerForMinimumLoad(); - IMediaServerItem getMediaServerForMinimumLoad(); + void setZLMConfig(MediaServerItem mediaServerItem); - void setZLMConfig(IMediaServerItem mediaServerItem); - - void init(); + SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId); void closeRTPServer(Device device, String channelId); - void update(MediaConfig mediaConfig); + void clearRTPServer(MediaServerItem mediaServerItem); + + void update(MediaServerItem mediaSerItem); void addCount(String mediaServerId); void removeCount(String mediaServerId); + + void releaseSsrc(MediaServerItem mediaServerItem, String ssrc); + + void clearMediaServerForOnline(); + + void add(MediaServerItem mediaSerItem); + + void resetOnlineServerItem(MediaServerItem serverItem); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java index 868a831..54f8315 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java @@ -2,7 +2,6 @@ import com.alibaba.fastjson.JSONArray; import com.genersoft.iot.vmp.common.StreamInfo; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; /** @@ -33,7 +32,7 @@ * @param stream * @return */ - StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaServerItem, String app, String stream, JSONArray tracks); + StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaServerItem, String app, String stream, JSONArray tracks); /** * 鏍规嵁搴旂敤鍚嶅拰娴両D鑾峰彇鎾斁鍦板潃, 鍙槸鍦板潃鎷兼帴锛岃繑鍥炵殑ip浣跨敤杩滅▼璁块棶ip锛岄�傜敤涓巣lm涓巜vp鍦ㄤ竴鍙颁富鏈虹殑鎯呭喌 @@ -41,5 +40,5 @@ * @param stream * @return */ - StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaInfo, String app, String stream, JSONArray tracks, String addr); + StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, JSONArray tracks, String addr); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java b/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java index fdc86d6..9e5c444 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java @@ -4,7 +4,6 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; @@ -13,10 +12,10 @@ */ public interface IPlayService { - void onPublishHandlerForPlayBack(IMediaServerItem mediaServerItem,JSONObject resonse, String deviceId, String channelId, String uuid); - void onPublishHandlerForPlay(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid); + void onPublishHandlerForPlayBack(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid); + void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid); - PlayResult play(IMediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); + PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); - IMediaServerItem getNewMediaServerItem(Device device); + MediaServerItem getNewMediaServerItem(Device device); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java b/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java index fa79d69..12e4898 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java @@ -1,7 +1,6 @@ package com.genersoft.iot.vmp.service; import com.alibaba.fastjson.JSONObject; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.github.pagehelper.PageInfo; @@ -63,5 +62,5 @@ * 鑾峰彇ffmpeg.cmd妯℃澘 * @return */ - JSONObject getFFmpegCMDs(IMediaServerItem mediaServerItem); + JSONObject getFFmpegCMDs(MediaServerItem mediaServerItem); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java b/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java index eaf2490..899da98 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java @@ -1,7 +1,7 @@ package com.genersoft.iot.vmp.service; import com.genersoft.iot.vmp.gb28181.bean.GbStream; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.github.pagehelper.PageInfo; @@ -9,7 +9,7 @@ public interface IStreamPushService { - List<StreamPushItem> handleJSON(String json, IMediaServerItem mediaServerItem); + List<StreamPushItem> handleJSON(String json, MediaServerItem mediaServerItem); /** * 灏嗗簲鐢ㄥ悕鍜屾祦ID鍔犲叆鍥芥爣鍏宠仈 diff --git a/src/main/java/com/genersoft/iot/vmp/service/bean/SSRCInfo.java b/src/main/java/com/genersoft/iot/vmp/service/bean/SSRCInfo.java new file mode 100644 index 0000000..faab1c8 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/service/bean/SSRCInfo.java @@ -0,0 +1,38 @@ +package com.genersoft.iot.vmp.service.bean; + +public class SSRCInfo { + + private int port; + private String ssrc; + private String StreamId; + + public SSRCInfo(int port, String ssrc, String streamId) { + this.port = port; + this.ssrc = ssrc; + StreamId = streamId; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getSsrc() { + return ssrc; + } + + public void setSsrc(String ssrc) { + this.ssrc = ssrc; + } + + public String getStreamId() { + return StreamId; + } + + public void setStreamId(String streamId) { + StreamId = streamId; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java index 52c9f85..3d66665 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java @@ -1,29 +1,32 @@ package com.genersoft.iot.vmp.service.impl; -import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.genersoft.iot.vmp.common.StreamInfo; +import com.genersoft.iot.vmp.common.VideoManagerConstants; import com.genersoft.iot.vmp.conf.MediaConfig; -import com.genersoft.iot.vmp.conf.ProxyServletConfig; +import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.gb28181.session.SsrcConfig; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; -import com.genersoft.iot.vmp.media.zlm.dto.ZLMRunInfo; import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.dao.MediaServerMapper; -import org.mitre.dsmiley.httpproxy.ProxyServlet; +import com.genersoft.iot.vmp.utils.redis.JedisUtil; +import com.genersoft.iot.vmp.utils.redis.RedisUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.CommandLineRunner; +import org.springframework.core.annotation.Order; import org.springframework.stereotype.Service; +import java.sql.Array; import java.text.SimpleDateFormat; import java.util.*; @@ -31,15 +34,13 @@ * 濯掍綋鏈嶅姟鍣ㄨ妭鐐圭鐞� */ @Service -public class MediaServerServiceImpl implements IMediaServerService { +@Order(value=2) +public class MediaServerServiceImpl implements IMediaServerService, CommandLineRunner { private final static Logger logger = LoggerFactory.getLogger(MediaServerServiceImpl.class); - private Map<String, IMediaServerItem> zlmServers = new HashMap<>(); // 鎵�鏈夋暟鎹簱鐨剒lm鐨勭紦瀛� - private Map<String, Integer> zlmServerStatus = new LinkedHashMap<>(); // 鎵�鏈変笂绾跨殑zlm鐨勭紦瀛樹互鍙婅礋杞� - - @Value("${sip.ip}") - private String sipIp; + @Autowired + private SipConfig sipConfig; @Value("${server.ssl.enabled:false}") private boolean sslEnabled; @@ -56,7 +57,6 @@ @Autowired private MediaServerMapper mediaServerMapper; - @Autowired private IRedisCatchStorage redisCatchStorage; @@ -66,53 +66,134 @@ @Autowired private ZLMRTPServerFactory zlmrtpServerFactory; - private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + @Autowired + private RedisUtil redisUtil; + + @Autowired + JedisUtil jedisUtil; + + private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); /** * 鍒濆鍖� */ @Override - public void init() { - zlmServers.clear(); - zlmServerStatus.clear(); + public void run(String... args) throws Exception { + logger.info("Media Server 缂撳瓨鍒濆鍖�"); List<MediaServerItem> mediaServerItemList = mediaServerMapper.queryAll(); - for (IMediaServerItem mediaServerItem : mediaServerItemList) { - zlmServers.put(mediaServerItem.getId(), mediaServerItem); + for (MediaServerItem mediaServerItem : mediaServerItemList) { + // 鏇存柊 + if (mediaServerItem.getSsrcConfig() == null) { + SsrcConfig ssrcConfig = new SsrcConfig(mediaServerItem.getId(), null, sipConfig.getSipDomain()); + mediaServerItem.setSsrcConfig(ssrcConfig); + redisUtil.set(VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerItem.getId(), mediaServerItem); + } + // 鏌ヨredis鏄惁瀛樺湪姝ediaServer + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerItem.getId(); + if (!redisUtil.hasKey(key)) { + redisUtil.set(key, mediaServerItem); + } + } + } + + @Override + public SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId) { + if (mediaServerItem == null || mediaServerItem.getId() == null) return null; + // 鑾峰彇mediaServer鍙敤鐨剆src + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerItem.getId(); + + SsrcConfig ssrcConfig = mediaServerItem.getSsrcConfig(); + if (ssrcConfig == null) { + logger.info("media server [ {} ] ssrcConfig is null", mediaServerItem.getId()); + return null; + }else { + String ssrc = ssrcConfig.getPlaySsrc(); + if (streamId == null) streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); + int rtpServerPort = mediaServerItem.getRtpProxyPort(); + if (mediaServerItem.isRtpEnable()) { + rtpServerPort = zlmrtpServerFactory.createRTPServer(mediaServerItem, streamId); + } + redisUtil.set(key, mediaServerItem); + return new SSRCInfo(rtpServerPort, ssrc, streamId); } } @Override public void closeRTPServer(Device device, String channelId) { - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId); - IMediaServerItem mediaServerItem = null; - if (streamInfo != null) { - mediaServerItem = this.getOne (streamInfo.getMediaServerId()); + String mediaServerId = streamSession.getMediaServerId(device.getDeviceId(), channelId); + MediaServerItem mediaServerItem = this.getOne(mediaServerId); + if (mediaServerItem != null) { + String streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); + zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId); + releaseSsrc(mediaServerItem, streamSession.getSSRC(device.getDeviceId(), channelId)); } - String streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); - zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId); streamSession.remove(device.getDeviceId(), channelId); } @Override - public void update(MediaConfig mediaConfig) { + public void releaseSsrc(MediaServerItem mediaServerItem, String ssrc) { + if (mediaServerItem == null || ssrc == null) return; + SsrcConfig ssrcConfig = mediaServerItem.getSsrcConfig(); + ssrcConfig.releaseSsrc(ssrc); + mediaServerItem.setSsrcConfig(ssrcConfig); + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerItem.getId(); + redisUtil.set(key, mediaServerItem); + } + /** + * zlm 閲嶅惎鍚庨噸缃粬鐨勬帹娴佷俊鎭紝 TODO 缁欐鍦ㄤ娇鐢ㄧ殑璁惧鍙戦�佸仠姝㈠懡浠� + * @param mediaServerItem + */ + @Override + public void clearRTPServer(MediaServerItem mediaServerItem) { + mediaServerItem.setSsrcConfig(new SsrcConfig(mediaServerItem.getId(), null, sipConfig.getSipDomain())); + redisUtil.zAdd(VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX, mediaServerItem.getId(), 0); + } + + + @Override + public void update(MediaServerItem mediaSerItem) { + mediaServerMapper.update(mediaSerItem); + MediaServerItem mediaServerItemInRedis = getOne(mediaSerItem.getId()); + MediaServerItem mediaServerItemInDataBase = mediaServerMapper.queryOne(mediaSerItem.getId()); + if (mediaServerItemInRedis != null && mediaServerItemInRedis.getSsrcConfig() != null) { + mediaServerItemInDataBase.setSsrcConfig(mediaServerItemInRedis.getSsrcConfig()); + }else { + mediaServerItemInDataBase.setSsrcConfig( + new SsrcConfig( + mediaServerItemInDataBase.getId(), + null, + sipConfig.getSipDomain() + ) + ); + } + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerItemInDataBase.getId(); + redisUtil.set(key, mediaServerItemInDataBase); } @Override - public List<IMediaServerItem> getAll() { - if (zlmServers.size() == 0) { - init(); - } - List<IMediaServerItem> result = new ArrayList<>(); - for (String id : zlmServers.keySet()) { - IMediaServerItem mediaServerItem = zlmServers.get(id); - mediaServerItem.setCount(zlmServerStatus.get(id) == null ? 0 : zlmServerStatus.get(id)); - result.add(mediaServerItem); + public List<MediaServerItem> getAll() { + List<MediaServerItem> result = new ArrayList<>(); + List<Object> mediaServerKeys = redisUtil.scan(String.format("%S*", VideoManagerConstants.MEDIA_SERVER_PREFIX)); + for (int i = 0; i < mediaServerKeys.size(); i++) { + String key = (String) mediaServerKeys.get(i); + result.add((MediaServerItem)redisUtil.get(key)); } return result; + } - -// return mediaServerMapper.queryAll(); + @Override + public List<MediaServerItem> getAllOnline() { + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX; + Set<String> mediaServerIdSet = redisUtil.zRevRange(key, 0, -1); + List<MediaServerItem> result = new ArrayList<>(); + if (mediaServerIdSet != null && mediaServerIdSet.size() > 0) { + for (String mediaServerId : mediaServerIdSet) { + String serverKey = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerId; + result.add((MediaServerItem) redisUtil.get(serverKey)); + } + } + return result; } /** @@ -121,24 +202,26 @@ * @return MediaServerItem */ @Override - public IMediaServerItem getOne(String mediaServerId) { - if (mediaServerId ==null) return null; - IMediaServerItem mediaServerItem = zlmServers.get(mediaServerId); - if (mediaServerItem != null) { - mediaServerItem.setCount(zlmServerStatus.get(mediaServerId) == null ? 0 : zlmServerStatus.get(mediaServerId)); - return mediaServerItem; - }else { - IMediaServerItem item = mediaServerMapper.queryOne(mediaServerId); - if (item != null) { - zlmServers.put(item.getId(), item); - } - return item; - } + public MediaServerItem getOne(String mediaServerId) { + if (mediaServerId == null) return null; + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + mediaServerId; + return (MediaServerItem)redisUtil.get(key); } @Override - public IMediaServerItem getOneByHostAndPort(String host, int port) { + public MediaServerItem getOneByHostAndPort(String host, int port) { return mediaServerMapper.queryOneByHostAndPort(host, port); + } + + @Override + public void clearMediaServerForOnline() { + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX; + redisUtil.del(key); + } + + @Override + public void add(MediaServerItem mediaSerItem) { + mediaServerMapper.add(mediaSerItem); } /** @@ -150,111 +233,100 @@ logger.info("[ {} ]-[ {}:{} ]宸茶繛鎺�", zlmServerConfig.getGeneralMediaServerId(), zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); - IMediaServerItem serverItem = getOne(zlmServerConfig.getGeneralMediaServerId()); - String now = this.format.format(new Date(System.currentTimeMillis())); - if (serverItem != null) { - serverItem.setSecret(zlmServerConfig.getApiSecret()); - serverItem.setIp(zlmServerConfig.getIp()); + MediaServerItem serverItem = mediaServerMapper.queryOne(zlmServerConfig.getGeneralMediaServerId()); + if (serverItem == null) { + serverItem = mediaServerMapper.queryOneByHostAndPort(zlmServerConfig.getIp(), zlmServerConfig.getHttpPort()); + } + if (zlmServerConfig.getGeneralMediaServerId().equals(mediaConfig.getId()) + || (zlmServerConfig.getIp().equals(mediaConfig.getIp()) && zlmServerConfig.getHttpPort() == mediaConfig.getHttpPort())) { + // 閰嶇疆鏂囦欢鐨剒lm // 濡傛灉鏄厤缃枃浠朵腑鐨剒lm銆� 涔熷氨鏄粯璁lm銆� 涓�鍒囦互閰嶇疆鏂囦欢鍐呭涓哄噯 - // docker閮ㄧ讲涓嶄細浣跨敤zlm閰嶇疆鐨勭鍙e彿; - // 鐩存帴缂栬瘧閮ㄧ讲鐨勪娇鐢ㄩ厤缃枃浠剁殑绔彛鍙凤紝濡傛灉zlm淇敼閰嶆敼浜嗛厤缃紝wvp鑷姩淇敼 + // docker閮ㄧ讲涓嶄細浣跨敤zlm閰嶇疆鐨勭鍙e彿涓嶆槸榛樿鐨勫垯涓嶅仛鏇存柊锛� 閰嶇疆淇敼闇�瑕佽嚜琛屼慨鏀箂erver閰嶇疆; + MediaServerItem serverItemFromConfig = mediaConfig.getMediaSerItem(); + serverItemFromConfig.setId(zlmServerConfig.getGeneralMediaServerId()); + if (mediaConfig.getHttpPort() == 0) serverItemFromConfig.setHttpPort(zlmServerConfig.getHttpPort()); + if (mediaConfig.getHttpSSlPort() == 0) serverItemFromConfig.setHttpSSlPort(zlmServerConfig.getHttpSSLport()); + if (mediaConfig.getRtmpPort() == 0) serverItemFromConfig.setRtmpPort(zlmServerConfig.getRtmpPort()); + if (mediaConfig.getRtmpSSlPort() == 0) serverItemFromConfig.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); + if (mediaConfig.getRtspPort() == 0) serverItemFromConfig.setRtspPort(zlmServerConfig.getRtspPort()); + if (mediaConfig.getRtspSSLPort() == 0) serverItemFromConfig.setRtspSSLPort(zlmServerConfig.getRtspSSlport()); + if (mediaConfig.getRtpProxyPort() == 0) serverItemFromConfig.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); + if (serverItem != null){ + // 鍙兘鏄悓涓�涓獄lm浣唅d鍙戠敓浜嗗彉鍖� + if (!serverItem.getId().equals(zlmServerConfig.getGeneralMediaServerId())) { + mediaServerMapper.delOne(serverItem.getId()); + redisUtil.del(VideoManagerConstants.MEDIA_SERVER_PREFIX + serverItem.getId()); - if (serverItem.getId().equals(mediaConfig.getId()) - || (serverItem.getIp().equals(mediaConfig.getIp()) && serverItem.getHttpPort() == mediaConfig.getHttpPort())) { - // 閰嶇疆鏂囦欢鐨剒lm - mediaConfig.setId(zlmServerConfig.getGeneralMediaServerId()); - mediaConfig.setUpdateTime(now); - if (mediaConfig.getHttpPort() == 0) mediaConfig.setHttpPort(zlmServerConfig.getHttpPort()); - if (mediaConfig.getHttpSSlPort() == 0) mediaConfig.setHttpSSlPort(zlmServerConfig.getHttpSSLport()); - if (mediaConfig.getRtmpPort() == 0) mediaConfig.setRtmpPort(zlmServerConfig.getRtmpPort()); - if (mediaConfig.getRtmpSSlPort() == 0) mediaConfig.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); - if (mediaConfig.getRtspPort() == 0) mediaConfig.setRtspPort(zlmServerConfig.getRtspPort()); - if (mediaConfig.getRtspSSLPort() == 0) mediaConfig.setRtspSSLPort(zlmServerConfig.getRtspSSlport()); - if (mediaConfig.getRtpProxyPort() == 0) mediaConfig.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); - mediaServerMapper.update(mediaConfig); - serverItem = mediaConfig.getMediaSerItem(); - setZLMConfig(mediaConfig); - }else { - if (!serverItem.isDocker()) { - serverItem.setHttpPort(zlmServerConfig.getHttpPort()); - serverItem.setHttpSSlPort(zlmServerConfig.getHttpSSLport()); - serverItem.setRtmpPort(zlmServerConfig.getRtmpPort()); - serverItem.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); - serverItem.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); - serverItem.setRtspPort(zlmServerConfig.getRtspPort()); - + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + serverItemFromConfig.getId(); + serverItemFromConfig.setSsrcConfig(new SsrcConfig(serverItemFromConfig.getId(), null, sipConfig.getSipDomain())); + redisUtil.set(key, serverItemFromConfig); + mediaServerMapper.add(serverItemFromConfig); + }else { + mediaServerMapper.update(serverItemFromConfig); } - serverItem.setUpdateTime(now); - mediaServerMapper.update(serverItem); + }else { + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + serverItemFromConfig.getId(); + serverItemFromConfig.setSsrcConfig(new SsrcConfig(serverItemFromConfig.getId(), null, sipConfig.getSipDomain())); + redisUtil.set(key, serverItemFromConfig); + mediaServerMapper.add(serverItemFromConfig); + } + resetOnlineServerItem(serverItemFromConfig); + setZLMConfig(serverItemFromConfig); + }else { + String now = this.format.format(new Date(System.currentTimeMillis())); + if (serverItem == null){ + // 涓�涓柊鐨剒lm鎺ュ叆wvp + serverItem = new MediaServerItem(zlmServerConfig, sipConfig.getSipIp()); + serverItem.setCreateTime(now); + serverItem.setUpdateTime(now); + String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + serverItem.getId(); + serverItem.setSsrcConfig(new SsrcConfig(serverItem.getId(), null, sipConfig.getSipDomain())); + redisUtil.set(key, serverItem); + // 瀛樺叆鏁版嵁搴� + mediaServerMapper.add(serverItem); setZLMConfig(serverItem); } - }else { - if (zlmServerConfig.getGeneralMediaServerId().equals(mediaConfig.getId()) - || (zlmServerConfig.getIp().equals(mediaConfig.getIp()) && zlmServerConfig.getHttpPort() == mediaConfig.getHttpPort())) { - mediaConfig.setId(zlmServerConfig.getGeneralMediaServerId()); - mediaConfig.setCreateTime(now); - mediaConfig.setUpdateTime(now); - serverItem = mediaConfig.getMediaSerItem(); - mediaServerMapper.add(mediaConfig); - }else { - // 涓�涓柊鐨剒lm鎺ュ叆wvp - serverItem = new MediaServerItem(zlmServerConfig, sipIp); - serverItem.setCreateTime(now); - serverItem.setUpdateTime(now); - mediaServerMapper.add(serverItem); - } + resetOnlineServerItem(serverItem); } - // 鏇存柊缂撳瓨 - if (zlmServerStatus.get(serverItem.getId()) == null) { - zlmServers.put(serverItem.getId(), serverItem); - zlmServerStatus.put(serverItem.getId(),0); - } - // 鏌ヨ鏈嶅姟娴佹暟閲� - IMediaServerItem finalServerItem = serverItem; - zlmresTfulUtils.getMediaList(serverItem, null, null, "rtmp",(mediaList ->{ - Integer code = mediaList.getInteger("code"); - if (code == 0) { - JSONArray data = mediaList.getJSONArray("data"); - if (data != null) { - zlmServerStatus.put(finalServerItem.getId(),data.size()); - }else { - zlmServerStatus.put(finalServerItem.getId(),0); - } - - } - })); - } - /** - * 鏇存柊缂撳瓨 - * @param mediaServerItem zlm鏈嶅姟 - * @param count 鍦ㄧ嚎鏁� - * @param online 鍦ㄧ嚎鐘舵�� - */ @Override - public void updateServerCatch(IMediaServerItem mediaServerItem, Integer count, Boolean online) { - if (mediaServerItem != null) { - zlmServers.put(mediaServerItem.getId(), mediaServerItem); - Collection<Integer> values = zlmServerStatus.values(); - if (online != null && count != null) { - zlmServerStatus.put(mediaServerItem.getId(), count); - } + public void resetOnlineServerItem(MediaServerItem serverItem) { + // 鏇存柊缂撳瓨 + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX; + // 浣跨敤zset鐨勫垎鏁颁綔涓哄綋鍓嶅苟鍙戦噺锛� 榛樿鍊艰缃负0 + if (redisUtil.zScore(key, serverItem.getId()) == null) { // 涓嶅瓨鍦ㄥ垯璁剧疆榛樿鍊� 宸插瓨鍦ㄥ垯閲嶇疆 + redisUtil.zAdd(key, serverItem.getId(), 0L); + // 鏌ヨ鏈嶅姟娴佹暟閲� + zlmresTfulUtils.getMediaList(serverItem, null, null, "rtmp",(mediaList ->{ + Integer code = mediaList.getInteger("code"); + if (code == 0) { + JSONArray data = mediaList.getJSONArray("data"); + if (data != null) { + redisUtil.zAdd(key, serverItem.getId(), data.size()); + } + } + })); + }else { + clearRTPServer(serverItem); } + } + @Override public void addCount(String mediaServerId) { - if (zlmServerStatus.get(mediaServerId) != null) { - zlmServerStatus.put(mediaServerId, zlmServerStatus.get(mediaServerId) + 1); - } + if (mediaServerId == null) return; + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX; + Double aDouble = redisUtil.zScore(key, mediaServerId); + redisUtil.zIncrScore(key, mediaServerId, 1); + } @Override public void removeCount(String mediaServerId) { - if (zlmServerStatus.get(mediaServerId) != null) { - zlmServerStatus.put(mediaServerId, zlmServerStatus.get(mediaServerId) - 1); - } + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX; + redisUtil.zIncrScore(key, mediaServerId, - 1); } /** @@ -262,35 +334,18 @@ * @return MediaServerItem */ @Override - public IMediaServerItem getMediaServerForMinimumLoad() { - int mediaCount = -1; - String key = null; - System.out.println(JSON.toJSONString(zlmServerStatus)); - if (zlmServerStatus.size() == 1) { - Map.Entry entry = zlmServerStatus.entrySet().iterator().next(); - key= (String) entry.getKey(); - }else { - for (String id : zlmServerStatus.keySet()) { - if (key == null) { - key = id; - mediaCount = zlmServerStatus.get(id); - } - if (zlmServerStatus.get(id) == 0) { - key = id; - break; - }else if (mediaCount >= zlmServerStatus.get(id)){ - mediaCount = zlmServerStatus.get(id); - key = id; - } - } + public MediaServerItem getMediaServerForMinimumLoad() { + String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX; + + if (redisUtil.zSize(key) == null || redisUtil.zSize(key) == 0) { + logger.info("鑾峰彇璐熻浇鏈�浣庣殑鑺傜偣鏃舵棤鍦ㄧ嚎鑺傜偣"); } - if (key == null) { - logger.info("鑾峰彇璐熻浇鏈�浣庣殑鑺傜偣鏃舵棤鍦ㄧ嚎鑺傜偣"); - return null; - }else{ - return zlmServers.get(key); - } + // 鑾峰彇鍒嗘暟鏈�浣庣殑锛屽強骞跺彂鏈�浣庣殑 + Set<Object> objects = redisUtil.ZRange(key, 0, -1); + ArrayList<Object> MediaServerObjectS = new ArrayList<>(objects); + String mediaServerId = (String)MediaServerObjectS.get(0); + return getOne(mediaServerId); } /** @@ -298,7 +353,7 @@ * @param mediaServerItem 鏈嶅姟ID */ @Override - public void setZLMConfig(IMediaServerItem mediaServerItem) { + public void setZLMConfig(MediaServerItem mediaServerItem) { logger.info("[ {} ]-[ {}:{} ]璁剧疆zlm", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); String protocol = sslEnabled ? "https" : "http"; @@ -333,8 +388,10 @@ logger.info("[ {} ]-[ {}:{} ]璁剧疆zlm鎴愬姛", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); }else { - logger.info("[ {} ]-[ {}:{} ]璁剧疆zlm澶辫触" + responseJSON.getString("msg"), + logger.info("[ {} ]-[ {}:{} ]璁剧疆zlm澶辫触", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); } } + + } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index 465ca88..fb95861 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -4,9 +4,7 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.common.StreamInfo; -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -33,14 +31,14 @@ @Override - public StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaInfo, String app, String stream, JSONArray tracks) { + public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, JSONArray tracks) { return getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, null); } @Override public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, String addr) { StreamInfo streamInfo = null; - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo == null) { return streamInfo; } @@ -63,7 +61,7 @@ } @Override - public StreamInfo getStreamInfoByAppAndStream(IMediaServerItem mediaInfo, String app, String stream, JSONArray tracks, String addr) { + public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, JSONArray tracks, String addr) { StreamInfo streamInfoResult = new StreamInfo(); streamInfoResult.setStreamId(stream); streamInfoResult.setApp(app); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 85a4f48..c21f599 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -14,11 +14,12 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; +import com.genersoft.iot.vmp.utils.redis.RedisUtil; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; import com.genersoft.iot.vmp.service.IMediaService; @@ -54,6 +55,9 @@ private IRedisCatchStorage redisCatchStorage; @Autowired + private RedisUtil redis; + + @Autowired private DeferredResultHolder resultHolder; @Autowired @@ -73,7 +77,7 @@ @Override - public PlayResult play(IMediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent) { + public PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent) { PlayResult playResult = new PlayResult(); if (mediaServerItem == null) { RequestMessage msg = new RequestMessage(); @@ -97,14 +101,21 @@ // 瓒呮椂澶勭悊 result.onTimeout(()->{ logger.warn(String.format("璁惧鐐规挱瓒呮椂锛宒eviceId锛�%s 锛宑hannelId锛�%s", deviceId, channelId)); - // 閲婃斁rtpserver - mediaServerService.closeRTPServer(playResult.getDevice(), channelId); RequestMessage msg = new RequestMessage(); msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + playResult.getUuid()); WVPResult wvpResult = new WVPResult(); wvpResult.setCode(-1); - wvpResult.setMsg("Timeout"); + SIPDialog dialog = streamSession.getDialog(deviceId, channelId); + if (dialog != null) { + wvpResult.setMsg("鏀舵祦瓒呮椂锛岃绋嶅�欓噸璇�"); + }else { + wvpResult.setMsg("鐐规挱瓒呮椂锛岃绋嶅�欓噸璇�"); + } msg.setData(wvpResult); + // 鐐规挱瓒呮椂鍥炲BYE + cmder.streamByeCmd(device.getDeviceId(), channelId); + // 閲婃斁rtpserver + mediaServerService.closeRTPServer(playResult.getDevice(), channelId); resultHolder.invokeResult(msg); }); result.onCompletion(()->{ @@ -131,7 +142,7 @@ WVPResult wvpResult = (WVPResult)responseEntity.getBody(); if (wvpResult.getCode() == 0) { StreamInfo streamInfoForSuccess = (StreamInfo)wvpResult.getData(); - IMediaServerItem mediaInfo = mediaServerService.getOne(streamInfoForSuccess.getMediaServerId()); + MediaServerItem mediaInfo = mediaServerService.getOne(streamInfoForSuccess.getMediaServerId()); String streamUrl = streamInfoForSuccess.getFmp4(); // 璇锋眰鎴浘 zlmresTfulUtils.getSnap(mediaInfo, streamUrl, 15, 1, path, fileName); @@ -142,14 +153,23 @@ } }); if (streamInfo == null) { + SSRCInfo ssrcInfo; + String streamId = null; + if (mediaServerItem.isRtpEnable()) { + streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); + } + + ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId); + // 鍙戦�佺偣鎾秷鎭� - cmder.playStreamCmd(mediaServerItem, device, channelId, (IMediaServerItem mediaServerItemInUse, JSONObject response) -> { + cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInUse, JSONObject response) -> { logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); onPublishHandlerForPlay(mediaServerItemInUse, response, deviceId, channelId, uuid.toString()); if (hookEvent != null) { hookEvent.response(mediaServerItem, response); } }, (event) -> { + // 鐐规挱杩斿洖sip閿欒 RequestMessage msg = new RequestMessage(); msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); Response response = event.getResponse(); @@ -162,6 +182,7 @@ if (errorEvent != null) { errorEvent.response(event); } + }); } else { String streamId = streamInfo.getStreamId(); @@ -176,7 +197,7 @@ return playResult; } String mediaServerId = streamInfo.getMediaServerId(); - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId); if (rtpInfo != null && rtpInfo.getBoolean("exist")) { @@ -194,9 +215,17 @@ hookEvent.response(mediaServerItem, JSONObject.parseObject(JSON.toJSONString(streamInfo))); } } else { + // TODO 鐐规挱鍓嶆槸鍚﹂噸缃姸鎬� redisCatchStorage.stopPlay(streamInfo); storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); - cmder.playStreamCmd(mediaServerItem, device, channelId, (IMediaServerItem mediaServerItemInuse, JSONObject response) -> { + SSRCInfo ssrcInfo; + String streamId2 = null; + if (mediaServerItem.isRtpEnable()) { + streamId2 = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); + } + ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId2); + + cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> { logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString()); }, (event) -> { @@ -218,7 +247,7 @@ } @Override - public void onPublishHandlerForPlay(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { + public void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { RequestMessage msg = new RequestMessage(); msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid); @@ -228,14 +257,6 @@ deviceChannel.setStreamId(streamInfo.getStreamId()); storager.startPlay(deviceId, channelId, streamInfo.getStreamId()); } - ClientTransaction transaction = streamSession.getTransaction(deviceId, channelId); - SIPDialog dialog = (SIPDialog)transaction.getDialog(); - StreamInfo.TransactionInfo transactionInfo = new StreamInfo.TransactionInfo(); - transactionInfo.callId = dialog.getCallId().getCallId(); - transactionInfo.localTag = dialog.getLocalTag(); - transactionInfo.remoteTag = dialog.getRemoteTag(); - transactionInfo.branch = dialog.getFirstTransactionInt().getBranchId(); - streamInfo.setTransactionInfo(transactionInfo); redisCatchStorage.startPlay(streamInfo); msg.setData(JSON.toJSONString(streamInfo)); @@ -254,10 +275,10 @@ } @Override - public IMediaServerItem getNewMediaServerItem(Device device) { + public MediaServerItem getNewMediaServerItem(Device device) { if (device == null) return null; String mediaServerId = device.getMediaServerId(); - IMediaServerItem mediaServerItem = null; + MediaServerItem mediaServerItem = null; if (mediaServerId == null) { mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(); }else { @@ -270,7 +291,7 @@ } @Override - public void onPublishHandlerForPlayBack(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { + public void onPublishHandlerForPlayBack(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { RequestMessage msg = new RequestMessage(); msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid); StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid); @@ -285,7 +306,7 @@ } } - public StreamInfo onPublishHandler(IMediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { + public StreamInfo onPublishHandler(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { String streamId = resonse.getString("stream"); JSONArray tracks = resonse.getJSONArray("tracks"); StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem,"rtp", streamId, tracks); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index fe49c3b..bbcad1c 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -3,7 +3,6 @@ import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.service.IGbStreamService; @@ -58,7 +57,7 @@ @Override public String save(StreamProxyItem param) { - IMediaServerItem mediaInfo; + MediaServerItem mediaInfo; if ("auto".equals(param.getMediaServerId())){ mediaInfo = mediaServerService.getMediaServerForMinimumLoad(); }else { @@ -120,7 +119,7 @@ @Override public JSONObject addStreamProxyToZlm(StreamProxyItem param) { JSONObject result = null; - IMediaServerItem mediaServerItem = null; + MediaServerItem mediaServerItem = null; if (param.getMediaServerId() == null) { logger.warn("娣诲姞浠g悊鏃禡ediaServerId 涓簄ull"); return null; @@ -141,7 +140,7 @@ @Override public JSONObject removeStreamProxyFromZlm(StreamProxyItem param) { if (param ==null) return null; - IMediaServerItem mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); + MediaServerItem mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); JSONObject result = zlmresTfulUtils.closeStreams(mediaServerItem, param.getApp(), param.getStream()); return result; } @@ -198,7 +197,7 @@ } @Override - public JSONObject getFFmpegCMDs(IMediaServerItem mediaServerItem) { + public JSONObject getFFmpegCMDs(MediaServerItem mediaServerItem) { JSONObject result = new JSONObject(); JSONObject mediaServerConfigResuly = zlmresTfulUtils.getMediaServerConfig(mediaServerItem); if (mediaServerConfigResuly != null && mediaServerConfigResuly.getInteger("code") == 0 diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java index 3692e54..aabf35f 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java @@ -5,7 +5,6 @@ import com.alibaba.fastjson.TypeReference; import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; @@ -43,7 +42,7 @@ private IMediaServerService mediaServerService; @Override - public List<StreamPushItem> handleJSON(String jsonData, IMediaServerItem mediaServerItem) { + public List<StreamPushItem> handleJSON(String jsonData, MediaServerItem mediaServerItem) { if (jsonData == null) return null; Map<String, StreamPushItem> result = new HashMap<>(); @@ -98,7 +97,7 @@ @Override public boolean removeFromGB(GbStream stream) { int del = gbStreamMapper.del(stream.getApp(), stream.getStream()); - IMediaServerItem mediaInfo = mediaServerService.getOne(stream.getMediaServerId()); + MediaServerItem mediaInfo = mediaServerService.getOne(stream.getMediaServerId()); JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaInfo, stream.getApp(), stream.getStream()); if (mediaList == null) { streamPushMapper.del(stream.getApp(), stream.getStream()); diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java index a4edb08..f5b2b1b 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java @@ -5,8 +5,6 @@ import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import java.util.List; import java.util.Map; diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java index 97c3794..223a5e8 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java @@ -3,7 +3,6 @@ import java.util.List; import com.genersoft.iot.vmp.gb28181.bean.*; -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java index 475ec6d..16ed401 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java @@ -1,7 +1,5 @@ package com.genersoft.iot.vmp.storager.dao; -import com.genersoft.iot.vmp.conf.MediaConfig; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; @@ -35,6 +33,7 @@ "rtpEnable, " + "rtpPortRange, " + "recordAssistPort, " + + "defaultServer, " + "createTime, " + "updateTime" + ") VALUES " + @@ -57,9 +56,10 @@ "${rtpEnable}, " + "'${rtpPortRange}', " + "${recordAssistPort}, " + + "${defaultServer}, " + "'${createTime}', " + "'${updateTime}')") - int add(IMediaServerItem mediaServerItem); + int add(MediaServerItem mediaServerItem); @Update(value = {" <script>" + "UPDATE media_server " + @@ -83,7 +83,7 @@ "<if test=\"recordAssistPort != null\">, recordAssistPort=${recordAssistPort}</if>" + "WHERE id='${id}'"+ " </script>"}) - int update(IMediaServerItem mediaServerItem); + int update(MediaServerItem mediaServerItem); @Select("SELECT * FROM media_server WHERE id='${id}'") MediaServerItem queryOne(String id); @@ -92,7 +92,7 @@ List<MediaServerItem> queryAll(); @Select("DELETE FROM media_server WHERE id='${id}'") - int delOne(String secret); + void delOne(String id); @Select("SELECT * FROM media_server WHERE ip='${host}' and httpPort=${port}") MediaServerItem queryOneByHostAndPort(String host, int port); diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java index eafb8a0..08eb9d1 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java @@ -3,10 +3,7 @@ import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.common.VideoManagerConstants; -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; import com.genersoft.iot.vmp.gb28181.bean.*; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; import com.genersoft.iot.vmp.utils.redis.RedisUtil; diff --git a/src/main/java/com/genersoft/iot/vmp/utils/ConfigConst.java b/src/main/java/com/genersoft/iot/vmp/utils/ConfigConst.java new file mode 100644 index 0000000..125d818 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/utils/ConfigConst.java @@ -0,0 +1,8 @@ +package com.genersoft.iot.vmp.utils; + +public class ConfigConst { + /** + * 鎾祦鏈�澶у苟鍙戜釜鏁� + */ + public static final Integer MAX_STRTEAM_COUNT = 10000; +} diff --git a/src/main/java/com/genersoft/iot/vmp/utils/SerializeUtils.java b/src/main/java/com/genersoft/iot/vmp/utils/SerializeUtils.java new file mode 100644 index 0000000..ae91ad5 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/utils/SerializeUtils.java @@ -0,0 +1,31 @@ +package com.genersoft.iot.vmp.utils; + +import java.io.*; + +public class SerializeUtils { + public static byte[] serialize(Object obj){ + byte[] bytes = null; + try { + ByteArrayOutputStream baos=new ByteArrayOutputStream();; + ObjectOutputStream oos=new ObjectOutputStream(baos); + oos.writeObject(obj); + bytes=baos.toByteArray(); + baos.close(); + oos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return bytes; + } + public static Object deSerialize(byte[] bytes){ + Object obj=null; + try { + ByteArrayInputStream bais=new ByteArrayInputStream(bytes); + ObjectInputStream ois=new ObjectInputStream(bais); + obj=ois.readObject(); + } catch (Exception e) { + e.printStackTrace(); + } + return obj; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/utils/redis/JedisUtil.java b/src/main/java/com/genersoft/iot/vmp/utils/redis/JedisUtil.java new file mode 100644 index 0000000..54e5422 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/utils/redis/JedisUtil.java @@ -0,0 +1,97 @@ +package com.genersoft.iot.vmp.utils.redis; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; + +import java.util.Set; + +/** + * @Description:Jedis宸ュ叿绫� + * @author: wangshaopeng@sunnybs.com + * @date: 2021骞�03鏈�22鏃� 涓嬪崍8:27:29 + */ +@Component +public class JedisUtil { + + @Autowired + private JedisPool jedisPool; + + // ============================== Key ============================== + + /** + * 妫�鏌ョ粰瀹� key 鏄惁瀛樺湪銆� + * + * @param key + * @return + */ + public Boolean exists(String key) { + Jedis jedis = null; + try { + jedis = jedisPool.getResource(); + Boolean exists = jedis.exists(key); + return exists; + } finally { + returnToPool(jedis); + } + } + + + // ============================== Set ============================== + + /** + * SADD key member [member ...] + * 灏嗕竴涓垨澶氫釜 member 鍏冪礌鍔犲叆鍒伴泦鍚� key 褰撲腑锛屽凡缁忓瓨鍦ㄤ簬闆嗗悎鐨� member 鍏冪礌灏嗚蹇界暐銆� + * 鍋囧 key 涓嶅瓨鍦紝鍒欏垱寤轰竴涓彧鍖呭惈 member 鍏冪礌浣滄垚鍛樼殑闆嗗悎銆� + * 褰� key 涓嶆槸闆嗗悎绫诲瀷鏃讹紝杩斿洖涓�涓敊璇�� + */ + public Long sadd(String key, String... members) { + Jedis jedis = null; + try { + jedis = jedisPool.getResource(); + Long smove = jedis.sadd(key, members); + return smove; + } finally { + returnToPool(jedis); + } + } + + /** + * SMEMBERS key + * 杩斿洖闆嗗悎 key 涓殑鎵�鏈夋垚鍛樸�� + * 涓嶅瓨鍦ㄧ殑 key 琚涓虹┖闆嗗悎銆� + */ + public Set<String> smembers(String key) { + Jedis jedis = null; + try { + jedis = jedisPool.getResource(); + Set<String> smembers = jedis.smembers(key); + return smembers; + } finally { + returnToPool(jedis); + } + } + + + /** + * SREM key member1 [member2] + * 绉婚櫎闆嗗悎涓竴涓垨澶氫釜鎴愬憳 + */ + public Long srem(String key, String... member) { + Jedis jedis = null; + try { + jedis = jedisPool.getResource(); + Long srem = jedis.srem(key, member); + return srem; + } finally { + returnToPool(jedis); + } + } + + private void returnToPool(Jedis jedis) { + if (jedis != null) { + jedis.close(); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java b/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java index 5db3c7f..dd5614f 100644 --- a/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java +++ b/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java @@ -415,10 +415,10 @@ * * @param key * @param value - * @param score + * @param delta -1 琛ㄧず鍑� 1 琛ㄧず鍔�1 */ - public Double zIncrScore(Object key, Object value, double score) { - return redisTemplate.opsForZSet().incrementScore(key, value, score); + public Double zIncrScore(Object key, Object value, double delta) { + return redisTemplate.opsForZSet().incrementScore(key, value, delta); } /** diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java index aae9cce..d6545b5 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java @@ -2,13 +2,12 @@ import com.alibaba.fastjson.JSONArray; import com.genersoft.iot.vmp.common.StreamInfo; +import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -37,7 +36,7 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import org.springframework.web.context.request.async.DeferredResult; -import java.util.Enumeration; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -89,7 +88,7 @@ // 鑾峰彇鍙敤鐨剒lm Device device = storager.queryVideoDevice(deviceId); - IMediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); + MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); PlayResult playResult = playService.play(newMediaServerItem, deviceId, channelId, null, null); return playResult.getResult(); @@ -174,7 +173,7 @@ logger.warn("瑙嗛杞爜API璋冪敤澶辫触锛�, 瑙嗛娴佸凡缁忓仠姝�!"); return new ResponseEntity<String>("鏈壘鍒拌棰戞祦淇℃伅, 瑙嗛娴佸彲鑳藉凡缁忓仠姝�", HttpStatus.OK); } - IMediaServerItem mediaInfo = mediaServerService.getOne(streamInfo.getMediaServerId()); + MediaServerItem mediaInfo = mediaServerService.getOne(streamInfo.getMediaServerId()); JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaInfo, streamId); if (!rtpInfo.getBoolean("exist")) { logger.warn("瑙嗛杞爜API璋冪敤澶辫触锛�, 瑙嗛娴佸凡鍋滄鎺ㄦ祦!"); @@ -219,7 +218,7 @@ result.put("msg", "mediaServerId is null"); return new ResponseEntity<String>( result.toJSONString(), HttpStatus.BAD_REQUEST); } - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo == null) { result.put("code", 0); result.put("msg", "浣跨敤鐨勬祦濯掍綋宸茬粡鍋滄杩愯"); @@ -307,16 +306,16 @@ logger.debug("鑾峰彇鎵�鏈夌殑ssrc"); } JSONArray objects = new JSONArray(); - for(Map.Entry<String, String> entry: streamSession.getSsrcMap().entrySet()) { - System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); + List<SsrcTransaction> allSsrc = streamSession.getAllSsrc(); + for (SsrcTransaction transaction : allSsrc) { JSONObject jsonObject = new JSONObject(); - String[] keyArray = entry.getKey().split("_"); - jsonObject.put("deviceId", keyArray[0]); - jsonObject.put("channelId", keyArray[1]); - jsonObject.put("ssrc", entry.getValue()); - jsonObject.put("streamId", streamSession.getStreamIdMap().get(entry.getKey())); + jsonObject.put("deviceId", transaction.getDeviceId()); + jsonObject.put("channelId", transaction.getChannelId()); + jsonObject.put("ssrc", transaction.getSsrc()); + jsonObject.put("streamId", transaction.getStreamId()); objects.add(jsonObject); } + WVPResult<JSONObject> result = new WVPResult<>(); result.setCode(0); result.setMsg("success"); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/DownloadController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/DownloadController.java index 218debf..2ca4aba 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/DownloadController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/DownloadController.java @@ -3,9 +3,9 @@ import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; -//import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.service.IPlayService; import io.swagger.annotations.Api; @@ -58,6 +58,9 @@ @Autowired private DeferredResultHolder resultHolder; + @Autowired + private IMediaServerService mediaServerService; + @ApiOperation("寮�濮嬪巻鍙插獟浣撲笅杞�") @ApiImplicitParams({ @ApiImplicitParam(name = "deviceId", value = "璁惧ID", dataTypeClass = String.class), @@ -90,7 +93,7 @@ cmder.streamByeCmd(deviceId, channelId); } resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result); - IMediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); + MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); if (newMediaServerItem == null) { logger.warn(String.format("璁惧涓嬭浇鍝嶅簲瓒呮椂锛宒eviceId锛�%s 锛宑hannelId锛�%s", deviceId, channelId)); RequestMessage msg = new RequestMessage(); @@ -99,7 +102,10 @@ resultHolder.invokeResult(msg); return result; } - cmder.downloadStreamCmd(newMediaServerItem, device, channelId, startTime, endTime, downloadSpeed, (IMediaServerItem mediaServerItem, JSONObject response) -> { + + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null); + + cmder.downloadStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, (MediaServerItem mediaServerItem, JSONObject response) -> { logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); playService.onPublishHandlerForPlayBack(mediaServerItem, response, deviceId, channelId, uuid.toString()); }, event -> { diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java index d2a30fa..9fd05b2 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java @@ -4,8 +4,9 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; //import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.service.IPlayService; import io.swagger.annotations.Api; @@ -58,6 +59,9 @@ @Autowired private DeferredResultHolder resultHolder; + @Autowired + private IMediaServerService mediaServerService; + @ApiOperation("寮�濮嬭棰戝洖鏀�") @ApiImplicitParams({ @ApiImplicitParam(name = "deviceId", value = "璁惧ID", dataTypeClass = String.class), @@ -74,6 +78,15 @@ } UUID uuid = UUID.randomUUID(); DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(30000L); + + Device device = storager.queryVideoDevice(deviceId); + if (device == null) { + result.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST)); + return result; + } + MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null); + // 瓒呮椂澶勭悊 result.onTimeout(()->{ logger.warn(String.format("璁惧鍥炴斁瓒呮椂锛宒eviceId锛�%s 锛宑hannelId锛�%s", deviceId, channelId)); @@ -82,14 +95,14 @@ msg.setData("Timeout"); resultHolder.invokeResult(msg); }); - Device device = storager.queryVideoDevice(deviceId); + StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId); if (streamInfo != null) { // 鍋滄涔嬪墠鐨勫洖鏀� cmder.streamByeCmd(deviceId, channelId); } resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result); - IMediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); + if (newMediaServerItem == null) { logger.warn(String.format("璁惧鍥炴斁瓒呮椂锛宒eviceId锛�%s 锛宑hannelId锛�%s", deviceId, channelId)); RequestMessage msg = new RequestMessage(); @@ -98,7 +111,8 @@ resultHolder.invokeResult(msg); return result; } - cmder.playbackStreamCmd(newMediaServerItem, device, channelId, startTime, endTime, (IMediaServerItem mediaServerItem, JSONObject response) -> { + + cmder.playbackStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, (MediaServerItem mediaServerItem, JSONObject response) -> { logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); playService.onPublishHandlerForPlayBack(mediaServerItem, response, deviceId, channelId, uuid.toString()); }, event -> { diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/session/PlayTypeEnum.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/session/PlayTypeEnum.java new file mode 100644 index 0000000..58fbb26 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/session/PlayTypeEnum.java @@ -0,0 +1,23 @@ +package com.genersoft.iot.vmp.vmanager.gb28181.session; + +public enum PlayTypeEnum { + + PLAY("0", "鐩存挱"), + PLAY_BACK("1", "鍥炴斁"); + + private String value; + private String name; + + PlayTypeEnum(String value, String name) { + this.value = value; + this.name = name; + } + + public String getValue() { + return value; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java index 45eeac8..76ad86c 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java @@ -1,10 +1,8 @@ package com.genersoft.iot.vmp.vmanager.server; import com.genersoft.iot.vmp.VManageBootstrap; -import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.utils.SpringBeanFactory; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import gov.nist.javax.sip.SipStackImpl; @@ -17,7 +15,6 @@ import javax.sip.ListeningPoint; import javax.sip.ObjectInUseException; import javax.sip.SipProvider; -import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -38,19 +35,30 @@ @ApiOperation("娴佸獟浣撴湇鍔″垪琛�") @GetMapping(value = "/media_server/list") @ResponseBody - public WVPResult<List<IMediaServerItem>> getMediaServerList(){ - WVPResult<List<IMediaServerItem>> result = new WVPResult<>(); + public WVPResult<List<MediaServerItem>> getMediaServerList(){ + WVPResult<List<MediaServerItem>> result = new WVPResult<>(); result.setCode(0); result.setMsg("success"); result.setData(mediaServerService.getAll()); return result; } + @ApiOperation("鍦ㄧ嚎娴佸獟浣撴湇鍔″垪琛�") + @GetMapping(value = "/media_server/online/list") + @ResponseBody + public WVPResult<List<MediaServerItem>> getOnlineMediaServerList(){ + WVPResult<List<MediaServerItem>> result = new WVPResult<>(); + result.setCode(0); + result.setMsg("success"); + result.setData(mediaServerService.getAllOnline()); + return result; + } + @ApiOperation("鑾峰彇娴佸獟浣撴湇鍔�") @GetMapping(value = "/media_server/one/{id}") @ResponseBody - public WVPResult<IMediaServerItem> getMediaServer(@PathVariable String id){ - WVPResult<IMediaServerItem> result = new WVPResult<>(); + public WVPResult<MediaServerItem> getMediaServer(@PathVariable String id){ + WVPResult<MediaServerItem> result = new WVPResult<>(); result.setCode(0); result.setMsg("success"); result.setData(mediaServerService.getOne(id)); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java index f099631..f8c01dd 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java @@ -1,7 +1,6 @@ package com.genersoft.iot.vmp.vmanager.streamProxy; import com.alibaba.fastjson.JSONObject; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.service.IMediaServerService; @@ -9,7 +8,6 @@ import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import com.github.pagehelper.PageInfo; -import io.netty.util.internal.StringUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; @@ -86,7 +84,7 @@ public WVPResult getFFmpegCMDs(@RequestParam String mediaServerId){ logger.debug("鑾峰彇鑺傜偣[ {} ]ffmpeg.cmd妯℃澘", mediaServerId ); - IMediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); + MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); JSONObject data = streamProxyService.getFFmpegCMDs(mediaServerItem); WVPResult<JSONObject> result = new WVPResult<>(); result.setCode(0); diff --git a/src/main/resources/all-application.yml b/src/main/resources/all-application.yml index 2552e01..c4bd7ca 100644 --- a/src/main/resources/all-application.yml +++ b/src/main/resources/all-application.yml @@ -17,6 +17,12 @@ password: # [鍙�塢 瓒呮椂鏃堕棿 timeout: 10000 + # [鍙�塢 涓�涓猵ool鏈�澶氬彲鍒嗛厤澶氬皯涓猨edis瀹炰緥 + poolMaxTotal: 1000 + # [鍙�塢 涓�涓猵ool鏈�澶氭湁澶氬皯涓姸鎬佷负idle(绌洪棽)鐨刯edis瀹炰緥 + poolMaxIdle: 500 + # [鍙�塢 鏈�澶х殑绛夊緟鏃堕棿(绉�) + poolMaxWait: 5 # [鍙�塢 jdbc鏁版嵁搴撻厤缃�, 椤圭洰浣跨敤sqlite浣滀负鏁版嵁搴擄紝涓�鑸笉闇�瑕侀厤缃� datasource: # 浣跨敤mysql 鎵撳紑23-28琛屾敞閲婏紝 鍒犻櫎29-36琛� @@ -124,6 +130,7 @@ level: com.genersoft.iot: debug com.genersoft.iot.vmp.storager.dao: info + com.genersoft.iot.vmp.gb28181: info # [鏍规嵁涓氬姟闇�姹傞厤缃甝 user-settings: # [鍙�塢 鑷姩鐐规挱锛� 浣跨敤鍥哄畾娴佸湴鍧�杩涜鎾斁鏃讹紝濡傛灉鏈偣鎾垯鑷姩杩涜鐐规挱, 闇�瑕乺tp.enable=true diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index b756be9..dd2e0f7 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -76,6 +76,8 @@ level: com.genersoft.iot: debug com.genersoft.iot.vmp.storager.dao: info + com.genersoft.iot.vmp.gb28181: info + # [鏍规嵁涓氬姟闇�姹傞厤缃甝 user-settings: # 鎺ㄦ祦鐩存挱鏄惁褰曞埗 diff --git a/src/main/resources/wvp.sqlite b/src/main/resources/wvp.sqlite index 8e41983..500607c 100644 --- a/src/main/resources/wvp.sqlite +++ b/src/main/resources/wvp.sqlite Binary files differ diff --git a/web_src/src/components/service/MediaServer.js b/web_src/src/components/service/MediaServer.js index a63d19c..b905352 100644 --- a/web_src/src/components/service/MediaServer.js +++ b/web_src/src/components/service/MediaServer.js @@ -9,7 +9,7 @@ getMediaServerList(callback){ this.$axios({ method: 'get', - url:`/api/server/media_server/list`, + url:`/api/server/media_server/online/list`, }).then(function (res) { if (typeof (callback) == "function") callback(res.data) }).catch(function (error) { -- Gitblit v1.8.0