Commit 19a52a20f358b22211dde9da9d25b65c9cbaddcf
1 parent
acac24f0
固定时区为Asia/Shanghai
Showing
5 changed files
with
117 additions
and
40 deletions
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
| ... | ... | @@ -104,6 +104,14 @@ public interface ISIPCommanderForPlatform { |
| 104 | 104 | boolean recordInfo(DeviceChannel deviceChannel, ParentPlatform parentPlatform, String fromTag, RecordInfo recordInfo); |
| 105 | 105 | |
| 106 | 106 | /** |
| 107 | + * 录像播放推送完成时发送MediaStatus消息 | |
| 108 | + * @param platform | |
| 109 | + * @param sendRtpItem | |
| 110 | + * @return | |
| 111 | + */ | |
| 112 | + boolean sendMediaStatusNotify(ParentPlatform platform, SendRtpItem sendRtpItem); | |
| 113 | + | |
| 114 | + /** | |
| 107 | 115 | * 向发起点播的上级回复bye |
| 108 | 116 | * @param platform 平台信息 |
| 109 | 117 | * @param callId callId | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
| ... | ... | @@ -746,6 +746,56 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 746 | 746 | } |
| 747 | 747 | |
| 748 | 748 | @Override |
| 749 | + public boolean sendMediaStatusNotify(ParentPlatform platform, SendRtpItem sendRtpItem) { | |
| 750 | + if (sendRtpItem == null) { | |
| 751 | + return false; | |
| 752 | + } | |
| 753 | + if (platform == null) { | |
| 754 | + return false; | |
| 755 | + } | |
| 756 | + | |
| 757 | + byte[] dialogByteArray = sendRtpItem.getDialog(); | |
| 758 | + if (dialogByteArray == null) { | |
| 759 | + return false; | |
| 760 | + } | |
| 761 | + try{ | |
| 762 | + SIPDialog dialog = (SIPDialog) SerializeUtils.deSerialize(dialogByteArray); | |
| 763 | + SIPRequest messageRequest = (SIPRequest)dialog.createRequest(Request.MESSAGE); | |
| 764 | + String characterSet = platform.getCharacterSet(); | |
| 765 | + StringBuffer mediaStatusXml = new StringBuffer(200); | |
| 766 | + mediaStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n"); | |
| 767 | + mediaStatusXml.append("<Notify>\r\n"); | |
| 768 | + mediaStatusXml.append("<CmdType>MediaStatus</CmdType>\r\n"); | |
| 769 | + mediaStatusXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n"); | |
| 770 | + mediaStatusXml.append("<DeviceID>" + sendRtpItem.getChannelId() + "</DeviceID>\r\n"); | |
| 771 | + mediaStatusXml.append("<NotifyType>121</NotifyType>\r\n"); | |
| 772 | + mediaStatusXml.append("</Notify>\r\n"); | |
| 773 | + ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml"); | |
| 774 | + messageRequest.setContent(mediaStatusXml.toString(), contentTypeHeader); | |
| 775 | + SipURI sipURI = (SipURI) messageRequest.getRequestURI(); | |
| 776 | + sipURI.setHost(platform.getServerIP()); | |
| 777 | + sipURI.setPort(platform.getServerPort()); | |
| 778 | + | |
| 779 | + ClientTransaction transaction = null; | |
| 780 | + if ("TCP".equals(platform.getTransport())) { | |
| 781 | + transaction = tcpSipProvider.getNewClientTransaction(messageRequest); | |
| 782 | + } else if ("UDP".equals(platform.getTransport())) { | |
| 783 | + transaction = udpSipProvider.getNewClientTransaction(messageRequest); | |
| 784 | + } | |
| 785 | + transaction.sendRequest(); | |
| 786 | + } catch (SipException e) { | |
| 787 | + e.printStackTrace(); | |
| 788 | + return false; | |
| 789 | + } catch (ParseException e) { | |
| 790 | + e.printStackTrace(); | |
| 791 | + return false; | |
| 792 | + } | |
| 793 | + return true; | |
| 794 | + | |
| 795 | + | |
| 796 | + } | |
| 797 | + | |
| 798 | + @Override | |
| 749 | 799 | public void streamByeCmd(ParentPlatform platform, String callId) { |
| 750 | 800 | if (platform == null) { |
| 751 | 801 | return; |
| ... | ... | @@ -765,41 +815,40 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 765 | 815 | SIPDialog sipDialog = ((SipStackImpl) sipStack).putDialog(dialog); |
| 766 | 816 | if (dialog != sipDialog) { |
| 767 | 817 | dialog = sipDialog; |
| 768 | - } else { | |
| 769 | - try { | |
| 770 | - dialog.setSipProvider(udpSipProvider); | |
| 771 | - Field sipStackField = SIPDialog.class.getDeclaredField("sipStack"); | |
| 772 | - sipStackField.setAccessible(true); | |
| 773 | - sipStackField.set(dialog, sipStack); | |
| 774 | - Field eventListenersField = SIPDialog.class.getDeclaredField("eventListeners"); | |
| 775 | - eventListenersField.setAccessible(true); | |
| 776 | - eventListenersField.set(dialog, new HashSet<>()); | |
| 777 | - | |
| 778 | - byte[] transactionByteArray = sendRtpItem.getTransaction(); | |
| 779 | - ClientTransaction clientTransaction = (ClientTransaction) SerializeUtils.deSerialize(transactionByteArray); | |
| 780 | - Request byeRequest = dialog.createRequest(Request.BYE); | |
| 781 | - | |
| 782 | - SipURI byeURI = (SipURI) byeRequest.getRequestURI(); | |
| 783 | - SIPRequest request = (SIPRequest) clientTransaction.getRequest(); | |
| 784 | - byeURI.setHost(request.getRemoteAddress().getHostAddress()); | |
| 785 | - byeURI.setPort(request.getRemotePort()); | |
| 786 | - if ("TCP".equals(platform.getTransport())) { | |
| 787 | - clientTransaction = tcpSipProvider.getNewClientTransaction(byeRequest); | |
| 788 | - } else if ("UDP".equals(platform.getTransport())) { | |
| 789 | - clientTransaction = udpSipProvider.getNewClientTransaction(byeRequest); | |
| 790 | - } | |
| 791 | - dialog.sendRequest(clientTransaction); | |
| 792 | - } catch (SipException e) { | |
| 793 | - e.printStackTrace(); | |
| 794 | - } catch (ParseException e) { | |
| 795 | - e.printStackTrace(); | |
| 796 | - } catch (NoSuchFieldException e) { | |
| 797 | - e.printStackTrace(); | |
| 798 | - } catch (IllegalAccessException e) { | |
| 799 | - e.printStackTrace(); | |
| 818 | + } | |
| 819 | + try { | |
| 820 | + dialog.setSipProvider(udpSipProvider); | |
| 821 | + Field sipStackField = SIPDialog.class.getDeclaredField("sipStack"); | |
| 822 | + sipStackField.setAccessible(true); | |
| 823 | + sipStackField.set(dialog, sipStack); | |
| 824 | + Field eventListenersField = SIPDialog.class.getDeclaredField("eventListeners"); | |
| 825 | + eventListenersField.setAccessible(true); | |
| 826 | + eventListenersField.set(dialog, new HashSet<>()); | |
| 827 | + | |
| 828 | + byte[] transactionByteArray = sendRtpItem.getTransaction(); | |
| 829 | + ClientTransaction clientTransaction = (ClientTransaction) SerializeUtils.deSerialize(transactionByteArray); | |
| 830 | + Request byeRequest = dialog.createRequest(Request.BYE); | |
| 831 | + | |
| 832 | + SipURI byeURI = (SipURI) byeRequest.getRequestURI(); | |
| 833 | + SIPRequest request = (SIPRequest) clientTransaction.getRequest(); | |
| 834 | + byeURI.setHost(request.getRemoteAddress().getHostAddress()); | |
| 835 | + byeURI.setPort(request.getRemotePort()); | |
| 836 | + if ("TCP".equals(platform.getTransport())) { | |
| 837 | + clientTransaction = tcpSipProvider.getNewClientTransaction(byeRequest); | |
| 838 | + } else if ("UDP".equals(platform.getTransport())) { | |
| 839 | + clientTransaction = udpSipProvider.getNewClientTransaction(byeRequest); | |
| 800 | 840 | } |
| 801 | - | |
| 841 | + dialog.sendRequest(clientTransaction); | |
| 842 | + } catch (SipException e) { | |
| 843 | + e.printStackTrace(); | |
| 844 | + } catch (ParseException e) { | |
| 845 | + e.printStackTrace(); | |
| 846 | + } catch (NoSuchFieldException e) { | |
| 847 | + e.printStackTrace(); | |
| 848 | + } catch (IllegalAccessException e) { | |
| 849 | + e.printStackTrace(); | |
| 802 | 850 | } |
| 851 | + | |
| 803 | 852 | } |
| 804 | 853 | } |
| 805 | 854 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
| ... | ... | @@ -188,8 +188,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 188 | 188 | startTime = startTimeFiled.getStartTime(); |
| 189 | 189 | stopTime = startTimeFiled.getStopTime(); |
| 190 | 190 | |
| 191 | - start = Instant.ofEpochMilli(startTime*1000); | |
| 192 | - end = Instant.ofEpochMilli(stopTime*1000); | |
| 191 | + start = Instant.ofEpochSecond(startTime); | |
| 192 | + end = Instant.ofEpochSecond(stopTime); | |
| 193 | 193 | } |
| 194 | 194 | // 获取支持的格式 |
| 195 | 195 | Vector mediaDescriptions = sdp.getMediaDescriptions(true); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java
| ... | ... | @@ -3,13 +3,16 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify |
| 3 | 3 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 4 | 4 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 6 | +import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | |
| 6 | 7 | import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; |
| 7 | 8 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 8 | 9 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
| 10 | +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; | |
| 9 | 11 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| 10 | 12 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; |
| 11 | 13 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; |
| 12 | 14 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 15 | +import com.genersoft.iot.vmp.storager.IVideoManagerStorage; | |
| 13 | 16 | import org.dom4j.Element; |
| 14 | 17 | import org.slf4j.Logger; |
| 15 | 18 | import org.slf4j.LoggerFactory; |
| ... | ... | @@ -39,9 +42,15 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i |
| 39 | 42 | private SIPCommander cmder; |
| 40 | 43 | |
| 41 | 44 | @Autowired |
| 45 | + private SIPCommanderFroPlatform sipCommanderFroPlatform; | |
| 46 | + | |
| 47 | + @Autowired | |
| 42 | 48 | private IRedisCatchStorage redisCatchStorage; |
| 43 | 49 | |
| 44 | 50 | @Autowired |
| 51 | + private IVideoManagerStorage storage; | |
| 52 | + | |
| 53 | + @Autowired | |
| 45 | 54 | private VideoStreamSessionManager sessionManager; |
| 46 | 55 | |
| 47 | 56 | @Override |
| ... | ... | @@ -64,7 +73,7 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i |
| 64 | 73 | } |
| 65 | 74 | CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME); |
| 66 | 75 | String NotifyType =getText(rootElement, "NotifyType"); |
| 67 | - if (NotifyType.equals("121")){ | |
| 76 | + if ("121".equals(NotifyType)){ | |
| 68 | 77 | logger.info("[录像流]推送完毕,收到关流通知"); |
| 69 | 78 | // 查询是设备 |
| 70 | 79 | StreamInfo streamInfo = redisCatchStorage.queryDownload(null, null, null, callIdHeader.getCallId()); |
| ... | ... | @@ -78,8 +87,17 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i |
| 78 | 87 | SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransaction(null, null, callIdHeader.getCallId(), null); |
| 79 | 88 | if (ssrcTransaction != null) { // 兼容海康 媒体通知 消息from字段不是设备ID的问题 |
| 80 | 89 | cmder.streamByeCmd(device.getDeviceId(), ssrcTransaction.getChannelId(), null, callIdHeader.getCallId()); |
| 90 | + // 如果级联播放,需要给上级发送此通知 | |
| 91 | + SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, ssrcTransaction.getChannelId(), null, callIdHeader.getCallId()); | |
| 92 | + if (sendRtpItem != null) { | |
| 93 | + ParentPlatform parentPlatform = storage.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); | |
| 94 | + if (parentPlatform == null) { | |
| 95 | + logger.warn("[级联消息发送]:发送MediaStatus发现上级平台{}不存在", sendRtpItem.getPlatformId()); | |
| 96 | + return; | |
| 97 | + } | |
| 98 | + sipCommanderFroPlatform.sendMediaStatusNotify(parentPlatform, sendRtpItem); | |
| 99 | + } | |
| 81 | 100 | } |
| 82 | - // TODO 如果级联播放,需要给上级发送此通知 | |
| 83 | 101 | |
| 84 | 102 | } |
| 85 | 103 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java
| ... | ... | @@ -32,12 +32,14 @@ public class DateUtil { |
| 32 | 32 | */ |
| 33 | 33 | public static final String PATTERN = "yyyy-MM-dd HH:mm:ss"; |
| 34 | 34 | |
| 35 | + public static final String zoneStr = "Asia/Shanghai"; | |
| 35 | 36 | |
| 36 | - public static final DateTimeFormatter formatterCompatibleISO8601 = DateTimeFormatter.ofPattern(ISO8601_COMPATIBLE_PATTERN, Locale.getDefault()).withZone(ZoneId.systemDefault()); | |
| 37 | - public static final DateTimeFormatter formatterISO8601 = DateTimeFormatter.ofPattern(ISO8601_PATTERN, Locale.getDefault()).withZone(ZoneId.systemDefault()); | |
| 38 | - public static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN, Locale.getDefault()).withZone(ZoneId.systemDefault()); | |
| 37 | + public static final DateTimeFormatter formatterCompatibleISO8601 = DateTimeFormatter.ofPattern(ISO8601_COMPATIBLE_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr)); | |
| 38 | + public static final DateTimeFormatter formatterISO8601 = DateTimeFormatter.ofPattern(ISO8601_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr)); | |
| 39 | + public static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr)); | |
| 39 | 40 | |
| 40 | 41 | public static String yyyy_MM_dd_HH_mm_ssToISO8601(String formatTime) { |
| 42 | + | |
| 41 | 43 | return formatterISO8601.format(formatter.parse(formatTime)); |
| 42 | 44 | } |
| 43 | 45 | ... | ... |