diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java index 1f1d10a6..6aa20e4d 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java @@ -15,26 +15,26 @@ import javax.sip.InvalidArgumentException; import javax.sip.SipException; import java.text.ParseException; -/** - * @description:设备能力接口,用于定义设备的控制、查询能力 +/** + * @description:设备能力接口,用于定义设备的控制、查询能力 * @author: swwheihei - * @date: 2020年5月3日 下午9:16:34 + * @date: 2020年5月3日 下午9:16:34 */ public interface ISIPCommander { /** * 云台方向放控制,使用配置文件中的默认镜头移动速度 - * + * * @param device 控制设备 * @param channelId 预览通道 * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移 * @param upDown 镜头上移下移 0:停止 1:上移 2:下移 */ void ptzdirectCmd(Device device,String channelId,int leftRight, int upDown) throws InvalidArgumentException, ParseException, SipException; - + /** * 云台方向放控制 - * + * * @param device 控制设备 * @param channelId 预览通道 * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移 @@ -42,28 +42,28 @@ public interface ISIPCommander { * @param moveSpeed 镜头移动速度 */ void ptzdirectCmd(Device device,String channelId,int leftRight, int upDown, int moveSpeed) throws InvalidArgumentException, ParseException, SipException; - + /** * 云台缩放控制,使用配置文件中的默认镜头缩放速度 - * + * * @param device 控制设备 * @param channelId 预览通道 * @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大 */ void ptzZoomCmd(Device device,String channelId,int inOut) throws InvalidArgumentException, ParseException, SipException; - + /** * 云台缩放控制 - * + * * @param device 控制设备 * @param channelId 预览通道 * @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大 */ void ptzZoomCmd(Device device,String channelId,int inOut, int moveSpeed) throws InvalidArgumentException, ParseException, SipException; - + /** * 云台控制,支持方向与缩放控制 - * + * * @param device 控制设备 * @param channelId 预览通道 * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移 @@ -73,10 +73,10 @@ public interface ISIPCommander { * @param zoomSpeed 镜头缩放速度 */ void ptzCmd(Device device,String channelId,int leftRight, int upDown, int inOut, int moveSpeed, int zoomSpeed) throws InvalidArgumentException, SipException, ParseException; - + /** * 前端控制,包括PTZ指令、FI指令、预置位指令、巡航指令、扫描指令和辅助开关指令 - * + * * @param device 控制设备 * @param channelId 预览通道 * @param cmdCode 指令码 @@ -85,7 +85,7 @@ public interface ISIPCommander { * @param combineCode2 组合码2 */ void frontEndCmd(Device device, String channelId, int cmdCode, int parameter1, int parameter2, int combineCode2) throws SipException, InvalidArgumentException, ParseException; - + /** * 前端控制指令(用于转发上级指令) * @param device 控制设备 @@ -103,7 +103,7 @@ public interface ISIPCommander { /** * 请求回放视频流 - * + * * @param device 视频设备 * @param channelId 预览通道 * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss @@ -113,16 +113,16 @@ public interface ISIPCommander { /** * 请求历史媒体下载 - * + * * @param device 视频设备 * @param channelId 预览通道 * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss * @param downloadSpeed 下载倍速参数 - */ + */ void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, String startTime, String endTime, int downloadSpeed, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent, - SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; + SipSubscribe.Event errorEvent,SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException; /** * 视频流停止 @@ -150,7 +150,7 @@ public interface ISIPCommander { * 回放倍速播放 */ void playSpeedCmd(Device device, StreamInfo streamInfo, Double speed) throws InvalidArgumentException, ParseException, SipException; - + /** * 回放控制 * @param device @@ -162,55 +162,55 @@ public interface ISIPCommander { /** * 语音广播 - * + * * @param device 视频设备 * @param channelId 预览通道 */ void audioBroadcastCmd(Device device,String channelId); - + /** * 语音广播 - * + * * @param device 视频设备 */ void audioBroadcastCmd(Device device, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException; void audioBroadcastCmd(Device device) throws InvalidArgumentException, SipException, ParseException; - + /** * 音视频录像控制 - * + * * @param device 视频设备 * @param channelId 预览通道 * @param recordCmdStr 录像命令:Record / StopRecord */ void recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException; - + /** * 远程启动控制命令 - * + * * @param device 视频设备 */ void teleBootCmd(Device device) throws InvalidArgumentException, SipException, ParseException; /** * 报警布防/撤防命令 - * + * * @param device 视频设备 */ void guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException; - + /** * 报警复位命令 - * + * * @param device 视频设备 * @param alarmMethod 报警方式(可选) * @param alarmType 报警类型(可选) */ void alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException; - + /** * 强制关键帧命令,设备收到此命令应立刻发送一个IDR帧 - * + * * @param device 视频设备 * @param channelId 预览通道 */ @@ -230,58 +230,58 @@ public interface ISIPCommander { /** * 设备配置命令 - * + * * @param device 视频设备 */ void deviceConfigCmd(Device device); - + /** * 设备配置命令:basicParam - * + * * @param device 视频设备 * @param channelId 通道编码(可选) * @param name 设备/通道名称(可选) * @param expiration 注册过期时间(可选) * @param heartBeatInterval 心跳间隔时间(可选) * @param heartBeatCount 心跳超时次数(可选) - */ + */ void deviceBasicConfigCmd(Device device, String channelId, String name, String expiration, String heartBeatInterval, String heartBeatCount, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; /** * 查询设备状态 - * + * * @param device 视频设备 */ void deviceStatusQuery(Device device, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; - + /** * 查询设备信息 - * + * * @param device 视频设备 - * @return + * @return */ void deviceInfoQuery(Device device) throws InvalidArgumentException, SipException, ParseException; - + /** * 查询目录列表 - * + * * @param device 视频设备 */ void catalogQuery(Device device, int sn, SipSubscribe.Event errorEvent) throws SipException, InvalidArgumentException, ParseException; - + /** * 查询录像信息 - * + * * @param device 视频设备 * @param startTime 开始时间,格式要求:yyyy-MM-dd HH:mm:ss * @param endTime 结束时间,格式要求:yyyy-MM-dd HH:mm:ss * @param sn */ void recordInfoQuery(Device device, String channelId, String startTime, String endTime, int sn, Integer Secrecy, String type, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; - + /** * 查询报警信息 - * + * * @param device 视频设备 * @param startPriority 报警起始级别(可选) * @param endPriority 报警终止级别(可选) @@ -293,33 +293,33 @@ public interface ISIPCommander { */ void alarmInfoQuery(Device device, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; - + /** * 查询设备配置 - * + * * @param device 视频设备 * @param channelId 通道编码(可选) * @param configType 配置类型: */ void deviceConfigQuery(Device device, String channelId, String configType, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; - + /** * 查询设备预置位置 - * + * * @param device 视频设备 */ void presetQuery(Device device, String channelId, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; - + /** * 查询移动设备位置数据 - * + * * @param device 视频设备 */ void mobilePostitionQuery(Device device, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; /** * 订阅、取消订阅移动位置 - * + * * @param device 视频设备 * @return true = 命令发送成功 */ diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index fbd9ecec..0d1bf2a8 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -29,7 +29,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import javax.sip.InvalidArgumentException; import javax.sip.ResponseEvent; @@ -57,7 +56,7 @@ public class SIPCommander implements ISIPCommander { @Autowired private SIPSender sipSender; - + @Autowired private SIPRequestHeaderProvider headerProvider; @@ -181,7 +180,7 @@ public class SIPCommander implements ISIPCommander { ptzXml.append("5\r\n"); ptzXml.append("\r\n"); ptzXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()),request); @@ -244,8 +243,8 @@ public class SIPCommander implements ISIPCommander { ptzXml.append("5\r\n"); ptzXml.append("\r\n"); ptzXml.append("\r\n"); - - + + Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()),request, errorEvent, okEvent); @@ -365,7 +364,8 @@ public class SIPCommander implements ISIPCommander { */ @Override public void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, - String startTime, String endTime, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent, + String startTime, String endTime, + InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { @@ -411,7 +411,8 @@ public class SIPCommander implements ISIPCommander { content.append("a=setup:active\r\n"); content.append("a=connection:new\r\n"); } - } else { + } else + { if ("TCP-PASSIVE".equalsIgnoreCase(streamMode)) { content.append("m=video " + ssrcInfo.getPort() + " TCP/RTP/AVP 96 97 98 99\r\n"); } else if ("TCP-ACTIVE".equalsIgnoreCase(streamMode)) { @@ -471,8 +472,9 @@ public class SIPCommander implements ISIPCommander { */ @Override public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, - String startTime, String endTime, int downloadSpeed, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent, - SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { + String startTime, String endTime, int downloadSpeed, + InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent, + SipSubscribe.Event errorEvent,SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException { logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); String sdpIp; @@ -541,10 +543,11 @@ public class SIPCommander implements ISIPCommander { content.append("a=downloadspeed:" + downloadSpeed + "\r\n"); content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc - + HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, null, mediaServerItem.getId()); // 添加订阅 - subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json) -> { + subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json) -> + { hookEvent.call(new InviteStreamInfo(mediaServerItem, json,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId(), "rtp", ssrcInfo.getStream())); subscribe.removeSubscribe(hookSubscribe); hookSubscribe.getContent().put("regist", false); @@ -567,10 +570,11 @@ public class SIPCommander implements ISIPCommander { inviteStreamCallback.call(new InviteStreamInfo(mediaServerItem, null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId(), "rtp", ssrcInfo.getStream())); } - sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, okEvent -> { - ResponseEvent responseEvent = (ResponseEvent) okEvent.event; + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, event -> { + ResponseEvent responseEvent = (ResponseEvent) event.event; SIPResponse response = (SIPResponse) responseEvent.getResponse(); streamSession.put(device.getDeviceId(), channelId, response.getCallIdHeader().getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), response, VideoStreamSessionManager.SessionType.download); + okEvent.response(event); }); } @@ -628,7 +632,7 @@ public class SIPCommander implements ISIPCommander { broadcastXml.append("" + device.getDeviceId() + "\r\n"); broadcastXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, broadcastXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request); @@ -648,7 +652,7 @@ public class SIPCommander implements ISIPCommander { broadcastXml.append("" + device.getDeviceId() + "\r\n"); broadcastXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, broadcastXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent); @@ -679,7 +683,7 @@ public class SIPCommander implements ISIPCommander { cmdXml.append("" + recordCmdStr + "\r\n"); cmdXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent,okEvent); @@ -703,7 +707,7 @@ public class SIPCommander implements ISIPCommander { cmdXml.append("Boot\r\n"); cmdXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request); @@ -762,7 +766,7 @@ public class SIPCommander implements ISIPCommander { } cmdXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent,okEvent); @@ -791,7 +795,7 @@ public class SIPCommander implements ISIPCommander { cmdXml.append("Send\r\n"); cmdXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request); @@ -802,7 +806,6 @@ public class SIPCommander implements ISIPCommander { * * @param device 视频设备 * @param channelId 通道id,非通道则是设备本身 - * @param frontCmd 上级平台的指令,如果存在则直接下发 * @param enabled 看守位使能:1 = 开启,0 = 关闭 * @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s) * @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255 @@ -840,7 +843,7 @@ public class SIPCommander implements ISIPCommander { cmdXml.append("\r\n"); cmdXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent,okEvent); @@ -903,7 +906,7 @@ public class SIPCommander implements ISIPCommander { cmdXml.append("\r\n"); cmdXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent); @@ -926,7 +929,7 @@ public class SIPCommander implements ISIPCommander { catalogXml.append("" + device.getDeviceId() + "\r\n"); catalogXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); @@ -950,7 +953,7 @@ public class SIPCommander implements ISIPCommander { catalogXml.append("" + device.getDeviceId() + "\r\n"); catalogXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); @@ -975,7 +978,7 @@ public class SIPCommander implements ISIPCommander { catalogXml.append(" " + device.getDeviceId() + "\r\n"); catalogXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); @@ -1020,7 +1023,7 @@ public class SIPCommander implements ISIPCommander { } recordInfoXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, recordInfoXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); @@ -1071,7 +1074,7 @@ public class SIPCommander implements ISIPCommander { } cmdXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent); @@ -1101,7 +1104,7 @@ public class SIPCommander implements ISIPCommander { cmdXml.append("" + configType + "\r\n"); cmdXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent); @@ -1128,7 +1131,7 @@ public class SIPCommander implements ISIPCommander { } cmdXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent); @@ -1152,7 +1155,7 @@ public class SIPCommander implements ISIPCommander { mobilePostitionXml.append("60\r\n"); mobilePostitionXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, mobilePostitionXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); @@ -1237,7 +1240,7 @@ public class SIPCommander implements ISIPCommander { } cmdXml.append("\r\n"); - + Request request = headerProvider.createSubscribeRequest(device, cmdXml.toString(), null, expires, "presence",sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request); @@ -1287,14 +1290,14 @@ public class SIPCommander implements ISIPCommander { } dragXml.append(cmdString); dragXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, dragXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); logger.debug("拉框信令: " + request.toString()); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()),request); } - + /** @@ -1398,7 +1401,7 @@ public class SIPCommander implements ISIPCommander { deviceStatusXml.append("\r\n"); deviceStatusXml.append("\r\n"); - + Request request = headerProvider.createMessageRequest(device, deviceStatusXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()),request); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index b8e7c8e5..96027d4c 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -258,7 +258,8 @@ public class PlayServiceImpl implements IPlayService { return; } try { - cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> { + cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> + { logger.info("收到订阅消息: " + response.toJSONString()); dynamicTask.stop(timeOutTaskKey); @@ -273,7 +274,8 @@ public class PlayServiceImpl implements IPlayService { logger.info("[请求截图]: " + fileName); zlmresTfulUtils.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName); - }, (event) -> { + }, (event) -> + { ResponseEvent responseEvent = (ResponseEvent) event.event; String contentString = new String(responseEvent.getResponse().getRawContent()); // 获取ssrc @@ -322,7 +324,8 @@ public class PlayServiceImpl implements IPlayService { } } - }, (event) -> { + }, (event) -> + { dynamicTask.stop(timeOutTaskKey); mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); // 释放ssrc @@ -513,7 +516,8 @@ public class PlayServiceImpl implements IPlayService { try { cmder.playbackStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, infoCallBack, - hookEvent, eventResult -> { + hookEvent, eventResult -> + { if (eventResult.type == SipSubscribe.EventResultType.response) { ResponseEvent responseEvent = (ResponseEvent) eventResult.event; String contentString = new String(responseEvent.getResponse().getRawContent()); @@ -582,6 +586,7 @@ public class PlayServiceImpl implements IPlayService { if (device == null) { return; } + //获取录像下载的服务,配置文件中的record-assist-port不为0 MediaServerItem newMediaServerItem = getNewMediaServerItemHasAssist(device); if (newMediaServerItem == null) { PlayBackResult downloadResult = new PlayBackResult<>(); @@ -651,7 +656,59 @@ public class PlayServiceImpl implements IPlayService { downloadResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem()); downloadResult.setResponse(inviteStreamInfo.getResponse()); hookCallBack.call(downloadResult); - }, errorEvent); + }, errorEvent, eventResult -> + { + if (eventResult.type == SipSubscribe.EventResultType.response) { + ResponseEvent responseEvent = (ResponseEvent) eventResult.event; + String contentString = new String(responseEvent.getResponse().getRawContent()); + // 获取ssrc + int ssrcIndex = contentString.indexOf("y="); + // 检查是否有y字段 + if (ssrcIndex >= 0) { + //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 TODO 后续对不规范的非10位ssrc兼容 + String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); + // 查询到ssrc不一致且开启了ssrc校验则需要针对处理 + if (ssrcInfo.getSsrc().equals(ssrcInResponse)) { + return; + } + logger.info("[回放消息] 收到invite 200, 发现下级自定义了ssrc: {}", ssrcInResponse); + if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) { + logger.info("[回放消息] SSRC修正 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse); + + if (!mediaServerItem.getSsrcConfig().checkSsrc(ssrcInResponse)) { + // ssrc 不可用 + // 释放ssrc + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); + streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); + eventResult.msg = "下级自定义了ssrc,但是此ssrc不可用"; + eventResult.statusCode = 400; + errorEvent.response(eventResult); + return; + } + + // 单端口模式streamId也有变化,需要重新设置监听 + if (!mediaServerItem.isRtpEnable()) { + // 添加订阅 + HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId()); + subscribe.removeSubscribe(hookSubscribe); + hookSubscribe.getContent().put("stream", String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase()); + subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject response) -> { + logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + response.toJSONString()); + dynamicTask.stop(downLoadTimeOutTaskKey); + // hook响应,TODO 此处待处理 +// onPublishHandlerForPlayback(mediaServerItemInUse, response, device.getDeviceId(), channelId, playBackCallback); +// hookCallBack.call(new InviteStreamInfo(mediaServerItem, null, eventResult.callId, "rtp", ssrcInfo.getStream())); + }); + } + // 关闭rtp server + mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); + // 重新开启ssrc server + mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort()); + } + } + } + + }); } catch (InvalidArgumentException | SipException | ParseException e) { logger.error("[命令发送失败] 录像下载: {}", e.getMessage());