Commit 5a152791c0677bd47d4386a1ba54ccf9060849ce

Authored by 648540858
1 parent 57192a49

添加获取截图接口

src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
@@ -51,6 +51,8 @@ public class DeferredResultHolder { @@ -51,6 +51,8 @@ public class DeferredResultHolder {
51 51
52 public static final String CALLBACK_CMD_BROADCAST = "CALLBACK_BROADCAST"; 52 public static final String CALLBACK_CMD_BROADCAST = "CALLBACK_BROADCAST";
53 53
  54 + public static final String CALLBACK_CMD_SNAP= "CALLBACK_SNAP";
  55 +
54 private Map<String, Map<String, DeferredResultEx>> map = new ConcurrentHashMap<>(); 56 private Map<String, Map<String, DeferredResultEx>> map = new ConcurrentHashMap<>();
55 57
56 58
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
@@ -19,7 +19,7 @@ import com.genersoft.iot.vmp.service.IMediaServerService; @@ -19,7 +19,7 @@ import com.genersoft.iot.vmp.service.IMediaServerService;
19 import com.genersoft.iot.vmp.service.IPlayService; 19 import com.genersoft.iot.vmp.service.IPlayService;
20 import com.genersoft.iot.vmp.service.IStreamProxyService; 20 import com.genersoft.iot.vmp.service.IStreamProxyService;
21 import com.genersoft.iot.vmp.service.IStreamPushService; 21 import com.genersoft.iot.vmp.service.IStreamPushService;
22 -import com.genersoft.iot.vmp.service.bean.InviteErrorCallback; 22 +import com.genersoft.iot.vmp.service.bean.ErrorCallback;
23 import com.genersoft.iot.vmp.service.bean.InviteErrorCode; 23 import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
24 import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; 24 import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
25 import com.genersoft.iot.vmp.service.bean.SSRCInfo; 25 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
@@ -377,7 +377,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -377,7 +377,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
377 377
378 Long finalStartTime = startTime; 378 Long finalStartTime = startTime;
379 Long finalStopTime = stopTime; 379 Long finalStopTime = stopTime;
380 - InviteErrorCallback<Object> hookEvent = (code, msg, data) -> { 380 + ErrorCallback<Object> hookEvent = (code, msg, data) -> {
381 StreamInfo streamInfo = (StreamInfo)data; 381 StreamInfo streamInfo = (StreamInfo)data;
382 MediaServerItem mediaServerItemInUSe = mediaServerService.getOne(streamInfo.getMediaServerId()); 382 MediaServerItem mediaServerItemInUSe = mediaServerService.getOne(streamInfo.getMediaServerId());
383 logger.info("[上级Invite]下级已经开始推流。 回复200OK(SDP), {}/{}", streamInfo.getApp(), streamInfo.getStream()); 383 logger.info("[上级Invite]下级已经开始推流。 回复200OK(SDP), {}/{}", streamInfo.getApp(), streamInfo.getStream());
@@ -426,7 +426,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -426,7 +426,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
426 logger.error("[命令发送失败] 国标级联 回复SdpAck", e); 426 logger.error("[命令发送失败] 国标级联 回复SdpAck", e);
427 } 427 }
428 }; 428 };
429 - InviteErrorCallback<Object> errorEvent = ((statusCode, msg, data) -> { 429 + ErrorCallback<Object> errorEvent = ((statusCode, msg, data) -> {
430 // 未知错误。直接转发设备点播的错误 430 // 未知错误。直接转发设备点播的错误
431 try { 431 try {
432 if (statusCode > 0) { 432 if (statusCode > 0) {
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
@@ -154,7 +154,6 @@ public class ZLMRESTfulUtils { @@ -154,7 +154,6 @@ public class ZLMRESTfulUtils {
154 154
155 public void sendGetForImg(MediaServerItem mediaServerItem, String api, Map<String, Object> params, String targetPath, String fileName) { 155 public void sendGetForImg(MediaServerItem mediaServerItem, String api, Map<String, Object> params, String targetPath, String fileName) {
156 String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api); 156 String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api);
157 - logger.debug(url);  
158 HttpUrl parseUrl = HttpUrl.parse(url); 157 HttpUrl parseUrl = HttpUrl.parse(url);
159 if (parseUrl == null) { 158 if (parseUrl == null) {
160 return; 159 return;
src/main/java/com/genersoft/iot/vmp/service/IInviteStreamService.java
@@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.service; @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.service;
2 2
3 import com.genersoft.iot.vmp.common.InviteInfo; 3 import com.genersoft.iot.vmp.common.InviteInfo;
4 import com.genersoft.iot.vmp.common.InviteSessionType; 4 import com.genersoft.iot.vmp.common.InviteSessionType;
5 -import com.genersoft.iot.vmp.service.bean.InviteErrorCallback; 5 +import com.genersoft.iot.vmp.service.bean.ErrorCallback;
6 6
7 /** 7 /**
8 * 记录国标点播的状态,包括实时预览,下载,录像回放 8 * 记录国标点播的状态,包括实时预览,下载,录像回放
@@ -54,7 +54,7 @@ public interface IInviteStreamService { @@ -54,7 +54,7 @@ public interface IInviteStreamService {
54 /** 54 /**
55 * 添加一个invite回调 55 * 添加一个invite回调
56 */ 56 */
57 - void once(InviteSessionType type, String deviceId, String channelId, String stream, InviteErrorCallback<Object> callback); 57 + void once(InviteSessionType type, String deviceId, String channelId, String stream, ErrorCallback<Object> callback);
58 58
59 /** 59 /**
60 * 调用一个invite回调 60 * 调用一个invite回调
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
@@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.common.StreamInfo; @@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.common.StreamInfo;
4 import com.genersoft.iot.vmp.conf.exception.ServiceException; 4 import com.genersoft.iot.vmp.conf.exception.ServiceException;
5 import com.genersoft.iot.vmp.gb28181.bean.Device; 5 import com.genersoft.iot.vmp.gb28181.bean.Device;
6 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 6 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
7 -import com.genersoft.iot.vmp.service.bean.InviteErrorCallback; 7 +import com.genersoft.iot.vmp.service.bean.ErrorCallback;
8 import com.genersoft.iot.vmp.service.bean.SSRCInfo; 8 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
9 9
10 import javax.sip.InvalidArgumentException; 10 import javax.sip.InvalidArgumentException;
@@ -17,8 +17,8 @@ import java.text.ParseException; @@ -17,8 +17,8 @@ import java.text.ParseException;
17 public interface IPlayService { 17 public interface IPlayService {
18 18
19 void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, 19 void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
20 - InviteErrorCallback<Object> callback);  
21 - SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, InviteErrorCallback<Object> callback); 20 + ErrorCallback<Object> callback);
  21 + SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, ErrorCallback<Object> callback);
22 22
23 MediaServerItem getNewMediaServerItem(Device device); 23 MediaServerItem getNewMediaServerItem(Device device);
24 24
@@ -27,13 +27,13 @@ public interface IPlayService { @@ -27,13 +27,13 @@ public interface IPlayService {
27 */ 27 */
28 MediaServerItem getNewMediaServerItemHasAssist(Device device); 28 MediaServerItem getNewMediaServerItemHasAssist(Device device);
29 29
30 - void playBack(String deviceId, String channelId, String startTime, String endTime, InviteErrorCallback<Object> callback);  
31 - void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, InviteErrorCallback<Object> callback); 30 + void playBack(String deviceId, String channelId, String startTime, String endTime, ErrorCallback<Object> callback);
  31 + void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, ErrorCallback<Object> callback);
32 32
33 void zlmServerOffline(String mediaServerId); 33 void zlmServerOffline(String mediaServerId);
34 34
35 - void download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteErrorCallback<Object> callback);  
36 - void download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteErrorCallback<Object> callback); 35 + void download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, ErrorCallback<Object> callback);
  36 + void download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, ErrorCallback<Object> callback);
37 37
38 StreamInfo getDownLoadInfo(String deviceId, String channelId, String stream); 38 StreamInfo getDownLoadInfo(String deviceId, String channelId, String stream);
39 39
@@ -42,4 +42,6 @@ public interface IPlayService { @@ -42,4 +42,6 @@ public interface IPlayService {
42 void pauseRtp(String streamId) throws ServiceException, InvalidArgumentException, ParseException, SipException; 42 void pauseRtp(String streamId) throws ServiceException, InvalidArgumentException, ParseException, SipException;
43 43
44 void resumeRtp(String streamId) throws ServiceException, InvalidArgumentException, ParseException, SipException; 44 void resumeRtp(String streamId) throws ServiceException, InvalidArgumentException, ParseException, SipException;
  45 +
  46 + void getSnap(String deviceId, String channelId, String fileName, ErrorCallback errorCallback);
45 } 47 }
src/main/java/com/genersoft/iot/vmp/service/bean/InviteErrorCallback.java renamed to src/main/java/com/genersoft/iot/vmp/service/bean/ErrorCallback.java
1 package com.genersoft.iot.vmp.service.bean; 1 package com.genersoft.iot.vmp.service.bean;
2 2
3 -public interface InviteErrorCallback<T> { 3 +public interface ErrorCallback<T> {
4 4
5 void run(int code, String msg, T data); 5 void run(int code, String msg, T data);
6 } 6 }
src/main/java/com/genersoft/iot/vmp/service/bean/InviteErrorCode.java
@@ -5,6 +5,7 @@ package com.genersoft.iot.vmp.service.bean; @@ -5,6 +5,7 @@ package com.genersoft.iot.vmp.service.bean;
5 */ 5 */
6 public enum InviteErrorCode { 6 public enum InviteErrorCode {
7 SUCCESS(0, "成功"), 7 SUCCESS(0, "成功"),
  8 + FAIL(-100, "失败"),
8 ERROR_FOR_SIGNALLING_TIMEOUT(-1, "信令超时"), 9 ERROR_FOR_SIGNALLING_TIMEOUT(-1, "信令超时"),
9 ERROR_FOR_STREAM_TIMEOUT(-2, "收流超时"), 10 ERROR_FOR_STREAM_TIMEOUT(-2, "收流超时"),
10 ERROR_FOR_RESOURCE_EXHAUSTION(-3, "资源耗尽"), 11 ERROR_FOR_RESOURCE_EXHAUSTION(-3, "资源耗尽"),
src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java
@@ -6,7 +6,7 @@ import com.genersoft.iot.vmp.common.InviteSessionStatus; @@ -6,7 +6,7 @@ import com.genersoft.iot.vmp.common.InviteSessionStatus;
6 import com.genersoft.iot.vmp.common.InviteSessionType; 6 import com.genersoft.iot.vmp.common.InviteSessionType;
7 import com.genersoft.iot.vmp.common.VideoManagerConstants; 7 import com.genersoft.iot.vmp.common.VideoManagerConstants;
8 import com.genersoft.iot.vmp.service.IInviteStreamService; 8 import com.genersoft.iot.vmp.service.IInviteStreamService;
9 -import com.genersoft.iot.vmp.service.bean.InviteErrorCallback; 9 +import com.genersoft.iot.vmp.service.bean.ErrorCallback;
10 import com.genersoft.iot.vmp.utils.redis.RedisUtil; 10 import com.genersoft.iot.vmp.utils.redis.RedisUtil;
11 import org.slf4j.Logger; 11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory; 12 import org.slf4j.LoggerFactory;
@@ -24,7 +24,7 @@ public class InviteStreamServiceImpl implements IInviteStreamService { @@ -24,7 +24,7 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
24 24
25 private final Logger logger = LoggerFactory.getLogger(InviteStreamServiceImpl.class); 25 private final Logger logger = LoggerFactory.getLogger(InviteStreamServiceImpl.class);
26 26
27 - private final Map<String, List<InviteErrorCallback<Object>>> inviteErrorCallbackMap = new ConcurrentHashMap<>(); 27 + private final Map<String, List<ErrorCallback<Object>>> inviteErrorCallbackMap = new ConcurrentHashMap<>();
28 28
29 @Autowired 29 @Autowired
30 private RedisTemplate<Object, Object> redisTemplate; 30 private RedisTemplate<Object, Object> redisTemplate;
@@ -141,9 +141,9 @@ public class InviteStreamServiceImpl implements IInviteStreamService { @@ -141,9 +141,9 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
141 } 141 }
142 142
143 @Override 143 @Override
144 - public void once(InviteSessionType type, String deviceId, String channelId, String stream, InviteErrorCallback<Object> callback) { 144 + public void once(InviteSessionType type, String deviceId, String channelId, String stream, ErrorCallback<Object> callback) {
145 String key = buildKey(type, deviceId, channelId, stream); 145 String key = buildKey(type, deviceId, channelId, stream);
146 - List<InviteErrorCallback<Object>> callbacks = inviteErrorCallbackMap.get(key); 146 + List<ErrorCallback<Object>> callbacks = inviteErrorCallbackMap.get(key);
147 if (callbacks == null) { 147 if (callbacks == null) {
148 callbacks = new CopyOnWriteArrayList<>(); 148 callbacks = new CopyOnWriteArrayList<>();
149 inviteErrorCallbackMap.put(key, callbacks); 149 inviteErrorCallbackMap.put(key, callbacks);
@@ -155,11 +155,11 @@ public class InviteStreamServiceImpl implements IInviteStreamService { @@ -155,11 +155,11 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
155 @Override 155 @Override
156 public void call(InviteSessionType type, String deviceId, String channelId, String stream, int code, String msg, Object data) { 156 public void call(InviteSessionType type, String deviceId, String channelId, String stream, int code, String msg, Object data) {
157 String key = buildKey(type, deviceId, channelId, stream); 157 String key = buildKey(type, deviceId, channelId, stream);
158 - List<InviteErrorCallback<Object>> callbacks = inviteErrorCallbackMap.get(key); 158 + List<ErrorCallback<Object>> callbacks = inviteErrorCallbackMap.get(key);
159 if (callbacks == null) { 159 if (callbacks == null) {
160 return; 160 return;
161 } 161 }
162 - for (InviteErrorCallback<Object> callback : callbacks) { 162 + for (ErrorCallback<Object> callback : callbacks) {
163 callback.run(code, msg, data); 163 callback.run(code, msg, data);
164 } 164 }
165 inviteErrorCallbackMap.remove(key); 165 inviteErrorCallbackMap.remove(key);
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -26,7 +26,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; @@ -26,7 +26,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
26 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; 26 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
27 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 27 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
28 import com.genersoft.iot.vmp.service.*; 28 import com.genersoft.iot.vmp.service.*;
29 -import com.genersoft.iot.vmp.service.bean.InviteErrorCallback; 29 +import com.genersoft.iot.vmp.service.bean.ErrorCallback;
30 import com.genersoft.iot.vmp.service.bean.InviteErrorCode; 30 import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
31 import com.genersoft.iot.vmp.service.bean.SSRCInfo; 31 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
32 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 32 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
@@ -44,6 +44,7 @@ import javax.sdp.*; @@ -44,6 +44,7 @@ import javax.sdp.*;
44 import javax.sip.InvalidArgumentException; 44 import javax.sip.InvalidArgumentException;
45 import javax.sip.ResponseEvent; 45 import javax.sip.ResponseEvent;
46 import javax.sip.SipException; 46 import javax.sip.SipException;
  47 +import java.io.File;
47 import java.math.BigDecimal; 48 import java.math.BigDecimal;
48 import java.math.RoundingMode; 49 import java.math.RoundingMode;
49 import java.text.ParseException; 50 import java.text.ParseException;
@@ -114,7 +115,7 @@ public class PlayServiceImpl implements IPlayService { @@ -114,7 +115,7 @@ public class PlayServiceImpl implements IPlayService {
114 115
115 116
116 @Override 117 @Override
117 - public SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, InviteErrorCallback<Object> callback) { 118 + public SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, ErrorCallback<Object> callback) {
118 if (mediaServerItem == null) { 119 if (mediaServerItem == null) {
119 throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到可用的zlm"); 120 throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到可用的zlm");
120 } 121 }
@@ -179,7 +180,7 @@ public class PlayServiceImpl implements IPlayService { @@ -179,7 +180,7 @@ public class PlayServiceImpl implements IPlayService {
179 180
180 @Override 181 @Override
181 public void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, 182 public void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
182 - InviteErrorCallback<Object> callback) { 183 + ErrorCallback<Object> callback) {
183 184
184 if (mediaServerItem == null || ssrcInfo == null) { 185 if (mediaServerItem == null || ssrcInfo == null) {
185 callback.run(InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getCode(), 186 callback.run(InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getCode(),
@@ -522,7 +523,7 @@ public class PlayServiceImpl implements IPlayService { @@ -522,7 +523,7 @@ public class PlayServiceImpl implements IPlayService {
522 523
523 @Override 524 @Override
524 public void playBack(String deviceId, String channelId, String startTime, 525 public void playBack(String deviceId, String channelId, String startTime,
525 - String endTime, InviteErrorCallback<Object> callback) { 526 + String endTime, ErrorCallback<Object> callback) {
526 Device device = storager.queryVideoDevice(deviceId); 527 Device device = storager.queryVideoDevice(deviceId);
527 if (device == null) { 528 if (device == null) {
528 return; 529 return;
@@ -535,7 +536,7 @@ public class PlayServiceImpl implements IPlayService { @@ -535,7 +536,7 @@ public class PlayServiceImpl implements IPlayService {
535 @Override 536 @Override
536 public void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, 537 public void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,
537 String deviceId, String channelId, String startTime, 538 String deviceId, String channelId, String startTime,
538 - String endTime, InviteErrorCallback<Object> callback) { 539 + String endTime, ErrorCallback<Object> callback) {
539 if (mediaServerItem == null || ssrcInfo == null) { 540 if (mediaServerItem == null || ssrcInfo == null) {
540 callback.run(InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getCode(), 541 callback.run(InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getCode(),
541 InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getMsg(), 542 InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getMsg(),
@@ -725,7 +726,7 @@ public class PlayServiceImpl implements IPlayService { @@ -725,7 +726,7 @@ public class PlayServiceImpl implements IPlayService {
725 726
726 727
727 @Override 728 @Override
728 - public void download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteErrorCallback<Object> callback) { 729 + public void download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, ErrorCallback<Object> callback) {
729 Device device = storager.queryVideoDevice(deviceId); 730 Device device = storager.queryVideoDevice(deviceId);
730 if (device == null) { 731 if (device == null) {
731 return; 732 return;
@@ -743,7 +744,7 @@ public class PlayServiceImpl implements IPlayService { @@ -743,7 +744,7 @@ public class PlayServiceImpl implements IPlayService {
743 744
744 745
745 @Override 746 @Override
746 - public void download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteErrorCallback<Object> callback) { 747 + public void download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, ErrorCallback<Object> callback) {
747 if (mediaServerItem == null || ssrcInfo == null) { 748 if (mediaServerItem == null || ssrcInfo == null) {
748 callback.run(InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getCode(), 749 callback.run(InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getCode(),
749 InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getMsg(), 750 InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getMsg(),
@@ -1127,4 +1128,53 @@ public class PlayServiceImpl implements IPlayService { @@ -1127,4 +1128,53 @@ public class PlayServiceImpl implements IPlayService {
1127 Device device = storager.queryVideoDevice(inviteInfo.getDeviceId()); 1128 Device device = storager.queryVideoDevice(inviteInfo.getDeviceId());
1128 cmder.playResumeCmd(device, inviteInfo.getStreamInfo()); 1129 cmder.playResumeCmd(device, inviteInfo.getStreamInfo());
1129 } 1130 }
  1131 +
  1132 + @Override
  1133 + public void getSnap(String deviceId, String channelId, String fileName, ErrorCallback errorCallback) {
  1134 + Device device = deviceService.getDevice(deviceId);
  1135 + if (device == null) {
  1136 + errorCallback.run(InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getCode(), InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getMsg(), null);
  1137 + return;
  1138 + }
  1139 +
  1140 + InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
  1141 + if (inviteInfo != null) {
  1142 + if (inviteInfo.getStreamInfo() != null) {
  1143 + // 已存在线直接截图
  1144 + MediaServerItem mediaServerItemInuse = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId());
  1145 + String streamUrl;
  1146 + if (mediaServerItemInuse.getRtspPort() != 0) {
  1147 + streamUrl = String.format("rtsp://127.0.0.1:%s/%s/%s", mediaServerItemInuse.getRtspPort(), "rtp", inviteInfo.getStreamInfo().getStream());
  1148 + }else {
  1149 + streamUrl = String.format("http://127.0.0.1:%s/%s/%s.live.mp4", mediaServerItemInuse.getHttpPort(), "rtp", inviteInfo.getStreamInfo().getStream());
  1150 + }
  1151 + String path = "snap";
  1152 + // 请求截图
  1153 + logger.info("[请求截图]: " + fileName);
  1154 + zlmresTfulUtils.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName);
  1155 + File snapFile = new File(path + File.separator + fileName);
  1156 + if (snapFile.exists()) {
  1157 + errorCallback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), snapFile.getAbsoluteFile());
  1158 + }else {
  1159 + errorCallback.run(InviteErrorCode.FAIL.getCode(), InviteErrorCode.FAIL.getMsg(), null);
  1160 + }
  1161 + return;
  1162 + }
  1163 + }
  1164 +
  1165 + MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
  1166 + play(newMediaServerItem, deviceId, channelId, (code, msg, data)->{
  1167 + if (code == InviteErrorCode.SUCCESS.getCode()) {
  1168 + InviteInfo inviteInfoForPlay = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
  1169 + if (inviteInfoForPlay != null && inviteInfoForPlay.getStreamInfo() != null) {
  1170 + getSnap(deviceId, channelId, fileName, errorCallback);
  1171 + }else {
  1172 + errorCallback.run(InviteErrorCode.FAIL.getCode(), InviteErrorCode.FAIL.getMsg(), null);
  1173 + }
  1174 + }else {
  1175 + errorCallback.run(InviteErrorCode.FAIL.getCode(), InviteErrorCode.FAIL.getMsg(), null);
  1176 + }
  1177 + });
  1178 + }
  1179 +
1130 } 1180 }
src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java
@@ -32,11 +32,17 @@ public class DateUtil { @@ -32,11 +32,17 @@ public class DateUtil {
32 */ 32 */
33 public static final String PATTERN = "yyyy-MM-dd HH:mm:ss"; 33 public static final String PATTERN = "yyyy-MM-dd HH:mm:ss";
34 34
  35 + /**
  36 + * wvp内部统一时间格式
  37 + */
  38 + public static final String URL_PATTERN = "yyyyMMddHHmmss";
  39 +
35 public static final String zoneStr = "Asia/Shanghai"; 40 public static final String zoneStr = "Asia/Shanghai";
36 41
37 public static final DateTimeFormatter formatterCompatibleISO8601 = DateTimeFormatter.ofPattern(ISO8601_COMPATIBLE_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr)); 42 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)); 43 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)); 44 public static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr));
  45 + public static final DateTimeFormatter urlFormatter = DateTimeFormatter.ofPattern(URL_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr));
40 46
41 public static String yyyy_MM_dd_HH_mm_ssToISO8601(String formatTime) { 47 public static String yyyy_MM_dd_HH_mm_ssToISO8601(String formatTime) {
42 48
@@ -68,6 +74,15 @@ public class DateUtil { @@ -68,6 +74,15 @@ public class DateUtil {
68 } 74 }
69 75
70 /** 76 /**
  77 + * 获取当前时间
  78 + * @return
  79 + */
  80 + public static String getNowForUrl() {
  81 + LocalDateTime nowDateTime = LocalDateTime.now();
  82 + return urlFormatter.format(nowDateTime);
  83 + }
  84 +
  85 + /**
71 * 格式校验 86 * 格式校验
72 * @param timeStr 时间字符串 87 * @param timeStr 时间字符串
73 * @param dateTimeFormatter 待校验的格式 88 * @param dateTimeFormatter 待校验的格式
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
@@ -24,6 +24,7 @@ import com.genersoft.iot.vmp.service.IPlayService; @@ -24,6 +24,7 @@ import com.genersoft.iot.vmp.service.IPlayService;
24 import com.genersoft.iot.vmp.service.bean.InviteErrorCode; 24 import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
25 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 25 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
26 import com.genersoft.iot.vmp.storager.IVideoManagerStorage; 26 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
  27 +import com.genersoft.iot.vmp.utils.DateUtil;
27 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; 28 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
28 import com.genersoft.iot.vmp.vmanager.bean.StreamContent; 29 import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
29 import com.genersoft.iot.vmp.vmanager.bean.WVPResult; 30 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
@@ -337,5 +338,35 @@ public class PlayController { @@ -337,5 +338,35 @@ public class PlayController {
337 return jsonObject; 338 return jsonObject;
338 } 339 }
339 340
  341 + @Operation(summary = "获取截图")
  342 + @Parameter(name = "deviceId", description = "设备国标编号", required = true)
  343 + @Parameter(name = "channelId", description = "通道国标编号", required = true)
  344 + @GetMapping("/snap")
  345 + public DeferredResult<String> getSnap(String deviceId, String channelId) {
  346 + if (logger.isDebugEnabled()) {
  347 + logger.debug("获取截图: {}/{}", deviceId, channelId);
  348 + }
  349 +
  350 + DeferredResult<String> result = new DeferredResult<>(3 * 1000L);
  351 + String key = DeferredResultHolder.CALLBACK_CMD_SNAP + deviceId;
  352 + String uuid = UUID.randomUUID().toString();
  353 + resultHolder.put(key, uuid, result);
  354 +
  355 + RequestMessage message = new RequestMessage();
  356 + message.setKey(key);
  357 + message.setId(uuid);
  358 +
  359 + String fileName = deviceId + "_" + channelId + "_" + DateUtil.getNowForUrl() + "jpg";
  360 + playService.getSnap(deviceId, channelId, fileName, (code, msg, data) -> {
  361 + if (code == InviteErrorCode.SUCCESS.getCode()) {
  362 + message.setData(data);
  363 + }else {
  364 + message.setData(WVPResult.fail(code, msg));
  365 + }
  366 + resultHolder.invokeResult(message);
  367 + });
  368 + return result;
  369 + }
  370 +
340 } 371 }
341 372