Commit daac0010b16fc03ef72b6b0712b5ba38dde2801d
1 parent
9b036fb7
优化云端录像定时清理
Showing
13 changed files
with
340 additions
and
74 deletions
sql/2.6.9更新.sql
| ... | ... | @@ -5,7 +5,7 @@ alter table wvp_platform |
| 5 | 5 | add auto_push_channel bool default false |
| 6 | 6 | |
| 7 | 7 | alter table wvp_stream_proxy |
| 8 | - add stream_key varying(255) | |
| 8 | + add stream_key character varying(255) | |
| 9 | 9 | |
| 10 | 10 | create table wvp_cloud_record ( |
| 11 | 11 | id serial primary key, |
| ... | ... | @@ -18,8 +18,17 @@ create table wvp_cloud_record ( |
| 18 | 18 | file_name character varying(255), |
| 19 | 19 | folder character varying(255), |
| 20 | 20 | file_path character varying(255), |
| 21 | - collect_type character varying(255), | |
| 21 | + collect bool default false, | |
| 22 | + reserve bool default false, | |
| 22 | 23 | file_size integer, |
| 23 | 24 | time_len integer, |
| 24 | 25 | constraint uk_stream_push_app_stream_path unique (app, stream, file_path) |
| 25 | 26 | ); |
| 27 | + | |
| 28 | +alter table wvp_media_server | |
| 29 | + add record_path character varying(255); | |
| 30 | + | |
| 31 | +alter table wvp_media_server | |
| 32 | + add record_date integer default 7; | |
| 33 | + | |
| 34 | + | ... | ... |
sql/初始化.sql
| ... | ... | @@ -164,6 +164,8 @@ create table wvp_media_server ( |
| 164 | 164 | create_time character varying(50), |
| 165 | 165 | update_time character varying(50), |
| 166 | 166 | hook_alive_interval integer, |
| 167 | + record_path character varying(255), | |
| 168 | + record_date integer default 7, | |
| 167 | 169 | constraint uk_media_server_unique_ip_http_port unique (ip, http_port) |
| 168 | 170 | ); |
| 169 | 171 | |
| ... | ... | @@ -267,20 +269,21 @@ create table wvp_stream_push ( |
| 267 | 269 | constraint uk_stream_push_app_stream unique (app, stream) |
| 268 | 270 | ); |
| 269 | 271 | create table wvp_cloud_record ( |
| 270 | - id serial primary key, | |
| 271 | - app character varying(255), | |
| 272 | - stream character varying(255), | |
| 273 | - call_id character varying(255), | |
| 274 | - start_time integer, | |
| 275 | - end_time integer, | |
| 276 | - media_server_id character varying(50), | |
| 277 | - file_name character varying(255), | |
| 278 | - folder character varying(255), | |
| 279 | - file_path character varying(255), | |
| 280 | - collect_type character varying(255), | |
| 281 | - file_size integer, | |
| 282 | - time_len integer, | |
| 283 | - constraint uk_stream_push_app_stream_path unique (app, stream, file_path) | |
| 272 | + id serial primary key, | |
| 273 | + app character varying(255), | |
| 274 | + stream character varying(255), | |
| 275 | + call_id character varying(255), | |
| 276 | + start_time integer, | |
| 277 | + end_time integer, | |
| 278 | + media_server_id character varying(50), | |
| 279 | + file_name character varying(255), | |
| 280 | + folder character varying(255), | |
| 281 | + file_path character varying(255), | |
| 282 | + collect bool default false, | |
| 283 | + reserve bool default false, | |
| 284 | + file_size integer, | |
| 285 | + time_len integer, | |
| 286 | + constraint uk_stream_push_app_stream_path unique (app, stream, file_path) | |
| 284 | 287 | ); |
| 285 | 288 | |
| 286 | 289 | create table wvp_user ( | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/CloudRecordTimer.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.conf; | |
| 2 | + | |
| 3 | + | |
| 4 | +import com.alibaba.fastjson2.JSONObject; | |
| 5 | +import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils; | |
| 6 | +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | |
| 7 | +import com.genersoft.iot.vmp.service.IMediaServerService; | |
| 8 | +import com.genersoft.iot.vmp.storager.dao.CloudRecordServiceMapper; | |
| 9 | +import com.genersoft.iot.vmp.vmanager.cloudRecord.CloudRecordController; | |
| 10 | +import org.slf4j.Logger; | |
| 11 | +import org.slf4j.LoggerFactory; | |
| 12 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 13 | +import org.springframework.scheduling.annotation.Scheduled; | |
| 14 | +import org.springframework.stereotype.Component; | |
| 15 | + | |
| 16 | +import java.util.ArrayList; | |
| 17 | +import java.util.Calendar; | |
| 18 | +import java.util.Date; | |
| 19 | +import java.util.List; | |
| 20 | + | |
| 21 | +/** | |
| 22 | + * 录像文件定时删除 | |
| 23 | + */ | |
| 24 | +@Component | |
| 25 | +public class CloudRecordTimer { | |
| 26 | + | |
| 27 | + private final static Logger logger = LoggerFactory.getLogger(CloudRecordTimer.class); | |
| 28 | + | |
| 29 | + @Autowired | |
| 30 | + private IMediaServerService mediaServerService; | |
| 31 | + | |
| 32 | + @Autowired | |
| 33 | + private CloudRecordServiceMapper cloudRecordServiceMapper; | |
| 34 | + | |
| 35 | + @Autowired | |
| 36 | + private AssistRESTfulUtils assistRESTfulUtils; | |
| 37 | + | |
| 38 | + /** | |
| 39 | + * 定时查询待删除的录像文件 | |
| 40 | + */ | |
| 41 | + @Scheduled(cron = "0 0 0 * * ?") //每天的0点执行 | |
| 42 | + public void execute(){ | |
| 43 | + // 获取配置了assist的流媒体节点 | |
| 44 | + List<MediaServerItem> mediaServerItemList = mediaServerService.getAllWithAssistPort(); | |
| 45 | + if (mediaServerItemList.isEmpty()) { | |
| 46 | + return; | |
| 47 | + } | |
| 48 | + long result = 0; | |
| 49 | + for (MediaServerItem mediaServerItem : mediaServerItemList) { | |
| 50 | + | |
| 51 | + Calendar lastCalendar = Calendar.getInstance(); | |
| 52 | + if (mediaServerItem.getRecordDate() > 0) { | |
| 53 | + lastCalendar.setTime(new Date()); | |
| 54 | + // 获取保存的最后截至日期,因为每个节点都有一个日期,也就是支持每个节点设置不同的保存日期, | |
| 55 | + lastCalendar.add(Calendar.DAY_OF_MONTH, -mediaServerItem.getRecordDate()); | |
| 56 | + Long lastDate = lastCalendar.getTimeInMillis(); | |
| 57 | + // 获取到截至日期之前的录像文件列表,文件列表满足未被收藏和保持的。这两个字段目前共能一致, | |
| 58 | + // 为我自己业务系统相关的代码,大家使用的时候直接使用收藏(collect)这一个类型即可 | |
| 59 | + List<String> filePathList = cloudRecordServiceMapper.queryRecordFilePathListForDelete(lastDate, mediaServerItem.getId()); | |
| 60 | + if (filePathList.isEmpty()) { | |
| 61 | + continue; | |
| 62 | + } | |
| 63 | + // 先调用assist删除磁盘文件,删除成功后再删除数据库记录 | |
| 64 | + JSONObject jsonObject = assistRESTfulUtils.deleteFiles(mediaServerItem, filePathList); | |
| 65 | + if (jsonObject != null && jsonObject.getInteger("code") == 0 && jsonObject.getInteger("data") > 0) { | |
| 66 | + result += jsonObject.getInteger("data"); | |
| 67 | + cloudRecordServiceMapper.deleteByFileList(filePathList, mediaServerItem.getId()); | |
| 68 | + } | |
| 69 | + } | |
| 70 | + } | |
| 71 | + logger.info("[录像文件定时清理] 共清理{}个过期录像文件", result); | |
| 72 | + } | |
| 73 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/AssistRESTfulUtils.java
| ... | ... | @@ -29,8 +29,6 @@ public class AssistRESTfulUtils { |
| 29 | 29 | private OkHttpClient client; |
| 30 | 30 | |
| 31 | 31 | |
| 32 | - | |
| 33 | - | |
| 34 | 32 | public interface RequestCallback{ |
| 35 | 33 | void run(JSONObject response); |
| 36 | 34 | } |
| ... | ... | @@ -271,4 +269,13 @@ public class AssistRESTfulUtils { |
| 271 | 269 | return sendGet(mediaServerItem, "api/record/file/download/task/list", param, null); |
| 272 | 270 | } |
| 273 | 271 | |
| 272 | + public JSONObject addCollect(MediaServerItem mediaServerItem, JSONObject jsonObject) { | |
| 273 | + return sendPost(mediaServerItem, "api/record/file/collection/add", jsonObject, null, 30); | |
| 274 | + } | |
| 275 | + | |
| 276 | + public JSONObject deleteFiles(MediaServerItem mediaServerItem, List<String> filePathList) { | |
| 277 | + JSONObject jsonObject = new JSONObject(); | |
| 278 | + jsonObject.put("filePathList", filePathList); | |
| 279 | + return sendPost(mediaServerItem, "api/record/file/delete", jsonObject, null, 15*60); | |
| 280 | + } | |
| 274 | 281 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java
| ... | ... | @@ -80,8 +80,13 @@ public class MediaServerItem{ |
| 80 | 80 | @Schema(description = "是否是默认ZLM") |
| 81 | 81 | private boolean defaultServer; |
| 82 | 82 | |
| 83 | - @Schema(description = "当前使用到的端口") | |
| 84 | - private int currentPort; | |
| 83 | + @Schema(description = "录像存储路径") | |
| 84 | + private String recordPath; | |
| 85 | + | |
| 86 | + @Schema(description = "录像存储时长") | |
| 87 | + private int recordDate; | |
| 88 | + | |
| 89 | + | |
| 85 | 90 | |
| 86 | 91 | |
| 87 | 92 | public MediaServerItem() { |
| ... | ... | @@ -269,14 +274,6 @@ public class MediaServerItem{ |
| 269 | 274 | this.updateTime = updateTime; |
| 270 | 275 | } |
| 271 | 276 | |
| 272 | - public int getCurrentPort() { | |
| 273 | - return currentPort; | |
| 274 | - } | |
| 275 | - | |
| 276 | - public void setCurrentPort(int currentPort) { | |
| 277 | - this.currentPort = currentPort; | |
| 278 | - } | |
| 279 | - | |
| 280 | 277 | public boolean isStatus() { |
| 281 | 278 | return status; |
| 282 | 279 | } |
| ... | ... | @@ -308,4 +305,20 @@ public class MediaServerItem{ |
| 308 | 305 | public void setSendRtpPortRange(String sendRtpPortRange) { |
| 309 | 306 | this.sendRtpPortRange = sendRtpPortRange; |
| 310 | 307 | } |
| 308 | + | |
| 309 | + public String getRecordPath() { | |
| 310 | + return recordPath; | |
| 311 | + } | |
| 312 | + | |
| 313 | + public void setRecordPath(String recordPath) { | |
| 314 | + this.recordPath = recordPath; | |
| 315 | + } | |
| 316 | + | |
| 317 | + public int getRecordDate() { | |
| 318 | + return recordDate; | |
| 319 | + } | |
| 320 | + | |
| 321 | + public void setRecordDate(int recordDate) { | |
| 322 | + this.recordDate = recordDate; | |
| 323 | + } | |
| 311 | 324 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java
| 1 | 1 | package com.genersoft.iot.vmp.service; |
| 2 | 2 | |
| 3 | 3 | import com.alibaba.fastjson2.JSONArray; |
| 4 | -import com.alibaba.fastjson2.JSONObject; | |
| 5 | 4 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 6 | 5 | import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; |
| 7 | 6 | import com.genersoft.iot.vmp.service.bean.CloudRecordItem; |
| ... | ... | @@ -40,4 +39,15 @@ public interface ICloudRecordService { |
| 40 | 39 | * 查询合并任务列表 |
| 41 | 40 | */ |
| 42 | 41 | JSONArray queryTask(String taskId, String mediaServerId, Boolean isEnd); |
| 42 | + | |
| 43 | + /** | |
| 44 | + * 收藏视频,收藏的视频过期不会删除 | |
| 45 | + */ | |
| 46 | + void changeCollect(String type, boolean result, String app, String stream, String mediaServerId, String startTime, String endTime, String callId, String collectType); | |
| 47 | + | |
| 48 | + /** | |
| 49 | + * 添加指定录像收藏 | |
| 50 | + */ | |
| 51 | + void changeCollectById(Integer recordId, String collectType, boolean result); | |
| 52 | + | |
| 43 | 53 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
src/main/java/com/genersoft/iot/vmp/service/bean/CloudRecordItem.java
| ... | ... | @@ -57,9 +57,14 @@ public class CloudRecordItem { |
| 57 | 57 | private String folder; |
| 58 | 58 | |
| 59 | 59 | /** |
| 60 | - * 收藏类型,收藏的文件不移除 | |
| 60 | + * 收藏,收藏的文件不移除 | |
| 61 | 61 | */ |
| 62 | - private String collectType; | |
| 62 | + private Boolean collect; | |
| 63 | + | |
| 64 | + /** | |
| 65 | + * 保留,收藏的文件不移除 | |
| 66 | + */ | |
| 67 | + private Boolean reserve; | |
| 63 | 68 | |
| 64 | 69 | /** |
| 65 | 70 | * 文件大小 |
| ... | ... | @@ -182,11 +187,19 @@ public class CloudRecordItem { |
| 182 | 187 | this.timeLen = timeLen; |
| 183 | 188 | } |
| 184 | 189 | |
| 185 | - public String getCollectType() { | |
| 186 | - return collectType; | |
| 190 | + public Boolean getCollect() { | |
| 191 | + return collect; | |
| 192 | + } | |
| 193 | + | |
| 194 | + public void setCollect(Boolean collect) { | |
| 195 | + this.collect = collect; | |
| 196 | + } | |
| 197 | + | |
| 198 | + public Boolean getReserve() { | |
| 199 | + return reserve; | |
| 187 | 200 | } |
| 188 | 201 | |
| 189 | - public void setCollectType(String collectType) { | |
| 190 | - this.collectType = collectType; | |
| 202 | + public void setReserve(Boolean reserve) { | |
| 203 | + this.reserve = reserve; | |
| 191 | 204 | } |
| 192 | 205 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java
| ... | ... | @@ -3,8 +3,6 @@ package com.genersoft.iot.vmp.service.impl; |
| 3 | 3 | import com.alibaba.fastjson2.JSONArray; |
| 4 | 4 | import com.alibaba.fastjson2.JSONObject; |
| 5 | 5 | import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| 6 | -import com.genersoft.iot.vmp.gb28181.bean.GbStream; | |
| 7 | -import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; | |
| 8 | 6 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 9 | 7 | import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils; |
| 10 | 8 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| ... | ... | @@ -19,14 +17,13 @@ import com.genersoft.iot.vmp.utils.DateUtil; |
| 19 | 17 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| 20 | 18 | import com.github.pagehelper.PageHelper; |
| 21 | 19 | import com.github.pagehelper.PageInfo; |
| 20 | +import org.apache.commons.lang3.ObjectUtils; | |
| 22 | 21 | import org.slf4j.Logger; |
| 23 | 22 | import org.slf4j.LoggerFactory; |
| 24 | 23 | import org.springframework.beans.factory.annotation.Autowired; |
| 25 | 24 | import org.springframework.stereotype.Service; |
| 26 | -import org.springframework.util.unit.DataUnit; | |
| 27 | 25 | |
| 28 | 26 | import java.time.*; |
| 29 | -import java.time.temporal.TemporalAccessor; | |
| 30 | 27 | import java.util.*; |
| 31 | 28 | |
| 32 | 29 | @Service |
| ... | ... | @@ -167,4 +164,73 @@ public class CloudRecordServiceImpl implements ICloudRecordService { |
| 167 | 164 | } |
| 168 | 165 | return result.getJSONArray("data"); |
| 169 | 166 | } |
| 167 | + | |
| 168 | + @Override | |
| 169 | + public void changeCollect(String type, boolean result, String app, String stream, String mediaServerId, String startTime, String endTime, String callId, String collectType) { | |
| 170 | + // 开始时间和结束时间在数据库中都是以秒为单位的 | |
| 171 | + Long startTimeStamp = null; | |
| 172 | + Long endTimeStamp = null; | |
| 173 | + if (startTime != null ) { | |
| 174 | + if (!DateUtil.verification(startTime, DateUtil.formatter)) { | |
| 175 | + throw new ControllerException(ErrorCode.ERROR100.getCode(), "开始时间格式错误,正确格式为: " + DateUtil.formatter); | |
| 176 | + } | |
| 177 | + startTimeStamp = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime); | |
| 178 | + | |
| 179 | + } | |
| 180 | + if (endTime != null ) { | |
| 181 | + if (!DateUtil.verification(endTime, DateUtil.formatter)) { | |
| 182 | + throw new ControllerException(ErrorCode.ERROR100.getCode(), "结束时间格式错误,正确格式为: " + DateUtil.formatter); | |
| 183 | + } | |
| 184 | + endTimeStamp = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime); | |
| 185 | + | |
| 186 | + } | |
| 187 | + | |
| 188 | + List<MediaServerItem> mediaServerItems; | |
| 189 | + if (!ObjectUtils.isEmpty(mediaServerId)) { | |
| 190 | + mediaServerItems = new ArrayList<>(); | |
| 191 | + MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); | |
| 192 | + if (mediaServerItem == null) { | |
| 193 | + throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到流媒体: " + mediaServerId); | |
| 194 | + } | |
| 195 | + mediaServerItems.add(mediaServerItem); | |
| 196 | + } else { | |
| 197 | + mediaServerItems = null; | |
| 198 | + } | |
| 199 | + | |
| 200 | + List<CloudRecordItem> all = cloudRecordServiceMapper.getList(null, app, stream, startTimeStamp, endTimeStamp, | |
| 201 | + callId, mediaServerItems); | |
| 202 | + if (all.isEmpty()) { | |
| 203 | + throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到待收藏的视频"); | |
| 204 | + } | |
| 205 | + int limitCount = 50; | |
| 206 | + if (all.size() > limitCount) { | |
| 207 | + for (int i = 0; i < all.size(); i += limitCount) { | |
| 208 | + int toIndex = i + limitCount; | |
| 209 | + if (i + limitCount > all.size()) { | |
| 210 | + toIndex = all.size(); | |
| 211 | + } | |
| 212 | + if ("collect".equals(collectType)) { | |
| 213 | + cloudRecordServiceMapper.updateCollectList(result, all.subList(i, toIndex)); | |
| 214 | + }else if ("reserve".equals(collectType)) { | |
| 215 | + cloudRecordServiceMapper.updateReserveList(result, all.subList(i, toIndex)); | |
| 216 | + } | |
| 217 | + | |
| 218 | + } | |
| 219 | + }else { | |
| 220 | + if ("collect".equals(collectType)) { | |
| 221 | + cloudRecordServiceMapper.updateCollectList(result, all); | |
| 222 | + }else if ("reserve".equals(collectType)) { | |
| 223 | + cloudRecordServiceMapper.updateReserveList(result, all); | |
| 224 | + } | |
| 225 | + } | |
| 226 | + } | |
| 227 | + | |
| 228 | + @Override | |
| 229 | + public void changeCollectById(Integer recordId, String collectType, boolean result) { | |
| 230 | + if ("collect".equals(collectType)) { | |
| 231 | + cloudRecordServiceMapper.changeCollectById(result, recordId); | |
| 232 | + }else if ("reserve".equals(collectType)) { | |
| 233 | + cloudRecordServiceMapper.changeReserveById(result, recordId); | |
| 234 | + } | |
| 235 | + } | |
| 170 | 236 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
| ... | ... | @@ -752,4 +752,9 @@ public class MediaServerServiceImpl implements IMediaServerService { |
| 752 | 752 | result.setGbSend(redisCatchStorage.getGbSendCount(mediaServerItem.getId())); |
| 753 | 753 | return result; |
| 754 | 754 | } |
| 755 | + | |
| 756 | + @Override | |
| 757 | + public List<MediaServerItem> getAllWithAssistPort() { | |
| 758 | + return mediaServerMapper.queryAllWithAssistPort(); | |
| 759 | + } | |
| 755 | 760 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java
| ... | ... | @@ -2,10 +2,7 @@ package com.genersoft.iot.vmp.storager.dao; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 4 | 4 | import com.genersoft.iot.vmp.service.bean.CloudRecordItem; |
| 5 | -import org.apache.ibatis.annotations.Insert; | |
| 6 | -import org.apache.ibatis.annotations.Mapper; | |
| 7 | -import org.apache.ibatis.annotations.Param; | |
| 8 | -import org.apache.ibatis.annotations.Select; | |
| 5 | +import org.apache.ibatis.annotations.*; | |
| 9 | 6 | |
| 10 | 7 | import java.util.List; |
| 11 | 8 | |
| ... | ... | @@ -78,4 +75,42 @@ public interface CloudRecordServiceMapper { |
| 78 | 75 | @Param("startTimeStamp")Long startTimeStamp, @Param("endTimeStamp")Long endTimeStamp, |
| 79 | 76 | @Param("callId")String callId, List<MediaServerItem> mediaServerItemList); |
| 80 | 77 | |
| 78 | + @Update(" <script>" + | |
| 79 | + "update wvp_cloud_record set collect = #{collect} where file_path in " + | |
| 80 | + " <foreach collection='cloudRecordItemList' item='item' open='(' separator=',' close=')' > #{item.filePath}</foreach>" + | |
| 81 | + " </script>") | |
| 82 | + void updateCollectList(@Param("collect") boolean collect, List<CloudRecordItem> cloudRecordItemList); | |
| 83 | + | |
| 84 | + @Delete(" <script>" + | |
| 85 | + "delete from wvp_cloud_record where media_server_id=#{mediaServerId} file_path in " + | |
| 86 | + " <foreach collection='filePathList' item='item' open='(' separator=',' close=')' > #{item}</foreach>" + | |
| 87 | + " </script>") | |
| 88 | + void deleteByFileList(List<String> filePathList, @Param("mediaServerId") String mediaServerId); | |
| 89 | + | |
| 90 | + | |
| 91 | + @Select(" <script>" + | |
| 92 | + "select file_path" + | |
| 93 | + " from wvp_cloud_record " + | |
| 94 | + " where collect = false and reserve = false " + | |
| 95 | + " <if test= 'endTimeStamp != null '> and start_time <= #{endTimeStamp}</if>" + | |
| 96 | + " <if test= 'callId != null '> and call_id = #{callId}</if>" + | |
| 97 | + " <if test= 'mediaServerId != null ' > and media_server_id = #{mediaServerId} </if>" + | |
| 98 | + " </script>") | |
| 99 | + List<String> queryRecordFilePathListForDelete(@Param("endTimeStamp")Long endTimeStamp, String mediaServerId); | |
| 100 | + | |
| 101 | + @Update(" <script>" + | |
| 102 | + "update wvp_cloud_record set reserve = #{reserve} where file_path in " + | |
| 103 | + " <foreach collection='cloudRecordItems' item='item' open='(' separator=',' close=')' > #{item.filePath}</foreach>" + | |
| 104 | + " </script>") | |
| 105 | + void updateReserveList(@Param("reserve") boolean reserve,List<CloudRecordItem> cloudRecordItems); | |
| 106 | + | |
| 107 | + @Update(" <script>" + | |
| 108 | + "update wvp_cloud_record set collect = #{collect} where id = #{recordId} " + | |
| 109 | + " </script>") | |
| 110 | + void changeCollectById(@Param("collect") boolean collect, @Param("recordId") Integer recordId); | |
| 111 | + | |
| 112 | + @Update(" <script>" + | |
| 113 | + "update wvp_cloud_record set reserve = #{reserve} where id = #{recordId} " + | |
| 114 | + " </script>") | |
| 115 | + void changeReserveById(@Param("reserve") boolean reserve, Integer recordId); | |
| 81 | 116 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java
| ... | ... | @@ -130,4 +130,8 @@ public interface MediaServerMapper { |
| 130 | 130 | |
| 131 | 131 | @Select("SELECT * FROM wvp_media_server WHERE default_server=true") |
| 132 | 132 | MediaServerItem queryDefault(); |
| 133 | + | |
| 134 | + @Select("SELECT * FROM wvp_media_server WHERE record_assist_port > 0") | |
| 135 | + List<MediaServerItem> queryAllWithAssistPort(); | |
| 136 | + | |
| 133 | 137 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java
| 1 | 1 | package com.genersoft.iot.vmp.vmanager.cloudRecord; |
| 2 | 2 | |
| 3 | 3 | import com.alibaba.fastjson2.JSONArray; |
| 4 | -import com.alibaba.fastjson2.JSONObject; | |
| 5 | 4 | import com.genersoft.iot.vmp.conf.DynamicTask; |
| 6 | 5 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 7 | 6 | import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| 8 | 7 | import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; |
| 9 | 8 | import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; |
| 10 | -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; | |
| 11 | 9 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 12 | 10 | import com.genersoft.iot.vmp.service.ICloudRecordService; |
| 13 | 11 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 14 | 12 | import com.genersoft.iot.vmp.service.bean.CloudRecordItem; |
| 15 | 13 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| 16 | -import com.genersoft.iot.vmp.vmanager.bean.RecordFile; | |
| 17 | 14 | import com.github.pagehelper.PageInfo; |
| 18 | 15 | import io.swagger.v3.oas.annotations.Operation; |
| 19 | 16 | import io.swagger.v3.oas.annotations.Parameter; |
| ... | ... | @@ -36,11 +33,6 @@ import java.util.List; |
| 36 | 33 | @RequestMapping("/api/cloud/record") |
| 37 | 34 | public class CloudRecordController { |
| 38 | 35 | |
| 39 | - @Autowired | |
| 40 | - private ZLMServerFactory zlmServerFactory; | |
| 41 | - | |
| 42 | - @Autowired | |
| 43 | - private SendRtpPortManager sendRtpPortManager; | |
| 44 | 36 | |
| 45 | 37 | private final static Logger logger = LoggerFactory.getLogger(CloudRecordController.class); |
| 46 | 38 | |
| ... | ... | @@ -50,14 +42,6 @@ public class CloudRecordController { |
| 50 | 42 | @Autowired |
| 51 | 43 | private IMediaServerService mediaServerService; |
| 52 | 44 | |
| 53 | - @Autowired | |
| 54 | - private UserSetting userSetting; | |
| 55 | - | |
| 56 | - @Autowired | |
| 57 | - private DynamicTask dynamicTask; | |
| 58 | - | |
| 59 | - @Autowired | |
| 60 | - private RedisTemplate<Object, Object> redisTemplate; | |
| 61 | 45 | |
| 62 | 46 | @ResponseBody |
| 63 | 47 | @GetMapping("/date/list") |
| ... | ... | @@ -68,8 +52,8 @@ public class CloudRecordController { |
| 68 | 52 | @Parameter(name = "month", description = "月,置空则查询当月", required = false) |
| 69 | 53 | @Parameter(name = "mediaServerId", description = "流媒体ID,置空则查询全部", required = false) |
| 70 | 54 | public List<String> openRtpServer( |
| 71 | - @RequestParam String app, | |
| 72 | - @RequestParam String stream, | |
| 55 | + @RequestParam(required = true) String app, | |
| 56 | + @RequestParam(required = true) String stream, | |
| 73 | 57 | @RequestParam(required = false) int year, |
| 74 | 58 | @RequestParam(required = false) int month, |
| 75 | 59 | @RequestParam(required = false) String mediaServerId |
| ... | ... | @@ -108,8 +92,8 @@ public class CloudRecordController { |
| 108 | 92 | @Parameter(name = "query", description = "检索内容", required = false) |
| 109 | 93 | @Parameter(name = "app", description = "应用名", required = false) |
| 110 | 94 | @Parameter(name = "stream", description = "流ID", required = false) |
| 111 | - @Parameter(name = "page", description = "当前页", required = false) | |
| 112 | - @Parameter(name = "count", description = "每页查询数量", required = false) | |
| 95 | + @Parameter(name = "page", description = "当前页", required = true) | |
| 96 | + @Parameter(name = "count", description = "每页查询数量", required = true) | |
| 113 | 97 | @Parameter(name = "startTime", description = "开始时间(yyyy-MM-dd HH:mm:ss)", required = false) |
| 114 | 98 | @Parameter(name = "endTime", description = "结束时间(yyyy-MM-dd HH:mm:ss)", required = false) |
| 115 | 99 | @Parameter(name = "mediaServerId", description = "流媒体ID,置空则查询全部流媒体", required = false) |
| ... | ... | @@ -162,16 +146,16 @@ public class CloudRecordController { |
| 162 | 146 | @ResponseBody |
| 163 | 147 | @GetMapping("/task/add") |
| 164 | 148 | @Operation(summary = "添加合并任务") |
| 165 | - @Parameter(name = "app", description = "应用名", required = true) | |
| 166 | - @Parameter(name = "stream", description = "流ID", required = true) | |
| 149 | + @Parameter(name = "app", description = "应用名", required = false) | |
| 150 | + @Parameter(name = "stream", description = "流ID", required = false) | |
| 167 | 151 | @Parameter(name = "mediaServerId", description = "流媒体ID", required = false) |
| 168 | 152 | @Parameter(name = "startTime", description = "鉴权ID", required = false) |
| 169 | 153 | @Parameter(name = "endTime", description = "鉴权ID", required = false) |
| 170 | 154 | @Parameter(name = "callId", description = "鉴权ID", required = false) |
| 171 | 155 | @Parameter(name = "remoteHost", description = "返回地址时的远程地址", required = false) |
| 172 | 156 | public String addTask( |
| 173 | - @RequestParam(required = true) String app, | |
| 174 | - @RequestParam(required = true) String stream, | |
| 157 | + @RequestParam(required = false) String app, | |
| 158 | + @RequestParam(required = false) String stream, | |
| 175 | 159 | @RequestParam(required = false) String mediaServerId, |
| 176 | 160 | @RequestParam(required = false) String startTime, |
| 177 | 161 | @RequestParam(required = false) String endTime, |
| ... | ... | @@ -198,19 +182,61 @@ public class CloudRecordController { |
| 198 | 182 | @ResponseBody |
| 199 | 183 | @GetMapping("/collect/add") |
| 200 | 184 | @Operation(summary = "添加收藏") |
| 201 | - @Parameter(name = "app", description = "应用名", required = true) | |
| 202 | - @Parameter(name = "stream", description = "流ID", required = true) | |
| 185 | + @Parameter(name = "app", description = "应用名", required = false) | |
| 186 | + @Parameter(name = "stream", description = "流ID", required = false) | |
| 203 | 187 | @Parameter(name = "mediaServerId", description = "流媒体ID", required = false) |
| 204 | 188 | @Parameter(name = "startTime", description = "鉴权ID", required = false) |
| 205 | 189 | @Parameter(name = "endTime", description = "鉴权ID", required = false) |
| 206 | 190 | @Parameter(name = "callId", description = "鉴权ID", required = false) |
| 207 | - @Parameter(name = "collectType", description = "收藏类型", required = false) | |
| 208 | - public JSONArray addCollect( | |
| 209 | - @RequestParam(required = false) String taskId, | |
| 191 | + @Parameter(name = "collectType", description = "收藏类型, collect/reserve", required = false) | |
| 192 | + public void addCollect( | |
| 193 | + @RequestParam(required = false) String app, | |
| 194 | + @RequestParam(required = false) String stream, | |
| 210 | 195 | @RequestParam(required = false) String mediaServerId, |
| 211 | - @RequestParam(required = false) Boolean isEnd | |
| 196 | + @RequestParam(required = false) String startTime, | |
| 197 | + @RequestParam(required = false) String endTime, | |
| 198 | + @RequestParam(required = false) String callId, | |
| 199 | + @RequestParam(required = false) String collectType, | |
| 200 | + @RequestParam(required = false) Integer recordId | |
| 212 | 201 | ){ |
| 213 | - return cloudRecordService.queryTask(taskId, mediaServerId, isEnd); | |
| 202 | + if (!"collect".equals(collectType) && !"reserve".equals(collectType)) { | |
| 203 | + collectType = "collect"; | |
| 204 | + } | |
| 205 | + if (recordId != null) { | |
| 206 | + cloudRecordService.changeCollectById(recordId, collectType, true); | |
| 207 | + }else { | |
| 208 | + cloudRecordService.changeCollect(collectType, true, app, stream, mediaServerId, startTime, endTime, callId, collectType); | |
| 209 | + } | |
| 210 | + } | |
| 211 | + | |
| 212 | + @ResponseBody | |
| 213 | + @GetMapping("/collect/delete") | |
| 214 | + @Operation(summary = "移除收藏") | |
| 215 | + @Parameter(name = "app", description = "应用名", required = false) | |
| 216 | + @Parameter(name = "stream", description = "流ID", required = false) | |
| 217 | + @Parameter(name = "mediaServerId", description = "流媒体ID", required = false) | |
| 218 | + @Parameter(name = "startTime", description = "鉴权ID", required = false) | |
| 219 | + @Parameter(name = "endTime", description = "鉴权ID", required = false) | |
| 220 | + @Parameter(name = "callId", description = "鉴权ID", required = false) | |
| 221 | + @Parameter(name = "collectType", description = "收藏类型, collect/reserve", required = false) | |
| 222 | + public void deleteCollect( | |
| 223 | + @RequestParam(required = false) String app, | |
| 224 | + @RequestParam(required = false) String stream, | |
| 225 | + @RequestParam(required = false) String mediaServerId, | |
| 226 | + @RequestParam(required = false) String startTime, | |
| 227 | + @RequestParam(required = false) String endTime, | |
| 228 | + @RequestParam(required = false) String callId, | |
| 229 | + @RequestParam(required = false) String collectType, | |
| 230 | + @RequestParam(required = false) Integer recordId | |
| 231 | + ){ | |
| 232 | + if (!"collect".equals(collectType) && !"reserve".equals(collectType)) { | |
| 233 | + collectType = "collect"; | |
| 234 | + } | |
| 235 | + if (recordId != null) { | |
| 236 | + cloudRecordService.changeCollectById(recordId, collectType, false); | |
| 237 | + }else { | |
| 238 | + cloudRecordService.changeCollect(collectType, false, app, stream, mediaServerId, startTime, endTime, callId, collectType); | |
| 239 | + } | |
| 214 | 240 | } |
| 215 | 241 | |
| 216 | 242 | ... | ... |