From 2b3b7dbc7973def2342eecd8caf7514f0a367c1b Mon Sep 17 00:00:00 2001
From: panlinlin <648540858@qq.com>
Date: 星期五, 16 四月 2021 17:52:30 +0800
Subject: [PATCH] 使用设备Id+通道Id作为session的识别标识,解决点播异常时无法释放session的问题

---
 src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java          |   18 +++--
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java                |   48 +++++++--------
 src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java                          |   13 ++++
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java     |    2 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java                    |    5 -
 src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java                               |    2 
 src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java             |   24 +++++---
 web_src/src/components/channelList.vue                                                         |    6 +-
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java                         |    4 
 src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java                   |    4 
 web_src/src/components/dialog/devicePlayer.vue                                                 |    2 
 src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java                           |    2 
 src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java                  |   31 ++++------
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java |    2 
 src/main/resources/application.yml                                                             |    2 
 15 files changed, 87 insertions(+), 78 deletions(-)

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 65e1e5f..360472f 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
@@ -16,6 +16,7 @@
 
 	private ConcurrentHashMap<String, ClientTransaction> sessionMap = new ConcurrentHashMap<>();
 	private ConcurrentHashMap<String, String> ssrcMap = new ConcurrentHashMap<>();
+	private ConcurrentHashMap<String, String> streamIdMap = new ConcurrentHashMap<>();
 
 	public String createPlaySsrc(){
 		return SsrcUtil.getPlaySsrc();
@@ -25,18 +26,23 @@
 		return SsrcUtil.getPlayBackSsrc();
 	}
 	
-	public void put(String streamId,String ssrc,ClientTransaction transaction){
-		sessionMap.put(streamId, transaction);
-		ssrcMap.put(streamId, ssrc);
+	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 get(String streamId){
-		return sessionMap.get(streamId);
+	public ClientTransaction getTransaction(String deviceId, String channelId){
+		return sessionMap.get(deviceId + "_" + channelId);
+	}
+
+	public String getStreamId(String deviceId, String channelId){
+		return streamIdMap.get(deviceId + "_" + channelId);
 	}
 	
-	public void remove(String streamId) {
-		sessionMap.remove(streamId);
-		SsrcUtil.releaseSsrc(ssrcMap.get(streamId));
-		ssrcMap.remove(streamId);
+	public void remove(String deviceId, String channelId) {
+		sessionMap.remove(deviceId + "_" + channelId);
+		SsrcUtil.releaseSsrc(ssrcMap.get(deviceId + "_" + channelId));
+		ssrcMap.remove(deviceId + "_" + channelId);
 	}
 }
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 dd50e06..4e111d6 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
@@ -87,7 +87,6 @@
 
 	/**
 	 * 璇锋眰棰勮瑙嗛娴�
-	 * 
 	 * @param device  瑙嗛璁惧
 	 * @param channelId  棰勮閫氶亾
 	 */
@@ -108,8 +107,8 @@
 	 * 
 	 * @param ssrc  ssrc
 	 */
-	void streamByeCmd(String ssrc, SipSubscribe.Event okEvent);
-	void streamByeCmd(String 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 84c0898..e0d0bf3 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
@@ -332,17 +332,17 @@
 	
 	 /**
 	 * 	璇锋眰棰勮瑙嗛娴�
-	 * @param device  瑙嗛璁惧
-	 * @param channelId  棰勮閫氶亾
-	 * @param event hook璁㈤槄
-	 * @param errorEvent sip閿欒璁㈤槄
-	 */
+	  * @param device  瑙嗛璁惧
+	  * @param channelId  棰勮閫氶亾
+	  * @param event hook璁㈤槄
+	  * @param errorEvent sip閿欒璁㈤槄
+	  */
 	@Override
 	public void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) {
+		String streamId = null;
 		try {
 			if (device == null) return;
 			String ssrc = streamSession.createPlaySsrc();
-			String streamId = null;
 			if (rtpEnable) {
 				streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId);
 			}else {
@@ -444,9 +444,12 @@
 
 			Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "FromInvt" + tm, null, ssrc, callIdHeader);
 
-			ClientTransaction transaction = transmitRequest(device, request, errorEvent);
-			streamSession.put(streamId,ssrc, transaction);
-
+			ClientTransaction transaction = transmitRequest(device, request, (e -> {
+				streamSession.remove(device.getDeviceId(), channelId);
+				errorEvent.response(e);
+			}));
+			streamSession.put(device.getDeviceId(), channelId ,ssrc,streamId, transaction);
+			
 		} catch ( SipException | ParseException | InvalidArgumentException e) {
 			e.printStackTrace();
 		}
@@ -552,7 +555,7 @@
 	        Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader);
 
 	        ClientTransaction transaction = transmitRequest(device, request, errorEvent);
-	        streamSession.put(streamId, ssrc, transaction);
+	        streamSession.put(device.getDeviceId(), channelId, ssrc, streamId, transaction);
 
 		} catch ( SipException | ParseException | InvalidArgumentException e) {
 			e.printStackTrace();
@@ -566,17 +569,17 @@
 	 * 
 	 */
 	@Override
-	public void streamByeCmd(String ssrc) {
-		streamByeCmd(ssrc, null);
+	public void streamByeCmd(String deviceId, String channelId) {
+		streamByeCmd(deviceId, channelId, null);
 	}
 	@Override
-	public void streamByeCmd(String streamId, SipSubscribe.Event okEvent) {
+	public void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent) {
 		
 		try {
-			ClientTransaction transaction = streamSession.get(streamId);
+			ClientTransaction transaction = streamSession.getTransaction(deviceId, channelId);
 			// 鏈嶅姟閲嶅惎鍚�
 			if (transaction == null) {
-				StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
+				StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
 				if (streamInfo != null) {
 
 				}
@@ -613,14 +616,9 @@
 			}
 
 			dialog.sendRequest(clientTransaction);
-
-			streamSession.remove(streamId);
-			zlmrtpServerFactory.closeRTPServer(streamId);
-		} catch (TransactionDoesNotExistException e) {
-			e.printStackTrace();
-		} catch (SipException e) {
-			e.printStackTrace();
-		} catch (ParseException e) {
+			zlmrtpServerFactory.closeRTPServer(streamSession.getStreamId(deviceId, channelId));
+			streamSession.remove(deviceId, channelId);
+		} catch (SipException | ParseException e) {
 			e.printStackTrace();
 		}
 	}
@@ -641,7 +639,6 @@
 	 * 璇煶骞挎挱
 	 * 
 	 * @param device  瑙嗛璁惧
-	 * @param channelId  棰勮閫氶亾
 	 */
 	@Override
 	public boolean audioBroadcastCmd(Device device) {
@@ -1140,7 +1137,7 @@
 	 * @param device		瑙嗛璁惧
 	 * @param startPriority	鎶ヨ璧峰绾у埆锛堝彲閫夛級
 	 * @param endPriority	鎶ヨ缁堟绾у埆锛堝彲閫夛級
-	 * @param alarmMethods	鎶ヨ鏂瑰紡鏉′欢锛堝彲閫夛級
+	 * @param alarmMethod	鎶ヨ鏂瑰紡鏉′欢锛堝彲閫夛級
 	 * @param alarmType		鎶ヨ绫诲瀷
 	 * @param startTime		鎶ヨ鍙戠敓璧峰鏃堕棿锛堝彲閫夛級
 	 * @param endTime		鎶ヨ鍙戠敓缁堟鏃堕棿锛堝彲閫夛級
@@ -1428,5 +1425,6 @@
 			String streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId);
 			zlmrtpServerFactory.closeRTPServer(streamId);
 		}
+		streamSession.remove(device.getDeviceId(), channelId);
 	}
 }
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 ec5f921..ec136e9 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
@@ -58,7 +58,7 @@
 				redisCatchStorage.deleteSendRTPServer(platformGbId, channelId);
 				if (zlmrtpServerFactory.totalReaderCount(sendRtpItem.getApp(), streamId) == 0) {
 					System.out.println(streamId + "鏃犲叾瀹冭鐪嬭�咃紝閫氱煡璁惧鍋滄鎺ㄦ祦");
-					cmder.streamByeCmd(streamId);
+					cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId);
 				}
 			}
 		} catch (SipException e) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
index 6341fb2..6306a98 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
@@ -922,7 +922,7 @@
 				StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, "*");
 				if (streamInfo != null) {
 					redisCatchStorage.stopPlayback(streamInfo);
-					cmder.streamByeCmd(streamInfo.getStreamId());
+					cmder.streamByeCmd(streamInfo.getDeviceID(), streamInfo.getChannelId());
 				}
 			}
 		} catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
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 2a76f26..183a544 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
@@ -306,12 +306,12 @@
 				if (redisCatchStorage.isChannelSendingRTP(streamInfo.getChannelId())) {
 					ret.put("close", false);
 				} else {
-					cmder.streamByeCmd(streamId);
+					cmder.streamByeCmd(streamInfo.getDeviceID(), streamInfo.getChannelId());
 					redisCatchStorage.stopPlay(streamInfo);
 					storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
 				}
 			}else{
-				cmder.streamByeCmd(streamId);
+				cmder.streamByeCmd(streamInfo.getDeviceID(), streamInfo.getChannelId());
 				streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId);
 				redisCatchStorage.stopPlayback(streamInfo);
 			}
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 f2579cd..b4076d0 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
@@ -63,7 +63,16 @@
         playResult.setResult(result);
         // 褰曞儚鏌ヨ浠hannelId浣滀负deviceId鏌ヨ
         resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result);
-
+        // 瓒呮椂澶勭悊
+        result.onTimeout(()->{
+            logger.warn(String.format("璁惧鐐规挱瓒呮椂锛宒eviceId锛�%s 锛宑hannelId锛�%s", deviceId, channelId));
+            // 閲婃斁rtpserver
+            cmder.closeRTPServer(playResult.getDevice(), channelId);
+            RequestMessage msg = new RequestMessage();
+            msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + playResult.getUuid());
+            msg.setData("Timeout");
+            resultHolder.invokeResult(msg);
+        });
         if (streamInfo == null) {
             // 鍙戦�佺偣鎾秷鎭�
             cmder.playStreamCmd(device, channelId, (JSONObject response) -> {
@@ -76,6 +85,7 @@
                 RequestMessage msg = new RequestMessage();
                 msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
                 Response response = event.getResponse();
+                cmder.closeRTPServer(playResult.getDevice(), channelId);
                 msg.setData(String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", response.getStatusCode(), response.getReasonPhrase()));
                 resultHolder.invokeResult(msg);
                 if (errorEvent != null) {
@@ -107,6 +117,7 @@
                     logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString());
                     onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString());
                 }, event -> {
+                    cmder.closeRTPServer(playResult.getDevice(), channelId);
                     RequestMessage msg = new RequestMessage();
                     msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
                     Response response = event.getResponse();
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 d0d07f7..8b2c2bf 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -36,7 +36,7 @@
 
     StreamInfo queryPlaybackByStreamId(String steamId);
 
-    StreamInfo queryPlayByDevice(String deviceId, String code);
+    StreamInfo queryPlayByDevice(String deviceId, String channelId);
 
     /**
      * 鏇存柊娴佸獟浣撲俊鎭�
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 3417acf..98795ef 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
@@ -75,11 +75,11 @@
     }
 
     @Override
-    public StreamInfo queryPlayByDevice(String deviceId, String code) {
+    public StreamInfo queryPlayByDevice(String deviceId, String channelId) {
 //		List<Object> playLeys = redis.keys(String.format("%S_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
         List<Object> playLeys = redis.scan(String.format("%S_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
                 deviceId,
-                code));
+                channelId));
         if (playLeys == null || playLeys.size() == 0) return null;
         return (StreamInfo)redis.get(playLeys.get(0).toString());
     }
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 18f1a74..f9b6a35 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
@@ -75,27 +75,19 @@
 
 		PlayResult playResult = playService.play(deviceId, channelId, null, null);
 
-		// 瓒呮椂澶勭悊
-		playResult.getResult().onTimeout(()->{
-			logger.warn(String.format("璁惧鐐规挱瓒呮椂锛宒eviceId锛�%s 锛宑hannelId锛�%s", deviceId, channelId));
-			// 閲婃斁rtpserver
-			cmder.closeRTPServer(playResult.getDevice(), channelId);
-			RequestMessage msg = new RequestMessage();
-			msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + playResult.getUuid());
-			msg.setData("Timeout");
-			resultHolder.invokeResult(msg);
-		});
+
 		return playResult.getResult();
 	}
 
 	@ApiOperation("鍋滄鐐规挱")
 	@ApiImplicitParams({
-			@ApiImplicitParam(name = "streamId", value = "瑙嗛娴両D", dataTypeClass = String.class),
+			@ApiImplicitParam(name = "deviceId", value = "璁惧ID", dataTypeClass = String.class),
+			@ApiImplicitParam(name = "channelId", value = "閫氶亾ID", dataTypeClass = String.class),
 	})
-	@GetMapping("/stop/{streamId}")
-	public DeferredResult<ResponseEntity<String>> playStop(@PathVariable String streamId) {
+	@GetMapping("/stop/{deviceId}/{channelId}")
+	public DeferredResult<ResponseEntity<String>> playStop(@PathVariable String deviceId, @PathVariable String channelId) {
 
-		logger.debug(String.format("璁惧棰勮/鍥炴斁鍋滄API璋冪敤锛宻treamId锛�%s", streamId));
+		logger.debug(String.format("璁惧棰勮/鍥炴斁鍋滄API璋冪敤锛宻treamId锛�%s/$s", deviceId, channelId ));
 
 		UUID uuid = UUID.randomUUID();
 		DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>();
@@ -103,8 +95,8 @@
 		// 褰曞儚鏌ヨ浠hannelId浣滀负deviceId鏌ヨ
 		resultHolder.put(DeferredResultHolder.CALLBACK_CMD_STOP + uuid, result);
 
-		cmder.streamByeCmd(streamId, event -> {
-			StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
+		cmder.streamByeCmd(deviceId, channelId, event -> {
+			StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
 			if (streamInfo == null) {
 				RequestMessage msg = new RequestMessage();
 				msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
@@ -121,9 +113,10 @@
 			}
 		});
 
-		if (streamId != null) {
+		if (deviceId != null || channelId != null) {
 			JSONObject json = new JSONObject();
-			json.put("streamId", streamId);
+			json.put("deviceId", deviceId);
+			json.put("channelId", channelId);
 			RequestMessage msg = new RequestMessage();
 			msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
 			msg.setData(json.toString());
@@ -138,7 +131,7 @@
 
 		// 瓒呮椂澶勭悊
 		result.onTimeout(()->{
-			logger.warn(String.format("璁惧棰勮/鍥炴斁鍋滄瓒呮椂锛宻treamId锛�%s ", streamId));
+			logger.warn(String.format("璁惧棰勮/鍥炴斁鍋滄瓒呮椂锛宒eviceId/channelId锛�%s/$s ", deviceId, channelId));
 			RequestMessage msg = new RequestMessage();
 			msg.setId(DeferredResultHolder.CALLBACK_CMD_STOP + uuid);
 			msg.setData("Timeout");
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 daa5557..11c210e 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
@@ -84,7 +84,7 @@
 		StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId);
 		if (streamInfo != null) {
 			// 鍋滄涔嬪墠鐨勫洖鏀�
-			cmder.streamByeCmd(streamInfo.getStreamId());
+			cmder.streamByeCmd(deviceId, channelId);
 		}
 		resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result);
 		cmder.playbackStreamCmd(device, channelId, startTime, endTime, (JSONObject response) -> {
@@ -103,20 +103,22 @@
 
 	@ApiOperation("鍋滄瑙嗛鍥炴斁")
 	@ApiImplicitParams({
-			@ApiImplicitParam(name = "ssrc", value = "瑙嗛娴佹爣璇�", dataTypeClass = String.class),
+			@ApiImplicitParam(name = "deviceId", value = "璁惧ID", dataTypeClass = String.class),
+			@ApiImplicitParam(name = "channelId", value = "閫氶亾ID", dataTypeClass = String.class),
 	})
-	@GetMapping("/stop/{ssrc}")
-	public ResponseEntity<String> playStop(@PathVariable String ssrc) {
+	@GetMapping("/stop/{deviceId}/{channelId}")
+	public ResponseEntity<String> playStop(@PathVariable String deviceId, @PathVariable String channelId) {
 
-		cmder.streamByeCmd(ssrc);
+		cmder.streamByeCmd(deviceId, channelId);
 
 		if (logger.isDebugEnabled()) {
-			logger.debug(String.format("璁惧褰曞儚鍥炴斁鍋滄 API璋冪敤锛宻src锛�%s", ssrc));
+			logger.debug(String.format("璁惧褰曞儚鍥炴斁鍋滄 API璋冪敤锛宒eviceId/channelId锛�%s/%s", deviceId, channelId));
 		}
 
-		if (ssrc != null) {
+		if (deviceId != null && channelId != null) {
 			JSONObject json = new JSONObject();
-			json.put("ssrc", ssrc);
+			json.put("deviceId", deviceId);
+			json.put("channelId", channelId);
 			return new ResponseEntity<String>(json.toString(), HttpStatus.OK);
 		} else {
 			logger.warn("璁惧褰曞儚鍥炴斁鍋滄API璋冪敤澶辫触锛�");
diff --git a/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java b/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java
index bc505ef..932684a 100644
--- a/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java
+++ b/src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java
@@ -163,7 +163,7 @@
             result.put("error","鏈壘鍒版祦淇℃伅");
             return result;
         }
-        cmder.streamByeCmd(streamInfo.getStreamId());
+        cmder.streamByeCmd(serial, code);
         redisCatchStorage.stopPlay(streamInfo);
         storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
         return null;
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index caf4dfc..ef46c2a 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -1,3 +1,3 @@
 spring:
   profiles:
-    active: dev
\ No newline at end of file
+    active: local
\ No newline at end of file
diff --git a/web_src/src/components/channelList.vue b/web_src/src/components/channelList.vue
index 89fe0ae..7dbed08 100644
--- a/web_src/src/components/channelList.vue
+++ b/web_src/src/components/channelList.vue
@@ -216,12 +216,12 @@
             var that = this;
             this.$axios({
                 method: 'get',
-                url: '/api/play/stop/' + itemData.streamId 
+                url: '/api/play/stop/' + this.deviceId + "/" + itemData.channelId
             }).then(function (res) {
                 console.log(JSON.stringify(res));
                 that.initData();
             }).catch(function (error) {
-              if (error.response.status == 402) { // 宸茬粡鍋滄杩�
+              if (error.response.status === 402) { // 宸茬粡鍋滄杩�
                 that.initData();
               }else {
                 console.log(error)
@@ -253,7 +253,7 @@
 
             this.$axios({
                 method: 'get',
-                url:`/api/device/query/sub_channels/${this.deviceId}/${this.parentChannelId}/channels`, 
+                url:`/api/device/query/sub_channels/${this.deviceId}/${this.parentChannelId}/channels`,
                 params: {
                     page: that.currentPage,
                     count: that.count,
diff --git a/web_src/src/components/dialog/devicePlayer.vue b/web_src/src/components/dialog/devicePlayer.vue
index f5c7d50..6d91da9 100644
--- a/web_src/src/components/dialog/devicePlayer.vue
+++ b/web_src/src/components/dialog/devicePlayer.vue
@@ -415,7 +415,7 @@
             this.videoUrl = '';
             this.$axios({
                 method: 'get',
-                url: '/api/playback/stop/' + this.streamId
+                url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId
             }).then(function (res) {
                 if (callback) callback()
             });

--
Gitblit v1.8.0