Pārlūkot izejas kodu

修复bug以及日志按照,错误/sip/数据库 分割

648540858 3 gadi atpakaļ
vecāks
revīzija
9f680a2e9e
25 mainītis faili ar 187 papildinājumiem un 113 dzēšanām
  1. 10 0
      src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
  2. 4 2
      src/main/java/com/genersoft/iot/vmp/conf/security/AnonymousAuthenticationEntryPoint.java
  3. 24 0
      src/main/java/com/genersoft/iot/vmp/conf/security/UrlTokenHandler.java
  4. 10 4
      src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
  5. 0 2
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java
  6. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
  7. 1 0
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
  8. 0 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java
  9. 1 1
      src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java
  10. 19 14
      src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
  11. 4 3
      src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
  12. 1 1
      src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
  13. 2 1
      src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
  14. 2 1
      src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
  15. 23 9
      src/main/java/com/genersoft/iot/vmp/service/impl/RedisAlarmMsgListener.java
  16. 1 1
      src/main/java/com/genersoft/iot/vmp/service/impl/RedisGbPlayMsgListener.java
  17. 1 2
      src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
  18. 2 0
      src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
  19. 18 0
      src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
  20. 5 0
      src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java
  21. 1 2
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java
  22. 27 47
      src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java
  23. 20 10
      src/main/resources/logback-spring-local.xml
  24. 1 1
      web_src/src/components/dialog/devicePlayer.vue
  25. 9 10
      web_src/src/components/dialog/platformEdit.vue

+ 10 - 0
src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java

@@ -31,6 +31,8 @@ public class StreamInfo {
     private String rtsp;
     private String rtsps;
     private String rtc;
+
+    private String rtcs;
     private String mediaServerId;
     private Object tracks;
     private String startTime;
@@ -302,4 +304,12 @@ public class StreamInfo {
     public void setIp(String ip) {
         this.ip = ip;
     }
+
+    public String getRtcs() {
+        return rtcs;
+    }
+
+    public void setRtcs(String rtcs) {
+        this.rtcs = rtcs;
+    }
 }

+ 4 - 2
src/main/java/com/genersoft/iot/vmp/conf/security/AnonymousAuthenticationEntryPoint.java

@@ -1,6 +1,8 @@
 package com.genersoft.iot.vmp.conf.security;
 
 import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
+import org.apache.poi.hssf.eventmodel.ERFListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.security.core.AuthenticationException;
@@ -28,8 +30,8 @@ public class AnonymousAuthenticationEntryPoint implements AuthenticationEntryPoi
         response.setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified");
         response.setHeader("Content-type", "application/json;charset=UTF-8");
         JSONObject jsonObject = new JSONObject();
-        jsonObject.put("code", "-1");
-        jsonObject.put("msg", "请登录后重新请求");
+        jsonObject.put("code", ErrorCode.ERROR401.getCode());
+        jsonObject.put("msg", ErrorCode.ERROR401.getMsg());
         String logUri = "api/user/login";
         if (request.getRequestURI().contains(logUri)){
             jsonObject.put("msg", e.getMessage());

+ 24 - 0
src/main/java/com/genersoft/iot/vmp/conf/security/UrlTokenHandler.java

@@ -0,0 +1,24 @@
+package com.genersoft.iot.vmp.conf.security;
+
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.SessionCookieConfig;
+import javax.servlet.SessionTrackingMode;
+import java.util.Collections;
+
+public class UrlTokenHandler extends SpringBootServletInitializer {
+
+    @Override
+    public void onStartup(ServletContext servletContext) throws ServletException {
+        super.onStartup(servletContext);
+
+        servletContext.setSessionTrackingModes(
+                Collections.singleton(SessionTrackingMode.COOKIE)
+        );
+        SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig();
+        sessionCookieConfig.setHttpOnly(true);
+
+    }
+}

+ 10 - 4
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java

@@ -2,8 +2,10 @@ package com.genersoft.iot.vmp.gb28181;
 
 import com.genersoft.iot.vmp.conf.SipConfig;
 import com.genersoft.iot.vmp.gb28181.transmit.ISIPProcessorObserver;
+import com.genersoft.iot.vmp.utils.DateUtil;
 import gov.nist.javax.sip.SipProviderImpl;
 import gov.nist.javax.sip.SipStackImpl;
+import org.apache.commons.lang3.time.DateFormatUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -13,6 +15,7 @@ import org.springframework.context.annotation.DependsOn;
 import org.springframework.stereotype.Component;
 
 import javax.sip.*;
+import java.text.DateFormat;
 import java.util.Properties;
 import java.util.TooManyListenersException;
 import java.util.concurrent.LinkedBlockingQueue;
@@ -52,7 +55,9 @@ public class SipLayer{
 		 * 完整配置参考 gov.nist.javax.sip.SipStackImpl,需要下载源码
 		 * gov/nist/javax/sip/SipStackImpl.class
 		 */
-		properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "true");
+		if (logger.isDebugEnabled()) {
+			properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "true");
+		}
 		// 接收所有notify请求,即使没有订阅
 		properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true");
 		// 为_NULL _对话框传递_终止的_事件
@@ -67,9 +72,10 @@ public class SipLayer{
 		 * 0; public static final int TRACE_MESSAGES = 16; public static final int
 		 * TRACE_EXCEPTION = 17; public static final int TRACE_DEBUG = 32;
 		 */
-		properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "0");
-		properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip_server_log");
-		properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip_debug_log");
+		if (logger.isDebugEnabled()) {
+			properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "DEBUG");
+		}
+		properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "INFO");
 		sipStack = (SipStackImpl) sipFactory.createSipStack(properties);
 
 		return sipStack;

+ 0 - 2
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java

@@ -71,7 +71,6 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
     @Override
     @Async
     public void processRequest(RequestEvent requestEvent) {
-        logger.debug("\n收到请求:\n{}", requestEvent.getRequest());
         String method = requestEvent.getRequest().getMethod();
         ISIPRequestProcessor sipRequestProcessor = requestProcessorMap.get(method);
         if (sipRequestProcessor == null) {
@@ -90,7 +89,6 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
     @Async
     public void processResponse(ResponseEvent responseEvent) {
         Response response = responseEvent.getResponse();
-        logger.debug("\n收到响应:\n{}", responseEvent.getResponse());
         int status = response.getStatusCode();
 
         if (((status >= 200) && (status < 300)) || status == Response.UNAUTHORIZED) { // Success!

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java

@@ -640,7 +640,7 @@ public class SIPCommander implements ISIPCommander {
 						hookEvent.call(new InviteStreamInfo(mediaServerItem, json, callIdHeader.getCallId(), "rtp", ssrcInfo.getStream()));
 						subscribe.removeSubscribe(hookSubscribe);
 						hookSubscribe.getContent().put("regist", false);
-						hookSubscribe.getContent().put("schema", "rtmp");
+						hookSubscribe.getContent().put("schema", "rtsp");
 						// 添加流注销的订阅,注销了后向设备发送bye
 						subscribe.addSubscribe(hookSubscribe,
 								(MediaServerItem mediaServerItemForEnd, JSONObject jsonForEnd)->{

+ 1 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java

@@ -410,6 +410,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
                                 streamId = String.format("%s_%s", device.getDeviceId(), channelId);
                             }
                             SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false);
+                            logger.info(JSONObject.toJSONString(ssrcInfo));
                             sendRtpItem.setStreamId(ssrcInfo.getStream());
                             // 写入redis, 超时时回复
                             redisCatchStorage.updateSendRTPSever(sendRtpItem);

+ 0 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/SubscribeRequestProcessor.java

@@ -180,7 +180,6 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
 
 	private void processNotifyCatalogList(RequestEvent evt, Element rootElement) throws SipException {
 
-		System.out.println(evt.getRequest().toString());
 		String platformId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
 		String deviceId = XmlUtil.getText(rootElement, "DeviceID");
 		ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId);

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java

@@ -164,7 +164,7 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
             }
         }
 
-        if (channelId.equals(sipConfig.getId())) {
+        if ("7".equals(deviceAlarm.getAlarmMethod()) ) {
             // 发送给平台的报警信息。 发送redis通知
             AlarmChannelMessage alarmChannelMessage = new AlarmChannelMessage();
             alarmChannelMessage.setAlarmSn(Integer.parseInt(deviceAlarm.getAlarmMethod()));

+ 19 - 14
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java

@@ -7,12 +7,10 @@ import java.util.Map;
 import com.alibaba.fastjson.JSON;
 import com.genersoft.iot.vmp.common.StreamInfo;
 import com.genersoft.iot.vmp.conf.UserSetting;
-import com.genersoft.iot.vmp.gb28181.bean.Device;
-import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
-import com.genersoft.iot.vmp.gb28181.bean.GbStream;
-import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
+import com.genersoft.iot.vmp.gb28181.bean.*;
 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
 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.dto.*;
 import com.genersoft.iot.vmp.service.*;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
@@ -49,6 +47,9 @@ public class ZLMHttpHookListener {
 	@Autowired
 	private SIPCommander cmder;
 
+	@Autowired
+	private SIPCommanderFroPlatform commanderFroPlatform;
+
 	@Autowired
 	private IPlayService playService;
 
@@ -237,7 +238,7 @@ public class ZLMHttpHookListener {
 			// 鉴权通过
 			redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo);
 			// 通知assist新的callId
-			if (mediaInfo != null) {
+			if (mediaInfo != null && mediaInfo.getRecordAssistPort() > 0) {
 				assistRESTfulUtils.addStreamCallInfo(mediaInfo, param.getApp(), param.getStream(), callId, null);
 			}
 		}else {
@@ -427,7 +428,7 @@ public class ZLMHttpHookListener {
 		}else {
 			redisCatchStorage.removeStreamAuthorityInfo(app, stream);
 		}
-		if ("rtmp".equals(schema)){
+		if ("rtsp".equals(schema)){
 			logger.info("on_stream_changed:注册->{}, app->{}, stream->{}", regist, app, stream);
 			if (regist) {
 				mediaServerService.addCount(mediaServerId);
@@ -523,17 +524,21 @@ public class ZLMHttpHookListener {
 		if ("rtp".equals(app)){
 			ret.put("close", true);
 			StreamInfo streamInfoForPlayCatch = redisCatchStorage.queryPlayByStreamId(streamId);
-			SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransaction(null, null, null, streamId);
 			if (streamInfoForPlayCatch != null) {
-				// 如果在给上级推流,也不停止。
+				// 收到无人观看说明流也没有在往上级推送
 				if (redisCatchStorage.isChannelSendingRTP(streamInfoForPlayCatch.getChannelId())) {
-					ret.put("close", false);
-				} else {
-					cmder.streamByeCmd(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId(),
-							streamInfoForPlayCatch.getStream(), null);
-					redisCatchStorage.stopPlay(streamInfoForPlayCatch);
-					storager.stopPlay(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId());
+					List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByChnnelId(streamInfoForPlayCatch.getChannelId());
+					if (sendRtpItems.size() > 0) {
+						for (SendRtpItem sendRtpItem : sendRtpItems) {
+							ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
+							commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId());
+						}
+					}
 				}
+				cmder.streamByeCmd(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId(),
+						streamInfoForPlayCatch.getStream(), null);
+				redisCatchStorage.stopPlay(streamInfoForPlayCatch);
+				storager.stopPlay(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId());
 			}else{
 				StreamInfo streamInfoForPlayBackCatch = redisCatchStorage.queryPlayback(null, null, streamId, null);
 				if (streamInfoForPlayBackCatch != null) {

+ 4 - 3
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java

@@ -92,6 +92,7 @@ public class ZLMRTPServerFactory {
         int result = -1;
         // 查询此rtp server 是否已经存在
         JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaServerItem, streamId);
+        logger.info(JSONObject.toJSONString(rtpInfo));
         if(rtpInfo.getInteger("code") == 0){
             if (rtpInfo.getBoolean("exist")) {
                 result = rtpInfo.getInteger("local_port");
@@ -113,7 +114,7 @@ public class ZLMRTPServerFactory {
         }
         param.put("ssrc", ssrc);
         JSONObject openRtpServerResultJson = zlmresTfulUtils.openRtpServer(mediaServerItem, param);
-
+        logger.info(JSONObject.toJSONString(openRtpServerResultJson));
         if (openRtpServerResultJson != null) {
             if (openRtpServerResultJson.getInteger("code") == 0) {
                 result= openRtpServerResultJson.getInteger("port");
@@ -270,7 +271,7 @@ public class ZLMRTPServerFactory {
      * 查询待转推的流是否就绪
      */
     public Boolean isRtpReady(MediaServerItem mediaServerItem, String streamId) {
-        JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem,"rtp", "rtmp", streamId);
+        JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem,"rtp", "rtsp", streamId);
         return (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online"));
     }
 
@@ -290,7 +291,7 @@ public class ZLMRTPServerFactory {
      * @return
      */
     public int totalReaderCount(MediaServerItem mediaServerItem, String app, String streamId) {
-        JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtmp", streamId);
+        JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtsp", streamId);
         if (mediaInfo == null) {
             return 0;
         }

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java

@@ -417,7 +417,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
         if (RedisUtil.zScore(key, serverItem.getId()) == null) {  // 不存在则设置默认值 已存在则重置
             RedisUtil.zAdd(key, serverItem.getId(), 0L);
             // 查询服务流数量
-            zlmresTfulUtils.getMediaList(serverItem, null, null, "rtmp",(mediaList ->{
+            zlmresTfulUtils.getMediaList(serverItem, null, null, "rtsp",(mediaList ->{
                 Integer code = mediaList.getInteger("code");
                 if (code == 0) {
                     JSONArray data = mediaList.getJSONArray("data");

+ 2 - 1
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java

@@ -112,6 +112,7 @@ public class MediaServiceImpl implements IMediaService {
         streamInfoResult.setWs_fmp4(String.format("ws://%s:%s/%s/%s.live.mp4%s", addr, mediaInfo.getHttpPort(), app,  stream, callIdParam));
         streamInfoResult.setTs(String.format("http://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpPort(), app,  stream, callIdParam));
         streamInfoResult.setWs_ts(String.format("ws://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpPort(), app,  stream, callIdParam));
+        streamInfoResult.setRtc(String.format("http://%s:%s/index/api/webrtc?app=%s&stream=%s&type=play%s", mediaInfo.getStreamIp(), mediaInfo.getHttpPort(), app,  stream, ObjectUtils.isEmpty(callId)?"":"&callId=" + callId));
         if (mediaInfo.getHttpSSlPort() != 0) {
             streamInfoResult.setHttps_flv(String.format("https://%s:%s/%s/%s.live.flv%s", addr, mediaInfo.getHttpSSlPort(), app,  stream, callIdParam));
             streamInfoResult.setWss_flv(String.format("wss://%s:%s/%s/%s.live.flv%s", addr, mediaInfo.getHttpSSlPort(), app,  stream, callIdParam));
@@ -122,7 +123,7 @@ public class MediaServiceImpl implements IMediaService {
             streamInfoResult.setHttps_ts(String.format("https://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app,  stream, callIdParam));
             streamInfoResult.setWss_ts(String.format("wss://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app,  stream, callIdParam));
             streamInfoResult.setWss_ts(String.format("wss://%s:%s/%s/%s.live.ts%s", addr, mediaInfo.getHttpSSlPort(), app,  stream, callIdParam));
-            streamInfoResult.setRtc(String.format("https://%s:%s/index/api/webrtc?app=%s&stream=%s&type=play%s", mediaInfo.getStreamIp(), mediaInfo.getHttpSSlPort(), app,  stream, ObjectUtils.isEmpty(callId)?"":"&callId=" + callId));
+            streamInfoResult.setRtcs(String.format("https://%s:%s/index/api/webrtc?app=%s&stream=%s&type=play%s", mediaInfo.getStreamIp(), mediaInfo.getHttpSSlPort(), app,  stream, ObjectUtils.isEmpty(callId)?"":"&callId=" + callId));
         }
 
         streamInfoResult.setTracks(tracks);

+ 2 - 1
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java

@@ -195,6 +195,7 @@ public class PlayServiceImpl implements IPlayService {
                 streamId = String.format("%s_%s", device.getDeviceId(), channelId);
             }
             SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, device.isSsrcCheck(), false);
+            logger.info(JSONObject.toJSONString(ssrcInfo));
             play(mediaServerItem, ssrcInfo, device, channelId, (mediaServerItemInUse, response)->{
                 if (hookEvent != null) {
                     hookEvent.response(mediaServerItem, response);
@@ -306,7 +307,7 @@ public class PlayServiceImpl implements IPlayService {
                     // 单端口模式streamId也有变化,需要重新设置监听
                     if (!mediaServerItem.isRtpEnable()) {
                         // 添加订阅
-                        HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtmp", mediaServerItem.getId());
+                        HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId());
                         subscribe.removeSubscribe(hookSubscribe);
                         hookSubscribe.getContent().put("stream", String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase());
                         subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject response)->{

+ 23 - 9
src/main/java/com/genersoft/iot/vmp/service/impl/RedisAlarmMsgListener.java

@@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSON;
 import com.genersoft.iot.vmp.gb28181.bean.*;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
+import com.genersoft.iot.vmp.service.IPlatformChannelService;
+import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
 import com.genersoft.iot.vmp.utils.DateUtil;
 import org.slf4j.Logger;
@@ -12,6 +14,9 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.connection.Message;
 import org.springframework.data.redis.connection.MessageListener;
 import org.springframework.stereotype.Component;
+import org.springframework.util.ObjectUtils;
+
+import java.util.List;
 
 
 @Component
@@ -37,8 +42,6 @@ public class RedisAlarmMsgListener implements MessageListener {
             return;
         }
         String gbId = alarmChannelMessage.getGbId();
-        Device device = storage.queryVideoDevice(gbId);
-        ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId);
 
         DeviceAlarm deviceAlarm = new DeviceAlarm();
         deviceAlarm.setCreateTime(DateUtil.getNow());
@@ -46,18 +49,29 @@ public class RedisAlarmMsgListener implements MessageListener {
         deviceAlarm.setAlarmDescription(alarmChannelMessage.getAlarmDescription());
         deviceAlarm.setAlarmMethod("" + alarmChannelMessage.getAlarmSn());
         deviceAlarm.setAlarmPriority("1");
-        deviceAlarm.setAlarmTime(DateUtil.getNow());
+        deviceAlarm.setAlarmTime(DateUtil.getNowForISO8601());
         deviceAlarm.setAlarmType("1");
         deviceAlarm.setLongitude(0);
         deviceAlarm.setLatitude(0);
 
-
-        if (device != null && platform == null) {
-            commander.sendAlarmMessage(device, deviceAlarm);
-        }else if (device == null && platform != null){
-            commanderForPlatform.sendAlarmMessage(platform, deviceAlarm);
+        if (ObjectUtils.isEmpty(gbId)) {
+            // 发送给所有的上级
+            List<ParentPlatform> parentPlatforms = storage.queryEnableParentPlatformList(true);
+            if (parentPlatforms.size() > 0) {
+                for (ParentPlatform parentPlatform : parentPlatforms) {
+                    commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm);
+                }
+            }
         }else {
-           logger.warn("无法确定" + gbId + "是平台还是设备");
+            Device device = storage.queryVideoDevice(gbId);
+            ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId);
+            if (device != null && platform == null) {
+                commander.sendAlarmMessage(device, deviceAlarm);
+            }else if (device == null && platform != null){
+                commanderForPlatform.sendAlarmMessage(platform, deviceAlarm);
+            }else {
+                logger.warn("无法确定" + gbId + "是平台还是设备");
+            }
         }
     }
 }

+ 1 - 1
src/main/java/com/genersoft/iot/vmp/service/impl/RedisGbPlayMsgListener.java

@@ -271,7 +271,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
             }, userSetting.getPlatformPlayTimeout());
 
             // 添加订阅
-            HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed(content.getApp(), content.getStream(), true, "rtmp", mediaServerItem.getId());
+            HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed(content.getApp(), content.getStream(), true, "rtsp", mediaServerItem.getId());
 
             subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json)->{
                         dynamicTask.stop(taskKey);

+ 1 - 2
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java

@@ -301,7 +301,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
             if (jsonObject == null) {
                 return false;
             }
-            System.out.println(jsonObject);
             if (jsonObject.getInteger("code") == 0) {
                 result = true;
                 streamProxy.setEnable(true);
@@ -427,7 +426,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
                         if(data != null && data.size() > 0) {
                             for (int i = 0; i < data.size(); i++) {
                                 JSONObject streamJSONObj = data.getJSONObject(i);
-                                if ("rtmp".equals(streamJSONObj.getString("schema"))) {
+                                if ("rtsp".equals(streamJSONObj.getString("schema"))) {
                                     StreamInfo streamInfo = new StreamInfo();
                                     String app = streamJSONObj.getString("app");
                                     String stream = streamJSONObj.getString("stream");

+ 2 - 0
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java

@@ -237,4 +237,6 @@ public interface IRedisCatchStorage {
      * 发送redis消息 查询所有推流设备的状态
      */
     void sendStreamPushRequestedMsgForStatus();
+
+    List<SendRtpItem> querySendRTPServerByChnnelId(String channelId);
 }

+ 18 - 0
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java

@@ -379,6 +379,24 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
         }
     }
 
+    @Override
+    public List<SendRtpItem> querySendRTPServerByChnnelId(String channelId) {
+        if (channelId == null) {
+            return null;
+        }
+        String platformGbId = "*";
+        String callId = "*";
+        String streamId = "*";
+        String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetting.getServerId() + "_" + platformGbId
+                + "_" + channelId + "_" + streamId + "_" + callId;
+        List<Object> scan = RedisUtil.scan(key);
+        List<SendRtpItem> result = new ArrayList<>();
+        for (Object o : scan) {
+            result.add((SendRtpItem) RedisUtil.get((String) o));
+        }
+        return result;
+    }
+
     @Override
     public List<SendRtpItem> querySendRTPServer(String platformGbId) {
         if (platformGbId == null) {

+ 5 - 0
src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java

@@ -82,4 +82,9 @@ public class DateUtil {
             return false;
         }
     }
+
+    public static String getNowForISO8601() {
+        LocalDateTime nowDateTime = LocalDateTime.now();
+        return formatterISO8601.format(nowDateTime);
+    }
 }

+ 1 - 2
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java

@@ -197,7 +197,7 @@ public class PlatformController {
     @Operation(summary = "保存上级平台信息")
     @PostMapping("/save")
     @ResponseBody
-    public String savePlatform(@RequestBody ParentPlatform parentPlatform) {
+    public void savePlatform(@RequestBody ParentPlatform parentPlatform) {
 
         if (logger.isDebugEnabled()) {
             logger.debug("保存上级平台信息API调用");
@@ -247,7 +247,6 @@ public class PlatformController {
                 // 停止订阅相关的定时任务
                 subscribeHolder.removeAllSubscribe(parentPlatform.getServerGBId());
             }
-            return null;
         } else {
             throw new ControllerException(ErrorCode.ERROR100.getCode(),"写入数据库失败");
         }

+ 27 - 47
src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java

@@ -5,6 +5,7 @@ import com.alibaba.excel.ExcelReader;
 import com.alibaba.excel.read.metadata.ReadSheet;
 import com.genersoft.iot.vmp.common.StreamInfo;
 import com.genersoft.iot.vmp.conf.UserSetting;
+import com.genersoft.iot.vmp.conf.exception.ControllerException;
 import com.genersoft.iot.vmp.conf.security.SecurityUtils;
 import com.genersoft.iot.vmp.conf.security.dto.LoginUser;
 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
@@ -17,6 +18,7 @@ import com.genersoft.iot.vmp.service.IMediaService;
 import com.genersoft.iot.vmp.service.IStreamPushService;
 import com.genersoft.iot.vmp.service.impl.StreamPushUploadFileHandler;
 import com.genersoft.iot.vmp.vmanager.bean.BatchGBStreamParam;
+import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
 import com.genersoft.iot.vmp.vmanager.bean.StreamPushExcelDto;
 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
 import com.github.pagehelper.PageInfo;
@@ -95,11 +97,9 @@ public class StreamPushController {
     @PostMapping(value = "/save_to_gb")
     @ResponseBody
     @Operation(summary = "将推流添加到国标")
-    public Object saveToGB(@RequestBody GbStream stream){
-        if (streamPushService.saveToGB(stream)){
-            return "success";
-        }else {
-            return "fail";
+    public void saveToGB(@RequestBody GbStream stream){
+        if (!streamPushService.saveToGB(stream)){
+           throw new ControllerException(ErrorCode.ERROR100);
         }
     }
 
@@ -107,11 +107,9 @@ public class StreamPushController {
     @DeleteMapping(value = "/remove_form_gb")
     @ResponseBody
     @Operation(summary = "将推流移出到国标")
-    public Object removeFormGB(@RequestBody GbStream stream){
-        if (streamPushService.removeFromGB(stream)){
-            return "success";
-        }else {
-            return "fail";
+    public void removeFormGB(@RequestBody GbStream stream){
+        if (!streamPushService.removeFromGB(stream)){
+            throw new ControllerException(ErrorCode.ERROR100);
         }
     }
 
@@ -121,25 +119,21 @@ public class StreamPushController {
     @Operation(summary = "中止一个推流")
     @Parameter(name = "app", description = "应用名", required = true)
     @Parameter(name = "stream", description = "流id", required = true)
-    public Object stop(String app, String streamId){
-        if (streamPushService.stop(app, streamId)){
-            return "success";
-        }else {
-            return "fail";
+    public void stop(String app, String streamId){
+        if (!streamPushService.stop(app, streamId)){
+            throw new ControllerException(ErrorCode.ERROR100);
         }
     }
 
     @DeleteMapping(value = "/batchStop")
     @ResponseBody
     @Operation(summary = "中止多个推流")
-    public Object batchStop(@RequestBody BatchGBStreamParam batchGBStreamParam){
+    public void batchStop(@RequestBody BatchGBStreamParam batchGBStreamParam){
         if (batchGBStreamParam.getGbStreams().size() == 0) {
-            return "fail";
+            throw new ControllerException(ErrorCode.ERROR100);
         }
-        if (streamPushService.batchStop(batchGBStreamParam.getGbStreams())){
-            return "success";
-        }else {
-            return "fail";
+        if (!streamPushService.batchStop(batchGBStreamParam.getGbStreams())){
+            throw new ControllerException(ErrorCode.ERROR100);
         }
     }
 
@@ -249,7 +243,7 @@ public class StreamPushController {
     @Parameter(name = "app", description = "应用名", required = true)
     @Parameter(name = "stream", description = "流id", required = true)
     @Parameter(name = "mediaServerId", description = "媒体服务器id")
-    public WVPResult<StreamInfo> getPlayUrl(@RequestParam String app,@RequestParam String stream,
+    public StreamInfo getPlayUrl(@RequestParam String app,@RequestParam String stream,
                                             @RequestParam(required = false) String mediaServerId){
         boolean authority = false;
         // 是否登陆用户, 登陆用户返回完整信息
@@ -257,52 +251,38 @@ public class StreamPushController {
         if (userInfo!= null) {
             authority = true;
         }
-        WVPResult<StreamInfo> result = new WVPResult<>();
         StreamPushItem push = streamPushService.getPush(app, stream);
         if (push != null && !push.isSelf()) {
-            result.setCode(-1);
-            result.setMsg("来自其他平台的推流信息");
-            return result;
+            throw new ControllerException(ErrorCode.ERROR100.getCode(), "来自其他平台的推流信息");
         }
         StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority);
-        if (streamInfo != null){
-            result.setCode(0);
-            result.setMsg("success");
-            result.setData(streamInfo);
-        }else {
-            result.setCode(-1);
-            result.setMsg("获取播放地址失败");
+        if (streamInfo == null){
+            throw new ControllerException(ErrorCode.ERROR100.getCode(), "获取播放地址失败");
         }
-
-        return result;
+        return streamInfo;
     }
 
     /**
-     * 获取推流播放地址
+     * 添加推流信息
      * @param stream 推流信息
      * @return
      */
     @PostMapping(value = "/add")
     @ResponseBody
-    @Operation(summary = "停止视频回放")
-    public WVPResult<StreamInfo> add(@RequestBody StreamPushItem stream){
+    @Operation(summary = "添加推流信息")
+    public void add(@RequestBody StreamPushItem stream){
         if (ObjectUtils.isEmpty(stream.getGbId())) {
-
-            return new WVPResult<>(400, "国标ID不可为空", null);
+            throw new ControllerException(ErrorCode.ERROR400.getCode(), "国标ID不可为空");
         }
         if (ObjectUtils.isEmpty(stream.getApp()) && ObjectUtils.isEmpty(stream.getStream())) {
-            return new WVPResult<>(400, "app或stream不可为空", null);
+            throw new ControllerException(ErrorCode.ERROR400.getCode(), "app或stream不可为空");
         }
         stream.setStatus(false);
         stream.setPushIng(false);
         stream.setAliveSecond(0L);
         stream.setTotalReaderCount("0");
-        boolean result = streamPushService.add(stream);
-
-        if (result) {
-            return new WVPResult<>(0, "success", null);
-        }else {
-            return new WVPResult<>(-1, "fail", null);
+        if (!streamPushService.add(stream)) {
+            throw new ControllerException(ErrorCode.ERROR100);
         }
     }
 }

+ 20 - 10
src/main/resources/logback-spring-local.xml

@@ -77,25 +77,35 @@
 		</encoder>
 	</appender>
 
+	<!-- 生成 SIP日志追加 -->
+	<appender name="sipRollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+			<!--历史日志文件输出的文件名 -->
+			<FileNamePattern>${LOG_HOME}/sip-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
+			<!--日志文件保留天数 -->
+			<MaxHistory>30</MaxHistory>
+			<maxFileSize>50MB</maxFileSize>
+		</rollingPolicy>
+		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>
+		</encoder>
+	</appender>
+
 
 	<!-- 日志输出级别 -->
 	<root level="INFO">
 		<appender-ref ref="STDOUT" />
-		<appender-ref ref="RollingFile" />
-		<appender-ref ref="RollingFileError" />
 	</root>
 
-<!--	<logger name="com.genersoft.iot.vmp.storager.dao" level="INFO">-->
-<!--		<appender-ref ref="STDOUT"/>-->
-<!--	</logger>-->
-<!--	<logger name="com.genersoft.iot.vmp.gb28181" level="INFO">-->
-<!--		<appender-ref ref="STDOUT"/>-->
-<!--	</logger>-->
+	<logger name="GB28181_SIP" level="debug" additivity="true">
+		<appender-ref ref="RollingFileError"/>
+		<appender-ref ref="sipRollingFile"/>
+	</logger>
 
 	<!--记录druid-sql的记录-->
-	<logger name="druid.sql.Statement" level="debug" additivity="true">
+	<logger name="com.genersoft.iot.vmp.storager.dao" level="info" additivity="true">
 		<!--AppenderRef ref="Console"/-->
-		<!--		<appender-ref ref="RollingFile"/>-->
 		<appender-ref ref="RollingFileError"/>
 		<appender-ref ref="druidSqlRollingFile"/>
 	</logger>

+ 1 - 1
web_src/src/components/dialog/devicePlayer.vue

@@ -371,7 +371,7 @@ export default {
             if (tab.name === "codec") {
                 this.$axios({
                     method: 'get',
-                    url: '/zlm/' +this.mediaServerId+ '/index/api/getMediaInfo?vhost=__defaultVhost__&schema=rtmp&app='+ this.app +'&stream='+ this.streamId
+                    url: '/zlm/' +this.mediaServerId+ '/index/api/getMediaInfo?vhost=__defaultVhost__&schema=rtsp&app='+ this.app +'&stream='+ this.streamId
                 }).then(function (res) {
                     that.tracksLoading = false;
                     if (res.data.code == 0 && res.data.tracks) {

+ 9 - 10
web_src/src/components/dialog/platformEdit.vue

@@ -268,30 +268,29 @@ export default {
       }
     },
     saveForm: function (){
-      var that = this;
-      that.$axios({
+      this.$axios({
         method: 'post',
         url: this.saveUrl,
-        data: that.platform
-      }).then(function (res) {
+        data: this.platform
+      }).then((res) =>{
         if (res.data.code === 0) {
-          that.$message({
+          this.$message({
             showClose: true,
             message: "保存成功",
             type: "success",
           });
-          that.showDialog = false;
-          if (that.listChangeCallback != null) {
-            that.listChangeCallback();
+          this.showDialog = false;
+          if (this.listChangeCallback != null) {
+            this.listChangeCallback();
           }
         }else {
-          that.$message({
+          this.$message({
             showClose: true,
             message: res.data.msg,
             type: "error",
           });
         }
-      }).catch(function (error) {
+      }).catch((error)=> {
         console.log(error);
       });
     },