临时提交
This commit is contained in:
@@ -658,7 +658,7 @@ public interface CommonGBChannelMapper {
|
||||
void saveLevel(List<ChannelForThin> channels);
|
||||
|
||||
@SelectProvider(type = ChannelProvider.class, method = "queryCameraChannelByIds")
|
||||
List<CameraChannel> queryCameraChannelByIds(List<Integer> ids);
|
||||
List<CameraChannel> queryCameraChannelByIds(List<CommonGBChannel> channelList);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -833,13 +833,13 @@ public class ChannelProvider {
|
||||
sqlBuild.append(BASE_SQL_FOR_CAMERA_DEVICE);
|
||||
sqlBuild.append(" where wdc.id in ( ");
|
||||
|
||||
List<Integer> ids = (List<Integer>)params.get("ids");
|
||||
List<CommonGBChannel> channelList = (List<CommonGBChannel>)params.get("channelList");
|
||||
boolean first = true;
|
||||
for (Integer id : ids) {
|
||||
for (CommonGBChannel channel : channelList) {
|
||||
if (!first) {
|
||||
sqlBuild.append(",");
|
||||
}
|
||||
sqlBuild.append(id);
|
||||
sqlBuild.append(channel.getGbId());
|
||||
first = false;
|
||||
}
|
||||
sqlBuild.append(" )");
|
||||
|
||||
@@ -74,7 +74,6 @@ public class EventPublisher {
|
||||
applicationEventPublisher.publishEvent(channelEvent);
|
||||
}
|
||||
|
||||
|
||||
public void catalogEventPublish(Platform platform, CommonGBChannel deviceChannel, String type) {
|
||||
catalogEventPublish(platform, Collections.singletonList(deviceChannel), type);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class ChannelEvent extends ApplicationEvent {
|
||||
|
||||
|
||||
public enum ChannelEventMessageType {
|
||||
ADD, UPDATE, DELETE, ONLINE, OFFLINE, VLOST, DEFECT
|
||||
ADD, UPDATE, DEL, ON, OFF, VLOST, DEFECT
|
||||
}
|
||||
|
||||
public static ChannelEvent getInstance(Object source, ChannelEventMessageType messageType, List<CommonGBChannel> channelList) {
|
||||
|
||||
@@ -78,7 +78,7 @@ public interface IDeviceChannelService {
|
||||
|
||||
void changeAudio(Integer channelId, Boolean audio);
|
||||
|
||||
void updateChannelStatus(DeviceChannel channel);
|
||||
void updateChannelStatusForNotify(DeviceChannel channel);
|
||||
|
||||
void addChannel(DeviceChannel channel);
|
||||
|
||||
|
||||
@@ -613,7 +613,7 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateChannelStatus(DeviceChannel channel) {
|
||||
public void updateChannelStatusForNotify(DeviceChannel channel) {
|
||||
channelMapper.updateStatus(channel);
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
commonGBChannelMapper.delete(gbId);
|
||||
try {
|
||||
// 发送通知
|
||||
eventPublisher.channelEventPublish(channel, ChannelEvent.ChannelEventMessageType.DELETE);
|
||||
eventPublisher.channelEventPublish(channel, ChannelEvent.ChannelEventMessageType.DEL);
|
||||
} catch (Exception e) {
|
||||
log.warn("[通道移除通知] 发送失败,{}", channel.getGbDeviceId(), e);
|
||||
}
|
||||
@@ -150,21 +150,6 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
} catch (Exception e) {
|
||||
log.warn("[更新通道通知] 发送失败,{}", commonGBChannel.getGbDeviceId(), e);
|
||||
}
|
||||
MobilePosition mobilePosition = new MobilePosition();
|
||||
mobilePosition.setLongitude(commonGBChannel.getGbLongitude());
|
||||
mobilePosition.setLatitude(commonGBChannel.getGbLatitude());
|
||||
mobilePosition.setCreateTime(DateUtil.getNow());
|
||||
mobilePosition.setDeviceId(commonGBChannel.getGbDeviceId());
|
||||
mobilePosition.setTime(DateUtil.getNow());
|
||||
mobilePosition.setAltitude(0.0);
|
||||
mobilePosition.setDirection(0.0);
|
||||
mobilePosition.setSpeed(0.0);
|
||||
mobilePosition.setChannelId(commonGBChannel.getGbId());
|
||||
try {
|
||||
eventPublisher.mobilePositionEventPublish(mobilePosition);
|
||||
}catch (Exception e) {
|
||||
log.error("[向上级转发移动位置失败] ", e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -179,7 +164,7 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
if (result > 0) {
|
||||
try {
|
||||
// 发送通知
|
||||
eventPublisher.channelEventPublish(commonGBChannel, ChannelEvent.ChannelEventMessageType.OFFLINE);
|
||||
eventPublisher.channelEventPublish(commonGBChannel, ChannelEvent.ChannelEventMessageType.OFF);
|
||||
} catch (Exception e) {
|
||||
log.warn("[通道离线通知] 发送失败,{}", commonGBChannel.getGbDeviceId(), e);
|
||||
}
|
||||
@@ -211,7 +196,7 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
if (result > 0) {
|
||||
try {
|
||||
// 发送catalog
|
||||
eventPublisher.channelEventPublish(commonGBChannelList, ChannelEvent.ChannelEventMessageType.OFFLINE);
|
||||
eventPublisher.channelEventPublish(commonGBChannelList, ChannelEvent.ChannelEventMessageType.OFF);
|
||||
} catch (Exception e) {
|
||||
log.warn("[多个通道离线] 发送失败,数量:{}", commonGBChannelList.size(), e);
|
||||
}
|
||||
@@ -229,7 +214,7 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
if (result > 0) {
|
||||
try {
|
||||
// 发送通知
|
||||
eventPublisher.channelEventPublish(commonGBChannel, ChannelEvent.ChannelEventMessageType.ONLINE);
|
||||
eventPublisher.channelEventPublish(commonGBChannel, ChannelEvent.ChannelEventMessageType.ON);
|
||||
} catch (Exception e) {
|
||||
log.warn("[通道上线通知] 发送失败,{}", commonGBChannel.getGbDeviceId(), e);
|
||||
}
|
||||
@@ -260,7 +245,7 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
}
|
||||
try {
|
||||
// 发送catalog
|
||||
eventPublisher.channelEventPublish(commonGBChannelList, ChannelEvent.ChannelEventMessageType.ONLINE);
|
||||
eventPublisher.channelEventPublish(commonGBChannelList, ChannelEvent.ChannelEventMessageType.ON);
|
||||
} catch (Exception e) {
|
||||
log.warn("[多个通道上线] 发送失败,数量:{}", commonGBChannelList.size(), e);
|
||||
}
|
||||
@@ -417,7 +402,7 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
// 发送通过更新通知
|
||||
try {
|
||||
// 发送通知
|
||||
eventPublisher.catalogEventPublish(null, channelNew, CatalogEvent.UPDATE);
|
||||
eventPublisher.channelEventPublishForUpdate(channelNew, channel);
|
||||
} catch (Exception e) {
|
||||
log.warn("[通道移除通知] 发送失败,{}", channelNew.getGbDeviceId(), e);
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ public class GroupServiceImpl implements IGroupService, CommandLineRunner {
|
||||
CommonGBChannel channel = CommonGBChannel.build(chjildGroup);
|
||||
try {
|
||||
// 发送catalog
|
||||
eventPublisher.catalogEventPublish(null, channel, CatalogEvent.UPDATE);
|
||||
eventPublisher.channelEventPublishForUpdate(channel, null);
|
||||
}catch (Exception e) {
|
||||
log.warn("[业务分组/虚拟组织变化] 发送失败,{}", group.getDeviceId(), e);
|
||||
}
|
||||
@@ -160,7 +160,7 @@ public class GroupServiceImpl implements IGroupService, CommandLineRunner {
|
||||
CommonGBChannel channel = CommonGBChannel.build(group);
|
||||
try {
|
||||
// 发送catalog
|
||||
eventPublisher.catalogEventPublish(null, channel, CatalogEvent.UPDATE);
|
||||
eventPublisher.channelEventPublishForUpdate(channel, null);
|
||||
}catch (Exception e) {
|
||||
log.warn("[业务分组/虚拟组织变化] 发送失败,{}", group.getDeviceId(), e);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import com.genersoft.iot.vmp.gb28181.bean.RegionTree;
|
||||
import com.genersoft.iot.vmp.gb28181.dao.CommonGBChannelMapper;
|
||||
import com.genersoft.iot.vmp.gb28181.dao.RegionMapper;
|
||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IGbChannelService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IRegionService;
|
||||
import com.genersoft.iot.vmp.utils.CivilCodeUtil;
|
||||
@@ -125,7 +124,7 @@ public class RegionServiceImpl implements IRegionService {
|
||||
// 发送变化通知
|
||||
try {
|
||||
// 发送catalog
|
||||
eventPublisher.catalogEventPublish(null, CommonGBChannel.build(region), CatalogEvent.UPDATE);
|
||||
eventPublisher.channelEventPublishForUpdate(CommonGBChannel.build(region), null);
|
||||
}catch (Exception e) {
|
||||
log.warn("[行政区划变化] 发送失败,{}", region.getDeviceId(), e);
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
|
||||
|
||||
@Autowired
|
||||
private IDeviceChannelService deviceChannelService;
|
||||
|
||||
|
||||
// @Scheduled(fixedRate = 2000) //每400毫秒执行一次
|
||||
// public void showSize(){
|
||||
// log.warn("[notify-目录订阅] 待处理消息数量: {}", taskQueue.size() );
|
||||
@@ -282,7 +282,7 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
|
||||
try {
|
||||
switch (notifyCatalogChannel.getType()) {
|
||||
case STATUS_CHANGED:
|
||||
deviceChannelService.updateChannelStatus(notifyCatalogChannel.getChannel());
|
||||
deviceChannelService.updateChannelStatusForNotify(notifyCatalogChannel.getChannel());
|
||||
break;
|
||||
case ADD:
|
||||
deviceChannelService.addChannel(notifyCatalogChannel.getChannel());
|
||||
|
||||
@@ -81,7 +81,8 @@ public class MessageRequestProcessor extends SIPRequestProcessorParent implement
|
||||
// 查询设备是否存在
|
||||
Device device = redisCatchStorage.getDevice(deviceId);
|
||||
// 查询上级平台是否存在
|
||||
Platform parentPlatform = platformService.queryPlatformByServerGBId(deviceId);
|
||||
// Platform parentPlatform = platformService.queryPlatformByServerGBId(deviceId);
|
||||
Platform parentPlatform = null;
|
||||
try {
|
||||
if (device != null && parentPlatform != null) {
|
||||
String hostAddress = request.getRemoteAddress().getHostAddress();
|
||||
|
||||
@@ -5,14 +5,20 @@ import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||
import com.genersoft.iot.vmp.conf.security.JwtUtils;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
|
||||
import com.genersoft.iot.vmp.media.bean.MediaServer;
|
||||
import com.genersoft.iot.vmp.media.service.IMediaServerService;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
|
||||
import com.genersoft.iot.vmp.service.ICloudRecordService;
|
||||
import com.genersoft.iot.vmp.service.bean.CloudRecordItem;
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.streamPush.service.IStreamPushPlayService;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
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.cloudRecord.bean.CloudRecordUrl;
|
||||
import com.genersoft.iot.vmp.web.custom.bean.*;
|
||||
import com.genersoft.iot.vmp.web.custom.service.CameraChannelService;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
@@ -21,6 +27,7 @@ import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
@@ -29,9 +36,15 @@ import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
@Tag(name = "第三方接口")
|
||||
@Slf4j
|
||||
@@ -52,6 +65,12 @@ public class CameraChannelController {
|
||||
@Autowired
|
||||
private IMediaServerService mediaServerService;
|
||||
|
||||
@Autowired
|
||||
private ICloudRecordService cloudRecordService;
|
||||
|
||||
@Autowired
|
||||
private IStreamPushPlayService streamPushPlayService;
|
||||
|
||||
|
||||
@GetMapping(value = "/camera/list")
|
||||
@ResponseBody
|
||||
@@ -330,5 +349,228 @@ public class CameraChannelController {
|
||||
return new StreamContent(streamInfo);
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/record/collect/add")
|
||||
@Operation(summary = "添加收藏")
|
||||
@Parameter(name = "app", description = "应用名", required = false)
|
||||
@Parameter(name = "stream", description = "流ID", required = false)
|
||||
@Parameter(name = "mediaServerId", description = "流媒体ID", required = false)
|
||||
@Parameter(name = "startTime", description = "鉴权ID", required = false)
|
||||
@Parameter(name = "endTime", description = "鉴权ID", required = false)
|
||||
@Parameter(name = "callId", description = "鉴权ID", required = false)
|
||||
@Parameter(name = "recordId", description = "录像记录的ID,用于精准收藏一个视频文件", required = false)
|
||||
public int addCollect(@RequestParam(required = false) String app, @RequestParam(required = false) String stream, @RequestParam(required = false) String mediaServerId, @RequestParam(required = false) String startTime, @RequestParam(required = false) String endTime, @RequestParam(required = false) String callId, @RequestParam(required = false) Integer recordId) {
|
||||
log.info("[云端录像] 添加收藏,app={},stream={},mediaServerId={},startTime={},endTime={},callId={},recordId={}", app, stream, mediaServerId, startTime, endTime, callId, recordId);
|
||||
if (recordId != null) {
|
||||
return cloudRecordService.changeCollectById(recordId, true);
|
||||
} else {
|
||||
return cloudRecordService.changeCollect(true, app, stream, mediaServerId, startTime, endTime, callId);
|
||||
}
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@GetMapping("/record/collect/delete")
|
||||
@Operation(summary = "移除收藏")
|
||||
@Parameter(name = "app", description = "应用名", required = false)
|
||||
@Parameter(name = "stream", description = "流ID", required = false)
|
||||
@Parameter(name = "mediaServerId", description = "流媒体ID", required = false)
|
||||
@Parameter(name = "startTime", description = "鉴权ID", required = false)
|
||||
@Parameter(name = "endTime", description = "鉴权ID", required = false)
|
||||
@Parameter(name = "callId", description = "鉴权ID", required = false)
|
||||
@Parameter(name = "recordId", description = "录像记录的ID,用于精准精准移除一个视频文件的收藏", required = false)
|
||||
public int deleteCollect(@RequestParam(required = false) String app, @RequestParam(required = false) String stream, @RequestParam(required = false) String mediaServerId, @RequestParam(required = false) String startTime, @RequestParam(required = false) String endTime, @RequestParam(required = false) String callId, @RequestParam(required = false) Integer recordId) {
|
||||
log.info("[云端录像] 移除收藏,app={},stream={},mediaServerId={},startTime={},endTime={},callId={},recordId={}", app, stream, mediaServerId, startTime, endTime, callId, recordId);
|
||||
if (recordId != null) {
|
||||
return cloudRecordService.changeCollectById(recordId, false);
|
||||
} else {
|
||||
return cloudRecordService.changeCollect(false, app, stream, mediaServerId, startTime, endTime, callId);
|
||||
}
|
||||
}
|
||||
|
||||
/************************* 以下这些接口只适合wvp和zlm部署在同一台服务器的情况,且wvp只有一个zlm节点的情况 ***************************************/
|
||||
|
||||
/**
|
||||
* 下载指定录像文件的压缩包
|
||||
* @param query 检索内容
|
||||
* @param app 应用名
|
||||
* @param stream 流ID
|
||||
* @param startTime 开始时间(yyyy-MM-dd HH:mm:ss)
|
||||
* @param endTime 结束时间(yyyy-MM-dd HH:mm:ss)
|
||||
* @param mediaServerId 流媒体ID,置空则查询全部流媒体
|
||||
* @param callId 每次录像的唯一标识,置空则查询全部流媒体
|
||||
* @param ids 指定的Id
|
||||
*/
|
||||
@ResponseBody
|
||||
@GetMapping("/record/zip")
|
||||
public void downloadZipFile(HttpServletResponse response, @RequestParam(required = false) String query, @RequestParam(required = false) String app, @RequestParam(required = false) String stream, @RequestParam(required = false) String startTime, @RequestParam(required = false) String endTime, @RequestParam(required = false) String mediaServerId, @RequestParam(required = false) String callId, @RequestParam(required = false) List<Integer> ids
|
||||
|
||||
) {
|
||||
log.info("[下载指定录像文件的压缩包] 查询 app->{}, stream->{}, mediaServerId->{}, startTime->{}, endTime->{}, callId->{}", app, stream, mediaServerId, startTime, endTime, callId);
|
||||
|
||||
List<MediaServer> mediaServers;
|
||||
if (!org.apache.commons.lang3.ObjectUtils.isEmpty(mediaServerId)) {
|
||||
mediaServers = new ArrayList<>();
|
||||
MediaServer mediaServer = mediaServerService.getOne(mediaServerId);
|
||||
if (mediaServer == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到流媒体: " + mediaServerId);
|
||||
}
|
||||
mediaServers.add(mediaServer);
|
||||
} else {
|
||||
mediaServers = mediaServerService.getAll();
|
||||
}
|
||||
if (mediaServers.isEmpty()) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "当前无流媒体");
|
||||
}
|
||||
if (query != null && org.apache.commons.lang3.ObjectUtils.isEmpty(query.trim())) {
|
||||
query = null;
|
||||
}
|
||||
if (app != null && org.apache.commons.lang3.ObjectUtils.isEmpty(app.trim())) {
|
||||
app = null;
|
||||
}
|
||||
if (stream != null && org.apache.commons.lang3.ObjectUtils.isEmpty(stream.trim())) {
|
||||
stream = null;
|
||||
}
|
||||
if (startTime != null && org.apache.commons.lang3.ObjectUtils.isEmpty(startTime.trim())) {
|
||||
startTime = null;
|
||||
}
|
||||
if (endTime != null && org.apache.commons.lang3.ObjectUtils.isEmpty(endTime.trim())) {
|
||||
endTime = null;
|
||||
}
|
||||
if (callId != null && org.apache.commons.lang3.ObjectUtils.isEmpty(callId.trim())) {
|
||||
callId = null;
|
||||
}
|
||||
if (stream != null && callId != null) {
|
||||
response.addHeader("Content-Disposition", "attachment;filename=" + stream + "_" + callId + ".zip");
|
||||
}
|
||||
List<CloudRecordItem> cloudRecordItemList = cloudRecordService.getAllList(query, app, stream, startTime, endTime, mediaServers, callId, ids);
|
||||
if (org.apache.commons.lang3.ObjectUtils.isEmpty(cloudRecordItemList)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
|
||||
for (CloudRecordItem cloudRecordItem : cloudRecordItemList) {
|
||||
zos.putNextEntry(new ZipEntry(DateUtil.timestampMsToUrlToyyyy_MM_dd_HH_mm_ss((long)cloudRecordItem.getStartTime()) + ".mp4"));
|
||||
File file = new File(cloudRecordItem.getFilePath());
|
||||
if (!file.exists() || file.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
FileInputStream fis = new FileInputStream(cloudRecordItem.getFilePath());
|
||||
byte[] buf = new byte[2 * 1024];
|
||||
int len;
|
||||
while ((len = fis.read(buf)) != -1) {
|
||||
zos.write(buf, 0, len);
|
||||
}
|
||||
zos.closeEntry();
|
||||
fis.close();
|
||||
}
|
||||
zos.close();
|
||||
} catch (IOException e) {
|
||||
log.error("[下载指定录像文件的压缩包] 失败: 查询 app->{}, stream->{}, mediaServerId->{}, startTime->{}, endTime->{}, callId->{}", app, stream, mediaServerId, startTime, endTime, callId, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param query 检索内容
|
||||
* @param app 应用名
|
||||
* @param stream 流ID
|
||||
* @param startTime 开始时间(yyyy-MM-dd HH:mm:ss)
|
||||
* @param endTime 结束时间(yyyy-MM-dd HH:mm:ss)
|
||||
* @param mediaServerId 流媒体ID,置空则查询全部流媒体
|
||||
* @param callId 每次录像的唯一标识,置空则查询全部流媒体
|
||||
* @param remoteHost 拼接播放地址时使用的远程地址
|
||||
*/
|
||||
@ResponseBody
|
||||
@GetMapping("/record/list-url")
|
||||
@Operation(summary = "分页查询云端录像", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "query", description = "检索内容", required = false)
|
||||
@Parameter(name = "app", description = "应用名", required = false)
|
||||
@Parameter(name = "stream", description = "流ID", required = false)
|
||||
@Parameter(name = "page", description = "当前页", required = true)
|
||||
@Parameter(name = "count", description = "每页查询数量", required = true)
|
||||
@Parameter(name = "startTime", description = "开始时间(yyyy-MM-dd HH:mm:ss)", required = false)
|
||||
@Parameter(name = "endTime", description = "结束时间(yyyy-MM-dd HH:mm:ss)", required = false)
|
||||
@Parameter(name = "mediaServerId", description = "流媒体ID,置空则查询全部流媒体", required = false)
|
||||
@Parameter(name = "callId", description = "每次录像的唯一标识,置空则查询全部流媒体", required = false)
|
||||
public PageInfo<CloudRecordUrl> getListWithUrl(HttpServletRequest request, @RequestParam(required = false) String query, @RequestParam(required = false) String app, @RequestParam(required = false) String stream, @RequestParam int page, @RequestParam int count, @RequestParam(required = false) String startTime, @RequestParam(required = false) String endTime, @RequestParam(required = false) String mediaServerId, @RequestParam(required = false) String callId, @RequestParam(required = false) String remoteHost
|
||||
|
||||
) {
|
||||
log.info("[云端录像] 查询URL app->{}, stream->{}, mediaServerId->{}, page->{}, count->{}, startTime->{}, endTime->{}, callId->{}", app, stream, mediaServerId, page, count, startTime, endTime, callId);
|
||||
|
||||
List<MediaServer> mediaServers;
|
||||
if (!org.apache.commons.lang3.ObjectUtils.isEmpty(mediaServerId)) {
|
||||
mediaServers = new ArrayList<>();
|
||||
MediaServer mediaServer = mediaServerService.getOne(mediaServerId);
|
||||
if (mediaServer == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到流媒体: " + mediaServerId);
|
||||
}
|
||||
mediaServers.add(mediaServer);
|
||||
} else {
|
||||
mediaServers = null;
|
||||
}
|
||||
if (query != null && org.apache.commons.lang3.ObjectUtils.isEmpty(query.trim())) {
|
||||
query = null;
|
||||
}
|
||||
if (app != null && org.apache.commons.lang3.ObjectUtils.isEmpty(app.trim())) {
|
||||
app = null;
|
||||
}
|
||||
if (stream != null && org.apache.commons.lang3.ObjectUtils.isEmpty(stream.trim())) {
|
||||
stream = null;
|
||||
}
|
||||
if (startTime != null && org.apache.commons.lang3.ObjectUtils.isEmpty(startTime.trim())) {
|
||||
startTime = null;
|
||||
}
|
||||
if (endTime != null && org.apache.commons.lang3.ObjectUtils.isEmpty(endTime.trim())) {
|
||||
endTime = null;
|
||||
}
|
||||
if (callId != null && org.apache.commons.lang3.ObjectUtils.isEmpty(callId.trim())) {
|
||||
callId = null;
|
||||
}
|
||||
MediaServer mediaServer = mediaServerService.getDefaultMediaServer();
|
||||
if (mediaServer == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到流媒体节点");
|
||||
}
|
||||
if (remoteHost == null) {
|
||||
remoteHost = request.getScheme() + "://" + request.getLocalAddr() + ":" + (request.getScheme().equals("https") ? mediaServer.getHttpSSlPort() : mediaServer.getHttpPort());
|
||||
}
|
||||
PageInfo<CloudRecordItem> cloudRecordItemPageInfo = cloudRecordService.getList(page, count, query, app, stream, startTime, endTime, mediaServers, callId, null);
|
||||
PageInfo<CloudRecordUrl> cloudRecordUrlPageInfo = new PageInfo<>();
|
||||
if (!org.apache.commons.lang3.ObjectUtils.isEmpty(cloudRecordItemPageInfo)) {
|
||||
cloudRecordUrlPageInfo.setPageNum(cloudRecordItemPageInfo.getPageNum());
|
||||
cloudRecordUrlPageInfo.setPageSize(cloudRecordItemPageInfo.getPageSize());
|
||||
cloudRecordUrlPageInfo.setSize(cloudRecordItemPageInfo.getSize());
|
||||
cloudRecordUrlPageInfo.setEndRow(cloudRecordItemPageInfo.getEndRow());
|
||||
cloudRecordUrlPageInfo.setStartRow(cloudRecordItemPageInfo.getStartRow());
|
||||
cloudRecordUrlPageInfo.setPages(cloudRecordItemPageInfo.getPages());
|
||||
cloudRecordUrlPageInfo.setPrePage(cloudRecordItemPageInfo.getPrePage());
|
||||
cloudRecordUrlPageInfo.setNextPage(cloudRecordItemPageInfo.getNextPage());
|
||||
cloudRecordUrlPageInfo.setIsFirstPage(cloudRecordItemPageInfo.isIsFirstPage());
|
||||
cloudRecordUrlPageInfo.setIsLastPage(cloudRecordItemPageInfo.isIsLastPage());
|
||||
cloudRecordUrlPageInfo.setHasPreviousPage(cloudRecordItemPageInfo.isHasPreviousPage());
|
||||
cloudRecordUrlPageInfo.setHasNextPage(cloudRecordItemPageInfo.isHasNextPage());
|
||||
cloudRecordUrlPageInfo.setNavigatePages(cloudRecordItemPageInfo.getNavigatePages());
|
||||
cloudRecordUrlPageInfo.setNavigateFirstPage(cloudRecordItemPageInfo.getNavigateFirstPage());
|
||||
cloudRecordUrlPageInfo.setNavigateLastPage(cloudRecordItemPageInfo.getNavigateLastPage());
|
||||
cloudRecordUrlPageInfo.setNavigatepageNums(cloudRecordItemPageInfo.getNavigatepageNums());
|
||||
cloudRecordUrlPageInfo.setTotal(cloudRecordItemPageInfo.getTotal());
|
||||
List<CloudRecordUrl> cloudRecordUrlList = new ArrayList<>(cloudRecordItemPageInfo.getList().size());
|
||||
List<CloudRecordItem> cloudRecordItemList = cloudRecordItemPageInfo.getList();
|
||||
for (CloudRecordItem cloudRecordItem : cloudRecordItemList) {
|
||||
CloudRecordUrl cloudRecordUrl = new CloudRecordUrl();
|
||||
cloudRecordUrl.setId(cloudRecordItem.getId());
|
||||
cloudRecordUrl.setDownloadUrl(remoteHost + "/index/api/downloadFile?file_path=" + cloudRecordItem.getFilePath() + "&save_name=" + cloudRecordItem.getStream() + "_" + cloudRecordItem.getCallId() + "_" + DateUtil.timestampMsToUrlToyyyy_MM_dd_HH_mm_ss((long)cloudRecordItem.getStartTime()));
|
||||
cloudRecordUrl.setPlayUrl(remoteHost + "/index/api/downloadFile?file_path=" + cloudRecordItem.getFilePath());
|
||||
cloudRecordUrlList.add(cloudRecordUrl);
|
||||
}
|
||||
cloudRecordUrlPageInfo.setList(cloudRecordUrlList);
|
||||
}
|
||||
return cloudRecordUrlPageInfo;
|
||||
}
|
||||
|
||||
@GetMapping(value = "/forceClose")
|
||||
@ResponseBody
|
||||
@Operation(summary = "强制停止推流", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
public void stop(String app, String stream){
|
||||
streamPushPlayService.stop(app, stream);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Group;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
|
||||
import com.genersoft.iot.vmp.gb28181.dao.CommonGBChannelMapper;
|
||||
import com.genersoft.iot.vmp.gb28181.dao.GroupMapper;
|
||||
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.event.channel.ChannelEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.event.subscribe.mobilePosition.MobilePositionEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IGbChannelControlService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IGbChannelPlayService;
|
||||
@@ -113,49 +113,120 @@ public class CameraChannelService implements CommandLineRunner {
|
||||
|
||||
// 监听通道变化,如果是移动设备则发送redis消息
|
||||
@EventListener
|
||||
public void onApplicationEvent(CatalogEvent event) {
|
||||
public void onApplicationEvent(ChannelEvent event) {
|
||||
List<CommonGBChannel> channels = event.getChannels();
|
||||
if (channels.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<CommonGBChannel> resultListForAdd = new ArrayList<>();
|
||||
List<CameraChannel> resultListForDelete = new ArrayList<>();
|
||||
List<CommonGBChannel> resultListForUpdate = new ArrayList<>();
|
||||
List<CommonGBChannel> resultListForOnline = new ArrayList<>();
|
||||
List<CommonGBChannel> resultListForOffline = new ArrayList<>();
|
||||
|
||||
List<CameraChannel> mobilechannelList = null;
|
||||
if (event.getType().equals(CatalogEvent.DEL)) {
|
||||
mobilechannelList = new ArrayList<>();
|
||||
for (CommonGBChannel channel : channels) {
|
||||
if (channel.getGbPtzType() != null && channel.getGbPtzType() == 99) {
|
||||
CameraChannel cameraChannel = new CameraChannel();
|
||||
cameraChannel.setGbDeviceId(channel.getGbDeviceId());
|
||||
mobilechannelList.add(cameraChannel);
|
||||
switch (event.getMessageType()) {
|
||||
case UPDATE:
|
||||
List<CommonGBChannel> oldChannelList = event.getOldChannels();
|
||||
List<CommonGBChannel> channelList = event.getChannels();
|
||||
// 更新操作
|
||||
if (oldChannelList == null || oldChannelList.isEmpty()) {
|
||||
// 无旧设备则不需要判断, 目前只有分组或行政区划转换为通道信息时没有旧的通道信息,这两个类型也是不需要发送通知的,直接忽略即可
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else {
|
||||
List<Integer> ids = new ArrayList<>();
|
||||
channels.forEach((channel -> {
|
||||
if (channel.getGbPtzType() != null && channel.getGbPtzType() == 99) {
|
||||
ids.add(channel.getGbId());
|
||||
// 需要比对旧数据,看看是否是新增的移动设备或者取消的移动设备
|
||||
// 将 channelList 转为以 gbDeviceId 为 key 的 Map
|
||||
Map<String, CommonGBChannel> oldChannelMap = new HashMap<>();
|
||||
for (CommonGBChannel channel : oldChannelList) {
|
||||
if (channel != null && channel.getGbDeviceId() != null) {
|
||||
oldChannelMap.put(channel.getGbDeviceId(), channel);
|
||||
}
|
||||
}
|
||||
}));
|
||||
if (ids.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
mobilechannelList = channelMapper.queryCameraChannelByIds(ids);
|
||||
for (CommonGBChannel channel : channelList) {
|
||||
if (channel.getGbPtzType() != null && channel.getGbPtzType() == 99) {
|
||||
CommonGBChannel oldChannel = oldChannelMap.get(channel.getGbDeviceId());
|
||||
if (oldChannel != null) {
|
||||
if (oldChannel.getGbPtzType() != null && oldChannel.getGbPtzType() == 99) {
|
||||
resultListForUpdate.add(channel);
|
||||
}else {
|
||||
resultListForAdd.add(channel);
|
||||
}
|
||||
}else {
|
||||
resultListForAdd.add(channel);
|
||||
}
|
||||
}else {
|
||||
CommonGBChannel oldChannel = oldChannelMap.get(channel.getGbDeviceId());
|
||||
if (oldChannel != null && oldChannel.getGbPtzType() != null && oldChannel.getGbPtzType() == 99) {
|
||||
CameraChannel cameraChannel = new CameraChannel();
|
||||
cameraChannel.setGbDeviceId(channel.getGbDeviceId());
|
||||
resultListForDelete.add(cameraChannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case DEL:
|
||||
for (CommonGBChannel channel : channels) {
|
||||
if (channel.getGbPtzType() != null && channel.getGbPtzType() == 99) {
|
||||
CameraChannel cameraChannel = new CameraChannel();
|
||||
cameraChannel.setGbDeviceId(channel.getGbDeviceId());
|
||||
resultListForDelete.add(cameraChannel);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ON:
|
||||
case OFF:
|
||||
case DEFECT:
|
||||
case VLOST:
|
||||
for (CommonGBChannel channel : channels) {
|
||||
if (channel.getGbPtzType() != null && channel.getGbPtzType() == 99) {
|
||||
if (event.getMessageType() == ChannelEvent.ChannelEventMessageType.ON) {
|
||||
resultListForOnline.add(channel);
|
||||
}else {
|
||||
resultListForOffline.add(channel);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ADD:
|
||||
for (CommonGBChannel channel : channels) {
|
||||
if (channel.getGbPtzType() != null && channel.getGbPtzType() == 99) {
|
||||
resultListForAdd.add(channel);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (mobilechannelList == null || mobilechannelList.isEmpty()) {
|
||||
if (!resultListForDelete.isEmpty()) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("type", ChannelEvent.ChannelEventMessageType.DEL);
|
||||
jsonObject.put("list", resultListForDelete);
|
||||
log.info("[SY-redis发送通知-DEL] 发送 通道信息变化 {}: {}", REDIS_CHANNEL_MESSAGE, jsonObject.toString());
|
||||
redisTemplate.convertAndSend(REDIS_CHANNEL_MESSAGE, jsonObject);
|
||||
}
|
||||
if (!resultListForAdd.isEmpty()) {
|
||||
sendChannelMessage(resultListForAdd, ChannelEvent.ChannelEventMessageType.ADD);
|
||||
}
|
||||
if (!resultListForUpdate.isEmpty()) {
|
||||
sendChannelMessage(resultListForAdd, ChannelEvent.ChannelEventMessageType.UPDATE);
|
||||
}
|
||||
if (!resultListForOnline.isEmpty()) {
|
||||
sendChannelMessage(resultListForAdd, ChannelEvent.ChannelEventMessageType.ON);
|
||||
}
|
||||
if (!resultListForOffline.isEmpty()) {
|
||||
sendChannelMessage(resultListForAdd, ChannelEvent.ChannelEventMessageType.OFF);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendChannelMessage(List<CommonGBChannel> channelList, ChannelEvent.ChannelEventMessageType type) {
|
||||
if (channelList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String type = event.getType();
|
||||
if (type.equals(CatalogEvent.VLOST) || type.equals(CatalogEvent.DEFECT)) {
|
||||
type = CatalogEvent.OFF;
|
||||
}
|
||||
|
||||
List<CameraChannel> cameraChannelList = channelMapper.queryCameraChannelByIds(channelList);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("type", type);
|
||||
jsonObject.put("list", mobilechannelList);
|
||||
log.info("[SY-redis发送通知] 发送 通道信息变化 {}: {}", REDIS_CHANNEL_MESSAGE, jsonObject.toString());
|
||||
jsonObject.put("list", cameraChannelList);
|
||||
log.info("[SY-redis发送通知-{}] 发送 通道信息变化 {}: {}", type, REDIS_CHANNEL_MESSAGE, jsonObject.toString());
|
||||
redisTemplate.convertAndSend(REDIS_CHANNEL_MESSAGE, jsonObject);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 监听GPS消息,如果是移动设备则发送redis消息
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
:add-channel-to-group="addChannelToGroup"
|
||||
/>
|
||||
<div style="padding: 0 20px">
|
||||
<el-form :inline="true" size="mini">
|
||||
<el-form :inline="true" size="mini" ref="queryForm">
|
||||
<el-form-item>
|
||||
<el-breadcrumb v-if="regionParents.length > 0" separator="/" style="display: ruby">
|
||||
<el-breadcrumb-item v-for="key in regionParents" :key="key">{{ key }}</el-breadcrumb-item>
|
||||
@@ -74,7 +74,7 @@
|
||||
ref="channelListTable"
|
||||
size="medium"
|
||||
:data="channelList"
|
||||
height="calc(100vh - 190px)"
|
||||
:height="tableHeight"
|
||||
style="width: 100%"
|
||||
header-row-class-name="table-header"
|
||||
@selection-change="handleSelectionChange"
|
||||
@@ -132,6 +132,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
channelList: [],
|
||||
tableHeight: `calc(100vh - ${this.$refs.queryForm.offsetHeight}px)`,
|
||||
searchStr: '',
|
||||
channelType: '',
|
||||
online: '',
|
||||
|
||||
Reference in New Issue
Block a user