/device/video.mp4 改为 返回 url
This commit is contained in:
parent
71b75038e2
commit
9bcade0b2e
@ -2,6 +2,7 @@ package cn.skcks.docking.gb28181.wvp.api.video;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.skcks.docking.gb28181.common.json.JsonResponse;
|
||||
import cn.skcks.docking.gb28181.media.config.ZlmMediaConfig;
|
||||
import cn.skcks.docking.gb28181.wvp.api.video.dto.VideoMp4Req;
|
||||
import cn.skcks.docking.gb28181.wvp.api.video.dto.VideoReq;
|
||||
@ -25,6 +26,7 @@ import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@ -60,10 +62,10 @@ public class VideoController {
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "获取视频 (返回视频流)")
|
||||
@GetMapping(value = "/device/video.mp4",produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
|
||||
@Operation(summary = "获取视频 (返回视频url)")
|
||||
@GetMapping(value = "/device/video.mp4")
|
||||
@ResponseBody
|
||||
public void video(HttpServletRequest request, HttpServletResponse response, @ParameterObject VideoMp4Req req) {
|
||||
public DeferredResult<JsonResponse<String>> video(@ParameterObject VideoMp4Req req) {
|
||||
long forward = gb28181DeviceVideoApiConfig.getOffset().getForward().toMillis();
|
||||
long back = gb28181DeviceVideoApiConfig.getOffset().getBack().toMillis();
|
||||
DateTime reqStartTime = DateUtil.date(req.getStartTime());
|
||||
@ -72,6 +74,6 @@ public class VideoController {
|
||||
Date endTime = DateUtil.offsetMillisecond(reqEndTime, (int) back);
|
||||
log.info("请求的时间范围 {} ~ {}", reqStartTime, reqEndTime);
|
||||
log.info("偏移后的时间范围 {} ~ {}", startTime, endTime);
|
||||
gb28181DownloadService.videoStream(request,response,req.getDeviceCode(), startTime, endTime);
|
||||
return gb28181DownloadService.videoUrl(req.getDeviceCode(), startTime, endTime);
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
|
||||
import javax.sdp.Connection;
|
||||
import javax.sdp.SdpFactory;
|
||||
@ -84,6 +85,7 @@ public class Gb28181DownloadService {
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
public static class VideoInfo {
|
||||
private String streamId;
|
||||
private String url;
|
||||
private String callId;
|
||||
private WvpProxyDevice device;
|
||||
@ -166,6 +168,42 @@ public class Gb28181DownloadService {
|
||||
});
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public DeferredResult<JsonResponse<String>> videoUrl(String deviceCode, Date startTime, Date endTime) {
|
||||
long time = DateUtil.between(startTime, endTime, DateUnit.MS);
|
||||
DeferredResult<JsonResponse<String>> result = new DeferredResult<>(time);
|
||||
result.onTimeout(()->{
|
||||
result.setResult(JsonResponse.error("请求超时"));
|
||||
});
|
||||
WvpProxyDevice device = deviceService.getDeviceByDeviceCode(deviceCode).orElse(null);
|
||||
if(device == null){
|
||||
result.setResult(JsonResponse.error("设备不存在"));
|
||||
return result;
|
||||
}
|
||||
WvpProxyDocking docking = dockingService.getDeviceByDeviceCode(device.getGbDeviceId()).orElse(null);
|
||||
if(docking == null){
|
||||
result.setResult(JsonResponse.error("设备(通道)不存在"));
|
||||
return result;
|
||||
}
|
||||
download(deviceCode, startTime, endTime).whenComplete((videoInfo, e)->{
|
||||
log.info("到达结束时间 发送 bye 关闭");
|
||||
String cacheKey = CacheUtil.getKey(docking.getGbDeviceId(), device.getGbDeviceChannelId());
|
||||
String existCallId = RedisUtil.StringOps.get(cacheKey);
|
||||
scheduledExecutorService.schedule(()->{
|
||||
String deviceIp = docking.getIp();
|
||||
int devicePort = Integer.parseInt(docking.getPort());
|
||||
sender.sendRequest((provider,localIp,localPort)->
|
||||
SipRequestBuilder.createByeRequest(deviceIp, devicePort, device.getGbDeviceChannelId(), SipUtil.generateFromTag(), null, existCallId));
|
||||
RedisUtil.KeyOps.delete(cacheKey);
|
||||
zlmMediaService.closeRtpServer(CloseRtpServer.builder()
|
||||
.streamId(videoInfo.streamId)
|
||||
.build());
|
||||
}, time, TimeUnit.MILLISECONDS);
|
||||
result.setResult(JsonResponse.success(videoInfo.getUrl()));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void videoStream(HttpServletRequest request, HttpServletResponse response, String deviceCode, Date startTime, Date endTime) {
|
||||
AsyncContext asyncContext = request.startAsync();
|
||||
@ -289,7 +327,7 @@ public class Gb28181DownloadService {
|
||||
SipRequestBuilder.createByeRequest(deviceIp, devicePort, device.getGbDeviceChannelId(), SipUtil.generateFromTag(), null, existCallId));
|
||||
RedisUtil.KeyOps.delete(cacheKey);
|
||||
log.info("关闭已存在的 点播请求 {} {}", cacheKey,existCallId);
|
||||
Thread.sleep(200);
|
||||
Thread.sleep(500);
|
||||
}
|
||||
|
||||
return (provider, ip, port) -> {
|
||||
@ -334,7 +372,7 @@ public class Gb28181DownloadService {
|
||||
subscribe.getByeSubscribe().addSubscribe(key, byeSubscriber(key,cacheKey, streamId, time, unit));
|
||||
return SipRequestBuilder.createAckRequest(Response.OK, ip, port, docking, device.getGbDeviceChannelId(), fromTag, toTag, callId);
|
||||
}));
|
||||
result.complete(new VideoInfo(videoUrl(streamId), callId, device));
|
||||
result.complete(new VideoInfo(streamId,videoUrl(streamId), callId, device));
|
||||
} else {
|
||||
log.info("订阅 {} {} 连接流媒体服务时出现异常, 终止订阅", MessageProcessor.Method.INVITE, subscribeKey);
|
||||
zlmMediaService.closeRtpServer(new CloseRtpServer(streamId));
|
||||
|
Loading…
Reference in New Issue
Block a user