Commit 2eb1ca2d94a09c2d3ced69de28de72d2d6d77d8e

Authored by 648540858
1 parent 6a4cdc36

国标录像支持多端同时播放

Showing 33 changed files with 282 additions and 230 deletions
src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
@@ -5,7 +5,7 @@ import com.alibaba.fastjson.JSONArray; @@ -5,7 +5,7 @@ import com.alibaba.fastjson.JSONArray;
5 public class StreamInfo { 5 public class StreamInfo {
6 6
7 private String app; 7 private String app;
8 - private String streamId; 8 + private String stream;
9 private String deviceID; 9 private String deviceID;
10 private String channelId; 10 private String channelId;
11 private String flv; 11 private String flv;
@@ -153,12 +153,12 @@ public class StreamInfo { @@ -153,12 +153,12 @@ public class StreamInfo {
153 this.ws_ts = ws_ts; 153 this.ws_ts = ws_ts;
154 } 154 }
155 155
156 - public String getStreamId() {  
157 - return streamId; 156 + public String getStream() {
  157 + return stream;
158 } 158 }
159 159
160 - public void setStreamId(String streamId) {  
161 - this.streamId = streamId; 160 + public void setStream(String stream) {
  161 + this.stream = stream;
162 } 162 }
163 163
164 public String getRtc() { 164 public String getRtc() {
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
@@ -29,6 +29,7 @@ public class VideoManagerConstants { @@ -29,6 +29,7 @@ public class VideoManagerConstants {
29 // 此处多了一个_,暂不修改 29 // 此处多了一个_,暂不修改
30 public static final String PLAYER_PREFIX = "VMP_PLAYER_"; 30 public static final String PLAYER_PREFIX = "VMP_PLAYER_";
31 public static final String PLAY_BLACK_PREFIX = "VMP_PLAYBACK_"; 31 public static final String PLAY_BLACK_PREFIX = "VMP_PLAYBACK_";
  32 + public static final String PLAY_INFO_PREFIX = "VMP_PLAY_INFO_";
32 33
33 public static final String DOWNLOAD_PREFIX = "VMP_DOWNLOAD_"; 34 public static final String DOWNLOAD_PREFIX = "VMP_DOWNLOAD_";
34 35
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SsrcTransaction.java
@@ -4,11 +4,12 @@ public class SsrcTransaction { @@ -4,11 +4,12 @@ public class SsrcTransaction {
4 4
5 private String deviceId; 5 private String deviceId;
6 private String channelId; 6 private String channelId;
7 - private String ssrc;  
8 - private String streamId; 7 + private String callId;
  8 + private String stream;
9 private byte[] transaction; 9 private byte[] transaction;
10 private byte[] dialog; 10 private byte[] dialog;
11 private String mediaServerId; 11 private String mediaServerId;
  12 + private String ssrc;
12 13
13 public String getDeviceId() { 14 public String getDeviceId() {
14 return deviceId; 15 return deviceId;
@@ -26,20 +27,20 @@ public class SsrcTransaction { @@ -26,20 +27,20 @@ public class SsrcTransaction {
26 this.channelId = channelId; 27 this.channelId = channelId;
27 } 28 }
28 29
29 - public String getSsrc() {  
30 - return ssrc; 30 + public String getCallId() {
  31 + return callId;
31 } 32 }
32 33
33 - public void setSsrc(String ssrc) {  
34 - this.ssrc = ssrc; 34 + public void setCallId(String callId) {
  35 + this.callId = callId;
35 } 36 }
36 37
37 - public String getStreamId() {  
38 - return streamId; 38 + public String getStream() {
  39 + return stream;
39 } 40 }
40 41
41 - public void setStreamId(String streamId) {  
42 - this.streamId = streamId; 42 + public void setStream(String stream) {
  43 + this.stream = stream;
43 } 44 }
44 45
45 public byte[] getTransaction() { 46 public byte[] getTransaction() {
@@ -65,4 +66,12 @@ public class SsrcTransaction { @@ -65,4 +66,12 @@ public class SsrcTransaction {
65 public void setMediaServerId(String mediaServerId) { 66 public void setMediaServerId(String mediaServerId) {
66 this.mediaServerId = mediaServerId; 67 this.mediaServerId = mediaServerId;
67 } 68 }
  69 +
  70 + public String getSsrc() {
  71 + return ssrc;
  72 + }
  73 +
  74 + public void setSsrc(String ssrc) {
  75 + this.ssrc = ssrc;
  76 + }
68 } 77 }
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
@@ -14,6 +14,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil; @@ -14,6 +14,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil;
14 import gov.nist.javax.sip.stack.SIPDialog; 14 import gov.nist.javax.sip.stack.SIPDialog;
15 import org.springframework.beans.factory.annotation.Autowired; 15 import org.springframework.beans.factory.annotation.Autowired;
16 import org.springframework.stereotype.Component; 16 import org.springframework.stereotype.Component;
  17 +import org.springframework.util.StringUtils;
17 18
18 /** 19 /**
19 * @description:视频流session管理器,管理视频预览、预览回放的通信句柄 20 * @description:视频流session管理器,管理视频预览、预览回放的通信句柄
@@ -29,39 +30,55 @@ public class VideoStreamSessionManager { @@ -29,39 +30,55 @@ public class VideoStreamSessionManager {
29 @Autowired 30 @Autowired
30 private UserSetup userSetup; 31 private UserSetup userSetup;
31 32
32 - public void put(String deviceId, String channelId ,String ssrc, String streamId, String mediaServerId, ClientTransaction transaction){ 33 + /**
  34 + * 添加一个点播/回放的事务信息
  35 + * 后续可以通过流Id/callID
  36 + * @param deviceId 设备ID
  37 + * @param channelId 通道ID
  38 + * @param callId 一次请求的CallID
  39 + * @param stream 流名称
  40 + * @param mediaServerId 所使用的流媒体ID
  41 + * @param transaction 事务
  42 + */
  43 + public void put(String deviceId, String channelId, String callId, String stream, String ssrc, String mediaServerId, ClientTransaction transaction){
33 SsrcTransaction ssrcTransaction = new SsrcTransaction(); 44 SsrcTransaction ssrcTransaction = new SsrcTransaction();
34 ssrcTransaction.setDeviceId(deviceId); 45 ssrcTransaction.setDeviceId(deviceId);
35 ssrcTransaction.setChannelId(channelId); 46 ssrcTransaction.setChannelId(channelId);
36 - ssrcTransaction.setStreamId(streamId); 47 + ssrcTransaction.setStream(stream);
37 byte[] transactionByteArray = SerializeUtils.serialize(transaction); 48 byte[] transactionByteArray = SerializeUtils.serialize(transaction);
38 ssrcTransaction.setTransaction(transactionByteArray); 49 ssrcTransaction.setTransaction(transactionByteArray);
  50 + ssrcTransaction.setCallId(callId);
39 ssrcTransaction.setSsrc(ssrc); 51 ssrcTransaction.setSsrc(ssrc);
40 ssrcTransaction.setMediaServerId(mediaServerId); 52 ssrcTransaction.setMediaServerId(mediaServerId);
41 53
42 - redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId() + "_" + deviceId + "_" + channelId, ssrcTransaction); 54 + redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId()
  55 + + "_" + deviceId + "_" + channelId + "_" + callId + "_" + stream, ssrcTransaction);
  56 + redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId()
  57 + + "_" + deviceId + "_" + channelId + "_" + callId + "_" + stream, ssrcTransaction);
43 } 58 }
44 59
45 - public void put(String deviceId, String channelId , Dialog dialog){  
46 - SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); 60 + public void put(String deviceId, String channelId, String callId, Dialog dialog){
  61 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, callId, null);
47 if (ssrcTransaction != null) { 62 if (ssrcTransaction != null) {
48 byte[] dialogByteArray = SerializeUtils.serialize(dialog); 63 byte[] dialogByteArray = SerializeUtils.serialize(dialog);
49 ssrcTransaction.setDialog(dialogByteArray); 64 ssrcTransaction.setDialog(dialogByteArray);
50 } 65 }
51 - redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId() + "_" + deviceId + "_" + channelId, ssrcTransaction); 66 + redisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId()
  67 + + "_" + deviceId + "_" + channelId + "_" + ssrcTransaction.getCallId() + "_"
  68 + + ssrcTransaction.getStream(), ssrcTransaction);
52 } 69 }
53 70
54 71
55 - public ClientTransaction getTransaction(String deviceId, String channelId){  
56 - SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); 72 + public ClientTransaction getTransactionByStream(String deviceId, String channelId, String stream){
  73 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream);
57 if (ssrcTransaction == null) return null; 74 if (ssrcTransaction == null) return null;
58 byte[] transactionByteArray = ssrcTransaction.getTransaction(); 75 byte[] transactionByteArray = ssrcTransaction.getTransaction();
59 ClientTransaction clientTransaction = (ClientTransaction)SerializeUtils.deSerialize(transactionByteArray); 76 ClientTransaction clientTransaction = (ClientTransaction)SerializeUtils.deSerialize(transactionByteArray);
60 return clientTransaction; 77 return clientTransaction;
61 } 78 }
62 79
63 - public SIPDialog getDialog(String deviceId, String channelId){  
64 - SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); 80 + public SIPDialog getDialogByStream(String deviceId, String channelId, String stream){
  81 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream);
65 if (ssrcTransaction == null) return null; 82 if (ssrcTransaction == null) return null;
66 byte[] dialogByteArray = ssrcTransaction.getDialog(); 83 byte[] dialogByteArray = ssrcTransaction.getDialog();
67 if (dialogByteArray == null) return null; 84 if (dialogByteArray == null) return null;
@@ -69,36 +86,37 @@ public class VideoStreamSessionManager { @@ -69,36 +86,37 @@ public class VideoStreamSessionManager {
69 return dialog; 86 return dialog;
70 } 87 }
71 88
72 - public SsrcTransaction getSsrcTransaction(String deviceId, String channelId){  
73 - SsrcTransaction ssrcTransaction = (SsrcTransaction)redisUtil.get(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId() + "_" + deviceId + "_" + channelId);  
74 - return ssrcTransaction; 89 + public SsrcTransaction getSsrcTransaction(String deviceId, String channelId, String callId, String stream){
  90 + if (StringUtils.isEmpty(callId)) callId ="*";
  91 + if (StringUtils.isEmpty(stream)) stream ="*";
  92 + String key = VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId() + "_" + deviceId + "_" + channelId + "_" + callId+ "_" + stream;
  93 + List<Object> scanResult = redisUtil.scan(key);
  94 + if (scanResult.size() == 0) return null;
  95 + return (SsrcTransaction)redisUtil.get((String) scanResult.get(0));
75 } 96 }
76 97
77 - public String getStreamId(String deviceId, String channelId){  
78 - SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId);  
79 - if (ssrcTransaction == null) return null;  
80 - return ssrcTransaction.getStreamId();  
81 - }  
82 - public String getMediaServerId(String deviceId, String channelId){  
83 - SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); 98 + public String getMediaServerId(String deviceId, String channelId, String stream){
  99 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream);
84 if (ssrcTransaction == null) return null; 100 if (ssrcTransaction == null) return null;
85 return ssrcTransaction.getMediaServerId(); 101 return ssrcTransaction.getMediaServerId();
86 } 102 }
87 103
88 - public String getSSRC(String deviceId, String channelId){  
89 - SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); 104 + public String getSSRC(String deviceId, String channelId, String stream){
  105 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream);
90 if (ssrcTransaction == null) return null; 106 if (ssrcTransaction == null) return null;
91 return ssrcTransaction.getSsrc(); 107 return ssrcTransaction.getSsrc();
92 } 108 }
93 109
94 - public void remove(String deviceId, String channelId) {  
95 - SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId); 110 + public void remove(String deviceId, String channelId, String stream) {
  111 + SsrcTransaction ssrcTransaction = getSsrcTransaction(deviceId, channelId, null, stream);
96 if (ssrcTransaction == null) return; 112 if (ssrcTransaction == null) return;
97 - redisUtil.del(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId() + "_" + deviceId + "_" + channelId); 113 + redisUtil.del(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetup.getServerId() + "_"
  114 + + deviceId + "_" + channelId + "_" + ssrcTransaction.getCallId() + "_" + ssrcTransaction.getStream());
98 } 115 }
99 116
  117 +
100 public List<SsrcTransaction> getAllSsrc() { 118 public List<SsrcTransaction> getAllSsrc() {
101 - List<Object> ssrcTransactionKeys = redisUtil.scan(String.format("%s_*_*", VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX+ userSetup.getServerId() + "_" )); 119 + List<Object> ssrcTransactionKeys = redisUtil.scan(String.format("%s_*_*_*_*", VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX+ userSetup.getServerId() + "_" ));
102 List<SsrcTransaction> result= new ArrayList<>(); 120 List<SsrcTransaction> result= new ArrayList<>();
103 for (int i = 0; i < ssrcTransactionKeys.size(); i++) { 121 for (int i = 0; i < ssrcTransactionKeys.size(); i++) {
104 String key = (String)ssrcTransactionKeys.get(i); 122 String key = (String)ssrcTransactionKeys.get(i);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
@@ -119,8 +119,8 @@ public interface ISIPCommander { @@ -119,8 +119,8 @@ public interface ISIPCommander {
119 /** 119 /**
120 * 视频流停止 120 * 视频流停止
121 */ 121 */
122 - void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent);  
123 - void streamByeCmd(String deviceId, String channelId); 122 + void streamByeCmd(String deviceId, String channelId, String ssrc, SipSubscribe.Event okEvent);
  123 + void streamByeCmd(String deviceId, String channelId, String ssrc);
124 124
125 /** 125 /**
126 * 回放暂停 126 * 回放暂停
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
@@ -17,7 +17,7 @@ public interface ISIPCommanderForPlatform { @@ -17,7 +17,7 @@ public interface ISIPCommanderForPlatform {
17 * @return 17 * @return
18 */ 18 */
19 boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent); 19 boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent);
20 - boolean register(ParentPlatform parentPlatform, String callId, WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent); 20 + boolean register(ParentPlatform parentPlatform, String callId, WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain);
21 21
22 /** 22 /**
23 * 向上级平台注销 23 * 向上级平台注销
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
@@ -128,7 +128,15 @@ public class SIPRequestHeaderPlarformProvider { @@ -128,7 +128,15 @@ public class SIPRequestHeaderPlarformProvider {
128 128
129 129
130 Request registerRequest = createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(Request.REGISTER), fromTag, viaTag, callIdHeader); 130 Request registerRequest = createRegisterRequest(parentPlatform, redisCatchStorage.getCSEQ(Request.REGISTER), fromTag, viaTag, callIdHeader);
131 - 131 + SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort());
  132 + if (www == null) {
  133 + AuthorizationHeader authorizationHeader = sipFactory.createHeaderFactory().createAuthorizationHeader("Digest");
  134 + authorizationHeader.setUsername(parentPlatform.getDeviceGBId());
  135 + authorizationHeader.setURI(requestURI);
  136 + authorizationHeader.setAlgorithm("MD5");
  137 + registerRequest.addHeader(authorizationHeader);
  138 + return registerRequest;
  139 + }
132 String realm = www.getRealm(); 140 String realm = www.getRealm();
133 String nonce = www.getNonce(); 141 String nonce = www.getNonce();
134 String scheme = www.getScheme(); 142 String scheme = www.getScheme();
@@ -139,7 +147,6 @@ public class SIPRequestHeaderPlarformProvider { @@ -139,7 +147,6 @@ public class SIPRequestHeaderPlarformProvider {
139 147
140 callIdHeader.setCallId(callId); 148 callIdHeader.setCallId(callId);
141 149
142 - SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort());  
143 String cNonce = null; 150 String cNonce = null;
144 String nc = "00000001"; 151 String nc = "00000001";
145 if (qop != null) { 152 if (qop != null) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
@@ -226,7 +226,7 @@ public class SIPRequestHeaderProvider { @@ -226,7 +226,7 @@ public class SIPRequestHeaderProvider {
226 throws PeerUnavailableException, ParseException, InvalidArgumentException { 226 throws PeerUnavailableException, ParseException, InvalidArgumentException {
227 Request request = null; 227 Request request = null;
228 if (streamInfo == null) return null; 228 if (streamInfo == null) return null;
229 - Dialog dialog = streamSession.getDialog(streamInfo.getDeviceID(), streamInfo.getChannelId()); 229 + Dialog dialog = streamSession.getDialogByStream(streamInfo.getDeviceID(), streamInfo.getChannelId(), streamInfo.getStream());
230 230
231 SipURI requestLine = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(), 231 SipURI requestLine = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(),
232 device.getHostAddress()); 232 device.getHostAddress());
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -331,7 +331,7 @@ public class SIPCommander implements ISIPCommander { @@ -331,7 +331,7 @@ public class SIPCommander implements ISIPCommander {
331 */ 331 */
332 @Override 332 @Override
333 public void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) { 333 public void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) {
334 - String streamId = ssrcInfo.getStreamId(); 334 + String streamId = ssrcInfo.getStream();
335 try { 335 try {
336 if (device == null) return; 336 if (device == null) return;
337 String streamMode = device.getStreamMode().toUpperCase(); 337 String streamMode = device.getStreamMode().toUpperCase();
@@ -404,6 +404,8 @@ public class SIPCommander implements ISIPCommander { @@ -404,6 +404,8 @@ public class SIPCommander implements ISIPCommander {
404 } 404 }
405 405
406 content.append("y="+ssrcInfo.getSsrc()+"\r\n");//ssrc 406 content.append("y="+ssrcInfo.getSsrc()+"\r\n");//ssrc
  407 + // f字段:f= v/编码格式/分辨率/帧率/码率类型/码率大小a/编码格式/码率大小/采样率
  408 +// content.append("f=v/2/5/25/1/4000a/1/8/1" + "\r\n"); // 未发现支持此特性的设备
407 409
408 String tm = Long.toString(System.currentTimeMillis()); 410 String tm = Long.toString(System.currentTimeMillis());
409 411
@@ -412,14 +414,14 @@ public class SIPCommander implements ISIPCommander { @@ -412,14 +414,14 @@ public class SIPCommander implements ISIPCommander {
412 414
413 Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "FromInvt" + tm, null, ssrcInfo.getSsrc(), callIdHeader); 415 Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "FromInvt" + tm, null, ssrcInfo.getSsrc(), callIdHeader);
414 416
415 - String finalStreamId = streamId;  
416 transmitRequest(device, request, (e -> { 417 transmitRequest(device, request, (e -> {
417 - streamSession.remove(device.getDeviceId(), channelId); 418 + streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
418 mediaServerService.releaseSsrc(mediaServerItem, ssrcInfo.getSsrc()); 419 mediaServerService.releaseSsrc(mediaServerItem, ssrcInfo.getSsrc());
419 errorEvent.response(e); 420 errorEvent.response(e);
420 }), e ->{ 421 }), e ->{
421 - streamSession.put(device.getDeviceId(), channelId ,ssrcInfo.getSsrc(), finalStreamId, mediaServerItem.getId(), ((ResponseEvent)e.event).getClientTransaction());  
422 - streamSession.put(device.getDeviceId(), channelId , e.dialog); 422 + // 这里为例避免一个通道的点播只有一个callID这个参数使用一个固定值
  423 + streamSession.put(device.getDeviceId(), channelId ,"play", streamId, ssrcInfo.getSsrc(), mediaServerItem.getId(), ((ResponseEvent)e.event).getClientTransaction());
  424 + streamSession.put(device.getDeviceId(), channelId ,"play", e.dialog);
423 }); 425 });
424 426
425 427
@@ -441,12 +443,12 @@ public class SIPCommander implements ISIPCommander { @@ -441,12 +443,12 @@ public class SIPCommander implements ISIPCommander {
441 , SipSubscribe.Event errorEvent) { 443 , SipSubscribe.Event errorEvent) {
442 try { 444 try {
443 445
444 - logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStreamId(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); 446 + logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort());
445 447
446 // 添加订阅 448 // 添加订阅
447 JSONObject subscribeKey = new JSONObject(); 449 JSONObject subscribeKey = new JSONObject();
448 subscribeKey.put("app", "rtp"); 450 subscribeKey.put("app", "rtp");
449 - subscribeKey.put("stream", ssrcInfo.getStreamId()); 451 + subscribeKey.put("stream", ssrcInfo.getStream());
450 subscribeKey.put("regist", true); 452 subscribeKey.put("regist", true);
451 subscribeKey.put("mediaServerId", mediaServerItem.getId()); 453 subscribeKey.put("mediaServerId", mediaServerItem.getId());
452 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString()); 454 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());
@@ -466,8 +468,6 @@ public class SIPCommander implements ISIPCommander { @@ -466,8 +468,6 @@ public class SIPCommander implements ISIPCommander {
466 content.append("t="+DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime)+" " 468 content.append("t="+DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime)+" "
467 +DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime) +"\r\n"); 469 +DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime) +"\r\n");
468 470
469 -  
470 -  
471 String streamMode = device.getStreamMode().toUpperCase(); 471 String streamMode = device.getStreamMode().toUpperCase();
472 472
473 if (userSetup.isSeniorSdp()) { 473 if (userSetup.isSeniorSdp()) {
@@ -527,8 +527,8 @@ public class SIPCommander implements ISIPCommander { @@ -527,8 +527,8 @@ public class SIPCommander implements ISIPCommander {
527 527
528 transmitRequest(device, request, errorEvent, okEvent -> { 528 transmitRequest(device, request, errorEvent, okEvent -> {
529 ResponseEvent responseEvent = (ResponseEvent) okEvent.event; 529 ResponseEvent responseEvent = (ResponseEvent) okEvent.event;
530 - streamSession.put(device.getDeviceId(), channelId, ssrcInfo.getSsrc(), ssrcInfo.getStreamId(), mediaServerItem.getId(), responseEvent.getClientTransaction());  
531 - streamSession.put(device.getDeviceId(), channelId, okEvent.dialog); 530 + streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), responseEvent.getClientTransaction());
  531 + streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), okEvent.dialog);
532 }); 532 });
533 } catch ( SipException | ParseException | InvalidArgumentException e) { 533 } catch ( SipException | ParseException | InvalidArgumentException e) {
534 e.printStackTrace(); 534 e.printStackTrace();
@@ -548,12 +548,12 @@ public class SIPCommander implements ISIPCommander { @@ -548,12 +548,12 @@ public class SIPCommander implements ISIPCommander {
548 public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event 548 public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event
549 , SipSubscribe.Event errorEvent) { 549 , SipSubscribe.Event errorEvent) {
550 try { 550 try {
551 - logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStreamId(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); 551 + logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort());
552 552
553 // 添加订阅 553 // 添加订阅
554 JSONObject subscribeKey = new JSONObject(); 554 JSONObject subscribeKey = new JSONObject();
555 subscribeKey.put("app", "rtp"); 555 subscribeKey.put("app", "rtp");
556 - subscribeKey.put("stream", ssrcInfo.getStreamId()); 556 + subscribeKey.put("stream", ssrcInfo.getStream());
557 subscribeKey.put("regist", true); 557 subscribeKey.put("regist", true);
558 subscribeKey.put("mediaServerId", mediaServerItem.getId()); 558 subscribeKey.put("mediaServerId", mediaServerItem.getId());
559 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString()); 559 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());
@@ -634,7 +634,8 @@ public class SIPCommander implements ISIPCommander { @@ -634,7 +634,8 @@ public class SIPCommander implements ISIPCommander {
634 Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc()); 634 Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc());
635 635
636 ClientTransaction transaction = transmitRequest(device, request, errorEvent); 636 ClientTransaction transaction = transmitRequest(device, request, errorEvent);
637 - streamSession.put(device.getDeviceId(), channelId, ssrcInfo.getSsrc(), ssrcInfo.getStreamId(), mediaServerItem.getId(), transaction); 637 + streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), transaction);
  638 + streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), transaction);
638 639
639 } catch ( SipException | ParseException | InvalidArgumentException e) { 640 } catch ( SipException | ParseException | InvalidArgumentException e) {
640 e.printStackTrace(); 641 e.printStackTrace();
@@ -645,17 +646,17 @@ public class SIPCommander implements ISIPCommander { @@ -645,17 +646,17 @@ public class SIPCommander implements ISIPCommander {
645 * 视频流停止, 不使用回调 646 * 视频流停止, 不使用回调
646 */ 647 */
647 @Override 648 @Override
648 - public void streamByeCmd(String deviceId, String channelId) {  
649 - streamByeCmd(deviceId, channelId, null); 649 + public void streamByeCmd(String deviceId, String channelId, String stream) {
  650 + streamByeCmd(deviceId, channelId, stream, null);
650 } 651 }
651 652
652 /** 653 /**
653 * 视频流停止 654 * 视频流停止
654 */ 655 */
655 @Override 656 @Override
656 - public void streamByeCmd(String deviceId, String channelId, SipSubscribe.Event okEvent) { 657 + public void streamByeCmd(String deviceId, String channelId, String stream, SipSubscribe.Event okEvent) {
657 try { 658 try {
658 - ClientTransaction transaction = streamSession.getTransaction(deviceId, channelId); 659 + ClientTransaction transaction = streamSession.getTransactionByStream(deviceId, channelId, stream);
659 if (transaction == null) { 660 if (transaction == null) {
660 logger.warn("[ {} -> {}]停止视频流的时候发现事务已丢失", deviceId, channelId); 661 logger.warn("[ {} -> {}]停止视频流的时候发现事务已丢失", deviceId, channelId);
661 SipSubscribe.EventResult<Object> eventResult = new SipSubscribe.EventResult<>(); 662 SipSubscribe.EventResult<Object> eventResult = new SipSubscribe.EventResult<>();
@@ -664,7 +665,7 @@ public class SIPCommander implements ISIPCommander { @@ -664,7 +665,7 @@ public class SIPCommander implements ISIPCommander {
664 } 665 }
665 return; 666 return;
666 } 667 }
667 - SIPDialog dialog = streamSession.getDialog(deviceId, channelId); 668 + SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, stream);
668 if (dialog == null) { 669 if (dialog == null) {
669 logger.warn("[ {} -> {}]停止视频流的时候发现对话已丢失", deviceId, channelId); 670 logger.warn("[ {} -> {}]停止视频流的时候发现对话已丢失", deviceId, channelId);
670 return; 671 return;
@@ -708,11 +709,11 @@ public class SIPCommander implements ISIPCommander { @@ -708,11 +709,11 @@ public class SIPCommander implements ISIPCommander {
708 709
709 dialog.sendRequest(clientTransaction); 710 dialog.sendRequest(clientTransaction);
710 711
711 - SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(deviceId, channelId); 712 + SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(deviceId, channelId, callIdHeader.getCallId(), null);
712 if (ssrcTransaction != null) { 713 if (ssrcTransaction != null) {
713 MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId()); 714 MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId());
714 mediaServerService.releaseSsrc(mediaServerItem, ssrcTransaction.getSsrc()); 715 mediaServerService.releaseSsrc(mediaServerItem, ssrcTransaction.getSsrc());
715 - streamSession.remove(deviceId, channelId); 716 + streamSession.remove(deviceId, channelId, ssrcTransaction.getStream());
716 } 717 }
717 } catch (SipException | ParseException e) { 718 } catch (SipException | ParseException e) {
718 e.printStackTrace(); 719 e.printStackTrace();
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
@@ -53,7 +53,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -53,7 +53,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
53 53
54 @Override 54 @Override
55 public boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) { 55 public boolean register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) {
56 - return register(parentPlatform, null, null, errorEvent, okEvent); 56 + return register(parentPlatform, null, null, errorEvent, okEvent, false);
57 } 57 }
58 58
59 @Override 59 @Override
@@ -65,15 +65,16 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -65,15 +65,16 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
65 redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); 65 redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
66 } 66 }
67 67
68 - return register(parentPlatform, null, null, errorEvent, okEvent); 68 + return register(parentPlatform, null, null, errorEvent, okEvent, false);
69 } 69 }
70 70
71 @Override 71 @Override
72 - public boolean register(ParentPlatform parentPlatform, @Nullable String callId, @Nullable WWWAuthenticateHeader www, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) { 72 + public boolean register(ParentPlatform parentPlatform, @Nullable String callId, @Nullable WWWAuthenticateHeader www,
  73 + SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent, boolean registerAgain) {
73 try { 74 try {
74 Request request = null; 75 Request request = null;
75 String tm = Long.toString(System.currentTimeMillis()); 76 String tm = Long.toString(System.currentTimeMillis());
76 - if (www == null ) { 77 + if (!registerAgain ) {
77 // //callid 78 // //callid
78 CallIdHeader callIdHeader = null; 79 CallIdHeader callIdHeader = null;
79 if(parentPlatform.getTransport().equals("TCP")) { 80 if(parentPlatform.getTransport().equals("TCP")) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
@@ -72,10 +72,10 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In @@ -72,10 +72,10 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
72 if (deviceId == null) { 72 if (deviceId == null) {
73 streamInfo = new StreamInfo(); 73 streamInfo = new StreamInfo();
74 streamInfo.setApp(sendRtpItem.getApp()); 74 streamInfo.setApp(sendRtpItem.getApp());
75 - streamInfo.setStreamId(sendRtpItem.getStreamId()); 75 + streamInfo.setStream(sendRtpItem.getStreamId());
76 }else { 76 }else {
77 streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); 77 streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
78 - sendRtpItem.setStreamId(streamInfo.getStreamId()); 78 + sendRtpItem.setStreamId(streamInfo.getStream());
79 streamInfo.setApp("rtp"); 79 streamInfo.setApp("rtp");
80 } 80 }
81 81
@@ -85,7 +85,7 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In @@ -85,7 +85,7 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
85 Map<String, Object> param = new HashMap<>(); 85 Map<String, Object> param = new HashMap<>();
86 param.put("vhost","__defaultVhost__"); 86 param.put("vhost","__defaultVhost__");
87 param.put("app",streamInfo.getApp()); 87 param.put("app",streamInfo.getApp());
88 - param.put("stream",streamInfo.getStreamId()); 88 + param.put("stream",streamInfo.getStream());
89 param.put("ssrc", sendRtpItem.getSsrc()); 89 param.put("ssrc", sendRtpItem.getSsrc());
90 param.put("dst_url",sendRtpItem.getIp()); 90 param.put("dst_url",sendRtpItem.getIp());
91 param.put("dst_port", sendRtpItem.getPort()); 91 param.put("dst_port", sendRtpItem.getPort());
@@ -98,21 +98,21 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In @@ -98,21 +98,21 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
98 try { 98 try {
99 if (System.currentTimeMillis() - startTime < 30 * 1000) { 99 if (System.currentTimeMillis() - startTime < 30 * 1000) {
100 MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); 100 MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
101 - if (zlmrtpServerFactory.isStreamReady(mediaInfo, streamInfo.getApp(), streamInfo.getStreamId())) { 101 + if (zlmrtpServerFactory.isStreamReady(mediaInfo, streamInfo.getApp(), streamInfo.getStream())) {
102 rtpPushed = true; 102 rtpPushed = true;
103 logger.info("已获取设备推流[{}/{}],开始向上级推流[{}:{}]", 103 logger.info("已获取设备推流[{}/{}],开始向上级推流[{}:{}]",
104 - streamInfo.getApp() ,streamInfo.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort()); 104 + streamInfo.getApp() ,streamInfo.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort());
105 zlmrtpServerFactory.startSendRtpStream(mediaInfo, param); 105 zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
106 } else { 106 } else {
107 logger.info("等待设备推流[{}/{}].......", 107 logger.info("等待设备推流[{}/{}].......",
108 - streamInfo.getApp() ,streamInfo.getStreamId()); 108 + streamInfo.getApp() ,streamInfo.getStream());
109 Thread.sleep(1000); 109 Thread.sleep(1000);
110 continue; 110 continue;
111 } 111 }
112 } else { 112 } else {
113 rtpPushed = true; 113 rtpPushed = true;
114 logger.info("设备推流[{}/{}]超时,终止向上级推流", 114 logger.info("设备推流[{}/{}]超时,终止向上级推流",
115 - streamInfo.getApp() ,streamInfo.getStreamId()); 115 + streamInfo.getApp() ,streamInfo.getStream());
116 } 116 }
117 } catch (InterruptedException e) { 117 } catch (InterruptedException e) {
118 e.printStackTrace(); 118 e.printStackTrace();
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
@@ -89,18 +89,19 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In @@ -89,18 +89,19 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
89 redisCatchStorage.deleteSendRTPServer(platformGbId, channelId); 89 redisCatchStorage.deleteSendRTPServer(platformGbId, channelId);
90 if (zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId) == 0) { 90 if (zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId) == 0) {
91 logger.info(streamId + "无其它观看者,通知设备停止推流"); 91 logger.info(streamId + "无其它观看者,通知设备停止推流");
92 - cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId); 92 + cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId, streamId);
93 } 93 }
94 } 94 }
95 // 可能是设备主动停止 95 // 可能是设备主动停止
96 Device device = storager.queryVideoDeviceByChannelId(platformGbId); 96 Device device = storager.queryVideoDeviceByChannelId(platformGbId);
97 if (device != null) { 97 if (device != null) {
98 StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId); 98 StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId);
  99 +
99 if (streamInfo != null) { 100 if (streamInfo != null) {
100 redisCatchStorage.stopPlay(streamInfo); 101 redisCatchStorage.stopPlay(streamInfo);
101 } 102 }
102 storager.stopPlay(device.getDeviceId(), channelId); 103 storager.stopPlay(device.getDeviceId(), channelId);
103 - mediaServerService.closeRTPServer(device, channelId); 104 + mediaServerService.closeRTPServer(device, channelId, streamInfo.getStream());
104 } 105 }
105 } 106 }
106 } catch (SipException e) { 107 } catch (SipException e) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java
@@ -62,7 +62,7 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i @@ -62,7 +62,7 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i
62 StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(device.getDeviceId(), "*"); 62 StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(device.getDeviceId(), "*");
63 if (streamInfo != null) { 63 if (streamInfo != null) {
64 redisCatchStorage.stopPlayback(streamInfo); 64 redisCatchStorage.stopPlayback(streamInfo);
65 - cmder.streamByeCmd(streamInfo.getDeviceID(), streamInfo.getChannelId()); 65 + cmder.streamByeCmd(streamInfo.getDeviceID(), streamInfo.getChannelId(), streamInfo.getStream());
66 } 66 }
67 } 67 }
68 } 68 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java
@@ -78,7 +78,7 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract { @@ -78,7 +78,7 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract {
78 78
79 if (response.getStatusCode() == 401) { 79 if (response.getStatusCode() == 401) {
80 WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME); 80 WWWAuthenticateHeader www = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME);
81 - sipCommanderForPlatform.register(parentPlatform, callId, www, null, null); 81 + sipCommanderForPlatform.register(parentPlatform, callId, www, null, null, true);
82 }else if (response.getStatusCode() == 200){ 82 }else if (response.getStatusCode() == 200){
83 // 注册/注销成功 83 // 注册/注销成功
84 logger.info(String.format("%s %s成功", platformGBId, action)); 84 logger.info(String.format("%s %s成功", platformGBId, action));
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -360,6 +360,7 @@ public class ZLMHttpHookListener { @@ -360,6 +360,7 @@ public class ZLMHttpHookListener {
360 StreamPushItem streamPushItem = null; 360 StreamPushItem streamPushItem = null;
361 StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaServerItem, app, streamId, tracks); 361 StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaServerItem, app, streamId, tracks);
362 item.setStreamInfo(streamInfoByAppAndStream); 362 item.setStreamInfo(streamInfoByAppAndStream);
  363 +
363 redisCatchStorage.addStream(mediaServerItem, type, app, streamId, item); 364 redisCatchStorage.addStream(mediaServerItem, type, app, streamId, item);
364 if (item.getOriginType() == OriginType.RTSP_PUSH.ordinal() 365 if (item.getOriginType() == OriginType.RTSP_PUSH.ordinal()
365 || item.getOriginType() == OriginType.RTMP_PUSH.ordinal() 366 || item.getOriginType() == OriginType.RTMP_PUSH.ordinal()
@@ -438,14 +439,16 @@ public class ZLMHttpHookListener { @@ -438,14 +439,16 @@ public class ZLMHttpHookListener {
438 if (redisCatchStorage.isChannelSendingRTP(streamInfoForPlayCatch.getChannelId())) { 439 if (redisCatchStorage.isChannelSendingRTP(streamInfoForPlayCatch.getChannelId())) {
439 ret.put("close", false); 440 ret.put("close", false);
440 } else { 441 } else {
441 - cmder.streamByeCmd(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId()); 442 + cmder.streamByeCmd(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId(),
  443 + streamInfoForPlayCatch.getStream());
442 redisCatchStorage.stopPlay(streamInfoForPlayCatch); 444 redisCatchStorage.stopPlay(streamInfoForPlayCatch);
443 storager.stopPlay(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId()); 445 storager.stopPlay(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId());
444 } 446 }
445 }else{ 447 }else{
446 StreamInfo streamInfoForPlayBackCatch = redisCatchStorage.queryPlaybackByStreamId(streamId); 448 StreamInfo streamInfoForPlayBackCatch = redisCatchStorage.queryPlaybackByStreamId(streamId);
447 if (streamInfoForPlayBackCatch != null) { 449 if (streamInfoForPlayBackCatch != null) {
448 - cmder.streamByeCmd(streamInfoForPlayBackCatch.getDeviceID(), streamInfoForPlayBackCatch.getChannelId()); 450 + cmder.streamByeCmd(streamInfoForPlayBackCatch.getDeviceID(),
  451 + streamInfoForPlayBackCatch.getChannelId(), streamInfoForPlayBackCatch.getStream());
449 redisCatchStorage.stopPlayback(streamInfoForPlayBackCatch); 452 redisCatchStorage.stopPlayback(streamInfoForPlayBackCatch);
450 }else { 453 }else {
451 StreamInfo streamInfoForDownload = redisCatchStorage.queryDownloadByStreamId(streamId); 454 StreamInfo streamInfoForDownload = redisCatchStorage.queryDownloadByStreamId(streamId);
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookSubscribe.java
@@ -91,7 +91,8 @@ public class ZLMHttpHookSubscribe { @@ -91,7 +91,8 @@ public class ZLMHttpHookSubscribe {
91 } 91 }
92 } 92 }
93 if (null != result && result){ 93 if (null != result && result){
94 - eventMap.remove(key); 94 + // TODO 报错未处理
  95 + iterator.remove();
95 } 96 }
96 } 97 }
97 } 98 }
src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
@@ -46,7 +46,7 @@ public interface IMediaServerService { @@ -46,7 +46,7 @@ public interface IMediaServerService {
46 46
47 SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, boolean isPlayback); 47 SSRCInfo openRTPServer(MediaServerItem mediaServerItem, String streamId, boolean isPlayback);
48 48
49 - void closeRTPServer(Device device, String channelId); 49 + void closeRTPServer(Device device, String channelId, String ssrc);
50 50
51 void clearRTPServer(MediaServerItem mediaServerItem); 51 void clearRTPServer(MediaServerItem mediaServerItem);
52 52
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
@@ -5,14 +5,16 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; @@ -5,14 +5,16 @@ import com.genersoft.iot.vmp.gb28181.bean.Device;
5 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 5 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
6 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; 6 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  8 +import com.genersoft.iot.vmp.service.bean.PlayBackCallback;
8 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; 9 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
  10 +import org.springframework.http.ResponseEntity;
  11 +import org.springframework.web.context.request.async.DeferredResult;
9 12
10 /** 13 /**
11 * 点播处理 14 * 点播处理
12 */ 15 */
13 public interface IPlayService { 16 public interface IPlayService {
14 17
15 - void onPublishHandlerForPlayBack(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid);  
16 void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid); 18 void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid);
17 19
18 PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent); 20 PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
@@ -20,4 +22,6 @@ public interface IPlayService { @@ -20,4 +22,6 @@ public interface IPlayService {
20 MediaServerItem getNewMediaServerItem(Device device); 22 MediaServerItem getNewMediaServerItem(Device device);
21 23
22 void onPublishHandlerForDownload(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String toString); 24 void onPublishHandlerForDownload(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String toString);
  25 +
  26 + DeferredResult<ResponseEntity<String>> playBack(String deviceId, String channelId, String startTime, String endTime, PlayBackCallback errorCallBack);
23 } 27 }
src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackCallback.java 0 → 100644
  1 +package com.genersoft.iot.vmp.service.bean;
  2 +
  3 +import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
  4 +
  5 +public interface PlayBackCallback {
  6 +
  7 + void call(RequestMessage msg);
  8 +
  9 +}
src/main/java/com/genersoft/iot/vmp/service/bean/SSRCInfo.java
@@ -4,12 +4,12 @@ public class SSRCInfo { @@ -4,12 +4,12 @@ public class SSRCInfo {
4 4
5 private int port; 5 private int port;
6 private String ssrc; 6 private String ssrc;
7 - private String StreamId; 7 + private String Stream;
8 8
9 - public SSRCInfo(int port, String ssrc, String streamId) { 9 + public SSRCInfo(int port, String ssrc, String stream) {
10 this.port = port; 10 this.port = port;
11 this.ssrc = ssrc; 11 this.ssrc = ssrc;
12 - StreamId = streamId; 12 + Stream = stream;
13 } 13 }
14 14
15 public int getPort() { 15 public int getPort() {
@@ -28,11 +28,11 @@ public class SSRCInfo { @@ -28,11 +28,11 @@ public class SSRCInfo {
28 this.ssrc = ssrc; 28 this.ssrc = ssrc;
29 } 29 }
30 30
31 - public String getStreamId() {  
32 - return StreamId; 31 + public String getStream() {
  32 + return Stream;
33 } 33 }
34 34
35 - public void setStreamId(String streamId) {  
36 - StreamId = streamId; 35 + public void setStream(String stream) {
  36 + Stream = stream;
37 } 37 }
38 } 38 }
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
@@ -162,15 +162,16 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR @@ -162,15 +162,16 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR
162 } 162 }
163 163
164 @Override 164 @Override
165 - public void closeRTPServer(Device device, String channelId) {  
166 - String mediaServerId = streamSession.getMediaServerId(device.getDeviceId(), channelId); 165 + public void closeRTPServer(Device device, String channelId, String stream) {
  166 + String mediaServerId = streamSession.getMediaServerId(device.getDeviceId(), channelId, stream);
  167 + String ssrc = streamSession.getSSRC(device.getDeviceId(), channelId, stream);
167 MediaServerItem mediaServerItem = this.getOne(mediaServerId); 168 MediaServerItem mediaServerItem = this.getOne(mediaServerId);
168 if (mediaServerItem != null) { 169 if (mediaServerItem != null) {
169 String streamId = String.format("%s_%s", device.getDeviceId(), channelId); 170 String streamId = String.format("%s_%s", device.getDeviceId(), channelId);
170 zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId); 171 zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId);
171 - releaseSsrc(mediaServerItem, streamSession.getSSRC(device.getDeviceId(), channelId)); 172 + releaseSsrc(mediaServerItem, ssrc);
172 } 173 }
173 - streamSession.remove(device.getDeviceId(), channelId); 174 + streamSession.remove(device.getDeviceId(), channelId, stream);
174 } 175 }
175 176
176 @Override 177 @Override
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
@@ -74,7 +74,7 @@ public class MediaServiceImpl implements IMediaService { @@ -74,7 +74,7 @@ public class MediaServiceImpl implements IMediaService {
74 @Override 74 @Override
75 public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String addr) { 75 public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String addr) {
76 StreamInfo streamInfoResult = new StreamInfo(); 76 StreamInfo streamInfoResult = new StreamInfo();
77 - streamInfoResult.setStreamId(stream); 77 + streamInfoResult.setStream(stream);
78 streamInfoResult.setApp(app); 78 streamInfoResult.setApp(app);
79 if (addr == null) { 79 if (addr == null) {
80 addr = mediaInfo.getStreamIp(); 80 addr = mediaInfo.getStreamIp();
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -16,10 +16,10 @@ import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; @@ -16,10 +16,10 @@ import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
16 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 16 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
17 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 17 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
18 import com.genersoft.iot.vmp.service.IMediaServerService; 18 import com.genersoft.iot.vmp.service.IMediaServerService;
  19 +import com.genersoft.iot.vmp.service.bean.PlayBackCallback;
19 import com.genersoft.iot.vmp.service.bean.SSRCInfo; 20 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
20 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 21 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
21 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 22 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
22 -import com.genersoft.iot.vmp.utils.redis.RedisUtil;  
23 import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 23 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
24 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; 24 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
25 import com.genersoft.iot.vmp.service.IMediaService; 25 import com.genersoft.iot.vmp.service.IMediaService;
@@ -54,9 +54,6 @@ public class PlayServiceImpl implements IPlayService { @@ -54,9 +54,6 @@ public class PlayServiceImpl implements IPlayService {
54 private IRedisCatchStorage redisCatchStorage; 54 private IRedisCatchStorage redisCatchStorage;
55 55
56 @Autowired 56 @Autowired
57 - private RedisUtil redis;  
58 -  
59 - @Autowired  
60 private DeferredResultHolder resultHolder; 57 private DeferredResultHolder resultHolder;
61 58
62 @Autowired 59 @Autowired
@@ -104,19 +101,21 @@ public class PlayServiceImpl implements IPlayService { @@ -104,19 +101,21 @@ public class PlayServiceImpl implements IPlayService {
104 logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId)); 101 logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));
105 WVPResult wvpResult = new WVPResult(); 102 WVPResult wvpResult = new WVPResult();
106 wvpResult.setCode(-1); 103 wvpResult.setCode(-1);
107 - SIPDialog dialog = streamSession.getDialog(deviceId, channelId); 104 + SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, streamInfo.getStream());
108 if (dialog != null) { 105 if (dialog != null) {
109 wvpResult.setMsg("收流超时,请稍候重试"); 106 wvpResult.setMsg("收流超时,请稍候重试");
110 }else { 107 }else {
111 wvpResult.setMsg("点播超时,请稍候重试"); 108 wvpResult.setMsg("点播超时,请稍候重试");
112 } 109 }
  110 +
113 msg.setData(wvpResult); 111 msg.setData(wvpResult);
114 // 点播超时回复BYE 112 // 点播超时回复BYE
115 - cmder.streamByeCmd(device.getDeviceId(), channelId); 113 + cmder.streamByeCmd(device.getDeviceId(), channelId, streamInfo.getStream());
116 // 释放rtpserver 114 // 释放rtpserver
117 - mediaServerService.closeRTPServer(playResult.getDevice(), channelId); 115 + mediaServerService.closeRTPServer(playResult.getDevice(), channelId, streamInfo.getStream());
118 // 回复之前所有的点播请求 116 // 回复之前所有的点播请求
119 resultHolder.invokeAllResult(msg); 117 resultHolder.invokeAllResult(msg);
  118 + // TODO 释放ssrc
120 }); 119 });
121 result.onCompletion(()->{ 120 result.onCompletion(()->{
122 // 点播结束时调用截图接口 121 // 点播结束时调用截图接口
@@ -154,14 +153,12 @@ public class PlayServiceImpl implements IPlayService { @@ -154,14 +153,12 @@ public class PlayServiceImpl implements IPlayService {
154 } 153 }
155 }); 154 });
156 if (streamInfo == null) { 155 if (streamInfo == null) {
157 - SSRCInfo ssrcInfo;  
158 String streamId = null; 156 String streamId = null;
159 if (mediaServerItem.isRtpEnable()) { 157 if (mediaServerItem.isRtpEnable()) {
160 streamId = String.format("%s_%s", device.getDeviceId(), channelId); 158 streamId = String.format("%s_%s", device.getDeviceId(), channelId);
161 } 159 }
162 160
163 - ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId);  
164 - 161 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId);
165 // 发送点播消息 162 // 发送点播消息
166 cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInUse, JSONObject response) -> { 163 cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInUse, JSONObject response) -> {
167 logger.info("收到订阅消息: " + response.toJSONString()); 164 logger.info("收到订阅消息: " + response.toJSONString());
@@ -173,7 +170,7 @@ public class PlayServiceImpl implements IPlayService { @@ -173,7 +170,7 @@ public class PlayServiceImpl implements IPlayService {
173 WVPResult wvpResult = new WVPResult(); 170 WVPResult wvpResult = new WVPResult();
174 wvpResult.setCode(-1); 171 wvpResult.setCode(-1);
175 // 点播返回sip错误 172 // 点播返回sip错误
176 - mediaServerService.closeRTPServer(playResult.getDevice(), channelId); 173 + mediaServerService.closeRTPServer(playResult.getDevice(), channelId, ssrcInfo.getStream());
177 wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg)); 174 wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg));
178 msg.setData(wvpResult); 175 msg.setData(wvpResult);
179 resultHolder.invokeAllResult(msg); 176 resultHolder.invokeAllResult(msg);
@@ -184,7 +181,7 @@ public class PlayServiceImpl implements IPlayService { @@ -184,7 +181,7 @@ public class PlayServiceImpl implements IPlayService {
184 181
185 }); 182 });
186 } else { 183 } else {
187 - String streamId = streamInfo.getStreamId(); 184 + String streamId = streamInfo.getStream();
188 if (streamId == null) { 185 if (streamId == null) {
189 WVPResult wvpResult = new WVPResult(); 186 WVPResult wvpResult = new WVPResult();
190 wvpResult.setCode(-1); 187 wvpResult.setCode(-1);
@@ -213,18 +210,16 @@ public class PlayServiceImpl implements IPlayService { @@ -213,18 +210,16 @@ public class PlayServiceImpl implements IPlayService {
213 // TODO 点播前是否重置状态 210 // TODO 点播前是否重置状态
214 redisCatchStorage.stopPlay(streamInfo); 211 redisCatchStorage.stopPlay(streamInfo);
215 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); 212 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
216 - SSRCInfo ssrcInfo;  
217 String streamId2 = null; 213 String streamId2 = null;
218 if (mediaServerItem.isRtpEnable()) { 214 if (mediaServerItem.isRtpEnable()) {
219 streamId2 = String.format("%s_%s", device.getDeviceId(), channelId); 215 streamId2 = String.format("%s_%s", device.getDeviceId(), channelId);
220 } 216 }
221 - ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId2);  
222 - 217 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId2);
223 cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> { 218 cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
224 logger.info("收到订阅消息: " + response.toJSONString()); 219 logger.info("收到订阅消息: " + response.toJSONString());
225 onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid); 220 onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid);
226 }, (event) -> { 221 }, (event) -> {
227 - mediaServerService.closeRTPServer(playResult.getDevice(), channelId); 222 + mediaServerService.closeRTPServer(playResult.getDevice(), channelId, ssrcInfo.getStream());
228 WVPResult wvpResult = new WVPResult(); 223 WVPResult wvpResult = new WVPResult();
229 wvpResult.setCode(-1); 224 wvpResult.setCode(-1);
230 wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg)); 225 wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg));
@@ -242,12 +237,12 @@ public class PlayServiceImpl implements IPlayService { @@ -242,12 +237,12 @@ public class PlayServiceImpl implements IPlayService {
242 RequestMessage msg = new RequestMessage(); 237 RequestMessage msg = new RequestMessage();
243 msg.setId(uuid); 238 msg.setId(uuid);
244 msg.setKey(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId); 239 msg.setKey(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId);
245 - StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid); 240 + StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId);
246 if (streamInfo != null) { 241 if (streamInfo != null) {
247 DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); 242 DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
248 if (deviceChannel != null) { 243 if (deviceChannel != null) {
249 - deviceChannel.setStreamId(streamInfo.getStreamId());  
250 - storager.startPlay(deviceId, channelId, streamInfo.getStreamId()); 244 + deviceChannel.setStreamId(streamInfo.getStream());
  245 + storager.startPlay(deviceId, channelId, streamInfo.getStream());
251 } 246 }
252 redisCatchStorage.startPlay(streamInfo); 247 redisCatchStorage.startPlay(streamInfo);
253 msg.setData(JSON.toJSONString(streamInfo)); 248 msg.setData(JSON.toJSONString(streamInfo));
@@ -284,29 +279,53 @@ public class PlayServiceImpl implements IPlayService { @@ -284,29 +279,53 @@ public class PlayServiceImpl implements IPlayService {
284 279
285 280
286 @Override 281 @Override
287 - public void onPublishHandlerForPlayBack(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { 282 + public DeferredResult<ResponseEntity<String>> playBack(String deviceId, String channelId, String startTime, String endTime, PlayBackCallback callback) {
  283 + String uuid = UUID.randomUUID().toString();
  284 + String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId;
  285 + DeferredResult<ResponseEntity<String>> result = new DeferredResult<>(30000L);
  286 + Device device = storager.queryVideoDevice(deviceId);
  287 + if (device == null) {
  288 + result.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST));
  289 + return result;
  290 + }
  291 +
  292 + MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
  293 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, true);
  294 + resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId, uuid, result);
288 RequestMessage msg = new RequestMessage(); 295 RequestMessage msg = new RequestMessage();
289 - msg.setKey(DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId);  
290 msg.setId(uuid); 296 msg.setId(uuid);
291 - StreamInfo streamInfo = onPublishHandler(mediaServerItem, resonse, deviceId, channelId, uuid);  
292 - if (streamInfo != null) { 297 + msg.setKey(key);
  298 + result.onTimeout(()->{
  299 + msg.setData("回放超时");
  300 + callback.call(msg);
  301 + });
  302 + cmder.playbackStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, (MediaServerItem mediaServerItem, JSONObject response) -> {
  303 + logger.info("收到订阅消息: " + response.toJSONString());
  304 + StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId);
  305 + if (streamInfo == null) {
  306 + logger.warn("设备回放API调用失败!");
  307 + msg.setData("设备回放API调用失败!");
  308 + callback.call(msg);
  309 + return;
  310 + }
293 redisCatchStorage.startPlayback(streamInfo); 311 redisCatchStorage.startPlayback(streamInfo);
294 msg.setData(JSON.toJSONString(streamInfo)); 312 msg.setData(JSON.toJSONString(streamInfo));
295 - resultHolder.invokeResult(msg);  
296 - } else {  
297 - logger.warn("设备回放API调用失败!");  
298 - msg.setData("设备回放API调用失败!");  
299 - resultHolder.invokeResult(msg);  
300 - } 313 + callback.call(msg);
  314 + }, event -> {
  315 + msg.setData(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg));
  316 + callback.call(msg);
  317 + });
  318 + return result;
301 } 319 }
302 320
303 321
  322 +
304 @Override 323 @Override
305 public void onPublishHandlerForDownload(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String uuid) { 324 public void onPublishHandlerForDownload(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String uuid) {
306 RequestMessage msg = new RequestMessage(); 325 RequestMessage msg = new RequestMessage();
307 msg.setKey(DeferredResultHolder.CALLBACK_CMD_DOWNLOAD + deviceId + channelId); 326 msg.setKey(DeferredResultHolder.CALLBACK_CMD_DOWNLOAD + deviceId + channelId);
308 msg.setId(uuid); 327 msg.setId(uuid);
309 - StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId, uuid); 328 + StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId);
310 if (streamInfo != null) { 329 if (streamInfo != null) {
311 redisCatchStorage.startDownload(streamInfo); 330 redisCatchStorage.startDownload(streamInfo);
312 msg.setData(JSON.toJSONString(streamInfo)); 331 msg.setData(JSON.toJSONString(streamInfo));
@@ -319,7 +338,7 @@ public class PlayServiceImpl implements IPlayService { @@ -319,7 +338,7 @@ public class PlayServiceImpl implements IPlayService {
319 } 338 }
320 339
321 340
322 - public StreamInfo onPublishHandler(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid) { 341 + public StreamInfo onPublishHandler(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId) {
323 String streamId = resonse.getString("stream"); 342 String streamId = resonse.getString("stream");
324 JSONArray tracks = resonse.getJSONArray("tracks"); 343 JSONArray tracks = resonse.getJSONArray("tracks");
325 StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem,"rtp", streamId, tracks); 344 StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem,"rtp", streamId, tracks);
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
@@ -132,7 +132,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -132,7 +132,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
132 }else { 132 }else {
133 streamLive = true; 133 streamLive = true;
134 StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream( 134 StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(
135 - mediaInfo, param.getApp(), param.getStream(), null); 135 + mediaInfo, param.getApp(), param.getStream(), null, null);
136 wvpResult.setData(streamInfo); 136 wvpResult.setData(streamInfo);
137 137
138 } 138 }
src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaItem; @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
8 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 8 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
9 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; 9 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
  10 +import com.genersoft.iot.vmp.service.bean.SSRCInfo;
10 import com.genersoft.iot.vmp.service.bean.ThirdPartyGB; 11 import com.genersoft.iot.vmp.service.bean.ThirdPartyGB;
11 12
12 import java.util.List; 13 import java.util.List;
@@ -220,4 +221,5 @@ public interface IRedisCatchStorage { @@ -220,4 +221,5 @@ public interface IRedisCatchStorage {
220 void addMemInfo(double memInfo); 221 void addMemInfo(double memInfo);
221 222
222 void addNetInfo(Map<String, String> networkInterfaces); 223 void addNetInfo(Map<String, String> networkInterfaces);
  224 +
223 } 225 }
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -10,6 +10,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaItem; @@ -10,6 +10,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
10 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 10 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
11 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 11 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
12 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; 12 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
  13 +import com.genersoft.iot.vmp.service.bean.SSRCInfo;
13 import com.genersoft.iot.vmp.service.bean.ThirdPartyGB; 14 import com.genersoft.iot.vmp.service.bean.ThirdPartyGB;
14 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 15 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
15 import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; 16 import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
@@ -91,7 +92,8 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -91,7 +92,8 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
91 */ 92 */
92 @Override 93 @Override
93 public boolean startPlay(StreamInfo stream) { 94 public boolean startPlay(StreamInfo stream) {
94 - return redis.set(String.format("%S_%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, userSetup.getServerId(), stream.getStreamId(),stream.getDeviceID(), stream.getChannelId()), 95 + return redis.set(String.format("%S_%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, userSetup.getServerId(),
  96 + stream.getStream(), stream.getDeviceID(), stream.getChannelId()),
95 stream); 97 stream);
96 } 98 }
97 99
@@ -105,7 +107,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -105,7 +107,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
105 if (streamInfo == null) return false; 107 if (streamInfo == null) return false;
106 return redis.del(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX, 108 return redis.del(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
107 userSetup.getServerId(), 109 userSetup.getServerId(),
108 - streamInfo.getStreamId(), 110 + streamInfo.getStream(),
109 streamInfo.getDeviceID(), 111 streamInfo.getDeviceID(),
110 streamInfo.getChannelId())); 112 streamInfo.getChannelId()));
111 } 113 }
@@ -119,7 +121,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -119,7 +121,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
119 return (StreamInfo)redis.get(String.format("%S_%s_%s_%s_%s", 121 return (StreamInfo)redis.get(String.format("%S_%s_%s_%s_%s",
120 VideoManagerConstants.PLAYER_PREFIX, 122 VideoManagerConstants.PLAYER_PREFIX,
121 userSetup.getServerId(), 123 userSetup.getServerId(),
122 - streamInfo.getStreamId(), 124 + streamInfo.getStream(),
123 streamInfo.getDeviceID(), 125 streamInfo.getDeviceID(),
124 streamInfo.getChannelId())); 126 streamInfo.getChannelId()));
125 } 127 }
@@ -165,14 +167,14 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -165,14 +167,14 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
165 167
166 @Override 168 @Override
167 public boolean startPlayback(StreamInfo stream) { 169 public boolean startPlayback(StreamInfo stream) {
168 - return redis.set(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, userSetup.getServerId(),stream.getStreamId(),  
169 - stream.getDeviceID(), stream.getChannelId()), stream); 170 + return redis.set(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX,
  171 + userSetup.getServerId(), stream.getStream(), stream.getDeviceID(), stream.getChannelId()), stream);
170 } 172 }
171 173
172 @Override 174 @Override
173 public boolean startDownload(StreamInfo streamInfo) { 175 public boolean startDownload(StreamInfo streamInfo) {
174 - return redis.set(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX, userSetup.getServerId(),streamInfo.getStreamId(),  
175 - streamInfo.getDeviceID(), streamInfo.getChannelId()), streamInfo); 176 + return redis.set(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX, userSetup.getServerId(),
  177 + streamInfo.getStream(), streamInfo.getDeviceID(), streamInfo.getChannelId()), streamInfo);
176 } 178 }
177 179
178 @Override 180 @Override
@@ -186,7 +188,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -186,7 +188,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
186 } 188 }
187 return redis.del(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX, 189 return redis.del(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX,
188 userSetup.getServerId(), 190 userSetup.getServerId(),
189 - streamInfo.getStreamId(), 191 + streamInfo.getStream(),
190 streamInfo.getDeviceID(), 192 streamInfo.getDeviceID(),
191 streamInfo.getChannelId())); 193 streamInfo.getChannelId()));
192 } 194 }
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
1 package com.genersoft.iot.vmp.storager.impl; 1 package com.genersoft.iot.vmp.storager.impl;
2 2
  3 +import com.genersoft.iot.vmp.common.StreamInfo;
3 import com.genersoft.iot.vmp.conf.SipConfig; 4 import com.genersoft.iot.vmp.conf.SipConfig;
4 import com.genersoft.iot.vmp.gb28181.bean.*; 5 import com.genersoft.iot.vmp.gb28181.bean.*;
5 import com.genersoft.iot.vmp.gb28181.event.EventPublisher; 6 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
@@ -156,7 +157,10 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -156,7 +157,10 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
156 public synchronized void updateChannel(String deviceId, DeviceChannel channel) { 157 public synchronized void updateChannel(String deviceId, DeviceChannel channel) {
157 String channelId = channel.getChannelId(); 158 String channelId = channel.getChannelId();
158 channel.setDeviceId(deviceId); 159 channel.setDeviceId(deviceId);
159 - channel.setStreamId(streamSession.getStreamId(deviceId, channel.getChannelId())); 160 + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
  161 + if (streamInfo != null) {
  162 + channel.setStreamId(streamInfo.getStream());
  163 + }
160 String now = this.format.format(System.currentTimeMillis()); 164 String now = this.format.format(System.currentTimeMillis());
161 channel.setUpdateTime(now); 165 channel.setUpdateTime(now);
162 DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(deviceId, channelId); 166 DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(deviceId, channelId);
@@ -178,7 +182,10 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -178,7 +182,10 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
178 if (channelList.size() == 0) { 182 if (channelList.size() == 0) {
179 for (DeviceChannel channel : channels) { 183 for (DeviceChannel channel : channels) {
180 channel.setDeviceId(deviceId); 184 channel.setDeviceId(deviceId);
181 - channel.setStreamId(streamSession.getStreamId(deviceId, channel.getChannelId())); 185 + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channel.getChannelId());
  186 + if (streamInfo != null) {
  187 + channel.setStreamId(streamInfo.getStream());
  188 + }
182 String now = this.format.format(System.currentTimeMillis()); 189 String now = this.format.format(System.currentTimeMillis());
183 channel.setUpdateTime(now); 190 channel.setUpdateTime(now);
184 channel.setCreateTime(now); 191 channel.setCreateTime(now);
@@ -189,9 +196,11 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -189,9 +196,11 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
189 channelsInStore.put(deviceChannel.getChannelId(), deviceChannel); 196 channelsInStore.put(deviceChannel.getChannelId(), deviceChannel);
190 } 197 }
191 for (DeviceChannel channel : channels) { 198 for (DeviceChannel channel : channels) {
192 - String channelId = channel.getChannelId();  
193 channel.setDeviceId(deviceId); 199 channel.setDeviceId(deviceId);
194 - channel.setStreamId(streamSession.getStreamId(deviceId, channel.getChannelId())); 200 + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channel.getChannelId());
  201 + if (streamInfo != null) {
  202 + channel.setStreamId(streamInfo.getStream());
  203 + }
195 String now = this.format.format(System.currentTimeMillis()); 204 String now = this.format.format(System.currentTimeMillis());
196 channel.setUpdateTime(now); 205 channel.setUpdateTime(now);
197 if (channelsInStore.get(channel.getChannelId()) != null) { 206 if (channelsInStore.get(channel.getChannelId()) != null) {
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
@@ -110,26 +110,26 @@ public class PlayController { @@ -110,26 +110,26 @@ public class PlayController {
110 String key = DeferredResultHolder.CALLBACK_CMD_STOP + deviceId + channelId; 110 String key = DeferredResultHolder.CALLBACK_CMD_STOP + deviceId + channelId;
111 resultHolder.put(key, uuid, result); 111 resultHolder.put(key, uuid, result);
112 Device device = storager.queryVideoDevice(deviceId); 112 Device device = storager.queryVideoDevice(deviceId);
113 - cmder.streamByeCmd(deviceId, channelId, (event) -> {  
114 - StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);  
115 - if (streamInfo == null) {  
116 - RequestMessage msg = new RequestMessage();  
117 - msg.setId(uuid);  
118 - msg.setKey(key);  
119 - msg.setData("点播未找到");  
120 - resultHolder.invokeAllResult(msg);  
121 - storager.stopPlay(deviceId, channelId);  
122 - }else {  
123 - redisCatchStorage.stopPlay(streamInfo);  
124 - storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());  
125 - RequestMessage msg = new RequestMessage();  
126 - msg.setId(uuid);  
127 - msg.setKey(key);  
128 - //Response response = event.getResponse();  
129 - msg.setData(String.format("success"));  
130 - resultHolder.invokeAllResult(msg);  
131 - }  
132 - mediaServerService.closeRTPServer(device, channelId); 113 + StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
  114 + if (streamInfo == null) {
  115 + RequestMessage msg = new RequestMessage();
  116 + msg.setId(uuid);
  117 + msg.setKey(key);
  118 + msg.setData("点播未找到");
  119 + resultHolder.invokeAllResult(msg);
  120 + storager.stopPlay(deviceId, channelId);
  121 + return result;
  122 + }
  123 + cmder.streamByeCmd(deviceId, channelId, streamInfo.getStream(), (event) -> {
  124 + redisCatchStorage.stopPlay(streamInfo);
  125 + storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
  126 + RequestMessage msg = new RequestMessage();
  127 + msg.setId(uuid);
  128 + msg.setKey(key);
  129 + //Response response = event.getResponse();
  130 + msg.setData(String.format("success"));
  131 + resultHolder.invokeAllResult(msg);
  132 + mediaServerService.closeRTPServer(device, channelId, streamInfo.getStream());
133 }); 133 });
134 134
135 if (deviceId != null || channelId != null) { 135 if (deviceId != null || channelId != null) {
@@ -329,7 +329,7 @@ public class PlayController { @@ -329,7 +329,7 @@ public class PlayController {
329 jsonObject.put("deviceId", transaction.getDeviceId()); 329 jsonObject.put("deviceId", transaction.getDeviceId());
330 jsonObject.put("channelId", transaction.getChannelId()); 330 jsonObject.put("channelId", transaction.getChannelId());
331 jsonObject.put("ssrc", transaction.getSsrc()); 331 jsonObject.put("ssrc", transaction.getSsrc());
332 - jsonObject.put("streamId", transaction.getStreamId()); 332 + jsonObject.put("streamId", transaction.getStream());
333 objects.add(jsonObject); 333 objects.add(jsonObject);
334 } 334 }
335 335
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/DownloadController.java
@@ -96,7 +96,7 @@ public class DownloadController { @@ -96,7 +96,7 @@ public class DownloadController {
96 StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId); 96 StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId);
97 if (streamInfo != null) { 97 if (streamInfo != null) {
98 // 停止之前的下载 98 // 停止之前的下载
99 - cmder.streamByeCmd(deviceId, channelId); 99 + cmder.streamByeCmd(deviceId, channelId, streamInfo.getStream());
100 } 100 }
101 101
102 MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device); 102 MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);
@@ -114,7 +114,7 @@ public class DownloadController { @@ -114,7 +114,7 @@ public class DownloadController {
114 114
115 cmder.downloadStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, (MediaServerItem mediaServerItem, JSONObject response) -> { 115 cmder.downloadStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, (MediaServerItem mediaServerItem, JSONObject response) -> {
116 logger.info("收到订阅消息: " + response.toJSONString()); 116 logger.info("收到订阅消息: " + response.toJSONString());
117 - playService.onPublishHandlerForDownload(mediaServerItem, response, deviceId, channelId, uuid.toString()); 117 + playService.onPublishHandlerForDownload(mediaServerItem, response, deviceId, channelId, uuid);
118 }, event -> { 118 }, event -> {
119 RequestMessage msg = new RequestMessage(); 119 RequestMessage msg = new RequestMessage();
120 msg.setId(uuid); 120 msg.setId(uuid);
@@ -130,11 +130,12 @@ public class DownloadController { @@ -130,11 +130,12 @@ public class DownloadController {
130 @ApiImplicitParams({ 130 @ApiImplicitParams({
131 @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class), 131 @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class),
132 @ApiImplicitParam(name = "channelId", value = "通道ID", dataTypeClass = String.class), 132 @ApiImplicitParam(name = "channelId", value = "通道ID", dataTypeClass = String.class),
  133 + @ApiImplicitParam(name = "stream", value = "流ID", dataTypeClass = String.class),
133 }) 134 })
134 - @GetMapping("/stop/{deviceId}/{channelId}")  
135 - public ResponseEntity<String> playStop(@PathVariable String deviceId, @PathVariable String channelId) { 135 + @GetMapping("/stop/{deviceId}/{channelId}/{stream}")
  136 + public ResponseEntity<String> playStop(@PathVariable String deviceId, @PathVariable String channelId, @PathVariable String stream) {
136 137
137 - cmder.streamByeCmd(deviceId, channelId); 138 + cmder.streamByeCmd(deviceId, channelId, stream);
138 139
139 if (logger.isDebugEnabled()) { 140 if (logger.isDebugEnabled()) {
140 logger.debug(String.format("设备历史媒体下载停止 API调用,deviceId/channelId:%s_%s", deviceId, channelId)); 141 logger.debug(String.format("设备历史媒体下载停止 API调用,deviceId/channelId:%s_%s", deviceId, channelId));
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java
@@ -18,6 +18,7 @@ import org.slf4j.LoggerFactory; @@ -18,6 +18,7 @@ import org.slf4j.LoggerFactory;
18 import org.springframework.beans.factory.annotation.Autowired; 18 import org.springframework.beans.factory.annotation.Autowired;
19 import org.springframework.http.HttpStatus; 19 import org.springframework.http.HttpStatus;
20 import org.springframework.http.ResponseEntity; 20 import org.springframework.http.ResponseEntity;
  21 +import org.springframework.util.StringUtils;
21 import org.springframework.web.bind.annotation.CrossOrigin; 22 import org.springframework.web.bind.annotation.CrossOrigin;
22 import org.springframework.web.bind.annotation.GetMapping; 23 import org.springframework.web.bind.annotation.GetMapping;
23 import org.springframework.web.bind.annotation.PathVariable; 24 import org.springframework.web.bind.annotation.PathVariable;
@@ -75,52 +76,8 @@ public class PlaybackController { @@ -75,52 +76,8 @@ public class PlaybackController {
75 if (logger.isDebugEnabled()) { 76 if (logger.isDebugEnabled()) {
76 logger.debug(String.format("设备回放 API调用,deviceId:%s ,channelId:%s", deviceId, channelId)); 77 logger.debug(String.format("设备回放 API调用,deviceId:%s ,channelId:%s", deviceId, channelId));
77 } 78 }
78 - String uuid = UUID.randomUUID().toString();  
79 - String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId;  
80 - DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(30000L);  
81 - Device device = storager.queryVideoDevice(deviceId);  
82 - if (device == null) {  
83 - result.setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST));  
84 - return result;  
85 - }  
86 - MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);  
87 - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, true);  
88 -  
89 - // 超时处理  
90 - result.onTimeout(()->{  
91 - logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId));  
92 - RequestMessage msg = new RequestMessage();  
93 - msg.setId(uuid);  
94 - msg.setKey(key);  
95 - msg.setData("Timeout");  
96 - resultHolder.invokeResult(msg);  
97 - });  
98 -  
99 - StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId);  
100 - if (streamInfo != null) {  
101 - // 停止之前的回放  
102 - cmder.streamByeCmd(deviceId, channelId);  
103 - }  
104 - resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId, uuid, result);  
105 -  
106 - if (newMediaServerItem == null) {  
107 - logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId));  
108 - RequestMessage msg = new RequestMessage();  
109 - msg.setId(uuid);  
110 - msg.setKey(key);  
111 - msg.setData("Timeout");  
112 - resultHolder.invokeResult(msg);  
113 - return result;  
114 - }  
115 79
116 - cmder.playbackStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, (MediaServerItem mediaServerItem, JSONObject response) -> {  
117 - logger.info("收到订阅消息: " + response.toJSONString());  
118 - playService.onPublishHandlerForPlayBack(mediaServerItem, response, deviceId, channelId, uuid.toString());  
119 - }, event -> {  
120 - RequestMessage msg = new RequestMessage();  
121 - msg.setId(uuid);  
122 - msg.setKey(key);  
123 - msg.setData(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg)); 80 + DeferredResult<ResponseEntity<String>> result = playService.playBack(deviceId, channelId, startTime, endTime, msg->{
124 resultHolder.invokeResult(msg); 81 resultHolder.invokeResult(msg);
125 }); 82 });
126 83
@@ -131,24 +88,31 @@ public class PlaybackController { @@ -131,24 +88,31 @@ public class PlaybackController {
131 @ApiImplicitParams({ 88 @ApiImplicitParams({
132 @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class), 89 @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class),
133 @ApiImplicitParam(name = "channelId", value = "通道ID", dataTypeClass = String.class), 90 @ApiImplicitParam(name = "channelId", value = "通道ID", dataTypeClass = String.class),
  91 + @ApiImplicitParam(name = "stream", value = "流ID", dataTypeClass = String.class),
134 }) 92 })
135 - @GetMapping("/stop/{deviceId}/{channelId}")  
136 - public ResponseEntity<String> playStop(@PathVariable String deviceId, @PathVariable String channelId) { 93 + @GetMapping("/stop/{deviceId}/{channelId}/{stream}")
  94 + public ResponseEntity<String> playStop(
  95 + @PathVariable String deviceId,
  96 + @PathVariable String channelId,
  97 + @PathVariable String stream) {
137 98
138 - cmder.streamByeCmd(deviceId, channelId); 99 + cmder.streamByeCmd(deviceId, channelId, stream);
139 100
140 if (logger.isDebugEnabled()) { 101 if (logger.isDebugEnabled()) {
141 logger.debug(String.format("设备录像回放停止 API调用,deviceId/channelId:%s/%s", deviceId, channelId)); 102 logger.debug(String.format("设备录像回放停止 API调用,deviceId/channelId:%s/%s", deviceId, channelId));
142 } 103 }
  104 + if (StringUtils.isEmpty(deviceId) || StringUtils.isEmpty(channelId) || StringUtils.isEmpty(stream)) {
  105 + return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
  106 + }
143 107
144 if (deviceId != null && channelId != null) { 108 if (deviceId != null && channelId != null) {
145 JSONObject json = new JSONObject(); 109 JSONObject json = new JSONObject();
146 json.put("deviceId", deviceId); 110 json.put("deviceId", deviceId);
147 json.put("channelId", channelId); 111 json.put("channelId", channelId);
148 - return new ResponseEntity<String>(json.toString(), HttpStatus.OK); 112 + return new ResponseEntity<>(json.toString(), HttpStatus.OK);
149 } else { 113 } else {
150 logger.warn("设备录像回放停止API调用失败!"); 114 logger.warn("设备录像回放停止API调用失败!");
151 - return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR); 115 + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
152 } 116 }
153 } 117 }
154 118
src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java
@@ -103,7 +103,7 @@ public class ApiStreamController { @@ -103,7 +103,7 @@ public class ApiStreamController {
103 PlayResult play = playService.play(newMediaServerItem, serial, code, (mediaServerItem, response)->{ 103 PlayResult play = playService.play(newMediaServerItem, serial, code, (mediaServerItem, response)->{
104 StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(serial, code); 104 StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(serial, code);
105 JSONObject result = new JSONObject(); 105 JSONObject result = new JSONObject();
106 - result.put("StreamID", streamInfo.getStreamId()); 106 + result.put("StreamID", streamInfo.getStream());
107 result.put("DeviceID", device.getDeviceId()); 107 result.put("DeviceID", device.getDeviceId());
108 result.put("ChannelID", code); 108 result.put("ChannelID", code);
109 result.put("ChannelName", deviceChannel.getName()); 109 result.put("ChannelName", deviceChannel.getName());
@@ -177,7 +177,7 @@ public class ApiStreamController { @@ -177,7 +177,7 @@ public class ApiStreamController {
177 result.put("error","未找到流信息"); 177 result.put("error","未找到流信息");
178 return result; 178 return result;
179 } 179 }
180 - cmder.streamByeCmd(serial, code); 180 + cmder.streamByeCmd(serial, code, streamInfo.getStream());
181 redisCatchStorage.stopPlay(streamInfo); 181 redisCatchStorage.stopPlay(streamInfo);
182 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId()); 182 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
183 return null; 183 return null;
src/main/resources/logback-spring-local.xml
@@ -83,7 +83,7 @@ @@ -83,7 +83,7 @@
83 <logger name="com.genersoft.iot.vmp.storager.dao" level="INFO"> 83 <logger name="com.genersoft.iot.vmp.storager.dao" level="INFO">
84 <appender-ref ref="STDOUT"/> 84 <appender-ref ref="STDOUT"/>
85 </logger> 85 </logger>
86 - <logger name="com.genersoft.iot.vmp.gb28181" level="DEBUG"> 86 + <logger name="com.genersoft.iot.vmp.gb28181" level="INFO">
87 <appender-ref ref="STDOUT"/> 87 <appender-ref ref="STDOUT"/>
88 </logger> 88 </logger>
89 89
web_src/src/components/dialog/devicePlayer.vue
@@ -307,7 +307,7 @@ export default { @@ -307,7 +307,7 @@ export default {
307 this.isLoging = false; 307 this.isLoging = false;
308 // this.videoUrl = streamInfo.rtc; 308 // this.videoUrl = streamInfo.rtc;
309 this.videoUrl = this.getUrlByStreamInfo(streamInfo); 309 this.videoUrl = this.getUrlByStreamInfo(streamInfo);
310 - this.streamId = streamInfo.streamId; 310 + this.streamId = streamInfo.stream;
311 this.app = streamInfo.app; 311 this.app = streamInfo.app;
312 this.mediaServerId = streamInfo.mediaServerId; 312 this.mediaServerId = streamInfo.mediaServerId;
313 this.playFromStreamInfo(false, streamInfo) 313 this.playFromStreamInfo(false, streamInfo)
@@ -485,8 +485,9 @@ export default { @@ -485,8 +485,9 @@ export default {
485 }).then(function (res) { 485 }).then(function (res) {
486 var streamInfo = res.data; 486 var streamInfo = res.data;
487 that.app = streamInfo.app; 487 that.app = streamInfo.app;
488 - that.streamId = streamInfo.streamId; 488 + that.streamId = streamInfo.stream;
489 that.mediaServerId = streamInfo.mediaServerId; 489 that.mediaServerId = streamInfo.mediaServerId;
  490 + that.ssrc = streamInfo.ssrc;
490 that.videoUrl = that.getUrlByStreamInfo(streamInfo); 491 that.videoUrl = that.getUrlByStreamInfo(streamInfo);
491 that.recordPlay = true; 492 that.recordPlay = true;
492 }); 493 });
@@ -497,7 +498,7 @@ export default { @@ -497,7 +498,7 @@ export default {
497 this.videoUrl = ''; 498 this.videoUrl = '';
498 this.$axios({ 499 this.$axios({
499 method: 'get', 500 method: 'get',
500 - url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId 501 + url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId
501 }).then(function (res) { 502 }).then(function (res) {
502 if (callback) callback() 503 if (callback) callback()
503 }); 504 });
@@ -517,7 +518,7 @@ export default { @@ -517,7 +518,7 @@ export default {
517 }).then(function (res) { 518 }).then(function (res) {
518 var streamInfo = res.data; 519 var streamInfo = res.data;
519 that.app = streamInfo.app; 520 that.app = streamInfo.app;
520 - that.streamId = streamInfo.streamId; 521 + that.streamId = streamInfo.stream;
521 that.mediaServerId = streamInfo.mediaServerId; 522 that.mediaServerId = streamInfo.mediaServerId;
522 that.videoUrl = that.getUrlByStreamInfo(streamInfo); 523 that.videoUrl = that.getUrlByStreamInfo(streamInfo);
523 that.recordPlay = true; 524 that.recordPlay = true;
@@ -529,7 +530,7 @@ export default { @@ -529,7 +530,7 @@ export default {
529 this.videoUrl = ''; 530 this.videoUrl = '';
530 this.$axios({ 531 this.$axios({
531 method: 'get', 532 method: 'get',
532 - url: '/api/download/stop/' + this.deviceId + "/" + this.channelId 533 + url: '/api/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId
533 }).then(function (res) { 534 }).then(function (res) {
534 if (callback) callback() 535 if (callback) callback()
535 }); 536 });
@@ -539,8 +540,6 @@ export default { @@ -539,8 +540,6 @@ export default {
539 let that = this; 540 let that = this;
540 this.$axios({ 541 this.$axios({
541 method: 'post', 542 method: 'post',
542 - // url: '/api/ptz/' + this.deviceId + '/' + this.channelId + '?leftRight=' + leftRight + '&upDown=' + upDown +  
543 - // '&inOut=' + zoom + '&moveSpeed=50&zoomSpeed=50'  
544 url: '/api/ptz/control/' + this.deviceId + '/' + this.channelId + '?command=' + command + '&horizonSpeed=' + this.controSpeed + '&verticalSpeed=' + this.controSpeed + '&zoomSpeed=' + this.controSpeed 543 url: '/api/ptz/control/' + this.deviceId + '/' + this.channelId + '?command=' + command + '&horizonSpeed=' + this.controSpeed + '&verticalSpeed=' + this.controSpeed + '&zoomSpeed=' + this.controSpeed
545 }).then(function (res) {}); 544 }).then(function (res) {});
546 }, 545 },