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 5 public class StreamInfo {
6 6  
7 7 private String app;
8   - private String streamId;
  8 + private String stream;
9 9 private String deviceID;
10 10 private String channelId;
11 11 private String flv;
... ... @@ -153,12 +153,12 @@ public class StreamInfo {
153 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 164 public String getRtc() {
... ...
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
... ... @@ -29,6 +29,7 @@ public class VideoManagerConstants {
29 29 // 此处多了一个_,暂不修改
30 30 public static final String PLAYER_PREFIX = "VMP_PLAYER_";
31 31 public static final String PLAY_BLACK_PREFIX = "VMP_PLAYBACK_";
  32 + public static final String PLAY_INFO_PREFIX = "VMP_PLAY_INFO_";
32 33  
33 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 4  
5 5 private String deviceId;
6 6 private String channelId;
7   - private String ssrc;
8   - private String streamId;
  7 + private String callId;
  8 + private String stream;
9 9 private byte[] transaction;
10 10 private byte[] dialog;
11 11 private String mediaServerId;
  12 + private String ssrc;
12 13  
13 14 public String getDeviceId() {
14 15 return deviceId;
... ... @@ -26,20 +27,20 @@ public class SsrcTransaction {
26 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 46 public byte[] getTransaction() {
... ... @@ -65,4 +66,12 @@ public class SsrcTransaction {
65 66 public void setMediaServerId(String mediaServerId) {
66 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 14 import gov.nist.javax.sip.stack.SIPDialog;
15 15 import org.springframework.beans.factory.annotation.Autowired;
16 16 import org.springframework.stereotype.Component;
  17 +import org.springframework.util.StringUtils;
17 18  
18 19 /**
19 20 * @description:视频流session管理器,管理视频预览、预览回放的通信句柄
... ... @@ -29,39 +30,55 @@ public class VideoStreamSessionManager {
29 30 @Autowired
30 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 44 SsrcTransaction ssrcTransaction = new SsrcTransaction();
34 45 ssrcTransaction.setDeviceId(deviceId);
35 46 ssrcTransaction.setChannelId(channelId);
36   - ssrcTransaction.setStreamId(streamId);
  47 + ssrcTransaction.setStream(stream);
37 48 byte[] transactionByteArray = SerializeUtils.serialize(transaction);
38 49 ssrcTransaction.setTransaction(transactionByteArray);
  50 + ssrcTransaction.setCallId(callId);
39 51 ssrcTransaction.setSsrc(ssrc);
40 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 62 if (ssrcTransaction != null) {
48 63 byte[] dialogByteArray = SerializeUtils.serialize(dialog);
49 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 74 if (ssrcTransaction == null) return null;
58 75 byte[] transactionByteArray = ssrcTransaction.getTransaction();
59 76 ClientTransaction clientTransaction = (ClientTransaction)SerializeUtils.deSerialize(transactionByteArray);
60 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 82 if (ssrcTransaction == null) return null;
66 83 byte[] dialogByteArray = ssrcTransaction.getDialog();
67 84 if (dialogByteArray == null) return null;
... ... @@ -69,36 +86,37 @@ public class VideoStreamSessionManager {
69 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 100 if (ssrcTransaction == null) return null;
85 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 106 if (ssrcTransaction == null) return null;
91 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 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 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 120 List<SsrcTransaction> result= new ArrayList<>();
103 121 for (int i = 0; i < ssrcTransactionKeys.size(); i++) {
104 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 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 17 * @return
18 18 */
19 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 128  
129 129  
130 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 140 String realm = www.getRealm();
133 141 String nonce = www.getNonce();
134 142 String scheme = www.getScheme();
... ... @@ -139,7 +147,6 @@ public class SIPRequestHeaderPlarformProvider {
139 147  
140 148 callIdHeader.setCallId(callId);
141 149  
142   - SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort());
143 150 String cNonce = null;
144 151 String nc = "00000001";
145 152 if (qop != null) {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
... ... @@ -226,7 +226,7 @@ public class SIPRequestHeaderProvider {
226 226 throws PeerUnavailableException, ParseException, InvalidArgumentException {
227 227 Request request = null;
228 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 231 SipURI requestLine = sipFactory.createAddressFactory().createSipURI(device.getDeviceId(),
232 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 331 */
332 332 @Override
333 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 335 try {
336 336 if (device == null) return;
337 337 String streamMode = device.getStreamMode().toUpperCase();
... ... @@ -404,6 +404,8 @@ public class SIPCommander implements ISIPCommander {
404 404 }
405 405  
406 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 410 String tm = Long.toString(System.currentTimeMillis());
409 411  
... ... @@ -412,14 +414,14 @@ public class SIPCommander implements ISIPCommander {
412 414  
413 415 Request request = headerProvider.createInviteRequest(device, channelId, content.toString(), null, "FromInvt" + tm, null, ssrcInfo.getSsrc(), callIdHeader);
414 416  
415   - String finalStreamId = streamId;
416 417 transmitRequest(device, request, (e -> {
417   - streamSession.remove(device.getDeviceId(), channelId);
  418 + streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
418 419 mediaServerService.releaseSsrc(mediaServerItem, ssrcInfo.getSsrc());
419 420 errorEvent.response(e);
420 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 443 , SipSubscribe.Event errorEvent) {
442 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 449 JSONObject subscribeKey = new JSONObject();
448 450 subscribeKey.put("app", "rtp");
449   - subscribeKey.put("stream", ssrcInfo.getStreamId());
  451 + subscribeKey.put("stream", ssrcInfo.getStream());
450 452 subscribeKey.put("regist", true);
451 453 subscribeKey.put("mediaServerId", mediaServerItem.getId());
452 454 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());
... ... @@ -466,8 +468,6 @@ public class SIPCommander implements ISIPCommander {
466 468 content.append("t="+DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime)+" "
467 469 +DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime) +"\r\n");
468 470  
469   -
470   -
471 471 String streamMode = device.getStreamMode().toUpperCase();
472 472  
473 473 if (userSetup.isSeniorSdp()) {
... ... @@ -527,8 +527,8 @@ public class SIPCommander implements ISIPCommander {
527 527  
528 528 transmitRequest(device, request, errorEvent, okEvent -> {
529 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 533 } catch ( SipException | ParseException | InvalidArgumentException e) {
534 534 e.printStackTrace();
... ... @@ -548,12 +548,12 @@ public class SIPCommander implements ISIPCommander {
548 548 public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, String downloadSpeed, ZLMHttpHookSubscribe.Event event
549 549 , SipSubscribe.Event errorEvent) {
550 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 554 JSONObject subscribeKey = new JSONObject();
555 555 subscribeKey.put("app", "rtp");
556   - subscribeKey.put("stream", ssrcInfo.getStreamId());
  556 + subscribeKey.put("stream", ssrcInfo.getStream());
557 557 subscribeKey.put("regist", true);
558 558 subscribeKey.put("mediaServerId", mediaServerItem.getId());
559 559 logger.debug("录像回放添加订阅,订阅内容:" + subscribeKey.toString());
... ... @@ -634,7 +634,8 @@ public class SIPCommander implements ISIPCommander {
634 634 Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc());
635 635  
636 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 640 } catch ( SipException | ParseException | InvalidArgumentException e) {
640 641 e.printStackTrace();
... ... @@ -645,17 +646,17 @@ public class SIPCommander implements ISIPCommander {
645 646 * 视频流停止, 不使用回调
646 647 */
647 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 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 658 try {
658   - ClientTransaction transaction = streamSession.getTransaction(deviceId, channelId);
  659 + ClientTransaction transaction = streamSession.getTransactionByStream(deviceId, channelId, stream);
659 660 if (transaction == null) {
660 661 logger.warn("[ {} -> {}]停止视频流的时候发现事务已丢失", deviceId, channelId);
661 662 SipSubscribe.EventResult<Object> eventResult = new SipSubscribe.EventResult<>();
... ... @@ -664,7 +665,7 @@ public class SIPCommander implements ISIPCommander {
664 665 }
665 666 return;
666 667 }
667   - SIPDialog dialog = streamSession.getDialog(deviceId, channelId);
  668 + SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, stream);
668 669 if (dialog == null) {
669 670 logger.warn("[ {} -> {}]停止视频流的时候发现对话已丢失", deviceId, channelId);
670 671 return;
... ... @@ -708,11 +709,11 @@ public class SIPCommander implements ISIPCommander {
708 709  
709 710 dialog.sendRequest(clientTransaction);
710 711  
711   - SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(deviceId, channelId);
  712 + SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(deviceId, channelId, callIdHeader.getCallId(), null);
712 713 if (ssrcTransaction != null) {
713 714 MediaServerItem mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId());
714 715 mediaServerService.releaseSsrc(mediaServerItem, ssrcTransaction.getSsrc());
715   - streamSession.remove(deviceId, channelId);
  716 + streamSession.remove(deviceId, channelId, ssrcTransaction.getStream());
716 717 }
717 718 } catch (SipException | ParseException e) {
718 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 53  
54 54 @Override
55 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 59 @Override
... ... @@ -65,15 +65,16 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
65 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 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 74 try {
74 75 Request request = null;
75 76 String tm = Long.toString(System.currentTimeMillis());
76   - if (www == null ) {
  77 + if (!registerAgain ) {
77 78 // //callid
78 79 CallIdHeader callIdHeader = null;
79 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 72 if (deviceId == null) {
73 73 streamInfo = new StreamInfo();
74 74 streamInfo.setApp(sendRtpItem.getApp());
75   - streamInfo.setStreamId(sendRtpItem.getStreamId());
  75 + streamInfo.setStream(sendRtpItem.getStreamId());
76 76 }else {
77 77 streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
78   - sendRtpItem.setStreamId(streamInfo.getStreamId());
  78 + sendRtpItem.setStreamId(streamInfo.getStream());
79 79 streamInfo.setApp("rtp");
80 80 }
81 81  
... ... @@ -85,7 +85,7 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
85 85 Map<String, Object> param = new HashMap<>();
86 86 param.put("vhost","__defaultVhost__");
87 87 param.put("app",streamInfo.getApp());
88   - param.put("stream",streamInfo.getStreamId());
  88 + param.put("stream",streamInfo.getStream());
89 89 param.put("ssrc", sendRtpItem.getSsrc());
90 90 param.put("dst_url",sendRtpItem.getIp());
91 91 param.put("dst_port", sendRtpItem.getPort());
... ... @@ -98,21 +98,21 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
98 98 try {
99 99 if (System.currentTimeMillis() - startTime < 30 * 1000) {
100 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 102 rtpPushed = true;
103 103 logger.info("已获取设备推流[{}/{}],开始向上级推流[{}:{}]",
104   - streamInfo.getApp() ,streamInfo.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort());
  104 + streamInfo.getApp() ,streamInfo.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort());
105 105 zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
106 106 } else {
107 107 logger.info("等待设备推流[{}/{}].......",
108   - streamInfo.getApp() ,streamInfo.getStreamId());
  108 + streamInfo.getApp() ,streamInfo.getStream());
109 109 Thread.sleep(1000);
110 110 continue;
111 111 }
112 112 } else {
113 113 rtpPushed = true;
114 114 logger.info("设备推流[{}/{}]超时,终止向上级推流",
115   - streamInfo.getApp() ,streamInfo.getStreamId());
  115 + streamInfo.getApp() ,streamInfo.getStream());
116 116 }
117 117 } catch (InterruptedException e) {
118 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 89 redisCatchStorage.deleteSendRTPServer(platformGbId, channelId);
90 90 if (zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId) == 0) {
91 91 logger.info(streamId + "无其它观看者,通知设备停止推流");
92   - cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId);
  92 + cmder.streamByeCmd(sendRtpItem.getDeviceId(), channelId, streamId);
93 93 }
94 94 }
95 95 // 可能是设备主动停止
96 96 Device device = storager.queryVideoDeviceByChannelId(platformGbId);
97 97 if (device != null) {
98 98 StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(device.getDeviceId(), channelId);
  99 +
99 100 if (streamInfo != null) {
100 101 redisCatchStorage.stopPlay(streamInfo);
101 102 }
102 103 storager.stopPlay(device.getDeviceId(), channelId);
103   - mediaServerService.closeRTPServer(device, channelId);
  104 + mediaServerService.closeRTPServer(device, channelId, streamInfo.getStream());
104 105 }
105 106 }
106 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 62 StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(device.getDeviceId(), "*");
63 63 if (streamInfo != null) {
64 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 78  
79 79 if (response.getStatusCode() == 401) {
80 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 82 }else if (response.getStatusCode() == 200){
83 83 // 注册/注销成功
84 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 360 StreamPushItem streamPushItem = null;
361 361 StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaServerItem, app, streamId, tracks);
362 362 item.setStreamInfo(streamInfoByAppAndStream);
  363 +
363 364 redisCatchStorage.addStream(mediaServerItem, type, app, streamId, item);
364 365 if (item.getOriginType() == OriginType.RTSP_PUSH.ordinal()
365 366 || item.getOriginType() == OriginType.RTMP_PUSH.ordinal()
... ... @@ -438,14 +439,16 @@ public class ZLMHttpHookListener {
438 439 if (redisCatchStorage.isChannelSendingRTP(streamInfoForPlayCatch.getChannelId())) {
439 440 ret.put("close", false);
440 441 } else {
441   - cmder.streamByeCmd(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId());
  442 + cmder.streamByeCmd(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId(),
  443 + streamInfoForPlayCatch.getStream());
442 444 redisCatchStorage.stopPlay(streamInfoForPlayCatch);
443 445 storager.stopPlay(streamInfoForPlayCatch.getDeviceID(), streamInfoForPlayCatch.getChannelId());
444 446 }
445 447 }else{
446 448 StreamInfo streamInfoForPlayBackCatch = redisCatchStorage.queryPlaybackByStreamId(streamId);
447 449 if (streamInfoForPlayBackCatch != null) {
448   - cmder.streamByeCmd(streamInfoForPlayBackCatch.getDeviceID(), streamInfoForPlayBackCatch.getChannelId());
  450 + cmder.streamByeCmd(streamInfoForPlayBackCatch.getDeviceID(),
  451 + streamInfoForPlayBackCatch.getChannelId(), streamInfoForPlayBackCatch.getStream());
449 452 redisCatchStorage.stopPlayback(streamInfoForPlayBackCatch);
450 453 }else {
451 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 91 }
92 92 }
93 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 46  
47 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 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 5 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
6 6 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
7 7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  8 +import com.genersoft.iot.vmp.service.bean.PlayBackCallback;
8 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 16 public interface IPlayService {
14 17  
15   - void onPublishHandlerForPlayBack(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid);
16 18 void onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject resonse, String deviceId, String channelId, String uuid);
17 19  
18 20 PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent);
... ... @@ -20,4 +22,6 @@ public interface IPlayService {
20 22 MediaServerItem getNewMediaServerItem(Device device);
21 23  
22 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 4  
5 5 private int port;
6 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 10 this.port = port;
11 11 this.ssrc = ssrc;
12   - StreamId = streamId;
  12 + Stream = stream;
13 13 }
14 14  
15 15 public int getPort() {
... ... @@ -28,11 +28,11 @@ public class SSRCInfo {
28 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 162 }
163 163  
164 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 168 MediaServerItem mediaServerItem = this.getOne(mediaServerId);
168 169 if (mediaServerItem != null) {
169 170 String streamId = String.format("%s_%s", device.getDeviceId(), channelId);
170 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 177 @Override
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
... ... @@ -74,7 +74,7 @@ public class MediaServiceImpl implements IMediaService {
74 74 @Override
75 75 public StreamInfo getStreamInfoByAppAndStream(MediaServerItem mediaInfo, String app, String stream, Object tracks, String addr) {
76 76 StreamInfo streamInfoResult = new StreamInfo();
77   - streamInfoResult.setStreamId(stream);
  77 + streamInfoResult.setStream(stream);
78 78 streamInfoResult.setApp(app);
79 79 if (addr == null) {
80 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 16 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
17 17 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
18 18 import com.genersoft.iot.vmp.service.IMediaServerService;
  19 +import com.genersoft.iot.vmp.service.bean.PlayBackCallback;
19 20 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
20 21 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
21 22 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
22   -import com.genersoft.iot.vmp.utils.redis.RedisUtil;
23 23 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
24 24 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
25 25 import com.genersoft.iot.vmp.service.IMediaService;
... ... @@ -54,9 +54,6 @@ public class PlayServiceImpl implements IPlayService {
54 54 private IRedisCatchStorage redisCatchStorage;
55 55  
56 56 @Autowired
57   - private RedisUtil redis;
58   -
59   - @Autowired
60 57 private DeferredResultHolder resultHolder;
61 58  
62 59 @Autowired
... ... @@ -104,19 +101,21 @@ public class PlayServiceImpl implements IPlayService {
104 101 logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));
105 102 WVPResult wvpResult = new WVPResult();
106 103 wvpResult.setCode(-1);
107   - SIPDialog dialog = streamSession.getDialog(deviceId, channelId);
  104 + SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, streamInfo.getStream());
108 105 if (dialog != null) {
109 106 wvpResult.setMsg("收流超时,请稍候重试");
110 107 }else {
111 108 wvpResult.setMsg("点播超时,请稍候重试");
112 109 }
  110 +
113 111 msg.setData(wvpResult);
114 112 // 点播超时回复BYE
115   - cmder.streamByeCmd(device.getDeviceId(), channelId);
  113 + cmder.streamByeCmd(device.getDeviceId(), channelId, streamInfo.getStream());
116 114 // 释放rtpserver
117   - mediaServerService.closeRTPServer(playResult.getDevice(), channelId);
  115 + mediaServerService.closeRTPServer(playResult.getDevice(), channelId, streamInfo.getStream());
118 116 // 回复之前所有的点播请求
119 117 resultHolder.invokeAllResult(msg);
  118 + // TODO 释放ssrc
120 119 });
121 120 result.onCompletion(()->{
122 121 // 点播结束时调用截图接口
... ... @@ -154,14 +153,12 @@ public class PlayServiceImpl implements IPlayService {
154 153 }
155 154 });
156 155 if (streamInfo == null) {
157   - SSRCInfo ssrcInfo;
158 156 String streamId = null;
159 157 if (mediaServerItem.isRtpEnable()) {
160 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 163 cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInUse, JSONObject response) -> {
167 164 logger.info("收到订阅消息: " + response.toJSONString());
... ... @@ -173,7 +170,7 @@ public class PlayServiceImpl implements IPlayService {
173 170 WVPResult wvpResult = new WVPResult();
174 171 wvpResult.setCode(-1);
175 172 // 点播返回sip错误
176   - mediaServerService.closeRTPServer(playResult.getDevice(), channelId);
  173 + mediaServerService.closeRTPServer(playResult.getDevice(), channelId, ssrcInfo.getStream());
177 174 wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg));
178 175 msg.setData(wvpResult);
179 176 resultHolder.invokeAllResult(msg);
... ... @@ -184,7 +181,7 @@ public class PlayServiceImpl implements IPlayService {
184 181  
185 182 });
186 183 } else {
187   - String streamId = streamInfo.getStreamId();
  184 + String streamId = streamInfo.getStream();
188 185 if (streamId == null) {
189 186 WVPResult wvpResult = new WVPResult();
190 187 wvpResult.setCode(-1);
... ... @@ -213,18 +210,16 @@ public class PlayServiceImpl implements IPlayService {
213 210 // TODO 点播前是否重置状态
214 211 redisCatchStorage.stopPlay(streamInfo);
215 212 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
216   - SSRCInfo ssrcInfo;
217 213 String streamId2 = null;
218 214 if (mediaServerItem.isRtpEnable()) {
219 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 218 cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
224 219 logger.info("收到订阅消息: " + response.toJSONString());
225 220 onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid);
226 221 }, (event) -> {
227   - mediaServerService.closeRTPServer(playResult.getDevice(), channelId);
  222 + mediaServerService.closeRTPServer(playResult.getDevice(), channelId, ssrcInfo.getStream());
228 223 WVPResult wvpResult = new WVPResult();
229 224 wvpResult.setCode(-1);
230 225 wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg));
... ... @@ -242,12 +237,12 @@ public class PlayServiceImpl implements IPlayService {
242 237 RequestMessage msg = new RequestMessage();
243 238 msg.setId(uuid);
244 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 241 if (streamInfo != null) {
247 242 DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
248 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 247 redisCatchStorage.startPlay(streamInfo);
253 248 msg.setData(JSON.toJSONString(streamInfo));
... ... @@ -284,29 +279,53 @@ public class PlayServiceImpl implements IPlayService {
284 279  
285 280  
286 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 295 RequestMessage msg = new RequestMessage();
289   - msg.setKey(DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId);
290 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 311 redisCatchStorage.startPlayback(streamInfo);
294 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 323 @Override
305 324 public void onPublishHandlerForDownload(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String uuid) {
306 325 RequestMessage msg = new RequestMessage();
307 326 msg.setKey(DeferredResultHolder.CALLBACK_CMD_DOWNLOAD + deviceId + channelId);
308 327 msg.setId(uuid);
309   - StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId, uuid);
  328 + StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId);
310 329 if (streamInfo != null) {
311 330 redisCatchStorage.startDownload(streamInfo);
312 331 msg.setData(JSON.toJSONString(streamInfo));
... ... @@ -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 342 String streamId = resonse.getString("stream");
324 343 JSONArray tracks = resonse.getJSONArray("tracks");
325 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 132 }else {
133 133 streamLive = true;
134 134 StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(
135   - mediaInfo, param.getApp(), param.getStream(), null);
  135 + mediaInfo, param.getApp(), param.getStream(), null, null);
136 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 7 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
8 8 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
9 9 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
  10 +import com.genersoft.iot.vmp.service.bean.SSRCInfo;
10 11 import com.genersoft.iot.vmp.service.bean.ThirdPartyGB;
11 12  
12 13 import java.util.List;
... ... @@ -220,4 +221,5 @@ public interface IRedisCatchStorage {
220 221 void addMemInfo(double memInfo);
221 222  
222 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 10 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
11 11 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
12 12 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
  13 +import com.genersoft.iot.vmp.service.bean.SSRCInfo;
13 14 import com.genersoft.iot.vmp.service.bean.ThirdPartyGB;
14 15 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
15 16 import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
... ... @@ -91,7 +92,8 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
91 92 */
92 93 @Override
93 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 97 stream);
96 98 }
97 99  
... ... @@ -105,7 +107,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
105 107 if (streamInfo == null) return false;
106 108 return redis.del(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
107 109 userSetup.getServerId(),
108   - streamInfo.getStreamId(),
  110 + streamInfo.getStream(),
109 111 streamInfo.getDeviceID(),
110 112 streamInfo.getChannelId()));
111 113 }
... ... @@ -119,7 +121,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
119 121 return (StreamInfo)redis.get(String.format("%S_%s_%s_%s_%s",
120 122 VideoManagerConstants.PLAYER_PREFIX,
121 123 userSetup.getServerId(),
122   - streamInfo.getStreamId(),
  124 + streamInfo.getStream(),
123 125 streamInfo.getDeviceID(),
124 126 streamInfo.getChannelId()));
125 127 }
... ... @@ -165,14 +167,14 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
165 167  
166 168 @Override
167 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 174 @Override
173 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 180 @Override
... ... @@ -186,7 +188,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
186 188 }
187 189 return redis.del(String.format("%S_%s_%s_%s_%s", VideoManagerConstants.PLAY_BLACK_PREFIX,
188 190 userSetup.getServerId(),
189   - streamInfo.getStreamId(),
  191 + streamInfo.getStream(),
190 192 streamInfo.getDeviceID(),
191 193 streamInfo.getChannelId()));
192 194 }
... ...
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
1 1 package com.genersoft.iot.vmp.storager.impl;
2 2  
  3 +import com.genersoft.iot.vmp.common.StreamInfo;
3 4 import com.genersoft.iot.vmp.conf.SipConfig;
4 5 import com.genersoft.iot.vmp.gb28181.bean.*;
5 6 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
... ... @@ -156,7 +157,10 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
156 157 public synchronized void updateChannel(String deviceId, DeviceChannel channel) {
157 158 String channelId = channel.getChannelId();
158 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 164 String now = this.format.format(System.currentTimeMillis());
161 165 channel.setUpdateTime(now);
162 166 DeviceChannel deviceChannel = deviceChannelMapper.queryChannel(deviceId, channelId);
... ... @@ -178,7 +182,10 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
178 182 if (channelList.size() == 0) {
179 183 for (DeviceChannel channel : channels) {
180 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 189 String now = this.format.format(System.currentTimeMillis());
183 190 channel.setUpdateTime(now);
184 191 channel.setCreateTime(now);
... ... @@ -189,9 +196,11 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
189 196 channelsInStore.put(deviceChannel.getChannelId(), deviceChannel);
190 197 }
191 198 for (DeviceChannel channel : channels) {
192   - String channelId = channel.getChannelId();
193 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 204 String now = this.format.format(System.currentTimeMillis());
196 205 channel.setUpdateTime(now);
197 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 110 String key = DeferredResultHolder.CALLBACK_CMD_STOP + deviceId + channelId;
111 111 resultHolder.put(key, uuid, result);
112 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 135 if (deviceId != null || channelId != null) {
... ... @@ -329,7 +329,7 @@ public class PlayController {
329 329 jsonObject.put("deviceId", transaction.getDeviceId());
330 330 jsonObject.put("channelId", transaction.getChannelId());
331 331 jsonObject.put("ssrc", transaction.getSsrc());
332   - jsonObject.put("streamId", transaction.getStreamId());
  332 + jsonObject.put("streamId", transaction.getStream());
333 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 96 StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId);
97 97 if (streamInfo != null) {
98 98 // 停止之前的下载
99   - cmder.streamByeCmd(deviceId, channelId);
  99 + cmder.streamByeCmd(deviceId, channelId, streamInfo.getStream());
100 100 }
101 101  
102 102 MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);
... ... @@ -114,7 +114,7 @@ public class DownloadController {
114 114  
115 115 cmder.downloadStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, (MediaServerItem mediaServerItem, JSONObject response) -> {
116 116 logger.info("收到订阅消息: " + response.toJSONString());
117   - playService.onPublishHandlerForDownload(mediaServerItem, response, deviceId, channelId, uuid.toString());
  117 + playService.onPublishHandlerForDownload(mediaServerItem, response, deviceId, channelId, uuid);
118 118 }, event -> {
119 119 RequestMessage msg = new RequestMessage();
120 120 msg.setId(uuid);
... ... @@ -130,11 +130,12 @@ public class DownloadController {
130 130 @ApiImplicitParams({
131 131 @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class),
132 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 140 if (logger.isDebugEnabled()) {
140 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 18 import org.springframework.beans.factory.annotation.Autowired;
19 19 import org.springframework.http.HttpStatus;
20 20 import org.springframework.http.ResponseEntity;
  21 +import org.springframework.util.StringUtils;
21 22 import org.springframework.web.bind.annotation.CrossOrigin;
22 23 import org.springframework.web.bind.annotation.GetMapping;
23 24 import org.springframework.web.bind.annotation.PathVariable;
... ... @@ -75,52 +76,8 @@ public class PlaybackController {
75 76 if (logger.isDebugEnabled()) {
76 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 81 resultHolder.invokeResult(msg);
125 82 });
126 83  
... ... @@ -131,24 +88,31 @@ public class PlaybackController {
131 88 @ApiImplicitParams({
132 89 @ApiImplicitParam(name = "deviceId", value = "设备ID", dataTypeClass = String.class),
133 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 101 if (logger.isDebugEnabled()) {
141 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 108 if (deviceId != null && channelId != null) {
145 109 JSONObject json = new JSONObject();
146 110 json.put("deviceId", deviceId);
147 111 json.put("channelId", channelId);
148   - return new ResponseEntity<String>(json.toString(), HttpStatus.OK);
  112 + return new ResponseEntity<>(json.toString(), HttpStatus.OK);
149 113 } else {
150 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 103 PlayResult play = playService.play(newMediaServerItem, serial, code, (mediaServerItem, response)->{
104 104 StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(serial, code);
105 105 JSONObject result = new JSONObject();
106   - result.put("StreamID", streamInfo.getStreamId());
  106 + result.put("StreamID", streamInfo.getStream());
107 107 result.put("DeviceID", device.getDeviceId());
108 108 result.put("ChannelID", code);
109 109 result.put("ChannelName", deviceChannel.getName());
... ... @@ -177,7 +177,7 @@ public class ApiStreamController {
177 177 result.put("error","未找到流信息");
178 178 return result;
179 179 }
180   - cmder.streamByeCmd(serial, code);
  180 + cmder.streamByeCmd(serial, code, streamInfo.getStream());
181 181 redisCatchStorage.stopPlay(streamInfo);
182 182 storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
183 183 return null;
... ...
src/main/resources/logback-spring-local.xml
... ... @@ -83,7 +83,7 @@
83 83 <logger name="com.genersoft.iot.vmp.storager.dao" level="INFO">
84 84 <appender-ref ref="STDOUT"/>
85 85 </logger>
86   - <logger name="com.genersoft.iot.vmp.gb28181" level="DEBUG">
  86 + <logger name="com.genersoft.iot.vmp.gb28181" level="INFO">
87 87 <appender-ref ref="STDOUT"/>
88 88 </logger>
89 89  
... ...
web_src/src/components/dialog/devicePlayer.vue
... ... @@ -307,7 +307,7 @@ export default {
307 307 this.isLoging = false;
308 308 // this.videoUrl = streamInfo.rtc;
309 309 this.videoUrl = this.getUrlByStreamInfo(streamInfo);
310   - this.streamId = streamInfo.streamId;
  310 + this.streamId = streamInfo.stream;
311 311 this.app = streamInfo.app;
312 312 this.mediaServerId = streamInfo.mediaServerId;
313 313 this.playFromStreamInfo(false, streamInfo)
... ... @@ -485,8 +485,9 @@ export default {
485 485 }).then(function (res) {
486 486 var streamInfo = res.data;
487 487 that.app = streamInfo.app;
488   - that.streamId = streamInfo.streamId;
  488 + that.streamId = streamInfo.stream;
489 489 that.mediaServerId = streamInfo.mediaServerId;
  490 + that.ssrc = streamInfo.ssrc;
490 491 that.videoUrl = that.getUrlByStreamInfo(streamInfo);
491 492 that.recordPlay = true;
492 493 });
... ... @@ -497,7 +498,7 @@ export default {
497 498 this.videoUrl = '';
498 499 this.$axios({
499 500 method: 'get',
500   - url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId
  501 + url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId
501 502 }).then(function (res) {
502 503 if (callback) callback()
503 504 });
... ... @@ -517,7 +518,7 @@ export default {
517 518 }).then(function (res) {
518 519 var streamInfo = res.data;
519 520 that.app = streamInfo.app;
520   - that.streamId = streamInfo.streamId;
  521 + that.streamId = streamInfo.stream;
521 522 that.mediaServerId = streamInfo.mediaServerId;
522 523 that.videoUrl = that.getUrlByStreamInfo(streamInfo);
523 524 that.recordPlay = true;
... ... @@ -529,7 +530,7 @@ export default {
529 530 this.videoUrl = '';
530 531 this.$axios({
531 532 method: 'get',
532   - url: '/api/download/stop/' + this.deviceId + "/" + this.channelId
  533 + url: '/api/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId
533 534 }).then(function (res) {
534 535 if (callback) callback()
535 536 });
... ... @@ -539,8 +540,6 @@ export default {
539 540 let that = this;
540 541 this.$axios({
541 542 method: 'post',
542   - // url: '/api/ptz/' + this.deviceId + '/' + this.channelId + '?leftRight=' + leftRight + '&upDown=' + upDown +
543   - // '&inOut=' + zoom + '&moveSpeed=50&zoomSpeed=50'
544 543 url: '/api/ptz/control/' + this.deviceId + '/' + this.channelId + '?command=' + command + '&horizonSpeed=' + this.controSpeed + '&verticalSpeed=' + this.controSpeed + '&zoomSpeed=' + this.controSpeed
545 544 }).then(function (res) {});
546 545 },
... ...