package com.zhgd.xmgl.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.zhgd.xmgl.async.AsyncEnvironment; import com.zhgd.xmgl.modules.policecamera.entity.PoliceCameraItem; import com.zhgd.xmgl.modules.policecamera.entity.PoliceCameraVideoConfig; import com.zhgd.xmgl.modules.policecamera.service.IPoliceCameraItemService; import com.zhgd.xmgl.modules.policecamera.service.IPoliceCameraVideoConfigService; import com.zhgd.xmgl.modules.project.entity.ProjectVideoConfig; import com.zhgd.xmgl.modules.project.entity.bo.ProjectVideoConfigBo; import com.zhgd.xmgl.modules.project.enums.ProjectVideoConfigVideoTypeEnum; import com.zhgd.xmgl.modules.project.mapper.ProjectVideoConfigMapper; import com.zhgd.xmgl.modules.video.entity.VideoItem; import com.zhgd.xmgl.modules.video.mapper.VideoItemMapper; import com.zhgd.xmgl.modules.video.service.impl.VideoItemServiceImpl; import com.zhgd.xmgl.util.HikVideoUtil; import com.zhgd.xmgl.util.YsVideoUtil; import lombok.extern.slf4j.Slf4j; import net.javacrumbs.shedlock.core.SchedulerLock; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.*; import java.util.stream.Collectors; /** * @program: wisdomSite * @description: 视频定时任务 * @author: Mr.Peng * @create: 2021-11-11 18:48 **/ @Slf4j @RestController @RequestMapping("/xmgl/task/") public class VideoTask { @Autowired private ProjectVideoConfigMapper projectVideoConfigMapper; @Autowired private VideoItemMapper videoItemMapper; @Autowired private AsyncEnvironment asyncEnvironment; @Value("${video-analysis-url}") private String videoAnalysisUrl; @Value("${serverUrl}") private String serverUrl; @Lazy @Autowired private VideoItemServiceImpl videoItemService; @Lazy @Autowired private IPoliceCameraVideoConfigService policeCameraVideoConfigService; @Lazy @Autowired private IPoliceCameraItemService policeCameraItemService; @SchedulerLock(name = "updateVideoState", lockAtMostFor = 1000 * 60 * 60, lockAtLeastFor = 1000 * 60 * 5) @Scheduled(cron = "0 */3 * * * ?") @RequestMapping("updateVideoState") public void updateVideoState() { try { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.lambda().eq(ProjectVideoConfig::getIsEnable, 1); List list = projectVideoConfigMapper.selectList(queryWrapper); if (list != null && list.size() > 0) { for (ProjectVideoConfig videoConfig : list) { updateProjectVideo(videoConfig); } } } catch (Exception e) { log.error("error:", e); } } private void updateProjectVideo(ProjectVideoConfig videoConfig) { try { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.lambda().eq(VideoItem::getVideoId, videoConfig.getId()); List list = videoItemMapper.selectList(queryWrapper); if (list != null && list.size() > 0) { if (Objects.equals(videoConfig.getVideoType(), ProjectVideoConfigVideoTypeEnum.YSY.getValue())) { String accessToken = YsVideoUtil.getToken(videoConfig.getAppId(), videoConfig.getAppSecret()); for (VideoItem videoItem : list) { Integer state = YsVideoUtil.getVideoStatus(videoConfig.getAppId(), videoConfig.getAppSecret(), videoItem.getSerialNumber(), accessToken); videoItem.setDeviceState(state); videoItemMapper.updateById(videoItem); } } else if (Objects.equals(videoConfig.getVideoType(), ProjectVideoConfigVideoTypeEnum.ISC.getValue())) { if (StringUtils.isNotEmpty(videoConfig.getAccount()) && StringUtils.isNotEmpty(videoConfig.getPassword()) && StringUtils.isNotEmpty(videoConfig.getAppId()) && StringUtils.isNotEmpty(videoConfig.getAppSecret())) { for (VideoItem videoItem : list) { if (StringUtils.isNotEmpty(videoItem.getSerialNumber())) { Boolean online = HikVideoUtil.callPostApiOnlineStatus(videoItem.getSerialNumber(), videoConfig.getAccount(), videoConfig.getPassword(), videoConfig.getAppId(), videoConfig.getAppSecret()); if (online != null) { if (online) { videoItem.setDeviceState(1); } else { videoItem.setDeviceState(2); } videoItemMapper.updateById(videoItem); } //sendVideoData(videoItem,videoConfig); } } } } else { QueryWrapper qu = new QueryWrapper<>(); qu.lambda().eq(VideoItem::getVideoId, videoConfig.getId()); VideoItem item = new VideoItem(); item.setDeviceState(2); item.setVideoId(videoConfig.getId()); videoItemMapper.update(item, qu); } } } catch (Exception e) { log.error("error:", e); } } /** * 高频更新isc监控状态 */ @Scheduled(cron = "*/10 * * * * ?") @RequestMapping("updateIscVideoState") public void updateIscVideoState() { try { List projectVideoConfigs = projectVideoConfigMapper.getIscConfigsGroupByConfig(); Map> videoIdMap = videoItemService.list(new LambdaQueryWrapper() .select(VideoItem::getItemId, VideoItem::getVideoId, VideoItem::getDeviceState, VideoItem::getSerialNumber)) .stream() .collect(Collectors.groupingBy(VideoItem::getVideoId)); for (ProjectVideoConfigBo videoConfig : projectVideoConfigs) { // 收集需要更新的视频设备 List videoItemsToUpdate = new ArrayList<>(); JSONObject resultJo; JSONArray alls = new JSONArray(); int pageNo = 0; if (StrUtil.isBlank(videoConfig.getIds())) { continue; } List itemDbs = StrUtil.split(videoConfig.getIds(), ",").stream().flatMap(vid -> { List videoItems = videoIdMap.get(Convert.toLong(vid)); if (CollUtil.isNotEmpty(videoItems)) { return videoItems.stream(); } return null; }).filter(Objects::nonNull).collect(Collectors.toList()); if (CollUtil.isEmpty(itemDbs)) { continue; } try { do { resultJo = HikVideoUtil.callPostApiOnlineStatus(videoConfig.getAccount(), videoConfig.getPassword(), videoConfig.getAppId(), videoConfig.getAppSecret(), ++pageNo); if (resultJo != null && "0".equals(resultJo.getString("code"))) { alls.addAll(resultJo.getJSONObject("data").getJSONArray("list")); } else { log.error("高频更新isc监控状态返回错误:项目sn:{}:code:{},msg:{}", videoConfig.getProjectSn(), resultJo != null ? resultJo.getString("code") : "", resultJo != null ? resultJo.getString("msg") : ""); break; } } while (pageNo * 1000 < resultJo.getJSONObject("data").getInteger("total")); } catch (Exception e) { log.error("高频更新isc监控状态返回异常", e); } Map indexCodeMap = alls.stream().collect(Collectors.toMap(j -> ((JSONObject) j).getString("indexCode"), j -> ((JSONObject) j), (o1, o2) -> o1)); for (VideoItem videoItem : itemDbs) { JSONObject jsonObject = indexCodeMap.get(videoItem.getSerialNumber()); Integer newOnlineStatus = jsonObject != null && Objects.equals(jsonObject.getInteger("online"), 1) ? 1 : 2; // 只有当设备状态发生变化时才更新 if (!newOnlineStatus.equals(videoItem.getDeviceState())) { videoItem.setDeviceState(newOnlineStatus); videoItemsToUpdate.add(videoItem); } } // 批量更新 if (CollUtil.isNotEmpty(videoItemsToUpdate)) { List onlineIds = videoItemsToUpdate.stream().filter(v -> Objects.equals(v.getDeviceState(), 1)).map(VideoItem::getItemId).collect(Collectors.toList()); if (CollUtil.isNotEmpty(onlineIds)) { videoItemService.update(null, new LambdaUpdateWrapper() .set(VideoItem::getDeviceState, 1) .in(VideoItem::getItemId, onlineIds) ); } List offlineIds = videoItemsToUpdate.stream().filter(v -> Objects.equals(v.getDeviceState(), 2)).map(VideoItem::getItemId).collect(Collectors.toList()); if (CollUtil.isNotEmpty(offlineIds)) { videoItemService.update(null, new LambdaUpdateWrapper() .set(VideoItem::getDeviceState, 2) .in(VideoItem::getItemId, offlineIds) ); } } } } catch (Exception e) { log.error("高频更新isc监控状态错误", e); } } /** * 高频更新执法记录仪的isc监控状态 */ @Scheduled(cron = "*/10 * * * * ?") @RequestMapping("updatePoliceCameraItemIscVideoState") public void updatePoliceCameraItemIscVideoState() { try { List configs = policeCameraVideoConfigService.list(new QueryWrapper<>()); Map> projectSnMap2ItemsMap = policeCameraItemService.list(new LambdaQueryWrapper()).stream().collect(Collectors.groupingBy(PoliceCameraItem::getProjectSn)); Map> projectSn2IndexCodeMap = new HashMap<>(); for (PoliceCameraVideoConfig videoConfig : configs) { // 收集需要更新的视频设备 List videoItemsToUpdate = new ArrayList<>(); List itemDbs = projectSnMap2ItemsMap.get(videoConfig.getProjectSn()); if (CollUtil.isEmpty(itemDbs)) { continue; } Map indexCodeMap = projectSn2IndexCodeMap.computeIfAbsent(StrUtil.format("{},{},{},{}", videoConfig.getIp(), videoConfig.getPort(), videoConfig.getAppId(), videoConfig.getAppSecret()), key -> { if (StrUtil.isBlank(videoConfig.getIp()) || StrUtil.isBlank(videoConfig.getPort()) || StrUtil.isBlank(videoConfig.getAppId()) || StrUtil.isBlank(videoConfig.getAppSecret())) { return new HashMap<>(); } JSONArray alls = new JSONArray(); try { JSONObject resultJo; int pageNo = 0; do { resultJo = HikVideoUtil.callPostApiOnlineStatus(videoConfig.getIp(), videoConfig.getPort(), videoConfig.getAppId(), videoConfig.getAppSecret(), ++pageNo); if (resultJo != null && "0".equals(resultJo.getString("code"))) { alls.addAll(resultJo.getJSONObject("data").getJSONArray("list")); } else { log.error("高频更新执法记录仪的isc监控状态返回错误:项目sn:{}:code:{},msg:{}", videoConfig.getProjectSn(), resultJo != null ? resultJo.getString("code") : "", resultJo != null ? resultJo.getString("msg") : ""); break; } } while (pageNo * 1000 < resultJo.getJSONObject("data").getInteger("total")); } catch (Exception e) { log.error("高频更新执法记录仪的isc监控状态返回异常", e); } return alls.stream().collect(Collectors.toMap(j -> ((JSONObject) j).getString("indexCode"), j -> ((JSONObject) j), (o1, o2) -> o1)); }); for (PoliceCameraItem item : itemDbs) { JSONObject jsonObject = indexCodeMap.get(item.getMonitoringNumber()); Integer newOnlineStatus = jsonObject != null && Objects.equals(jsonObject.getInteger("online"), 1) ? 1 : 2; // 只有当设备状态发生变化时才更新 if (!newOnlineStatus.equals(item.getDeviceState())) { item.setDeviceState(newOnlineStatus); videoItemsToUpdate.add(item); } } // 批量更新 if (CollUtil.isNotEmpty(videoItemsToUpdate)) { List onlineIds = videoItemsToUpdate.stream().filter(v -> Objects.equals(v.getDeviceState(), 1)).map(PoliceCameraItem::getItemId).collect(Collectors.toList()); if (CollUtil.isNotEmpty(onlineIds)) { policeCameraItemService.update(null, new LambdaUpdateWrapper() .set(PoliceCameraItem::getDeviceState, 1) .in(PoliceCameraItem::getItemId, onlineIds) ); } List offlineIds = videoItemsToUpdate.stream().filter(v -> Objects.equals(v.getDeviceState(), 2)).map(PoliceCameraItem::getItemId).collect(Collectors.toList()); if (CollUtil.isNotEmpty(offlineIds)) { policeCameraItemService.update(null, new LambdaUpdateWrapper() .set(PoliceCameraItem::getDeviceState, 2) .in(PoliceCameraItem::getItemId, offlineIds) ); } } } } catch (Exception e) { log.error("高频更新执法记录仪的isc监控状态返回错误", e); } } private void sendVideoData(VideoItem videoItem, ProjectVideoConfig videoConfig) { List> list = new ArrayList<>(); Map video = new HashMap<>(16); video.put("appId", videoConfig.getAppId()); video.put("appSecret", videoConfig.getAppSecret()); video.put("ip", videoConfig.getAccount()); video.put("port", videoConfig.getPassword()); video.put("serialNumber", videoItem.getSerialNumber()); list.add(video); List alarmIdList = new ArrayList<>(); alarmIdList.add(videoItem.getItemId()); Map object = new HashMap<>(16); object.put("projectSn", videoConfig.getProjectSn()); object.put("videoList", list); object.put("dataId", alarmIdList); object.put("resultUrl", serverUrl + "/xmgl/api/saveVideoAnalysisResult"); object.put("type", 2); log.info(JSONUtil.toJsonStr(object)); if (StringUtils.isNotEmpty(videoAnalysisUrl)) { asyncEnvironment.sendVideoAnalysisData(videoAnalysisUrl, object); } } /*public static void main(String[] args) { String Ip="182.101.141.23"; String port="18443"; String appkey="24017757"; String appSecret="VJz0FbzmE6drPQ7egsBi"; String url= HikVideoUtil.callPostApiGetPreviewURL("34ad8813a79d4cbaaebdbeaddaa53598", "rtmp",null,Ip, port,appkey, appSecret); log.info(url); *//*boolean status= VideoUtils.getVideoOnlineSate(url); log.info(status);*//* }*/ }