Commit fd3a4ef472a66c2c5b0663af1363271444f759e4

Authored by 648540858
1 parent d03e8b04

修复国标录像回放以及录像下载

src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
@@ -45,6 +45,8 @@ public class UserSetting { @@ -45,6 +45,8 @@ public class UserSetting {
45 45
46 private Boolean syncChannelOnDeviceOnline = Boolean.FALSE; 46 private Boolean syncChannelOnDeviceOnline = Boolean.FALSE;
47 47
  48 + private Boolean sipLog = Boolean.FALSE;
  49 +
48 private String serverId = "000000"; 50 private String serverId = "000000";
49 51
50 private String thirdPartyGBIdReg = "[\\s\\S]*"; 52 private String thirdPartyGBIdReg = "[\\s\\S]*";
@@ -206,4 +208,12 @@ public class UserSetting { @@ -206,4 +208,12 @@ public class UserSetting {
206 public void setSipUseSourceIpAsRemoteAddress(Boolean sipUseSourceIpAsRemoteAddress) { 208 public void setSipUseSourceIpAsRemoteAddress(Boolean sipUseSourceIpAsRemoteAddress) {
207 this.sipUseSourceIpAsRemoteAddress = sipUseSourceIpAsRemoteAddress; 209 this.sipUseSourceIpAsRemoteAddress = sipUseSourceIpAsRemoteAddress;
208 } 210 }
  211 +
  212 + public Boolean getSipLog() {
  213 + return sipLog;
  214 + }
  215 +
  216 + public void setSipLog(Boolean sipLog) {
  217 + this.sipLog = sipLog;
  218 + }
209 } 219 }
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
1 package com.genersoft.iot.vmp.gb28181; 1 package com.genersoft.iot.vmp.gb28181;
2 2
3 import com.genersoft.iot.vmp.conf.SipConfig; 3 import com.genersoft.iot.vmp.conf.SipConfig;
  4 +import com.genersoft.iot.vmp.conf.UserSetting;
4 import com.genersoft.iot.vmp.gb28181.conf.DefaultProperties; 5 import com.genersoft.iot.vmp.gb28181.conf.DefaultProperties;
5 import com.genersoft.iot.vmp.gb28181.transmit.ISIPProcessorObserver; 6 import com.genersoft.iot.vmp.gb28181.transmit.ISIPProcessorObserver;
6 import gov.nist.javax.sip.SipProviderImpl; 7 import gov.nist.javax.sip.SipProviderImpl;
@@ -29,6 +30,9 @@ public class SipLayer implements CommandLineRunner { @@ -29,6 +30,9 @@ public class SipLayer implements CommandLineRunner {
29 @Autowired 30 @Autowired
30 private ISIPProcessorObserver sipProcessorObserver; 31 private ISIPProcessorObserver sipProcessorObserver;
31 32
  33 + @Autowired
  34 + private UserSetting userSetting;
  35 +
32 private final Map<String, SipProviderImpl> tcpSipProviderMap = new ConcurrentHashMap<>(); 36 private final Map<String, SipProviderImpl> tcpSipProviderMap = new ConcurrentHashMap<>();
33 private final Map<String, SipProviderImpl> udpSipProviderMap = new ConcurrentHashMap<>(); 37 private final Map<String, SipProviderImpl> udpSipProviderMap = new ConcurrentHashMap<>();
34 38
@@ -61,7 +65,7 @@ public class SipLayer implements CommandLineRunner { @@ -61,7 +65,7 @@ public class SipLayer implements CommandLineRunner {
61 private void addListeningPoint(String monitorIp, int port){ 65 private void addListeningPoint(String monitorIp, int port){
62 SipStackImpl sipStack; 66 SipStackImpl sipStack;
63 try { 67 try {
64 - sipStack = (SipStackImpl)sipFactory.createSipStack(DefaultProperties.getProperties(monitorIp, false)); 68 + sipStack = (SipStackImpl)sipFactory.createSipStack(DefaultProperties.getProperties(monitorIp, false, userSetting.getSipLog()));
65 } catch (PeerUnavailableException e) { 69 } catch (PeerUnavailableException e) {
66 logger.error("[Sip Server] SIP服务启动失败, 监听地址{}失败,请检查ip是否正确", monitorIp); 70 logger.error("[Sip Server] SIP服务启动失败, 监听地址{}失败,请检查ip是否正确", monitorIp);
67 return; 71 return;
src/main/java/com/genersoft/iot/vmp/gb28181/conf/DefaultProperties.java
@@ -12,7 +12,7 @@ import java.util.Properties; @@ -12,7 +12,7 @@ import java.util.Properties;
12 */ 12 */
13 public class DefaultProperties { 13 public class DefaultProperties {
14 14
15 - public static Properties getProperties(String ip, boolean isDebug) { 15 + public static Properties getProperties(String ip, boolean isDebug, boolean sipLog) {
16 Properties properties = new Properties(); 16 Properties properties = new Properties();
17 properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP"); 17 properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
18 properties.setProperty("javax.sip.IP_ADDRESS", ip); 18 properties.setProperty("javax.sip.IP_ADDRESS", ip);
@@ -49,23 +49,28 @@ public class DefaultProperties { @@ -49,23 +49,28 @@ public class DefaultProperties {
49 * sip_server_log.log 和 sip_debug_log.log ERROR, INFO, WARNING, OFF, DEBUG, TRACE 49 * sip_server_log.log 和 sip_debug_log.log ERROR, INFO, WARNING, OFF, DEBUG, TRACE
50 */ 50 */
51 Logger logger = LoggerFactory.getLogger(AlarmNotifyMessageHandler.class); 51 Logger logger = LoggerFactory.getLogger(AlarmNotifyMessageHandler.class);
52 - if (logger.isDebugEnabled()) {  
53 - System.out.println("DEBUG");  
54 - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "DEBUG");  
55 - }else if (logger.isInfoEnabled()) {  
56 - System.out.println("INFO1");  
57 - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "INFO");  
58 - }else if (logger.isWarnEnabled()) {  
59 - System.out.println("WARNING");  
60 - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "WARNING");  
61 - }else if (logger.isErrorEnabled()) {  
62 - System.out.println("ERROR");  
63 - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "ERROR"); 52 + if (sipLog) {
  53 + if (logger.isDebugEnabled()) {
  54 + System.out.println("DEBUG");
  55 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "DEBUG");
  56 + }else if (logger.isInfoEnabled()) {
  57 + System.out.println("INFO1");
  58 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "INFO");
  59 + }else if (logger.isWarnEnabled()) {
  60 + System.out.println("WARNING");
  61 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "WARNING");
  62 + }else if (logger.isErrorEnabled()) {
  63 + System.out.println("ERROR");
  64 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "ERROR");
  65 + }else {
  66 + System.out.println("INFO2");
  67 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "INFO");
  68 + }
  69 + logger.info("[SIP日志]级别为: {}", properties.getProperty("gov.nist.javax.sip.TRACE_LEVEL"));
64 }else { 70 }else {
65 - System.out.println("INFO2");  
66 - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "INFO"); 71 + logger.info("[SIP日志]已关闭");
67 } 72 }
68 - logger.info("[SIP日志]级别为: {}", properties.getProperty("gov.nist.javax.sip.TRACE_LEVEL")); 73 +
69 74
70 75
71 return properties; 76 return properties;
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
@@ -12,8 +12,6 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; @@ -12,8 +12,6 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
12 import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback; 12 import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback;
13 import com.genersoft.iot.vmp.service.bean.PlayBackCallback; 13 import com.genersoft.iot.vmp.service.bean.PlayBackCallback;
14 import com.genersoft.iot.vmp.service.bean.SSRCInfo; 14 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
15 -import com.genersoft.iot.vmp.vmanager.bean.WVPResult;  
16 -import org.springframework.web.context.request.async.DeferredResult;  
17 15
18 import javax.sip.InvalidArgumentException; 16 import javax.sip.InvalidArgumentException;
19 import javax.sip.SipException; 17 import javax.sip.SipException;
@@ -35,13 +33,13 @@ public interface IPlayService { @@ -35,13 +33,13 @@ public interface IPlayService {
35 33
36 void onPublishHandlerForDownload(InviteStreamInfo inviteStreamInfo, String deviceId, String channelId, String toString); 34 void onPublishHandlerForDownload(InviteStreamInfo inviteStreamInfo, String deviceId, String channelId, String toString);
37 35
38 - DeferredResult<WVPResult<StreamInfo>> playBack(String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);  
39 - DeferredResult<WVPResult<StreamInfo>> playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack); 36 + void playBack(String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback playBackCallback);
  37 + void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
40 38
41 void zlmServerOffline(String mediaServerId); 39 void zlmServerOffline(String mediaServerId);
42 40
43 - DeferredResult<WVPResult<StreamInfo>> download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);  
44 - DeferredResult<WVPResult<StreamInfo>> download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack); 41 + void download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback playBackCallback);
  42 + void download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack);
45 43
46 StreamInfo getDownLoadInfo(String deviceId, String channelId, String stream); 44 StreamInfo getDownLoadInfo(String deviceId, String channelId, String stream);
47 45
src/main/java/com/genersoft/iot/vmp/service/bean/PlayBackCallback.java
1 package com.genersoft.iot.vmp.service.bean; 1 package com.genersoft.iot.vmp.service.bean;
2 2
3 -import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;  
4 -import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 3 +public interface PlayBackCallback<T> {
5 4
6 -public interface PlayBackCallback {  
7 -  
8 - void call(PlayBackResult<RequestMessage> msg); 5 + void call(PlayBackResult<T> msg);
9 6
10 } 7 }
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -43,7 +43,6 @@ import org.springframework.beans.factory.annotation.Qualifier; @@ -43,7 +43,6 @@ import org.springframework.beans.factory.annotation.Qualifier;
43 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 43 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
44 import org.springframework.stereotype.Service; 44 import org.springframework.stereotype.Service;
45 import org.springframework.util.ObjectUtils; 45 import org.springframework.util.ObjectUtils;
46 -import org.springframework.web.context.request.async.DeferredResult;  
47 46
48 import javax.sip.InvalidArgumentException; 47 import javax.sip.InvalidArgumentException;
49 import javax.sip.ResponseEvent; 48 import javax.sip.ResponseEvent;
@@ -381,14 +380,10 @@ public class PlayServiceImpl implements IPlayService { @@ -381,14 +380,10 @@ public class PlayServiceImpl implements IPlayService {
381 } 380 }
382 } 381 }
383 382
384 - private void onPublishHandlerForPlayback(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, String uuid) {  
385 - RequestMessage msg = new RequestMessage();  
386 - msg.setKey(DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId);  
387 - if (!ObjectUtils.isEmpty(uuid)) {  
388 - msg.setId(uuid);  
389 - }  
390 - StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId); 383 + private void onPublishHandlerForPlayback(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId, PlayBackCallback playBackCallback) {
391 384
  385 + StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId);
  386 + PlayBackResult<StreamInfo> playBackResult = new PlayBackResult<>();
392 if (streamInfo != null) { 387 if (streamInfo != null) {
393 DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); 388 DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
394 if (deviceChannel != null) { 389 if (deviceChannel != null) {
@@ -397,17 +392,16 @@ public class PlayServiceImpl implements IPlayService { @@ -397,17 +392,16 @@ public class PlayServiceImpl implements IPlayService {
397 } 392 }
398 redisCatchStorage.startPlay(streamInfo); 393 redisCatchStorage.startPlay(streamInfo);
399 394
400 - WVPResult wvpResult = new WVPResult();  
401 - wvpResult.setCode(ErrorCode.SUCCESS.getCode());  
402 - wvpResult.setMsg(ErrorCode.SUCCESS.getMsg());  
403 - wvpResult.setData(streamInfo);  
404 - msg.setData(wvpResult);  
405 395
406 - resultHolder.invokeAllResult(msg); 396 + playBackResult.setCode(ErrorCode.SUCCESS.getCode());
  397 + playBackResult.setMsg(ErrorCode.SUCCESS.getMsg());
  398 + playBackResult.setData(streamInfo);
  399 + playBackCallback.call(playBackResult);
407 } else { 400 } else {
408 logger.warn("录像回放调用失败!"); 401 logger.warn("录像回放调用失败!");
409 - msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), "录像回放调用失败!"));  
410 - resultHolder.invokeAllResult(msg); 402 + playBackResult.setCode(ErrorCode.ERROR100.getCode());
  403 + playBackResult.setMsg("录像回放调用失败!");
  404 + playBackCallback.call(playBackResult);
411 } 405 }
412 } 406 }
413 407
@@ -429,45 +423,39 @@ public class PlayServiceImpl implements IPlayService { @@ -429,45 +423,39 @@ public class PlayServiceImpl implements IPlayService {
429 } 423 }
430 424
431 @Override 425 @Override
432 - public DeferredResult<WVPResult<StreamInfo>> playBack(String deviceId, String channelId, String startTime, 426 + public void playBack(String deviceId, String channelId, String startTime,
433 String endTime, InviteStreamCallback inviteStreamCallback, 427 String endTime, InviteStreamCallback inviteStreamCallback,
434 PlayBackCallback callback) { 428 PlayBackCallback callback) {
435 Device device = storager.queryVideoDevice(deviceId); 429 Device device = storager.queryVideoDevice(deviceId);
436 if (device == null) { 430 if (device == null) {
437 - return null; 431 + return;
438 } 432 }
439 MediaServerItem newMediaServerItem = getNewMediaServerItem(device); 433 MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
440 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, device.isSsrcCheck(), true); 434 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, device.isSsrcCheck(), true);
441 435
442 - return playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, inviteStreamCallback, callback); 436 + playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, inviteStreamCallback, callback);
443 } 437 }
444 438
445 @Override 439 @Override
446 - public DeferredResult<WVPResult<StreamInfo>> playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, 440 + public void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,
447 String deviceId, String channelId, String startTime, 441 String deviceId, String channelId, String startTime,
448 String endTime, InviteStreamCallback infoCallBack, 442 String endTime, InviteStreamCallback infoCallBack,
449 PlayBackCallback playBackCallback) { 443 PlayBackCallback playBackCallback) {
450 if (mediaServerItem == null || ssrcInfo == null) { 444 if (mediaServerItem == null || ssrcInfo == null) {
451 - return null; 445 + return;
452 } 446 }
453 - String uuid = UUID.randomUUID().toString();  
454 - String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId; 447 +
455 Device device = storager.queryVideoDevice(deviceId); 448 Device device = storager.queryVideoDevice(deviceId);
456 if (device == null) { 449 if (device == null) {
457 throw new ControllerException(ErrorCode.ERROR100.getCode(), "设备: " + deviceId + "不存在"); 450 throw new ControllerException(ErrorCode.ERROR100.getCode(), "设备: " + deviceId + "不存在");
458 } 451 }
459 - DeferredResult<WVPResult<StreamInfo>> result = new DeferredResult<>(30000L);  
460 - resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId, uuid, result);  
461 - RequestMessage requestMessage = new RequestMessage();  
462 - requestMessage.setId(uuid);  
463 - requestMessage.setKey(key);  
464 - PlayBackResult<RequestMessage> playBackResult = new PlayBackResult<>(); 452 +
  453 + PlayBackResult<StreamInfo> playBackResult = new PlayBackResult<>();
465 String playBackTimeOutTaskKey = UUID.randomUUID().toString(); 454 String playBackTimeOutTaskKey = UUID.randomUUID().toString();
466 dynamicTask.startDelay(playBackTimeOutTaskKey, () -> { 455 dynamicTask.startDelay(playBackTimeOutTaskKey, () -> {
467 logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId)); 456 logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId));
468 playBackResult.setCode(ErrorCode.ERROR100.getCode()); 457 playBackResult.setCode(ErrorCode.ERROR100.getCode());
469 playBackResult.setMsg("回放超时"); 458 playBackResult.setMsg("回放超时");
470 - playBackResult.setData(requestMessage);  
471 459
472 try { 460 try {
473 cmder.streamByeCmd(device, channelId, ssrcInfo.getStream(), null); 461 cmder.streamByeCmd(device, channelId, ssrcInfo.getStream(), null);
@@ -479,19 +467,14 @@ public class PlayServiceImpl implements IPlayService { @@ -479,19 +467,14 @@ public class PlayServiceImpl implements IPlayService {
479 mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); 467 mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
480 streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); 468 streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
481 } 469 }
482 -  
483 // 回复之前所有的点播请求 470 // 回复之前所有的点播请求
484 playBackCallback.call(playBackResult); 471 playBackCallback.call(playBackResult);
485 - result.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "回放超时"));  
486 - resultHolder.exist(DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId, uuid);  
487 }, userSetting.getPlayTimeout()); 472 }, userSetting.getPlayTimeout());
488 473
489 SipSubscribe.Event errorEvent = event -> { 474 SipSubscribe.Event errorEvent = event -> {
490 dynamicTask.stop(playBackTimeOutTaskKey); 475 dynamicTask.stop(playBackTimeOutTaskKey);
491 - requestMessage.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg)));  
492 playBackResult.setCode(ErrorCode.ERROR100.getCode()); 476 playBackResult.setCode(ErrorCode.ERROR100.getCode());
493 playBackResult.setMsg(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg)); 477 playBackResult.setMsg(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg));
494 - playBackResult.setData(requestMessage);  
495 playBackResult.setEvent(event); 478 playBackResult.setEvent(event);
496 playBackCallback.call(playBackResult); 479 playBackCallback.call(playBackResult);
497 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); 480 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
@@ -509,11 +492,9 @@ public class PlayServiceImpl implements IPlayService { @@ -509,11 +492,9 @@ public class PlayServiceImpl implements IPlayService {
509 return; 492 return;
510 } 493 }
511 redisCatchStorage.startPlayback(streamInfo, inviteStreamInfo.getCallId()); 494 redisCatchStorage.startPlayback(streamInfo, inviteStreamInfo.getCallId());
512 - WVPResult<StreamInfo> success = WVPResult.success(streamInfo);  
513 - requestMessage.setData(success);  
514 playBackResult.setCode(ErrorCode.SUCCESS.getCode()); 495 playBackResult.setCode(ErrorCode.SUCCESS.getCode());
515 playBackResult.setMsg(ErrorCode.SUCCESS.getMsg()); 496 playBackResult.setMsg(ErrorCode.SUCCESS.getMsg());
516 - playBackResult.setData(requestMessage); 497 + playBackResult.setData(streamInfo);
517 playBackResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem()); 498 playBackResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem());
518 playBackResult.setResponse(inviteStreamInfo.getResponse()); 499 playBackResult.setResponse(inviteStreamInfo.getResponse());
519 playBackCallback.call(playBackResult); 500 playBackCallback.call(playBackResult);
@@ -560,7 +541,7 @@ public class PlayServiceImpl implements IPlayService { @@ -560,7 +541,7 @@ public class PlayServiceImpl implements IPlayService {
560 logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + response.toJSONString()); 541 logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + response.toJSONString());
561 dynamicTask.stop(playBackTimeOutTaskKey); 542 dynamicTask.stop(playBackTimeOutTaskKey);
562 // hook响应 543 // hook响应
563 - onPublishHandlerForPlayback(mediaServerItemInUse, response, device.getDeviceId(), channelId, uuid); 544 + onPublishHandlerForPlayback(mediaServerItemInUse, response, device.getDeviceId(), channelId, playBackCallback);
564 hookEvent.call(new InviteStreamInfo(mediaServerItem, null, eventResult.callId, "rtp", ssrcInfo.getStream())); 545 hookEvent.call(new InviteStreamInfo(mediaServerItem, null, eventResult.callId, "rtp", ssrcInfo.getStream()));
565 }); 546 });
566 } 547 }
@@ -580,50 +561,37 @@ public class PlayServiceImpl implements IPlayService { @@ -580,50 +561,37 @@ public class PlayServiceImpl implements IPlayService {
580 eventResult.msg = "命令发送失败"; 561 eventResult.msg = "命令发送失败";
581 errorEvent.response(eventResult); 562 errorEvent.response(eventResult);
582 } 563 }
583 - return result;  
584 } 564 }
585 565
586 566
587 567
588 @Override 568 @Override
589 - public DeferredResult<WVPResult<StreamInfo>> download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack) { 569 + public void download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack) {
590 Device device = storager.queryVideoDevice(deviceId); 570 Device device = storager.queryVideoDevice(deviceId);
591 if (device == null) { 571 if (device == null) {
592 - return null; 572 + return;
593 } 573 }
594 MediaServerItem newMediaServerItem = getNewMediaServerItem(device); 574 MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
595 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, device.isSsrcCheck(), true); 575 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, device.isSsrcCheck(), true);
596 576
597 - return download(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, downloadSpeed, infoCallBack, hookCallBack); 577 + download(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, downloadSpeed, infoCallBack, hookCallBack);
598 } 578 }
599 579
600 @Override 580 @Override
601 - public DeferredResult<WVPResult<StreamInfo>> download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack) { 581 + public void download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback infoCallBack, PlayBackCallback hookCallBack) {
602 if (mediaServerItem == null || ssrcInfo == null) { 582 if (mediaServerItem == null || ssrcInfo == null) {
603 - return null; 583 + return;
604 } 584 }
605 - String uuid = UUID.randomUUID().toString();  
606 - String key = DeferredResultHolder.CALLBACK_CMD_DOWNLOAD + deviceId + channelId;  
607 - DeferredResult<WVPResult<StreamInfo>> result = new DeferredResult<>(30000L); 585 +
608 Device device = storager.queryVideoDevice(deviceId); 586 Device device = storager.queryVideoDevice(deviceId);
609 if (device == null) { 587 if (device == null) {
610 throw new ControllerException(ErrorCode.ERROR400.getCode(), "设备:" + deviceId + "不存在"); 588 throw new ControllerException(ErrorCode.ERROR400.getCode(), "设备:" + deviceId + "不存在");
611 } 589 }
612 -  
613 - resultHolder.put(key, uuid, result);  
614 - RequestMessage requestMessage = new RequestMessage();  
615 - requestMessage.setId(uuid);  
616 - requestMessage.setKey(key);  
617 - WVPResult<StreamInfo> wvpResult = new WVPResult<>();  
618 - requestMessage.setData(wvpResult);  
619 - PlayBackResult<RequestMessage> downloadResult = new PlayBackResult<>();  
620 - downloadResult.setData(requestMessage); 590 + PlayBackResult<StreamInfo> downloadResult = new PlayBackResult<>();
621 591
622 String downLoadTimeOutTaskKey = UUID.randomUUID().toString(); 592 String downLoadTimeOutTaskKey = UUID.randomUUID().toString();
623 dynamicTask.startDelay(downLoadTimeOutTaskKey, () -> { 593 dynamicTask.startDelay(downLoadTimeOutTaskKey, () -> {
624 logger.warn(String.format("录像下载请求超时,deviceId:%s ,channelId:%s", deviceId, channelId)); 594 logger.warn(String.format("录像下载请求超时,deviceId:%s ,channelId:%s", deviceId, channelId));
625 - wvpResult.setCode(ErrorCode.ERROR100.getCode());  
626 - wvpResult.setMsg("录像下载请求超时");  
627 downloadResult.setCode(ErrorCode.ERROR100.getCode()); 595 downloadResult.setCode(ErrorCode.ERROR100.getCode());
628 downloadResult.setMsg("录像下载请求超时"); 596 downloadResult.setMsg("录像下载请求超时");
629 hookCallBack.call(downloadResult); 597 hookCallBack.call(downloadResult);
@@ -638,16 +606,12 @@ public class PlayServiceImpl implements IPlayService { @@ -638,16 +606,12 @@ public class PlayServiceImpl implements IPlayService {
638 mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); 606 mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
639 streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); 607 streamSession.remove(deviceId, channelId, ssrcInfo.getStream());
640 } 608 }
641 - // 回复之前所有的点播请求  
642 - hookCallBack.call(downloadResult);  
643 }, userSetting.getPlayTimeout()); 609 }, userSetting.getPlayTimeout());
644 610
645 SipSubscribe.Event errorEvent = event -> { 611 SipSubscribe.Event errorEvent = event -> {
646 dynamicTask.stop(downLoadTimeOutTaskKey); 612 dynamicTask.stop(downLoadTimeOutTaskKey);
647 downloadResult.setCode(ErrorCode.ERROR100.getCode()); 613 downloadResult.setCode(ErrorCode.ERROR100.getCode());
648 downloadResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg)); 614 downloadResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg));
649 - wvpResult.setCode(ErrorCode.ERROR100.getCode());  
650 - wvpResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg));  
651 downloadResult.setEvent(event); 615 downloadResult.setEvent(event);
652 hookCallBack.call(downloadResult); 616 hookCallBack.call(downloadResult);
653 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); 617 streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
@@ -662,11 +626,9 @@ public class PlayServiceImpl implements IPlayService { @@ -662,11 +626,9 @@ public class PlayServiceImpl implements IPlayService {
662 streamInfo.setStartTime(startTime); 626 streamInfo.setStartTime(startTime);
663 streamInfo.setEndTime(endTime); 627 streamInfo.setEndTime(endTime);
664 redisCatchStorage.startDownload(streamInfo, inviteStreamInfo.getCallId()); 628 redisCatchStorage.startDownload(streamInfo, inviteStreamInfo.getCallId());
665 - wvpResult.setCode(ErrorCode.SUCCESS.getCode());  
666 - wvpResult.setMsg(ErrorCode.SUCCESS.getMsg());  
667 - wvpResult.setData(streamInfo);  
668 downloadResult.setCode(ErrorCode.SUCCESS.getCode()); 629 downloadResult.setCode(ErrorCode.SUCCESS.getCode());
669 downloadResult.setMsg(ErrorCode.SUCCESS.getMsg()); 630 downloadResult.setMsg(ErrorCode.SUCCESS.getMsg());
  631 + downloadResult.setData(streamInfo);
670 downloadResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem()); 632 downloadResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem());
671 downloadResult.setResponse(inviteStreamInfo.getResponse()); 633 downloadResult.setResponse(inviteStreamInfo.getResponse());
672 hookCallBack.call(downloadResult); 634 hookCallBack.call(downloadResult);
@@ -678,7 +640,6 @@ public class PlayServiceImpl implements IPlayService { @@ -678,7 +640,6 @@ public class PlayServiceImpl implements IPlayService {
678 eventResult.msg = "命令发送失败"; 640 eventResult.msg = "命令发送失败";
679 errorEvent.response(eventResult); 641 errorEvent.response(eventResult);
680 } 642 }
681 - return result;  
682 } 643 }
683 644
684 @Override 645 @Override
src/main/java/com/genersoft/iot/vmp/vmanager/bean/ErrorCode.java
1 package com.genersoft.iot.vmp.vmanager.bean; 1 package com.genersoft.iot.vmp.vmanager.bean;
2 2
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -  
5 /** 3 /**
6 * 全局错误码 4 * 全局错误码
7 */ 5 */
@@ -9,6 +7,7 @@ public enum ErrorCode { @@ -9,6 +7,7 @@ public enum ErrorCode {
9 SUCCESS(0, "成功"), 7 SUCCESS(0, "成功"),
10 ERROR100(100, "失败"), 8 ERROR100(100, "失败"),
11 ERROR400(400, "参数不全或者错误"), 9 ERROR400(400, "参数不全或者错误"),
  10 + ERROR404(404, "资源未找到"),
12 ERROR403(403, "无权限操作"), 11 ERROR403(403, "无权限操作"),
13 ERROR401(401, "请登录后重新请求"), 12 ERROR401(401, "请登录后重新请求"),
14 ERROR500(500, "系统异常"); 13 ERROR500(500, "系统异常");
src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java
@@ -36,6 +36,12 @@ public class StreamContent { @@ -36,6 +36,12 @@ public class StreamContent {
36 private String mediaServerId; 36 private String mediaServerId;
37 private Object tracks; 37 private Object tracks;
38 38
  39 + private String startTime;
  40 +
  41 + private String endTime;
  42 +
  43 + private double progress;
  44 +
39 public StreamContent(StreamInfo streamInfo) { 45 public StreamContent(StreamInfo streamInfo) {
40 if (streamInfo == null) { 46 if (streamInfo == null) {
41 return; 47 return;
@@ -105,6 +111,9 @@ public class StreamContent { @@ -105,6 +111,9 @@ public class StreamContent {
105 111
106 this.mediaServerId = streamInfo.getMediaServerId(); 112 this.mediaServerId = streamInfo.getMediaServerId();
107 this.tracks = streamInfo.getTracks(); 113 this.tracks = streamInfo.getTracks();
  114 + this.startTime = streamInfo.getStartTime();
  115 + this.endTime = streamInfo.getEndTime();
  116 + this.progress = streamInfo.getProgress();
108 } 117 }
109 118
110 public String getApp() { 119 public String getApp() {
@@ -322,4 +331,28 @@ public class StreamContent { @@ -322,4 +331,28 @@ public class StreamContent {
322 public void setTracks(Object tracks) { 331 public void setTracks(Object tracks) {
323 this.tracks = tracks; 332 this.tracks = tracks;
324 } 333 }
  334 +
  335 + public String getStartTime() {
  336 + return startTime;
  337 + }
  338 +
  339 + public void setStartTime(String startTime) {
  340 + this.startTime = startTime;
  341 + }
  342 +
  343 + public String getEndTime() {
  344 + return endTime;
  345 + }
  346 +
  347 + public void setEndTime(String endTime) {
  348 + this.endTime = endTime;
  349 + }
  350 +
  351 + public double getProgress() {
  352 + return progress;
  353 + }
  354 +
  355 + public void setProgress(double progress) {
  356 + this.progress = progress;
  357 + }
325 } 358 }
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/playback/PlaybackController.java
@@ -10,6 +10,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; @@ -10,6 +10,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 10 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
11 import com.genersoft.iot.vmp.service.IPlayService; 11 import com.genersoft.iot.vmp.service.IPlayService;
12 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; 12 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  13 +import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
13 import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 14 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
14 import io.swagger.v3.oas.annotations.Operation; 15 import io.swagger.v3.oas.annotations.Operation;
15 import io.swagger.v3.oas.annotations.Parameter; 16 import io.swagger.v3.oas.annotations.Parameter;
@@ -32,6 +33,7 @@ import org.springframework.web.context.request.async.DeferredResult; @@ -32,6 +33,7 @@ import org.springframework.web.context.request.async.DeferredResult;
32 import javax.sip.InvalidArgumentException; 33 import javax.sip.InvalidArgumentException;
33 import javax.sip.SipException; 34 import javax.sip.SipException;
34 import java.text.ParseException; 35 import java.text.ParseException;
  36 +import java.util.UUID;
35 37
36 /** 38 /**
37 * @author lin 39 * @author lin
@@ -68,24 +70,37 @@ public class PlaybackController { @@ -68,24 +70,37 @@ public class PlaybackController {
68 @Parameter(name = "startTime", description = "开始时间", required = true) 70 @Parameter(name = "startTime", description = "开始时间", required = true)
69 @Parameter(name = "endTime", description = "结束时间", required = true) 71 @Parameter(name = "endTime", description = "结束时间", required = true)
70 @GetMapping("/start/{deviceId}/{channelId}") 72 @GetMapping("/start/{deviceId}/{channelId}")
71 - public DeferredResult<WVPResult<StreamInfo>> play(@PathVariable String deviceId, @PathVariable String channelId,  
72 - String startTime, String endTime) { 73 + public DeferredResult<WVPResult<StreamContent>> play(@PathVariable String deviceId, @PathVariable String channelId,
  74 + String startTime, String endTime) {
73 75
74 if (logger.isDebugEnabled()) { 76 if (logger.isDebugEnabled()) {
75 logger.debug(String.format("设备回放 API调用,deviceId:%s ,channelId:%s", deviceId, channelId)); 77 logger.debug(String.format("设备回放 API调用,deviceId:%s ,channelId:%s", deviceId, channelId));
76 } 78 }
77 79
  80 + String uuid = UUID.randomUUID().toString();
  81 + String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId;
  82 + DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(30000L);
  83 + resultHolder.put(key, uuid, result);
78 84
79 - return playService.playBack(deviceId, channelId, startTime, endTime, null, 85 + WVPResult<StreamContent> wvpResult = new WVPResult<>();
  86 +
  87 + RequestMessage msg = new RequestMessage();
  88 + msg.setKey(key);
  89 + msg.setId(uuid);
  90 +
  91 + playService.playBack(deviceId, channelId, startTime, endTime, null,
80 playBackResult->{ 92 playBackResult->{
81 - if (playBackResult.getCode() != ErrorCode.SUCCESS.getCode()) {  
82 - RequestMessage data = playBackResult.getData();  
83 - data.setData(WVPResult.fail(playBackResult.getCode(), playBackResult.getMsg()));  
84 - resultHolder.invokeResult(data);  
85 - }else {  
86 - resultHolder.invokeResult(playBackResult.getData()); 93 + wvpResult.setCode(playBackResult.getCode());
  94 + wvpResult.setMsg(playBackResult.getMsg());
  95 + if (playBackResult.getCode() == ErrorCode.SUCCESS.getCode()) {
  96 + StreamInfo streamInfo = (StreamInfo)playBackResult.getData();
  97 + wvpResult.setData(new StreamContent(streamInfo));
87 } 98 }
  99 + msg.setData(wvpResult);
  100 + resultHolder.invokeResult(msg);
88 }); 101 });
  102 +
  103 + return result;
89 } 104 }
90 105
91 106
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/record/GBRecordController.java
@@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.service.IDeviceService; @@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.service.IDeviceService;
8 import com.genersoft.iot.vmp.service.IPlayService; 8 import com.genersoft.iot.vmp.service.IPlayService;
9 import com.genersoft.iot.vmp.utils.DateUtil; 9 import com.genersoft.iot.vmp.utils.DateUtil;
10 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; 10 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  11 +import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
11 import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 12 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
12 13
13 import io.swagger.v3.oas.annotations.Operation; 14 import io.swagger.v3.oas.annotations.Operation;
@@ -121,15 +122,33 @@ public class GBRecordController { @@ -121,15 +122,33 @@ public class GBRecordController {
121 @Parameter(name = "endTime", description = "结束时间", required = true) 122 @Parameter(name = "endTime", description = "结束时间", required = true)
122 @Parameter(name = "downloadSpeed", description = "下载倍速", required = true) 123 @Parameter(name = "downloadSpeed", description = "下载倍速", required = true)
123 @GetMapping("/download/start/{deviceId}/{channelId}") 124 @GetMapping("/download/start/{deviceId}/{channelId}")
124 - public DeferredResult<WVPResult<StreamInfo>> download(@PathVariable String deviceId, @PathVariable String channelId, 125 + public DeferredResult<WVPResult<StreamContent>> download(@PathVariable String deviceId, @PathVariable String channelId,
125 String startTime, String endTime, String downloadSpeed) { 126 String startTime, String endTime, String downloadSpeed) {
126 127
127 if (logger.isDebugEnabled()) { 128 if (logger.isDebugEnabled()) {
128 logger.debug(String.format("历史媒体下载 API调用,deviceId:%s,channelId:%s,downloadSpeed:%s", deviceId, channelId, downloadSpeed)); 129 logger.debug(String.format("历史媒体下载 API调用,deviceId:%s,channelId:%s,downloadSpeed:%s", deviceId, channelId, downloadSpeed));
129 } 130 }
130 131
131 - DeferredResult<WVPResult<StreamInfo>> result = playService.download(deviceId, channelId, startTime, endTime, Integer.parseInt(downloadSpeed), null, hookCallBack->{  
132 - resultHolder.invokeResult(hookCallBack.getData()); 132 + String uuid = UUID.randomUUID().toString();
  133 + String key = DeferredResultHolder.CALLBACK_CMD_DOWNLOAD + deviceId + channelId;
  134 + DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(30000L);
  135 + resultHolder.put(key, uuid, result);
  136 + RequestMessage msg = new RequestMessage();
  137 + msg.setId(uuid);
  138 + msg.setKey(key);
  139 +
  140 + WVPResult<StreamContent> wvpResult = new WVPResult<>();
  141 +
  142 + playService.download(deviceId, channelId, startTime, endTime, Integer.parseInt(downloadSpeed), null, playBackResult->{
  143 +
  144 + wvpResult.setCode(playBackResult.getCode());
  145 + wvpResult.setMsg(playBackResult.getMsg());
  146 + if (playBackResult.getCode() == ErrorCode.SUCCESS.getCode()) {
  147 + StreamInfo streamInfo = (StreamInfo)playBackResult.getData();
  148 + wvpResult.setData(new StreamContent(streamInfo));
  149 + }
  150 + msg.setData(wvpResult);
  151 + resultHolder.invokeResult(msg);
133 }); 152 });
134 153
135 return result; 154 return result;
@@ -168,7 +187,11 @@ public class GBRecordController { @@ -168,7 +187,11 @@ public class GBRecordController {
168 @Parameter(name = "channelId", description = "通道国标编号", required = true) 187 @Parameter(name = "channelId", description = "通道国标编号", required = true)
169 @Parameter(name = "stream", description = "流ID", required = true) 188 @Parameter(name = "stream", description = "流ID", required = true)
170 @GetMapping("/download/progress/{deviceId}/{channelId}/{stream}") 189 @GetMapping("/download/progress/{deviceId}/{channelId}/{stream}")
171 - public StreamInfo getProgress(@PathVariable String deviceId, @PathVariable String channelId, @PathVariable String stream) {  
172 - return playService.getDownLoadInfo(deviceId, channelId, stream); 190 + public StreamContent getProgress(@PathVariable String deviceId, @PathVariable String channelId, @PathVariable String stream) {
  191 + StreamInfo downLoadInfo = playService.getDownLoadInfo(deviceId, channelId, stream);
  192 + if (downLoadInfo == null) {
  193 + throw new ControllerException(ErrorCode.ERROR404);
  194 + }
  195 + return new StreamContent(downLoadInfo);
173 } 196 }
174 } 197 }
src/main/resources/all-application.yml
@@ -197,6 +197,8 @@ user-settings: @@ -197,6 +197,8 @@ user-settings:
197 sync-channel-on-device-online: false 197 sync-channel-on-device-online: false
198 # 是否使用设备来源Ip作为回复IP, 不设置则为 false 198 # 是否使用设备来源Ip作为回复IP, 不设置则为 false
199 sip-use-source-ip-as-remote-address: false 199 sip-use-source-ip-as-remote-address: false
  200 + # 是否开启sip日志
  201 + sip-log: true
200 202
201 # 关闭在线文档(生产环境建议关闭) 203 # 关闭在线文档(生产环境建议关闭)
202 springdoc: 204 springdoc: