Merge branch 'wvp-28181-2.0' into main-dev
# Conflicts: # src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java # src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java # src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java # src/main/java/com/genersoft/iot/vmp/service/IPlayService.java # src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java # src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java # src/main/resources/all-application.yml # web_src/config/index.js # web_src/src/components/dialog/devicePlayer.vue
This commit is contained in:
@@ -6,7 +6,7 @@ package com.genersoft.iot.vmp.vmanager.bean;
|
||||
public enum ErrorCode {
|
||||
SUCCESS(0, "成功"),
|
||||
ERROR100(100, "失败"),
|
||||
ERROR400(400, "参数不全或者错误"),
|
||||
ERROR400(400, "参数或方法错误"),
|
||||
ERROR404(404, "资源未找到"),
|
||||
ERROR403(403, "无权限操作"),
|
||||
ERROR401(401, "请登录后重新请求"),
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
package com.genersoft.iot.vmp.vmanager.bean;
|
||||
|
||||
public class ResourceBaceInfo {
|
||||
public class ResourceBaseInfo {
|
||||
private int total;
|
||||
private int online;
|
||||
|
||||
public ResourceBaseInfo() {
|
||||
}
|
||||
|
||||
public ResourceBaseInfo(int total, int online) {
|
||||
this.total = total;
|
||||
this.online = online;
|
||||
}
|
||||
|
||||
public int getTotal() {
|
||||
return total;
|
||||
}
|
||||
@@ -2,40 +2,40 @@ package com.genersoft.iot.vmp.vmanager.bean;
|
||||
|
||||
public class ResourceInfo {
|
||||
|
||||
private ResourceBaceInfo device;
|
||||
private ResourceBaceInfo channel;
|
||||
private ResourceBaceInfo push;
|
||||
private ResourceBaceInfo proxy;
|
||||
private ResourceBaseInfo device;
|
||||
private ResourceBaseInfo channel;
|
||||
private ResourceBaseInfo push;
|
||||
private ResourceBaseInfo proxy;
|
||||
|
||||
public ResourceBaceInfo getDevice() {
|
||||
public ResourceBaseInfo getDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
public void setDevice(ResourceBaceInfo device) {
|
||||
public void setDevice(ResourceBaseInfo device) {
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
public ResourceBaceInfo getChannel() {
|
||||
public ResourceBaseInfo getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
public void setChannel(ResourceBaceInfo channel) {
|
||||
public void setChannel(ResourceBaseInfo channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public ResourceBaceInfo getPush() {
|
||||
public ResourceBaseInfo getPush() {
|
||||
return push;
|
||||
}
|
||||
|
||||
public void setPush(ResourceBaceInfo push) {
|
||||
public void setPush(ResourceBaseInfo push) {
|
||||
this.push = push;
|
||||
}
|
||||
|
||||
public ResourceBaceInfo getProxy() {
|
||||
public ResourceBaseInfo getProxy() {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
public void setProxy(ResourceBaceInfo proxy) {
|
||||
public void setProxy(ResourceBaseInfo proxy) {
|
||||
this.proxy = proxy;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.genersoft.iot.vmp.vmanager.bean;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "截图地址信息")
|
||||
public class SnapPath {
|
||||
|
||||
@Schema(description = "相对地址")
|
||||
private String path;
|
||||
|
||||
@Schema(description = "绝对地址")
|
||||
private String absoluteFilePath;
|
||||
|
||||
@Schema(description = "请求地址")
|
||||
private String url;
|
||||
|
||||
|
||||
public static SnapPath getInstance(String path, String absoluteFilePath, String url) {
|
||||
SnapPath snapPath = new SnapPath();
|
||||
snapPath.setPath(path);
|
||||
snapPath.setAbsoluteFilePath(absoluteFilePath);
|
||||
snapPath.setUrl(url);
|
||||
return snapPath;
|
||||
}
|
||||
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public String getAbsoluteFilePath() {
|
||||
return absoluteFilePath;
|
||||
}
|
||||
|
||||
public void setAbsoluteFilePath(String absoluteFilePath) {
|
||||
this.absoluteFilePath = absoluteFilePath;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
}
|
||||
@@ -102,7 +102,7 @@ public class MobilePositionController {
|
||||
public DeferredResult<MobilePosition> realTimePosition(@PathVariable String deviceId) {
|
||||
Device device = storager.queryVideoDevice(deviceId);
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_MOBILEPOSITION + deviceId;
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_MOBILE_POSITION + deviceId;
|
||||
try {
|
||||
cmder.mobilePostitionQuery(device, event -> {
|
||||
RequestMessage msg = new RequestMessage();
|
||||
|
||||
@@ -466,10 +466,12 @@ public class DeviceQuery {
|
||||
@Operation(summary = "请求截图")
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||
public void getSnap(HttpServletResponse resp, @PathVariable String deviceId, @PathVariable String channelId) {
|
||||
@Parameter(name = "mark", description = "标识", required = false)
|
||||
public void getSnap(HttpServletResponse resp, @PathVariable String deviceId, @PathVariable String channelId, @RequestParam(required = false) String mark) {
|
||||
|
||||
try {
|
||||
final InputStream in = Files.newInputStream(new File("snap" + File.separator + deviceId + "_" + channelId + ".jpg").toPath());
|
||||
|
||||
final InputStream in = Files.newInputStream(new File("snap" + File.separator + deviceId + "_" + channelId + (mark == null? ".jpg": ("_" + mark + ".jpg"))).toPath());
|
||||
resp.setContentType(MediaType.IMAGE_PNG_VALUE);
|
||||
IOUtils.copy(in, resp.getOutputStream());
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -403,8 +403,12 @@ public class PlatformController {
|
||||
if (platform == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "平台未找到");
|
||||
}
|
||||
if (platformId.equals(parentId)) {
|
||||
parentId = platform.getDeviceGBId();
|
||||
// if (platformId.equals(parentId)) {
|
||||
// parentId = platform.getDeviceGBId();
|
||||
// }
|
||||
|
||||
if (platformId.equals(platform.getDeviceGBId())) {
|
||||
parentId = null;
|
||||
}
|
||||
|
||||
return storager.getChildrenCatalogByPlatform(platformId, parentId);
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.genersoft.iot.vmp.service.IPlayService;
|
||||
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.*;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
|
||||
@@ -129,7 +130,7 @@ public class PlayController {
|
||||
if (data != null) {
|
||||
StreamInfo streamInfo = (StreamInfo)data;
|
||||
if (userSetting.getUseSourceIpAsStreamIp()) {
|
||||
streamInfo.channgeStreamIp(request.getLocalName());
|
||||
streamInfo.channgeStreamIp(request.getLocalAddr());
|
||||
}
|
||||
wvpResult.setData(new StreamContent(streamInfo));
|
||||
}
|
||||
@@ -146,8 +147,9 @@ public class PlayController {
|
||||
@Operation(summary = "停止点播")
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||
@Parameter(name = "isSubStream", description = "是否子码流(true-子码流,false-主码流),默认为false", required = true)
|
||||
@GetMapping("/stop/{deviceId}/{channelId}")
|
||||
public JSONObject playStop(@PathVariable String deviceId, @PathVariable String channelId) {
|
||||
public JSONObject playStop(@PathVariable String deviceId, @PathVariable String channelId,boolean isSubStream) {
|
||||
|
||||
logger.debug(String.format("设备预览/回放停止API调用,streamId:%s_%s", deviceId, channelId ));
|
||||
|
||||
@@ -174,11 +176,12 @@ public class PlayController {
|
||||
}
|
||||
}
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
||||
|
||||
storager.stopPlay(deviceId, channelId);
|
||||
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("deviceId", deviceId);
|
||||
json.put("channelId", channelId);
|
||||
json.put("isSubStream", isSubStream);
|
||||
return json;
|
||||
}
|
||||
|
||||
@@ -316,5 +319,36 @@ public class PlayController {
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
@Operation(summary = "获取截图")
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||
@Parameter(name = "isSubStream", description = "是否子码流(true-子码流,false-主码流),默认为false", required = true)
|
||||
@GetMapping("/snap")
|
||||
public DeferredResult<String> getSnap(String deviceId, String channelId,boolean isSubStream) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("获取截图: {}/{}", deviceId, channelId);
|
||||
}
|
||||
|
||||
DeferredResult<String> result = new DeferredResult<>(3 * 1000L);
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_SNAP + deviceId;
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
resultHolder.put(key, uuid, result);
|
||||
|
||||
RequestMessage message = new RequestMessage();
|
||||
message.setKey(key);
|
||||
message.setId(uuid);
|
||||
|
||||
String fileName = deviceId + "_" + channelId + "_" + DateUtil.getNowForUrl() + "jpg";
|
||||
playService.getSnap(deviceId, channelId, fileName, (code, msg, data) -> {
|
||||
if (code == InviteErrorCode.SUCCESS.getCode()) {
|
||||
message.setData(data);
|
||||
}else {
|
||||
message.setData(WVPResult.fail(code, msg));
|
||||
}
|
||||
resultHolder.invokeResult(message);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ public class PlaybackController {
|
||||
if (data != null) {
|
||||
StreamInfo streamInfo = (StreamInfo)data;
|
||||
if (userSetting.getUseSourceIpAsStreamIp()) {
|
||||
streamInfo.channgeStreamIp(request.getLocalName());
|
||||
streamInfo.channgeStreamIp(request.getLocalAddr());
|
||||
}
|
||||
wvpResult.setData(new StreamContent(streamInfo));
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ public class GBRecordController {
|
||||
if (data != null) {
|
||||
StreamInfo streamInfo = (StreamInfo)data;
|
||||
if (userSetting.getUseSourceIpAsStreamIp()) {
|
||||
streamInfo.channgeStreamIp(request.getLocalName());
|
||||
streamInfo.channgeStreamIp(request.getLocalAddr());
|
||||
}
|
||||
wvpResult.setData(new StreamContent(streamInfo));
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import com.genersoft.iot.vmp.service.*;
|
||||
import com.genersoft.iot.vmp.service.bean.MediaServerLoad;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ResourceInfo;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.SystemConfigInfo;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@@ -251,13 +251,13 @@ public class ServerController {
|
||||
@Operation(summary = "获取负载信息")
|
||||
public ResourceInfo getResourceInfo() {
|
||||
ResourceInfo result = new ResourceInfo();
|
||||
ResourceBaceInfo deviceInfo = deviceService.getOverview();
|
||||
ResourceBaseInfo deviceInfo = deviceService.getOverview();
|
||||
result.setDevice(deviceInfo);
|
||||
ResourceBaceInfo channelInfo = channelService.getOverview();
|
||||
ResourceBaseInfo channelInfo = channelService.getOverview();
|
||||
result.setChannel(channelInfo);
|
||||
ResourceBaceInfo pushInfo = pushService.getOverview();
|
||||
ResourceBaseInfo pushInfo = pushService.getOverview();
|
||||
result.setPush(pushInfo);
|
||||
ResourceBaceInfo proxyInfo = proxyService.getOverview();
|
||||
ResourceBaseInfo proxyInfo = proxyService.getOverview();
|
||||
result.setProxy(proxyInfo);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
package com.genersoft.iot.vmp.vmanager.streamProxy;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
|
||||
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||
import com.genersoft.iot.vmp.service.IStreamProxyService;
|
||||
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.github.pagehelper.PageInfo;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -18,6 +23,9 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
/**
|
||||
@@ -37,6 +45,12 @@ public class StreamProxyController {
|
||||
@Autowired
|
||||
private IStreamProxyService streamProxyService;
|
||||
|
||||
@Autowired
|
||||
private DeferredResultHolder resultHolder;
|
||||
|
||||
@Autowired
|
||||
private UserSetting userSetting;
|
||||
|
||||
|
||||
@Operation(summary = "分页查询流代理")
|
||||
@Parameter(name = "page", description = "当前页")
|
||||
@@ -58,7 +72,7 @@ public class StreamProxyController {
|
||||
})
|
||||
@PostMapping(value = "/save")
|
||||
@ResponseBody
|
||||
public StreamContent save(@RequestBody StreamProxyItem param){
|
||||
public DeferredResult<Object> save(@RequestBody StreamProxyItem param){
|
||||
logger.info("添加代理: " + JSONObject.toJSONString(param));
|
||||
if (ObjectUtils.isEmpty(param.getMediaServerId())) {
|
||||
param.setMediaServerId("auto");
|
||||
@@ -69,7 +83,33 @@ public class StreamProxyController {
|
||||
if (ObjectUtils.isEmpty(param.getGbId())) {
|
||||
param.setGbId(null);
|
||||
}
|
||||
return new StreamContent(streamProxyService.save(param));
|
||||
|
||||
RequestMessage requestMessage = new RequestMessage();
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_PROXY + param.getApp() + param.getStream();
|
||||
requestMessage.setKey(key);
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
requestMessage.setId(uuid);
|
||||
DeferredResult<Object> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
|
||||
// 录像查询以channelId作为deviceId查询
|
||||
resultHolder.put(key, uuid, result);
|
||||
result.onTimeout(()->{
|
||||
WVPResult<StreamInfo> wvpResult = new WVPResult<>();
|
||||
wvpResult.setCode(ErrorCode.ERROR100.getCode());
|
||||
wvpResult.setMsg("超时");
|
||||
requestMessage.setData(wvpResult);
|
||||
resultHolder.invokeAllResult(requestMessage);
|
||||
});
|
||||
|
||||
streamProxyService.save(param, (code, msg, streamInfo) -> {
|
||||
logger.info("[拉流代理] {}", code == ErrorCode.SUCCESS.getCode()? "成功":"失败: " + msg);
|
||||
if (code == ErrorCode.SUCCESS.getCode()) {
|
||||
requestMessage.setData(new StreamContent(streamInfo));
|
||||
}else {
|
||||
requestMessage.setData(WVPResult.fail(code, msg));
|
||||
}
|
||||
resultHolder.invokeAllResult(requestMessage);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@GetMapping(value = "/ffmpeg_cmd/list")
|
||||
|
||||
Reference in New Issue
Block a user