Commit 519a08e530556ef7c0b0eedb37f17acd8787fa32

Authored by mk1990
1 parent 4d2c36ed

添加国标级联录像控制功能

src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
... ... @@ -143,6 +143,14 @@ public interface ISIPCommander {
143 143 * 回放倍速播放
144 144 */
145 145 void playSpeedCmd(Device device, StreamInfo streamInfo, Double speed);
  146 +
  147 + /**
  148 + * 回放控制
  149 + * @param device
  150 + * @param streamInfo
  151 + * @param content
  152 + */
  153 + void playbackControlCmd(Device device, StreamInfo streamInfo, String content);
146 154  
147 155 /**
148 156 * 语音广播
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
... ... @@ -1828,6 +1828,28 @@ public class SIPCommander implements ISIPCommander {
1828 1828 e.printStackTrace();
1829 1829 }
1830 1830 }
  1831 +
  1832 + @Override
  1833 + public void playbackControlCmd(Device device, StreamInfo streamInfo, String content) {
  1834 + try {
  1835 + Request request = headerProvider.createInfoRequest(device, streamInfo, content);
  1836 + if (request == null) {
  1837 + return;
  1838 + }
  1839 + logger.info(request.toString());
  1840 + ClientTransaction clientTransaction = null;
  1841 + if ("TCP".equals(device.getTransport())) {
  1842 + clientTransaction = tcpSipProvider.getNewClientTransaction(request);
  1843 + } else if ("UDP".equals(device.getTransport())) {
  1844 + clientTransaction = udpSipProvider.getNewClientTransaction(request);
  1845 + }
  1846 +
  1847 + clientTransaction.sendRequest();
  1848 +
  1849 + } catch (SipException | ParseException | InvalidArgumentException e) {
  1850 + e.printStackTrace();
  1851 + }
  1852 + }
1831 1853  
1832 1854 @Override
1833 1855 public boolean sendAlarmMessage(Device device, DeviceAlarm deviceAlarm) {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/info/InfoRequestProcessor.java 0 → 100644
  1 +package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.info;
  2 +
  3 +import com.genersoft.iot.vmp.common.StreamInfo;
  4 +import com.genersoft.iot.vmp.gb28181.bean.*;
  5 +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
  6 +import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
  7 +import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
  8 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
  9 +import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
  10 +import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
  11 +import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
  12 +import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
  13 +import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
  14 +import gov.nist.javax.sip.message.SIPRequest;
  15 +import org.slf4j.Logger;
  16 +import org.slf4j.LoggerFactory;
  17 +import org.springframework.beans.factory.InitializingBean;
  18 +import org.springframework.beans.factory.annotation.Autowired;
  19 +import org.springframework.stereotype.Component;
  20 +import javax.sip.InvalidArgumentException;
  21 +import javax.sip.RequestEvent;
  22 +import javax.sip.SipException;
  23 +import javax.sip.header.*;
  24 +import javax.sip.message.Response;
  25 +import java.text.ParseException;
  26 +
  27 +@Component
  28 +public class InfoRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor {
  29 +
  30 + private final static Logger logger = LoggerFactory.getLogger(InfoRequestProcessor.class);
  31 +
  32 + private final String method = "INFO";
  33 +
  34 + @Autowired
  35 + private SIPProcessorObserver sipProcessorObserver;
  36 +
  37 + @Autowired
  38 + private IVideoManagerStorage storage;
  39 +
  40 + @Autowired
  41 + private SipSubscribe sipSubscribe;
  42 +
  43 + @Autowired
  44 + private IRedisCatchStorage redisCatchStorage;
  45 +
  46 + @Autowired
  47 + private IVideoManagerStorage storager;
  48 +
  49 + @Autowired
  50 + private SIPCommander cmder;
  51 +
  52 + @Autowired
  53 + private VideoStreamSessionManager sessionManager;
  54 +
  55 + @Override
  56 + public void afterPropertiesSet() throws Exception {
  57 + // 添加消息处理的订阅
  58 + sipProcessorObserver.addRequestProcessor(method, this);
  59 + }
  60 +
  61 + @Override
  62 + public void process(RequestEvent evt) {
  63 + logger.debug("接收到消息:" + evt.getRequest());
  64 + String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest());
  65 + CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME);
  66 + // 先从会话内查找
  67 + SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransaction(null, null, callIdHeader.getCallId(), null);
  68 + if (ssrcTransaction != null) { // 兼容海康 媒体通知 消息from字段不是设备ID的问题
  69 + deviceId = ssrcTransaction.getDeviceId();
  70 + }
  71 + // 查询设备是否存在
  72 + Device device = redisCatchStorage.getDevice(deviceId);
  73 + // 查询上级平台是否存在
  74 + ParentPlatform parentPlatform = storage.queryParentPlatByServerGBId(deviceId);
  75 + try {
  76 + if (device != null && parentPlatform != null) {
  77 + logger.warn("[重复]平台与设备编号重复:{}", deviceId);
  78 + SIPRequest request = (SIPRequest) evt.getRequest();
  79 + String hostAddress = request.getRemoteAddress().getHostAddress();
  80 + int remotePort = request.getRemotePort();
  81 + if (device.getHostAddress().equals(hostAddress + ":" + remotePort)) {
  82 + parentPlatform = null;
  83 + }else {
  84 + device = null;
  85 + }
  86 + }
  87 + if (device == null && parentPlatform == null) {
  88 + // 不存在则回复404
  89 + responseAck(evt, Response.NOT_FOUND, "device "+ deviceId +" not found");
  90 + logger.warn("[设备未找到 ]: {}", deviceId);
  91 + if (sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()) != null){
  92 + SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new DeviceNotFoundEvent(evt.getDialog()));
  93 + sipSubscribe.getErrorSubscribe(callIdHeader.getCallId()).response(eventResult);
  94 + };
  95 + }else {
  96 + ContentTypeHeader header = (ContentTypeHeader)evt.getRequest().getHeader(ContentTypeHeader.NAME);
  97 + String contentType = header.getContentType();
  98 + String contentSubType = header.getContentSubType();
  99 + if ("Application".equals(contentType) && "MANSRTSP".equals(contentSubType)) {
  100 + SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, null, callIdHeader.getCallId());
  101 + String streamId = sendRtpItem.getStreamId();
  102 + StreamInfo streamInfo = redisCatchStorage.queryPlayback(null, null, streamId, null);
  103 + if (null == streamInfo) {
  104 + responseAck(evt, Response.NOT_FOUND, "stream " + streamId + " not found");
  105 + return;
  106 + }
  107 + Device device1 = storager.queryVideoDevice(streamInfo.getDeviceID());
  108 + cmder.playbackControlCmd(device1,streamInfo,new String(evt.getRequest().getRawContent()));
  109 + }
  110 + }
  111 + } catch (SipException e) {
  112 + logger.warn("SIP 回复错误", e);
  113 + } catch (InvalidArgumentException e) {
  114 + logger.warn("参数无效", e);
  115 + } catch (ParseException e) {
  116 + logger.warn("SIP回复时解析异常", e);
  117 + }
  118 + }
  119 +
  120 +
  121 +}
... ...