From d21322a93258206eb910d7ac3a70a4812fc48cbc Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期四, 03 三月 2022 18:23:52 +0800
Subject: [PATCH] 优化国标级联录像预览

---
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java |  188 +++++++++++++++++--------------
 src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java                                |   55 +++++++++
 src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java               |    4 
 src/main/java/com/genersoft/iot/vmp/gb28181/bean/SDPInfo.java                                       |   14 ++
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java                     |    2 
 src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java                               |   36 ++++-
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java    |   31 ++--
 src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java                       |    1 
 src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackCallback.java                              |    3 
 src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java                        |   10 
 src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java                                |    2 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java    |    6 
 12 files changed, 227 insertions(+), 125 deletions(-)

diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SDPInfo.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SDPInfo.java
new file mode 100644
index 0000000..39225b5
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SDPInfo.java
@@ -0,0 +1,14 @@
+package com.genersoft.iot.vmp.gb28181.bean;
+
+import javax.sdp.SessionDescription;
+
+public class SDPInfo {
+    private byte[] source;
+    private SessionDescription sdpSource;
+    private String sessionName;
+    private Long startTime;
+    private Long stopTime;
+    private String username;
+    private String address;
+    private String ssrc;
+}
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 ff871e3..437c69d 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
@@ -453,6 +453,7 @@
 			subscribeKey.put("app", "rtp");
 			subscribeKey.put("stream", ssrcInfo.getStream());
 			subscribeKey.put("regist", true);
+			subscribeKey.put("schema", "rtmp");
 			subscribeKey.put("mediaServerId", mediaServerItem.getId());
 			logger.debug("褰曞儚鍥炴斁娣诲姞璁㈤槄锛岃闃呭唴瀹癸細" + subscribeKey.toString());
 			subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
@@ -718,6 +719,7 @@
 			if (ssrcTransaction != null) {
 				MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId());
 				mediaServerService.releaseSsrc(mediaServerItem, ssrcTransaction.getSsrc());
+				mediaServerService.closeRTPServer(deviceId, channelId, ssrcTransaction.getStream());
 				streamSession.remove(deviceId, channelId, ssrcTransaction.getStream());
 			}
 		} catch (SipException | ParseException e) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
index cb03d4c..d5bc99b 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
@@ -68,7 +68,7 @@
 	 */
 	@Override
 	public void process(RequestEvent evt) {
-		logger.debug("ACK璇锋眰锛� {}", ((System.currentTimeMillis())));
+		logger.info("ACK璇锋眰锛� {}", ((System.currentTimeMillis())));
 		Dialog dialog = evt.getDialog();
 		if (dialog == null) return;
 		if (dialog.getState()== DialogState.CONFIRMED) {
@@ -88,10 +88,6 @@
 				streamInfo = new StreamInfo();
 				streamInfo.setApp(sendRtpItem.getApp());
 				streamInfo.setStream(sendRtpItem.getStreamId());
-			}else {
-				streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
-				sendRtpItem.setStreamId(streamInfo.getStream());
-				streamInfo.setApp("rtp");
 			}
 			redisCatchStorage.updateSendRTPSever(sendRtpItem);
 			logger.info(platformGbId);
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
index 60ea11b..deda783 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
@@ -2,6 +2,7 @@
 
 import com.genersoft.iot.vmp.common.StreamInfo;
 import com.genersoft.iot.vmp.gb28181.bean.Device;
+import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
@@ -90,29 +91,31 @@
 					int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId);
 					if (totalReaderCount == 0) {
 						logger.info(streamId + "鏃犲叾瀹冭鐪嬭�咃紝閫氱煡璁惧鍋滄鎺ㄦ祦");
-						cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId);
+						cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId, streamId);
 					}else if (totalReaderCount == -1){
 						logger.warn(streamId + " 鏌ユ壘鍏跺畠瑙傜湅鑰呭け璐�");
 					}
 				}
 				// 鍙兘鏄澶囦富鍔ㄥ仠姝�
 				Device device = storager.queryVideoDeviceByChannelId(platformGbId);
-				if (device != null) {
-					if (sendRtpItem.isPlay()) {
-						StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId);
-						if (streamInfo != null) {
-							redisCatchStorage.stopPlay(streamInfo);
+                if (device != null) {
+					StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId);
+					if (sendRtpItem != null) {
+						if (sendRtpItem.isPlay()) {
+							if (streamInfo != null) {
+								redisCatchStorage.stopPlay(streamInfo);
+							}
+						}else {
+							if (streamInfo != null) {
+								redisCatchStorage.stopPlayback(streamInfo);
+							}
 						}
-					}else {
-						StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(device.getDeviceId(), channelId);
-						if (streamInfo != null) {
-							redisCatchStorage.stopPlayback(streamInfo);
-						}
-					}
 
-					storager.stopPlay(device.getDeviceId(), channelId);
-					mediaServerService.closeRTPServer(device, channelId, streamInfo.getStream());
+						storager.stopPlay(device.getDeviceId(), channelId);
+						mediaServerService.closeRTPServer(device.getDeviceId(), channelId, streamInfo.getStream());
+					}
 				}
+
 			}
 		} catch (SipException e) {
 			e.printStackTrace();
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
index e08d1fb..52859e6 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
@@ -12,6 +12,7 @@
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
+import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
@@ -101,19 +102,12 @@
 	@Override
 	public void process(RequestEvent evt) {
 		//  Invite Request娑堟伅瀹炵幇锛屾娑堟伅涓�鑸负绾ц仈娑堟伅锛屼笂绾х粰涓嬬骇鍙戦�佽姹傝棰戞寚浠�
-		Long startTimeForInvite = System.currentTimeMillis();
 		try {
 			Request request = evt.getRequest();
 			SipURI sipURI = (SipURI) request.getRequestURI();
 			String channelId = sipURI.getUser();
-			String requesterId = null;
-
-			FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME);
+			String requesterId = SipUtils.getUserIdFromFromHeader(request);
 			CallIdHeader callIdHeader = (CallIdHeader)request.getHeader(CallIdHeader.NAME);
-			AddressImpl address = (AddressImpl) fromHeader.getAddress();
-			SipUri uri = (SipUri) address.getURI();
-			requesterId = uri.getUser();
-
 			if (requesterId == null || channelId == null) {
 				logger.info("鏃犳硶浠嶧romHeader鐨凙ddress涓幏鍙栧埌骞冲彴id锛岃繑鍥�400");
 				responseAck(evt, Response.BAD_REQUEST); // 鍙傛暟涓嶅叏锛� 鍙�400锛岃姹傞敊璇�
@@ -122,7 +116,9 @@
 
 			// 鏌ヨ璇锋眰鏄惁鏉ヨ嚜涓婄骇骞冲彴\璁惧
 			ParentPlatform platform = storager.queryParentPlatByServerGBId(requesterId);
-			if (platform != null) {
+			if (platform == null) {
+				inviteFromDeviceHandle(evt, requesterId);
+			}else {
 				// 鏌ヨ骞冲彴涓嬫槸鍚︽湁璇ラ�氶亾
 				DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId);
 				GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId);
@@ -141,7 +137,7 @@
 					mediaServerItem = mediaServerService.getOne(mediaServerId);
 					if (mediaServerItem == null) {
 						logger.info("[ app={}, stream={} ]鎵句笉鍒皕lm {}锛岃繑鍥�410",gbStream.getApp(), gbStream.getStream(), mediaServerId);
-						responseAck(evt, Response.GONE, "media server not found");
+						responseAck(evt, Response.GONE);
 						return;
 					}
 					Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream());
@@ -197,7 +193,6 @@
 				// 鏌ョ湅鏄惁鏀寔PS 璐熻浇96
 				//String ip = null;
 				int port = -1;
-				//boolean recvonly = false;
 				boolean mediaTransmissionTCP = false;
 				Boolean tcpActive = null;
 				for (Object description : mediaDescriptions) {
@@ -233,7 +228,6 @@
 				}
 				String username = sdp.getOrigin().getUsername();
 				String addressStr = sdp.getOrigin().getAddress();
-				//String sessionName = sdp.getSessionName().getValue();
 				logger.info("[涓婄骇鐐规挱]鐢ㄦ埛锛歿}锛� 鍦板潃锛歿}:{}锛� ssrc锛歿}", username, addressStr, port, ssrc);
 				Device device  = null;
 				// 閫氳繃 channel 鍜� gbStream 鏄惁涓簄ull 鍊煎垽鏂潵婧愭槸鐩存挱娴佸悎閫傚浗鏍�
@@ -271,8 +265,10 @@
 					Long finalStartTime = startTime;
 					Long finalStopTime = stopTime;
 					ZLMHttpHookSubscribe.Event hookEvent = (mediaServerItemInUSe, responseJSON)->{
-						logger.info("[涓婄骇鐐规挱]鏀跺埌涓嬬骇寮�濮嬬偣鎾闃咃紝 {}/{}", sendRtpItem.getApp(), sendRtpItem.getStreamId());
-						// if (sendRtpItem == null) return;
+						logger.info("[涓婄骇鐐规挱]涓嬬骇宸茬粡寮�濮嬫帹娴併�� 鍥炲200OK(SDP)锛� {}/{}", sendRtpItem.getApp(), sendRtpItem.getStreamId());
+						//     * 0 绛夊緟璁惧鎺ㄦ祦涓婃潵
+						//     * 1 涓嬬骇宸茬粡鎺ㄦ祦锛岀瓑寰呬笂绾у钩鍙板洖澶峚ck
+						//     * 2 鎺ㄦ祦涓�
 						sendRtpItem.setStatus(1);
 						redisCatchStorage.updateSendRTPSever(sendRtpItem);
 
@@ -301,9 +297,6 @@
 						} catch (ParseException e) {
 							e.printStackTrace();
 						}
-						if ("Playback".equals(sessionName) && responseJSON != null) {
-							playService.onPublishHandlerForPlayBack(finalMediaServerItem, responseJSON, finalDevice.getDeviceId(), channelId, null);
-						}
 					};
 					SipSubscribe.Event errorEvent = ((event) -> {
 						// 鏈煡閿欒銆傜洿鎺ヨ浆鍙戣澶囩偣鎾殑閿欒
@@ -319,10 +312,29 @@
 					});
 					if ("Playback".equals(sessionName)) {
 						sendRtpItem.setPlay(false);
-						SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, sendRtpItem.getSsrc(), true);
 						sendRtpItem.setStreamId(ssrc);
 						SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-						commander.playbackStreamCmd(mediaServerItem, ssrcInfo, device, channelId, format.format(start), format.format(end), hookEvent, errorEvent);
+						playService.playBack(device.getDeviceId(), channelId, format.format(start), format.format(end),result -> {
+							if (result.getCode() != 0){
+								logger.warn("褰曞儚鍥炴斁澶辫触");
+								if (result.getEvent() != null) {
+									errorEvent.response(result.getEvent());
+								}
+								try {
+									responseAck(evt, Response.REQUEST_TIMEOUT);
+								} catch (SipException e) {
+									e.printStackTrace();
+								} catch (InvalidArgumentException e) {
+									e.printStackTrace();
+								} catch (ParseException e) {
+									e.printStackTrace();
+								}
+							}else {
+								if (result.getMediaServerItem() != null) {
+									hookEvent.response(result.getMediaServerItem(), result.getResponse());
+								}
+							}
+						});
 					}else {
 						sendRtpItem.setPlay(true);
 						StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId);
@@ -333,7 +345,7 @@
 							sendRtpItem.setPlay(false);
 							playService.play(mediaServerItem,device.getDeviceId(), channelId, hookEvent,errorEvent);
 						}else {
-							sendRtpItem.setStreamId(streamInfo.getStreamId());
+							sendRtpItem.setStreamId(streamInfo.getStream());
 							hookEvent.response(mediaServerItem, null);
 						}
 					}
@@ -379,72 +391,6 @@
 					}
 				}
 
-			} else {
-				// 闈炰笂绾у钩鍙拌姹傦紝鏌ヨ鏄惁璁惧璇锋眰锛堥�氬父涓烘帴鏀惰闊冲箍鎾殑璁惧锛�
-				Device device = redisCatchStorage.getDevice(requesterId);
-				if (device != null) {
-					logger.info("鏀跺埌璁惧" + requesterId + "鐨勮闊冲箍鎾璉nvite璇锋眰");
-					responseAck(evt, Response.TRYING);
-
-					String contentString = new String(request.getRawContent());
-					// jainSip涓嶆敮鎸亂=瀛楁锛� 绉婚櫎绉婚櫎浠ヨВ鏋愩��
-					String substring = contentString;
-					String ssrc = "0000000404";
-					int ssrcIndex = contentString.indexOf("y=");
-					if (ssrcIndex > 0) {
-						substring = contentString.substring(0, ssrcIndex);
-						ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
-					}
-					ssrcIndex = substring.indexOf("f=");
-					if (ssrcIndex > 0) {
-						substring = contentString.substring(0, ssrcIndex);
-					}
-					SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);
-
-					//  鑾峰彇鏀寔鐨勬牸寮�
-					Vector mediaDescriptions = sdp.getMediaDescriptions(true);
-					// 鏌ョ湅鏄惁鏀寔PS 璐熻浇96
-					int port = -1;
-					//boolean recvonly = false;
-					boolean mediaTransmissionTCP = false;
-					Boolean tcpActive = null;
-					for (int i = 0; i < mediaDescriptions.size(); i++) {
-						MediaDescription mediaDescription = (MediaDescription)mediaDescriptions.get(i);
-						Media media = mediaDescription.getMedia();
-
-						Vector mediaFormats = media.getMediaFormats(false);
-						if (mediaFormats.contains("8")) {
-							port = media.getMediaPort();
-							String protocol = media.getProtocol();
-							// 鍖哄垎TCP鍙戞祦杩樻槸udp锛� 褰撳墠榛樿udp
-							if ("TCP/RTP/AVP".equals(protocol)) {
-								String setup = mediaDescription.getAttribute("setup");
-								if (setup != null) {
-									mediaTransmissionTCP = true;
-									if ("active".equals(setup)) {
-										tcpActive = true;
-									} else if ("passive".equals(setup)) {
-										tcpActive = false;
-									}
-								}
-							}
-							break;
-						}
-					}
-					if (port == -1) {
-						logger.info("涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415");
-						// 鍥炲涓嶆敮鎸佺殑鏍煎紡
-						responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
-						return;
-					}
-					String username = sdp.getOrigin().getUsername();
-					String addressStr = sdp.getOrigin().getAddress();
-					logger.info("璁惧{}璇锋眰璇煶娴侊紝鍦板潃锛歿}:{}锛宻src锛歿}", username, addressStr, port, ssrc);
-
-				} else {
-					logger.warn("鏉ヨ嚜鏃犳晥璁惧/骞冲彴鐨勮姹�");
-					responseAck(evt, Response.BAD_REQUEST);
-				}
 			}
 
 		} catch (SipException | InvalidArgumentException | ParseException e) {
@@ -457,4 +403,74 @@
 			e.printStackTrace();
 		}
 	}
+
+	public void inviteFromDeviceHandle(RequestEvent evt, String requesterId) throws InvalidArgumentException, ParseException, SipException, SdpException {
+
+		// 闈炰笂绾у钩鍙拌姹傦紝鏌ヨ鏄惁璁惧璇锋眰锛堥�氬父涓烘帴鏀惰闊冲箍鎾殑璁惧锛�
+		Device device = redisCatchStorage.getDevice(requesterId);
+		Request request = evt.getRequest();
+		if (device != null) {
+			logger.info("鏀跺埌璁惧" + requesterId + "鐨勮闊冲箍鎾璉nvite璇锋眰");
+			responseAck(evt, Response.TRYING);
+
+			String contentString = new String(request.getRawContent());
+			// jainSip涓嶆敮鎸亂=瀛楁锛� 绉婚櫎绉婚櫎浠ヨВ鏋愩��
+			String substring = contentString;
+			String ssrc = "0000000404";
+			int ssrcIndex = contentString.indexOf("y=");
+			if (ssrcIndex > 0) {
+				substring = contentString.substring(0, ssrcIndex);
+				ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
+			}
+			ssrcIndex = substring.indexOf("f=");
+			if (ssrcIndex > 0) {
+				substring = contentString.substring(0, ssrcIndex);
+			}
+			SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);
+
+			//  鑾峰彇鏀寔鐨勬牸寮�
+			Vector mediaDescriptions = sdp.getMediaDescriptions(true);
+			// 鏌ョ湅鏄惁鏀寔PS 璐熻浇96
+			int port = -1;
+			//boolean recvonly = false;
+			boolean mediaTransmissionTCP = false;
+			Boolean tcpActive = null;
+			for (int i = 0; i < mediaDescriptions.size(); i++) {
+				MediaDescription mediaDescription = (MediaDescription)mediaDescriptions.get(i);
+				Media media = mediaDescription.getMedia();
+
+				Vector mediaFormats = media.getMediaFormats(false);
+				if (mediaFormats.contains("8")) {
+					port = media.getMediaPort();
+					String protocol = media.getProtocol();
+					// 鍖哄垎TCP鍙戞祦杩樻槸udp锛� 褰撳墠榛樿udp
+					if ("TCP/RTP/AVP".equals(protocol)) {
+						String setup = mediaDescription.getAttribute("setup");
+						if (setup != null) {
+							mediaTransmissionTCP = true;
+							if ("active".equals(setup)) {
+								tcpActive = true;
+							} else if ("passive".equals(setup)) {
+								tcpActive = false;
+							}
+						}
+					}
+					break;
+				}
+			}
+			if (port == -1) {
+				logger.info("涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415");
+				// 鍥炲涓嶆敮鎸佺殑鏍煎紡
+				responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
+				return;
+			}
+			String username = sdp.getOrigin().getUsername();
+			String addressStr = sdp.getOrigin().getAddress();
+			logger.info("璁惧{}璇锋眰璇煶娴侊紝鍦板潃锛歿}:{}锛宻src锛歿}", username, addressStr, port, ssrc);
+
+		} else {
+			logger.warn("鏉ヨ嚜鏃犳晥璁惧/骞冲彴鐨勮姹�");
+			responseAck(evt, Response.BAD_REQUEST);
+		}
+	}
 }
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 2e8a68e..8c12c78 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
@@ -48,7 +48,7 @@
 
     SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, boolean isPlayback);
 
-    void closeRTPServer(Device device, String channelId, String ssrc);
+    void closeRTPServer(String deviceId, String channelId, String ssrc);
 
     void clearRTPServer(MediaServerItem mediaServerItem);
 
diff --git a/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackCallback.java b/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackCallback.java
index 089523f..5ed6cf3 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackCallback.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackCallback.java
@@ -1,9 +1,10 @@
 package com.genersoft.iot.vmp.service.bean;
 
 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
+import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
 
 public interface PlayBackCallback {
 
-    void call(RequestMessage msg);
+    void call(PlayBackResult<RequestMessage> msg);
 
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java b/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java
new file mode 100644
index 0000000..10a2759
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackResult.java
@@ -0,0 +1,55 @@
+package com.genersoft.iot.vmp.service.bean;
+
+import com.alibaba.fastjson.JSONObject;
+import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
+
+import javax.sip.RequestEvent;
+
+public class PlayBackResult<T> {
+     private int code;
+     private T data;
+     private MediaServerItem mediaServerItem;
+    private JSONObject response;
+    private SipSubscribe.EventResult event;
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+
+    public MediaServerItem getMediaServerItem() {
+        return mediaServerItem;
+    }
+
+    public void setMediaServerItem(MediaServerItem mediaServerItem) {
+        this.mediaServerItem = mediaServerItem;
+    }
+
+    public JSONObject getResponse() {
+        return response;
+    }
+
+    public void setResponse(JSONObject response) {
+        this.response = response;
+    }
+
+    public SipSubscribe.EventResult getEvent() {
+        return event;
+    }
+
+    public void setEvent(SipSubscribe.EventResult event) {
+        this.event = event;
+    }
+}
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 4f08c99..f226a37 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
@@ -160,16 +160,16 @@
     }
 
     @Override
-    public void closeRTPServer(Device device, String channelId, String stream) {
-        String mediaServerId = streamSession.getMediaServerId(device.getDeviceId(), channelId, stream);
-        String ssrc = streamSession.getSSRC(device.getDeviceId(), channelId, stream);
+    public void closeRTPServer(String deviceId, String channelId, String stream) {
+        String mediaServerId = streamSession.getMediaServerId(deviceId, channelId, stream);
+        String ssrc = streamSession.getSSRC(deviceId, channelId, stream);
         MediaServerItem mediaServerItem = this.getOne(mediaServerId);
         if (mediaServerItem != null) {
-            String streamId = String.format("%s_%s", device.getDeviceId(), channelId);
+            String streamId = String.format("%s_%s", deviceId, channelId);
             zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId);
             releaseSsrc(mediaServerItem, ssrc);
         }
-        streamSession.remove(device.getDeviceId(), channelId, stream);
+        streamSession.remove(deviceId, channelId, stream);
     }
 
     @Override
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 de66508..0fefb0c 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
@@ -17,6 +17,7 @@
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
 import com.genersoft.iot.vmp.service.IMediaServerService;
 import com.genersoft.iot.vmp.service.bean.PlayBackCallback;
+import com.genersoft.iot.vmp.service.bean.PlayBackResult;
 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
@@ -115,11 +116,8 @@
             msg.setData(wvpResult);
             // 鐐规挱瓒呮椂鍥炲BYE
             cmder.streamByeCmd(device.getDeviceId(), channelId, streamInfo.getStream());
-            // 閲婃斁rtpserver
-            mediaServerService.closeRTPServer(playResult.getDevice(), channelId, streamInfo.getStream());
             // 鍥炲涔嬪墠鎵�鏈夌殑鐐规挱璇锋眰
             resultHolder.invokeAllResult(msg);
-            // TODO 閲婃斁ssrc
         });
         result.onCompletion(()->{
             // 鐐规挱缁撴潫鏃惰皟鐢ㄦ埅鍥炬帴鍙�
@@ -173,7 +171,10 @@
                 WVPResult wvpResult = new WVPResult();
                 wvpResult.setCode(-1);
                 // 鐐规挱杩斿洖sip閿欒
-                mediaServerService.closeRTPServer(playResult.getDevice(), channelId, ssrcInfo.getStream());
+                mediaServerService.closeRTPServer(playResult.getDevice().getDeviceId(), channelId, ssrcInfo.getStream());
+                // 閲婃斁ssrc
+                mediaServerService.releaseSsrc(mediaServerItem, ssrcInfo.getSsrc());
+                streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
                 wvpResult.setMsg(String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", event.statusCode, event.msg));
                 msg.setData(wvpResult);
                 resultHolder.invokeAllResult(msg);
@@ -222,7 +223,10 @@
                     logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString());
                     onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid);
                 }, (event) -> {
-                    mediaServerService.closeRTPServer(playResult.getDevice(), channelId, ssrcInfo.getStream());
+                    mediaServerService.closeRTPServer(playResult.getDevice().getDeviceId(), channelId, ssrcInfo.getStream());
+                    // 閲婃斁ssrc
+                    mediaServerService.releaseSsrc(mediaServerItem, ssrcInfo.getSsrc());
+                    streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
                     WVPResult wvpResult = new WVPResult();
                     wvpResult.setCode(-1);
                     wvpResult.setMsg(String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", event.statusCode, event.msg));
@@ -240,7 +244,7 @@
         RequestMessage msg = new RequestMessage();
         msg.setId(uuid);
         msg.setKey(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId);
-        StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId);
+        StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId);
         if (streamInfo != null) {
             DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
             if (deviceChannel != null) {
@@ -298,9 +302,12 @@
         RequestMessage msg = new RequestMessage();
         msg.setId(uuid);
         msg.setKey(key);
+        PlayBackResult<RequestMessage> playBackResult = new PlayBackResult<>();
         result.onTimeout(()->{
             msg.setData("鍥炴斁瓒呮椂");
-            callback.call(msg);
+            playBackResult.setCode(-1);
+            playBackResult.setData(msg);
+            callback.call(playBackResult);
         });
         cmder.playbackStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, (MediaServerItem mediaServerItem, JSONObject response) -> {
             logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString());
@@ -308,15 +315,24 @@
             if (streamInfo == null) {
                 logger.warn("璁惧鍥炴斁API璋冪敤澶辫触锛�");
                 msg.setData("璁惧鍥炴斁API璋冪敤澶辫触锛�");
-                callback.call(msg);
+                playBackResult.setCode(-1);
+                playBackResult.setData(msg);
+                callback.call(playBackResult);
                 return;
             }
             redisCatchStorage.startPlayback(streamInfo);
             msg.setData(JSON.toJSONString(streamInfo));
-            callback.call(msg);
+            playBackResult.setCode(0);
+            playBackResult.setData(msg);
+            playBackResult.setMediaServerItem(mediaServerItem);
+            playBackResult.setResponse(response);
+            callback.call(playBackResult);
         }, event -> {
             msg.setData(String.format("鍥炴斁澶辫触锛� 閿欒鐮侊細 %s, %s", event.statusCode, event.msg));
-            callback.call(msg);
+            playBackResult.setCode(-1);
+            playBackResult.setData(msg);
+            playBackResult.setEvent(event);
+            callback.call(playBackResult);
         });
         return result;
     }
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 8350d29..fd70690 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
@@ -129,7 +129,6 @@
 			//Response response = event.getResponse();
 			msg.setData(String.format("success"));
 			resultHolder.invokeAllResult(msg);
-			mediaServerService.closeRTPServer(device, channelId, streamInfo.getStream());
 		});
 
 		if (deviceId != null || channelId != null) {
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 3607a8d..b864f46 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
@@ -77,8 +77,8 @@
 			logger.debug(String.format("璁惧鍥炴斁 API璋冪敤锛宒eviceId锛�%s 锛宑hannelId锛�%s", deviceId, channelId));
 		}
 
-		DeferredResult<ResponseEntity<String>> result = playService.playBack(deviceId, channelId, startTime, endTime, msg->{
-			resultHolder.invokeResult(msg);
+		DeferredResult<ResponseEntity<String>> result = playService.playBack(deviceId, channelId, startTime, endTime, wvpResult->{
+			resultHolder.invokeResult(wvpResult.getData());
 		});
 
 		return result;

--
Gitblit v1.8.0