diff --git a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java index a35285bdd..1b7a1c433 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java +++ b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java @@ -178,6 +178,10 @@ public class VideoManagerConstants { //************************** 1078 **************************************** - public static final String INVITE_INFO_1078 = "INVITE_INFO_1078:"; + public static final String INVITE_INFO_1078_PLAY = "INVITE_INFO_1078_PLAY:"; + public static final String INVITE_INFO_1078_PLAYBACK = "INVITE_INFO_1078_PLAYBACK:"; + + + public static final String RECORD_LIST_1078 = "RECORD_LIST_1078:"; } diff --git a/src/main/java/com/genersoft/iot/vmp/jt1078/cmd/JT1078Template.java b/src/main/java/com/genersoft/iot/vmp/jt1078/cmd/JT1078Template.java index 98af47a9d..5b0d30e9f 100644 --- a/src/main/java/com/genersoft/iot/vmp/jt1078/cmd/JT1078Template.java +++ b/src/main/java/com/genersoft/iot/vmp/jt1078/cmd/JT1078Template.java @@ -22,6 +22,14 @@ public class JT1078Template { private static final String H9201 = "9201"; private static final String H9202 = "9202"; private static final String H9205 = "9205"; + private static final String H9206 = "9206"; + private static final String H9207 = "9207"; + private static final String H9301 = "9301"; + private static final String H9302 = "9302"; + private static final String H9303 = "9303"; + private static final String H9304 = "9304"; + private static final String H9305 = "9305"; + private static final String H9306 = "9306"; private static final String H0001 = "0001"; private static final String H1205 = "1205"; @@ -111,6 +119,142 @@ public class JT1078Template { return SessionManager.INSTANCE.request(cmd, timeOut); } + /** + * 文件上传 + * + * @param devId 设备号 + * @param j9206 文件上传参数 + */ + public String fileUpload(String devId, J9206 j9206, Integer timeOut) { + Cmd cmd = new Cmd.Builder() + .setDevId(devId) + .setPackageNo(randomInt()) + .setMsgId(H9206) + .setRespId(H0001) + .setRs(j9206) + .build(); + return SessionManager.INSTANCE.request(cmd, timeOut); + } + + /** + * 文件上传控制 + * + * @param devId 设备号 + * @param j9207 文件上传控制参数 + */ + public String fileUploadControl(String devId, J9207 j9207, Integer timeOut) { + Cmd cmd = new Cmd.Builder() + .setDevId(devId) + .setPackageNo(randomInt()) + .setMsgId(H9207) + .setRespId(H0001) + .setRs(j9207) + .build(); + return SessionManager.INSTANCE.request(cmd, timeOut); + } + + /** + * 云台控制指令-云台旋转 + * + * @param devId 设备号 + * @param j9301 云台旋转参数 + */ + public String ptzRotate(String devId, J9301 j9301, Integer timeOut) { + Cmd cmd = new Cmd.Builder() + .setDevId(devId) + .setPackageNo(randomInt()) + .setMsgId(H9301) + .setRespId(H0001) + .setRs(j9301) + .build(); + return SessionManager.INSTANCE.request(cmd, timeOut); + } + + /** + * 云台控制指令-云台调整焦距控制 + * + * @param devId 设备号 + * @param j9302 云台焦距控制参数 + */ + public String ptzFocal(String devId, J9302 j9302, Integer timeOut) { + Cmd cmd = new Cmd.Builder() + .setDevId(devId) + .setPackageNo(randomInt()) + .setMsgId(H9302) + .setRespId(H0001) + .setRs(j9302) + .build(); + return SessionManager.INSTANCE.request(cmd, timeOut); + } + + /** + * 云台控制指令-云台调整光圈控制 + * + * @param devId 设备号 + * @param j9303 云台光圈控制参数 + */ + public String ptzIris(String devId, J9303 j9303, Integer timeOut) { + Cmd cmd = new Cmd.Builder() + .setDevId(devId) + .setPackageNo(randomInt()) + .setMsgId(H9303) + .setRespId(H0001) + .setRs(j9303) + .build(); + return SessionManager.INSTANCE.request(cmd, timeOut); + } + + /** + * 云台控制指令-云台雨刷控制 + * + * @param devId 设备号 + * @param j9304 云台雨刷控制参数 + */ + public String ptzWiper(String devId, J9304 j9304, Integer timeOut) { + Cmd cmd = new Cmd.Builder() + .setDevId(devId) + .setPackageNo(randomInt()) + .setMsgId(H9304) + .setRespId(H0001) + .setRs(j9304) + .build(); + return SessionManager.INSTANCE.request(cmd, timeOut); + } + + /** + * 云台控制指令-红外补光控制 + * + * @param devId 设备号 + * @param j9305 云台红外补光控制参数 + */ + public String ptzSupplementaryLight(String devId, J9305 j9305, Integer timeOut) { + Cmd cmd = new Cmd.Builder() + .setDevId(devId) + .setPackageNo(randomInt()) + .setMsgId(H9305) + .setRespId(H0001) + .setRs(j9305) + .build(); + return SessionManager.INSTANCE.request(cmd, timeOut); + } + + /** + * 云台控制指令-变倍控制 + * + * @param devId 设备号 + * @param j9306 云台变倍控制参数 + */ + public String ptzZoom(String devId, J9306 j9306, Integer timeOut) { + Cmd cmd = new Cmd.Builder() + .setDevId(devId) + .setPackageNo(randomInt()) + .setMsgId(H9306) + .setRespId(H0001) + .setRs(j9306) + .build(); + return SessionManager.INSTANCE.request(cmd, timeOut); + } + private Long randomInt() { return (long) random.nextInt(1000) + 1; } diff --git a/src/main/java/com/genersoft/iot/vmp/jt1078/config/JT1078Controller.java b/src/main/java/com/genersoft/iot/vmp/jt1078/config/JT1078Controller.java index 4d9010149..3b700cef6 100644 --- a/src/main/java/com/genersoft/iot/vmp/jt1078/config/JT1078Controller.java +++ b/src/main/java/com/genersoft/iot/vmp/jt1078/config/JT1078Controller.java @@ -1,19 +1,14 @@ package com.genersoft.iot.vmp.jt1078.config; -import com.genersoft.iot.vmp.common.InviteSessionType; -import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.security.JwtUtils; -import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.jt1078.bean.JTDevice; -import com.genersoft.iot.vmp.jt1078.cmd.JT1078Template; -import com.genersoft.iot.vmp.jt1078.proc.response.*; +import com.genersoft.iot.vmp.jt1078.proc.request.J1205; import com.genersoft.iot.vmp.jt1078.service.Ijt1078Service; import com.genersoft.iot.vmp.service.bean.InviteErrorCode; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.StreamContent; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; -import com.genersoft.iot.vmp.vmanager.gb28181.play.PlayController; import com.github.pagehelper.PageInfo; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -120,6 +115,126 @@ public class JT1078Controller { service.stopPlay(deviceId, channelId); } + @Operation(summary = "1078-暂停点播", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号, 一般为从1开始的数字", required = true) + @GetMapping("/live/pause") + public void pauseLive(HttpServletRequest request, + @Parameter(required = true) String deviceId, + @Parameter(required = false) String channelId) { + if (ObjectUtils.isEmpty(channelId)) { + channelId = "1"; + } + service.pausePlay(deviceId, channelId); + } + + @Operation(summary = "1078-继续点播", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号, 一般为从1开始的数字", required = true) + @GetMapping("/live/continue") + public void continueLive(HttpServletRequest request, + @Parameter(required = true) String deviceId, + @Parameter(required = false) String channelId) { + if (ObjectUtils.isEmpty(channelId)) { + channelId = "1"; + } + service.continueLivePlay(deviceId, channelId); + } + + @Operation(summary = "1078-录像-查询资源列表", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号, 一般为从1开始的数字", required = true) + @Parameter(name = "startTime", description = "开始时间,格式: yyyy-MM-dd HH:mm:ss", required = true) + @Parameter(name = "endTime", description = "结束时间,格式: yyyy-MM-dd HH:mm:ss", required = true) + @GetMapping("/record/list") + public WVPResult> playbackList(HttpServletRequest request, + @Parameter(required = true) String deviceId, + @Parameter(required = false) String channelId, + @Parameter(required = true) String startTime, + @Parameter(required = true) String endTime + ) { + if (ObjectUtils.isEmpty(channelId)) { + channelId = "1"; + } + List recordList = service.getRecordList(deviceId, channelId, startTime, endTime); + if (recordList == null) { + return WVPResult.fail(ErrorCode.ERROR100); + }else { + return WVPResult.success(recordList); + } + } + @Operation(summary = "1078-开始回放", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号, 一般为从1开始的数字", required = true) + @Parameter(name = "startTime", description = "开始时间,格式: yyyy-MM-dd HH:mm:ss", required = true) + @Parameter(name = "endTime", description = "结束时间,格式: yyyy-MM-dd HH:mm:ss", required = true) + @GetMapping("/playback/start") + public DeferredResult> recordLive(HttpServletRequest request, + @Parameter(required = true) String deviceId, + @Parameter(required = false) String channelId, + @Parameter(required = true) String startTime, + @Parameter(required = true) String endTime) { + DeferredResult> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue()); + if (ObjectUtils.isEmpty(channelId)) { + channelId = "1"; + } + String finalChannelId = channelId; + result.onTimeout(()->{ + logger.info("[1078-回放-等待超时] deviceId:{}, channelId:{}, ", deviceId, finalChannelId); + // 释放rtpserver + WVPResult wvpResult = new WVPResult<>(); + wvpResult.setCode(ErrorCode.ERROR100.getCode()); + wvpResult.setMsg("回放超时"); + result.setResult(wvpResult); + service.stopPlay(deviceId, finalChannelId); + }); + + service.playback(deviceId, channelId, startTime, endTime, (code, msg, streamInfo) -> { + WVPResult wvpResult = new WVPResult<>(); + if (code == InviteErrorCode.SUCCESS.getCode()) { + wvpResult.setCode(ErrorCode.SUCCESS.getCode()); + wvpResult.setMsg(ErrorCode.SUCCESS.getMsg()); + + if (streamInfo != null) { + if (userSetting.getUseSourceIpAsStreamIp()) { + streamInfo=streamInfo.clone();//深拷贝 + String host; + try { + URL url=new URL(request.getRequestURL().toString()); + host=url.getHost(); + } catch (MalformedURLException e) { + host=request.getLocalAddr(); + } + streamInfo.channgeStreamIp(host); + } + wvpResult.setData(new StreamContent(streamInfo)); + }else { + wvpResult.setCode(code); + wvpResult.setMsg(msg); + } + }else { + wvpResult.setCode(code); + wvpResult.setMsg(msg); + } + result.setResult(wvpResult); + }); + + return result; + } + + @Operation(summary = "1078-结束回放", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号, 一般为从1开始的数字", required = true) + @GetMapping("/playback/stop") + public void stopPlayback(HttpServletRequest request, + @Parameter(required = true) String deviceId, + @Parameter(required = false) String channelId) { + if (ObjectUtils.isEmpty(channelId)) { + channelId = "1"; + } + service.stopPlayback(deviceId, channelId); + } + @Operation(summary = "分页查询部标设备", security = @SecurityRequirement(name = JwtUtils.HEADER)) @Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "count", description = "每页查询数量", required = true) diff --git a/src/main/java/com/genersoft/iot/vmp/jt1078/event/CallbackManager.java b/src/main/java/com/genersoft/iot/vmp/jt1078/event/CallbackManager.java new file mode 100644 index 000000000..8503feaec --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/jt1078/event/CallbackManager.java @@ -0,0 +1,69 @@ +package com.genersoft.iot.vmp.jt1078.event; + +import com.genersoft.iot.vmp.common.GeneralCallback; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 管理callback回调,支持设置超时时间,未设置则按照五分钟超时自动移除 + */ +@Component +public class CallbackManager { + + private final long expire = 5 * 60 * 1000; + + static class ManagerCallBack { + public String key; + public GeneralCallback callback; + public long createTime; + public long expire; + } + + private final Map allCallbacks = new ConcurrentHashMap<>(); + + + public void addCallback(String key, GeneralCallback callback) { + ManagerCallBack managerCallBack = new ManagerCallBack(); + managerCallBack.callback = callback; + managerCallBack.key = key; + managerCallBack.createTime = System.currentTimeMillis(); + managerCallBack.expire = expire; + allCallbacks.put(key, managerCallBack); + } + + public void addCallback(String key, GeneralCallback callback, long timeout) { + ManagerCallBack managerCallBack = new ManagerCallBack(); + managerCallBack.callback = callback; + managerCallBack.key = key; + managerCallBack.createTime = System.currentTimeMillis(); + managerCallBack.expire = timeout; + allCallbacks.put(key, managerCallBack); + } + + public GeneralCallback getCallback(String key){ + ManagerCallBack managerCallBack = allCallbacks.get(key); + if (managerCallBack != null) { + return managerCallBack.callback; + }else { + return null; + } + } + + public void removeCallback(String key){ + allCallbacks.remove(key); + } + /** + * 对订阅数据进行过期清理 + */ + @Scheduled(fixedRate=expire) //每5分钟执行一次 + public void execute(){ + for (ManagerCallBack callBack : allCallbacks.values()) { + if ((System.currentTimeMillis() - callBack.createTime - callBack.expire) > 0) { + allCallbacks.remove(callBack.key); + } + } + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/jt1078/proc/request/J1205.java b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/request/J1205.java index f42d78eca..f7cbba246 100644 --- a/src/main/java/com/genersoft/iot/vmp/jt1078/proc/request/J1205.java +++ b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/request/J1205.java @@ -45,14 +45,13 @@ public class J1205 extends Re { item.setSize(buf.readUnsignedInt()); recordList.add(item); } - return null; } @Override protected Rs handler(Header header, Session session, Ijt1078Service service) { + // TODO 可能未处理分包的情况 SessionManager.INSTANCE.response(header.getTerminalId(), "1205", (long) respNo, JSON.toJSONString(this)); - J8001 j8001 = new J8001(); j8001.setRespNo(header.getSn()); j8001.setRespId(header.getMsgId()); diff --git a/src/main/java/com/genersoft/iot/vmp/jt1078/proc/request/J1206.java b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/request/J1206.java new file mode 100644 index 000000000..e6079e5b2 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/request/J1206.java @@ -0,0 +1,75 @@ +package com.genersoft.iot.vmp.jt1078.proc.request; + +import com.alibaba.fastjson2.JSON; +import com.genersoft.iot.vmp.jt1078.annotation.MsgId; +import com.genersoft.iot.vmp.jt1078.proc.Header; +import com.genersoft.iot.vmp.jt1078.proc.response.J8001; +import com.genersoft.iot.vmp.jt1078.proc.response.Rs; +import com.genersoft.iot.vmp.jt1078.service.Ijt1078Service; +import com.genersoft.iot.vmp.jt1078.session.Session; +import com.genersoft.iot.vmp.jt1078.session.SessionManager; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import org.springframework.context.ApplicationEvent; + +import java.util.ArrayList; +import java.util.List; + +/** + * 文件上传完成通知 + * + */ +@MsgId(id = "1206") +public class J1206 extends Re { + Integer respNo; + + // 0:成功; 1:失败 + private int result; + + @Override + protected Rs decode0(ByteBuf buf, Header header, Session session) { + respNo = buf.readUnsignedShort(); + result = buf.readUnsignedByte(); + return null; + } + + @Override + protected Rs handler(Header header, Session session, Ijt1078Service service) { + J8001 j8001 = new J8001(); + j8001.setRespNo(header.getSn()); + j8001.setRespId(header.getMsgId()); + j8001.setResult(J8001.SUCCESS); + return j8001; + } + + + public Integer getRespNo() { + return respNo; + } + + public void setRespNo(Integer respNo) { + this.respNo = respNo; + } + + public int getResult() { + return result; + } + + public void setResult(int result) { + this.result = result; + } + + + @Override + public String toString() { + return "J1206{" + + "respNo=" + respNo + + ", result=" + result + + '}'; + } + + @Override + public ApplicationEvent getEvent() { + return null; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9206.java b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9206.java new file mode 100644 index 000000000..f00f25b24 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9206.java @@ -0,0 +1,201 @@ +package com.genersoft.iot.vmp.jt1078.proc.response; + +import com.genersoft.iot.vmp.jt1078.annotation.MsgId; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.util.CharsetUtil; + +/** + * 文件上传指令 + * + */ +@MsgId(id = "9206") +public class J9206 extends Rs { + + // 服务器地址 + private String serverIp; + // 服务器端口 + private int port; + // 用户名 + private String user; + // 密码 + private String password; + // 文件上传路径 + private String path; + // 逻辑通道号 + private int channelId; + + // 开始时间YYMMDDHHMMSS,全0表示无起始时间 + private String startTime; + + // 结束时间YYMMDDHHMMSS,全0表示无终止时间 + private String endTime; + + // 报警标志 + private final int warnType = 0; + + // 音视频资源类型:0.音视频 1.音频 2.视频 3.视频或音视频 + private int mediaType; + + // 码流类型:0.所有码流 1.主码流 2.子码流 + private int streamType = 0; + + // 存储器类型:0.所有存储器 1.主存储器 2.灾备存储器 + private int storageType = 0; + + // 任务执行条件, + // 1:仅WI-FI 下可下载, + // 2: 仅LAN 连接时可下载; + // 3: WI-FI + LAN 连接时可下载; + // 4: 仅3G/ 4G 连接时可下载 + // 5: WI-FI + 3G/ 4G 连接时可下载 + // 6: WI-FI + LAN 连接时可下载 + // 7: WI-FI + LAN + 3G/ 4G 连接时可下载 + private int taskConditions = 7; + + @Override + public ByteBuf encode() { + ByteBuf buffer = Unpooled.buffer(); + + buffer.writeByte(serverIp.getBytes().length); + buffer.writeCharSequence(serverIp, CharsetUtil.UTF_8); + buffer.writeByte(port); + buffer.writeByte(user.getBytes().length); + buffer.writeCharSequence(user, CharsetUtil.UTF_8); + buffer.writeByte(password.getBytes().length); + buffer.writeCharSequence(password, CharsetUtil.UTF_8); + buffer.writeByte(path.getBytes().length); + buffer.writeCharSequence(path, CharsetUtil.UTF_8); + buffer.writeByte(channelId); + buffer.writeBytes(ByteBufUtil.decodeHexDump(startTime)); + buffer.writeBytes(ByteBufUtil.decodeHexDump(endTime)); + buffer.writeLong(warnType); + buffer.writeByte(mediaType); + buffer.writeByte(streamType); + buffer.writeByte(storageType); + buffer.writeByte(taskConditions); + + return buffer; + } + + + public String getServerIp() { + return serverIp; + } + + public void setServerIp(String serverIp) { + this.serverIp = serverIp; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public int getChannelId() { + return channelId; + } + + public void setChannelId(int channelId) { + this.channelId = channelId; + } + + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + + public String getEndTime() { + return endTime; + } + + public void setEndTime(String endTime) { + this.endTime = endTime; + } + + public int getWarnType() { + return warnType; + } + + public int getMediaType() { + return mediaType; + } + + public void setMediaType(int mediaType) { + this.mediaType = mediaType; + } + + public int getStreamType() { + return streamType; + } + + public void setStreamType(int streamType) { + this.streamType = streamType; + } + + public int getStorageType() { + return storageType; + } + + public void setStorageType(int storageType) { + this.storageType = storageType; + } + + public int getTaskConditions() { + return taskConditions; + } + + public void setTaskConditions(int taskConditions) { + this.taskConditions = taskConditions; + } + + @Override + public String toString() { + return "J9206{" + + "serverIp='" + serverIp + '\'' + + ", port=" + port + + ", user='" + user + '\'' + + ", password='" + password + '\'' + + ", path='" + path + '\'' + + ", channelId=" + channelId + + ", startTime='" + startTime + '\'' + + ", endTime='" + endTime + '\'' + + ", warnType=" + warnType + + ", mediaType=" + mediaType + + ", streamType=" + streamType + + ", storageType=" + storageType + + ", taskConditions=" + taskConditions + + '}'; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9207.java b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9207.java new file mode 100644 index 000000000..43f8acac7 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9207.java @@ -0,0 +1,54 @@ +package com.genersoft.iot.vmp.jt1078.proc.response; + +import com.genersoft.iot.vmp.jt1078.annotation.MsgId; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; +import io.netty.util.CharsetUtil; + +/** + * 文件上传控制 + * + */ +@MsgId(id = "9207") +public class J9207 extends Rs { + + // 对应平台文件上传消息的流水号 + Integer respNo; + + // 控制: 0:暂停; 1:继续; 2:取消 + private int control; + + @Override + public ByteBuf encode() { + ByteBuf buffer = Unpooled.buffer(); + buffer.writeShort(respNo); + buffer.writeByte(control); + return buffer; + } + + + public Integer getRespNo() { + return respNo; + } + + public void setRespNo(Integer respNo) { + this.respNo = respNo; + } + + public int getControl() { + return control; + } + + public void setControl(int control) { + this.control = control; + } + + @Override + public String toString() { + return "J9207{" + + "respNo=" + respNo + + ", control=" + control + + '}'; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9301.java b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9301.java new file mode 100644 index 000000000..0c24762d6 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9301.java @@ -0,0 +1,64 @@ +package com.genersoft.iot.vmp.jt1078.proc.response; + +import com.genersoft.iot.vmp.jt1078.annotation.MsgId; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.buffer.Unpooled; + +/** + * 云台控制指令-云台旋转 + * + */ +@MsgId(id = "9301") +public class J9301 extends Rs { + // 逻辑通道号 + private int channel; + + // 方向: 0:停止; 1:上; 2:下; 3:左; 4:右 + private int direction; + + // 速度:0 ~ 255 + private int speed; + + @Override + public ByteBuf encode() { + ByteBuf buffer = Unpooled.buffer(); + buffer.writeByte(channel); + buffer.writeByte(direction); + buffer.writeByte(speed); + return buffer; + } + + public int getChannel() { + return channel; + } + + public void setChannel(int channel) { + this.channel = channel; + } + + public int getDirection() { + return direction; + } + + public void setDirection(int direction) { + this.direction = direction; + } + + public int getSpeed() { + return speed; + } + + public void setSpeed(int speed) { + this.speed = speed; + } + + @Override + public String toString() { + return "J9301{" + + "channel=" + channel + + ", direction=" + direction + + ", speed=" + speed + + '}'; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9302.java b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9302.java new file mode 100644 index 000000000..bb1ec2e31 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9302.java @@ -0,0 +1,50 @@ +package com.genersoft.iot.vmp.jt1078.proc.response; + +import com.genersoft.iot.vmp.jt1078.annotation.MsgId; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +/** + * 云台控制指令-焦距控制 + * + */ +@MsgId(id = "9302") +public class J9302 extends Rs { + // 逻辑通道号 + private int channel; + + // 方向: 0:焦距调大; 1:焦距调小 + private int focalDirection; + + @Override + public ByteBuf encode() { + ByteBuf buffer = Unpooled.buffer(); + buffer.writeByte(channel); + buffer.writeByte(focalDirection); + return buffer; + } + + public int getChannel() { + return channel; + } + + public void setChannel(int channel) { + this.channel = channel; + } + + public int getFocalDirection() { + return focalDirection; + } + + public void setFocalDirection(int focalDirection) { + this.focalDirection = focalDirection; + } + + @Override + public String toString() { + return "J9302{" + + "channel=" + channel + + ", zoomDirection=" + focalDirection + + '}'; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9303.java b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9303.java new file mode 100644 index 000000000..5661bcfda --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9303.java @@ -0,0 +1,50 @@ +package com.genersoft.iot.vmp.jt1078.proc.response; + +import com.genersoft.iot.vmp.jt1078.annotation.MsgId; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +/** + * 云台控制指令-光圈控制 + * + */ +@MsgId(id = "9303") +public class J9303 extends Rs { + // 逻辑通道号 + private int channel; + + // 调整方式: 0:调大; 1:调小 + private int iris; + + @Override + public ByteBuf encode() { + ByteBuf buffer = Unpooled.buffer(); + buffer.writeByte(channel); + buffer.writeByte(iris); + return buffer; + } + + public int getChannel() { + return channel; + } + + public void setChannel(int channel) { + this.channel = channel; + } + + public int getIris() { + return iris; + } + + public void setIris(int iris) { + this.iris = iris; + } + + @Override + public String toString() { + return "J9303{" + + "channel=" + channel + + ", iris=" + iris + + '}'; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9304.java b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9304.java new file mode 100644 index 000000000..8fbf13df2 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9304.java @@ -0,0 +1,50 @@ +package com.genersoft.iot.vmp.jt1078.proc.response; + +import com.genersoft.iot.vmp.jt1078.annotation.MsgId; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +/** + * 云台控制指令-云台雨刷控制 + * + */ +@MsgId(id = "9304") +public class J9304 extends Rs { + // 逻辑通道号 + private int channel; + + // 启停标识: 0:停止; 1:启动 + private int on; + + @Override + public ByteBuf encode() { + ByteBuf buffer = Unpooled.buffer(); + buffer.writeByte(channel); + buffer.writeByte(on); + return buffer; + } + + public int getChannel() { + return channel; + } + + public void setChannel(int channel) { + this.channel = channel; + } + + public int getOn() { + return on; + } + + public void setOn(int on) { + this.on = on; + } + + @Override + public String toString() { + return "J9304{" + + "channel=" + channel + + ", on=" + on + + '}'; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9305.java b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9305.java new file mode 100644 index 000000000..0f16ed1ed --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9305.java @@ -0,0 +1,50 @@ +package com.genersoft.iot.vmp.jt1078.proc.response; + +import com.genersoft.iot.vmp.jt1078.annotation.MsgId; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +/** + * 云台控制指令-红外补光控制 + * + */ +@MsgId(id = "9305") +public class J9305 extends Rs { + // 逻辑通道号 + private int channel; + + // 启停标识: 0:停止; 1:启动 + private int on; + + @Override + public ByteBuf encode() { + ByteBuf buffer = Unpooled.buffer(); + buffer.writeByte(channel); + buffer.writeByte(on); + return buffer; + } + + public int getChannel() { + return channel; + } + + public void setChannel(int channel) { + this.channel = channel; + } + + public int getOn() { + return on; + } + + public void setOn(int on) { + this.on = on; + } + + @Override + public String toString() { + return "J9305{" + + "channel=" + channel + + ", on=" + on + + '}'; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9306.java b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9306.java new file mode 100644 index 000000000..27a4d1419 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/jt1078/proc/response/J9306.java @@ -0,0 +1,50 @@ +package com.genersoft.iot.vmp.jt1078.proc.response; + +import com.genersoft.iot.vmp.jt1078.annotation.MsgId; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +/** + * 云台控制指令-云台变倍控制 + * + */ +@MsgId(id = "9306") +public class J9306 extends Rs { + // 逻辑通道号 + private int channel; + + // 0:调大; 1:调小 + private int zoom; + + @Override + public ByteBuf encode() { + ByteBuf buffer = Unpooled.buffer(); + buffer.writeByte(channel); + buffer.writeByte(zoom); + return buffer; + } + + public int getChannel() { + return channel; + } + + public void setChannel(int channel) { + this.channel = channel; + } + + public int getZoom() { + return zoom; + } + + public void setZoom(int zoom) { + this.zoom = zoom; + } + + @Override + public String toString() { + return "J9306{" + + "channel=" + channel + + ", zoom=" + zoom + + '}'; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/jt1078/service/Ijt1078Service.java b/src/main/java/com/genersoft/iot/vmp/jt1078/service/Ijt1078Service.java index 7406099df..3ac24c7e7 100644 --- a/src/main/java/com/genersoft/iot/vmp/jt1078/service/Ijt1078Service.java +++ b/src/main/java/com/genersoft/iot/vmp/jt1078/service/Ijt1078Service.java @@ -1,9 +1,9 @@ package com.genersoft.iot.vmp.jt1078.service; -import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.common.GeneralCallback; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.jt1078.bean.JTDevice; +import com.genersoft.iot.vmp.jt1078.proc.request.J1205; import com.github.pagehelper.PageInfo; import java.util.List; @@ -23,5 +23,15 @@ public interface Ijt1078Service { void play(String deviceId, String channelId, GeneralCallback callback); + void playback(String deviceId, String channelId, String startTime, String endTime, GeneralCallback callback); + void stopPlay(String deviceId, String channelId); + + void pausePlay(String deviceId, String channelId); + + void continueLivePlay(String deviceId, String channelId); + + List getRecordList(String deviceId, String channelId, String startTime, String endTime); + + void stopPlayback(String deviceId, String channelId); } diff --git a/src/main/java/com/genersoft/iot/vmp/jt1078/service/impl/jt1078ServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/jt1078/service/impl/jt1078ServiceImpl.java index af87e01b7..ef483060d 100644 --- a/src/main/java/com/genersoft/iot/vmp/jt1078/service/impl/jt1078ServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/jt1078/service/impl/jt1078ServiceImpl.java @@ -1,18 +1,18 @@ package com.genersoft.iot.vmp.jt1078.service.impl; +import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.common.GeneralCallback; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.common.VideoManagerConstants; import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.UserSetting; -import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; import com.genersoft.iot.vmp.jt1078.bean.JTDevice; import com.genersoft.iot.vmp.jt1078.cmd.JT1078Template; -import com.genersoft.iot.vmp.jt1078.config.JT1078Controller; import com.genersoft.iot.vmp.jt1078.dao.JTDeviceMapper; -import com.genersoft.iot.vmp.jt1078.proc.response.J9101; -import com.genersoft.iot.vmp.jt1078.proc.response.J9102; +import com.genersoft.iot.vmp.jt1078.event.CallbackManager; +import com.genersoft.iot.vmp.jt1078.proc.request.J1205; +import com.genersoft.iot.vmp.jt1078.proc.response.*; import com.genersoft.iot.vmp.jt1078.service.Ijt1078Service; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; @@ -23,24 +23,17 @@ import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaService; -import com.genersoft.iot.vmp.service.bean.ErrorCallback; import com.genersoft.iot.vmp.service.bean.InviteErrorCode; import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.utils.DateUtil; -import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; -import javax.annotation.Resource; -import javax.sip.InvalidArgumentException; -import javax.sip.SipException; -import java.text.ParseException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -78,6 +71,9 @@ public class jt1078ServiceImpl implements Ijt1078Service { @Autowired private ZLMRESTfulUtils zlmresTfulUtils; + @Autowired + private CallbackManager callbackManager; + @Override public JTDevice getDevice(String terminalId) { @@ -120,7 +116,7 @@ public class jt1078ServiceImpl implements Ijt1078Service { public void play(String deviceId, String channelId, GeneralCallback callback) { // 检查流是否已经存在,存在则返回 - String playKey = VideoManagerConstants.INVITE_INFO_1078 + deviceId + ":" + channelId; + String playKey = VideoManagerConstants.INVITE_INFO_1078_PLAY + deviceId + ":" + channelId; List> errorCallbacks = inviteErrorCallbackMap.computeIfAbsent(playKey, k -> new ArrayList<>()); errorCallbacks.add(callback); StreamInfo streamInfo = (StreamInfo)redisTemplate.opsForValue().get(playKey); @@ -146,7 +142,12 @@ public class jt1078ServiceImpl implements Ijt1078Service { } String stream = deviceId + "-" + channelId; MediaServerItem mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(null); - + if (mediaServerItem == null) { + for (GeneralCallback errorCallback : errorCallbacks) { + errorCallback.run(InviteErrorCode.FAIL.getCode(), "未找到可用的媒体节点", streamInfo); + } + return; + } // 设置hook监听 HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId()); subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, HookParam hookParam) -> { @@ -195,7 +196,7 @@ public class jt1078ServiceImpl implements Ijt1078Service { @Override public void stopPlay(String deviceId, String channelId) { - String playKey = VideoManagerConstants.INVITE_INFO_1078 + deviceId + ":" + channelId; + String playKey = VideoManagerConstants.INVITE_INFO_1078_PLAY + deviceId + ":" + channelId; dynamicTask.stop(playKey); StreamInfo streamInfo = (StreamInfo) redisTemplate.opsForValue().get(playKey); // 发送停止命令 @@ -205,6 +206,7 @@ public class jt1078ServiceImpl implements Ijt1078Service { j9102.setCloseType(0); j9102.setStreamType(1); jt1078Template.stopLive(deviceId, j9102, 6); + logger.info("[1078-停止点播] deviceId: {}, channelId: {}", deviceId, channelId); // 删除缓存数据 if (streamInfo != null) { // 关闭rtpServer @@ -218,4 +220,175 @@ public class jt1078ServiceImpl implements Ijt1078Service { } } } + + @Override + public void pausePlay(String deviceId, String channelId) { + String playKey = VideoManagerConstants.INVITE_INFO_1078_PLAY + deviceId + ":" + channelId; + dynamicTask.stop(playKey); + StreamInfo streamInfo = (StreamInfo) redisTemplate.opsForValue().get(playKey); + if (streamInfo == null) { + logger.info("[1078-暂停点播] 未找到点播信息 deviceId: {}, channelId: {}", deviceId, channelId); + } + logger.info("[1078-暂停点播] deviceId: {}, channelId: {}", deviceId, channelId); + // 发送暂停命令 + J9102 j9102 = new J9102(); + j9102.setChannel(Integer.valueOf(channelId)); + j9102.setCommand(2); + j9102.setCloseType(0); + j9102.setStreamType(1); + jt1078Template.stopLive(deviceId, j9102, 6); + } + + @Override + public void continueLivePlay(String deviceId, String channelId) { + String playKey = VideoManagerConstants.INVITE_INFO_1078_PLAY + deviceId + ":" + channelId; + dynamicTask.stop(playKey); + StreamInfo streamInfo = (StreamInfo) redisTemplate.opsForValue().get(playKey); + if (streamInfo == null) { + logger.info("[1078-继续点播] 未找到点播信息 deviceId: {}, channelId: {}", deviceId, channelId); + } + logger.info("[1078-继续点播] deviceId: {}, channelId: {}", deviceId, channelId); + // 发送暂停命令 + J9102 j9102 = new J9102(); + j9102.setChannel(Integer.valueOf(channelId)); + j9102.setCommand(2); + j9102.setCloseType(0); + j9102.setStreamType(1); + jt1078Template.stopLive(deviceId, j9102, 6); + } + + @Override + public List getRecordList(String deviceId, String channelId, String startTime, String endTime) { + logger.info("[1078-查询录像列表] deviceId: {}, channelId: {}, startTime: {}, endTime: {}" + , deviceId, channelId, startTime, endTime); + // 发送请求录像列表命令 + J9205 j9205 = new J9205(); + j9205.setChannelId(Integer.parseInt(channelId)); + j9205.setStartTime(DateUtil.yyyy_MM_dd_HH_mm_ssTo1078(startTime)); + j9205.setEndTime(DateUtil.yyyy_MM_dd_HH_mm_ssTo1078(endTime)); + j9205.setMediaType(0); + j9205.setStreamType(0); + j9205.setStorageType(0); + String J1205JSON = jt1078Template.queryBackTime(deviceId, j9205, 20); + if (J1205JSON == null) { + return null; + } + J1205 j1205 = JSON.parseObject(J1205JSON, J1205.class); + if (j1205 == null) { + return null; + } + logger.info("[1078-查询录像列表] deviceId: {}, channelId: {}, startTime: {}, endTime: {}, 结果: {}条" + , deviceId, channelId, startTime, endTime, j1205.getRecordList().size() ); + return j1205.getRecordList(); + } + + @Override + public void playback(String deviceId, String channelId, String startTime, String endTime, GeneralCallback callback) { + + // 检查流是否已经存在,存在则返回 + String playbackKey = VideoManagerConstants.INVITE_INFO_1078_PLAYBACK + deviceId + ":" + channelId; + List> errorCallbacks = inviteErrorCallbackMap.computeIfAbsent(playbackKey, k -> new ArrayList<>()); + errorCallbacks.add(callback); + String logInfo = String.format("deviceId:%s, channelId:%s, startTime:%s, endTime:%s", deviceId, channelId, startTime, endTime); + StreamInfo streamInfo = (StreamInfo)redisTemplate.opsForValue().get(playbackKey); + if (streamInfo != null) { + String mediaServerId = streamInfo.getMediaServerId(); + MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); + if (mediaServerItem != null) { + // 查询流是否存在,不存在则删除缓存数据 + JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo(mediaServerItem, "rtp", "rtsp", streamInfo.getStream()); + if (mediaInfo != null && mediaInfo.getInteger("code") == 0 ) { + Boolean online = mediaInfo.getBoolean("online"); + if (online != null && online) { + logger.info("[1078-回放] 回放已经存在,直接返回, logInfo: {}", logInfo); + for (GeneralCallback errorCallback : errorCallbacks) { + errorCallback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo); + } + return; + } + } + } + // 清理数据 + redisTemplate.delete(playbackKey); + } + String startTimeParam = DateUtil.yyyy_MM_dd_HH_mm_ssTo1078(startTime); + String endTimeParam = DateUtil.yyyy_MM_dd_HH_mm_ssTo1078(endTime); + String stream = deviceId + "-" + channelId + "-" + startTimeParam + "-" + endTimeParam; + MediaServerItem mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(null); + if (mediaServerItem == null) { + for (GeneralCallback errorCallback : errorCallbacks) { + errorCallback.run(InviteErrorCode.FAIL.getCode(), "未找到可用的媒体节点", streamInfo); + } + return; + } + // 设置hook监听 + HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId()); + subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, HookParam hookParam) -> { + OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam) hookParam; + dynamicTask.stop(playbackKey); + logger.info("[1078-回放] 回放成功, logInfo: {}", logInfo); + StreamInfo info = onPublishHandler(mediaServerItemInUse, streamChangedHookParam, deviceId, channelId); + + for (GeneralCallback errorCallback : errorCallbacks) { + errorCallback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), info); + } + subscribe.removeSubscribe(hookSubscribe); + redisTemplate.opsForValue().set(playbackKey, info); + }); + // 设置超时监听 + dynamicTask.startDelay(playbackKey, () -> { + logger.info("[1078-回放] 回放超时, logInfo: {}", logInfo); + for (GeneralCallback errorCallback : errorCallbacks) { + errorCallback.run(InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode(), + InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getMsg(), null); + } + + }, userSetting.getPlayTimeout()); + + // 开启收流端口 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, stream, null, false, false, 0, false, false, 1); + logger.info("[1078-回放] logInfo: {}, 端口: {}", logInfo, ssrcInfo.getPort()); + J9201 j9201 = new J9201(); + j9201.setChannel(Integer.parseInt(channelId)); + j9201.setIp(mediaServerItem.getSdpIp()); + j9201.setRate(0); + j9201.setPlaybackType(0); + j9201.setPlaybackSpeed(0); + j9201.setTcpPort(ssrcInfo.getPort()); + j9201.setUdpPort(ssrcInfo.getPort()); + j9201.setType(0); + j9201.setStartTime(DateUtil.yyyy_MM_dd_HH_mm_ssTo1078(startTime)); + j9201.setEndTime(DateUtil.yyyy_MM_dd_HH_mm_ssTo1078(endTime)); + String s = jt1078Template.startBackLive(deviceId, j9201, 20); + System.out.println("111ssss=== " + s); + + } + + @Override + public void stopPlayback(String deviceId, String channelId) { + String playKey = VideoManagerConstants.INVITE_INFO_1078_PLAYBACK + deviceId + ":" + channelId; + dynamicTask.stop(playKey); + StreamInfo streamInfo = (StreamInfo) redisTemplate.opsForValue().get(playKey); + // 发送停止命令 + J9202 j9202 = new J9202(); + j9202.setChannel(Integer.parseInt(channelId)); + j9202.setPlaybackType(0); + j9202.setPlaybackSpeed(0); + j9202.setPlaybackTime(""); + jt1078Template.controlBackLive(deviceId, j9202, 6); + logger.info("[1078-停止回放] deviceId: {}, channelId: {}", deviceId, channelId); + // 删除缓存数据 + if (streamInfo != null) { + // 关闭rtpServer + mediaServerService.closeRTPServer(streamInfo.getMediaServerId(), streamInfo.getStream()); + } + // 清理回调 + List> generalCallbacks = inviteErrorCallbackMap.get(playKey); + if (!generalCallbacks.isEmpty()) { + for (GeneralCallback callback : generalCallbacks) { + callback.run(InviteErrorCode.ERROR_FOR_FINISH.getCode(), InviteErrorCode.ERROR_FOR_FINISH.getMsg(), null); + } + } + } + } diff --git a/src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java b/src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java index ddcbb213c..da9724c40 100755 --- a/src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java +++ b/src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java @@ -49,6 +49,7 @@ public class DateUtil { * wvp内部统一时间格式 */ public static final String URL_PATTERN = "yyyyMMddHHmmss"; + public static final String PATTERN1078 = "yyMMddHHmmss"; /** * 日期格式 @@ -65,6 +66,7 @@ public class DateUtil { public static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr)); public static final DateTimeFormatter DateFormatter = DateTimeFormatter.ofPattern(date_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr)); public static final DateTimeFormatter urlFormatter = DateTimeFormatter.ofPattern(URL_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr)); + public static final DateTimeFormatter formatter1078 = DateTimeFormatter.ofPattern(PATTERN1078, Locale.getDefault()).withZone(ZoneId.of(zoneStr)); public static String yyyy_MM_dd_HH_mm_ssToISO8601(String formatTime) { @@ -86,6 +88,9 @@ public class DateUtil { public static String urlToyyyy_MM_dd_HH_mm_ss(String formatTime) { return formatter.format(urlFormatter.parse(formatTime)); } + public static String yyyy_MM_dd_HH_mm_ssTo1078(String formatTime) { + return formatter1078.format(formatter.parse(formatTime)); + } /** * yyyy_MM_dd_HH_mm_ss 转时间戳 diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/ErrorCode.java b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/ErrorCode.java index e2e3879bd..6506b666d 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/ErrorCode.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/ErrorCode.java @@ -10,6 +10,7 @@ public enum ErrorCode { ERROR404(404, "资源未找到"), ERROR403(403, "无权限操作"), ERROR401(401, "请登录后重新请求"), + ERROR408(408, "请求超时"), ERROR500(500, "系统异常"); private final int code;