Commit b7b35d9bad6b163c22ad57dbbd92255f358e2086
1 parent
3c59c549
添加录像巡查 超过保存时间的录像文件进行移除
Showing
5 changed files
with
161 additions
and
35 deletions
src/main/java/top/panll/assist/config/TaskConfig.java
| @@ -31,13 +31,13 @@ public class TaskConfig { | @@ -31,13 +31,13 @@ public class TaskConfig { | ||
| 31 | @Scheduled(cron = "0 0 0 * * ?") | 31 | @Scheduled(cron = "0 0 0 * * ?") |
| 32 | private void configureTasks() { | 32 | private void configureTasks() { |
| 33 | logger.info("录像过期自检任务执行"); | 33 | logger.info("录像过期自检任务执行"); |
| 34 | - List<File> appList = videoFileService.getAppList(); | 34 | + List<File> appList = videoFileService.getAppList(false); |
| 35 | Calendar calendar = Calendar.getInstance(); | 35 | Calendar calendar = Calendar.getInstance(); |
| 36 | calendar.add(Calendar.DATE, - 7); | 36 | calendar.add(Calendar.DATE, - 7); |
| 37 | Date monday = calendar.getTime(); | 37 | Date monday = calendar.getTime(); |
| 38 | if (appList != null && appList.size() > 0) { | 38 | if (appList != null && appList.size() > 0) { |
| 39 | for (File appFile : appList) { | 39 | for (File appFile : appList) { |
| 40 | - List<File> streamList = videoFileService.getStreamList(appFile.getName()); | 40 | + List<File> streamList = videoFileService.getStreamList(appFile.getName(), false); |
| 41 | if (streamList != null && streamList.size() > 0) { | 41 | if (streamList != null && streamList.size() > 0) { |
| 42 | for (File streamFile : streamList) { | 42 | for (File streamFile : streamList) { |
| 43 | File[] recordDateFileList = streamFile.listFiles(); | 43 | File[] recordDateFileList = streamFile.listFiles(); |
src/main/java/top/panll/assist/controller/RecordController.java
| @@ -79,9 +79,11 @@ public class RecordController { | @@ -79,9 +79,11 @@ public class RecordController { | ||
| 79 | @RequestParam int count){ | 79 | @RequestParam int count){ |
| 80 | WVPResult<PageInfo<String>> result = new WVPResult<>(); | 80 | WVPResult<PageInfo<String>> result = new WVPResult<>(); |
| 81 | List<String> resultData = new ArrayList<>(); | 81 | List<String> resultData = new ArrayList<>(); |
| 82 | - List<File> appList = videoFileService.getAppList(); | ||
| 83 | - for (File file : appList) { | ||
| 84 | - resultData.add(file.getName()); | 82 | + List<File> appList = videoFileService.getAppList(true); |
| 83 | + if (appList != null) { | ||
| 84 | + for (File file : appList) { | ||
| 85 | + resultData.add(file.getName()); | ||
| 86 | + } | ||
| 85 | } | 87 | } |
| 86 | result.setCode(0); | 88 | result.setCode(0); |
| 87 | result.setMsg("success"); | 89 | result.setMsg("success"); |
| @@ -114,9 +116,11 @@ public class RecordController { | @@ -114,9 +116,11 @@ public class RecordController { | ||
| 114 | result.setMsg("app不能为空"); | 116 | result.setMsg("app不能为空"); |
| 115 | return result; | 117 | return result; |
| 116 | } | 118 | } |
| 117 | - List<File> streamList = videoFileService.getStreamList(app); | ||
| 118 | - for (File file : streamList) { | ||
| 119 | - resultData.add(file.getName()); | 119 | + List<File> streamList = videoFileService.getStreamList(app, true); |
| 120 | + if (streamList != null) { | ||
| 121 | + for (File file : streamList) { | ||
| 122 | + resultData.add(file.getName()); | ||
| 123 | + } | ||
| 120 | } | 124 | } |
| 121 | result.setCode(0); | 125 | result.setCode(0); |
| 122 | result.setMsg("success"); | 126 | result.setMsg("success"); |
| @@ -155,7 +159,7 @@ public class RecordController { | @@ -155,7 +159,7 @@ public class RecordController { | ||
| 155 | result.setMsg("stream不能为空"); | 159 | result.setMsg("stream不能为空"); |
| 156 | return result; | 160 | return result; |
| 157 | } | 161 | } |
| 158 | - List<File> dateList = videoFileService.getDateList(app, stream, year, month); | 162 | + List<File> dateList = videoFileService.getDateList(app, stream, year, month, true); |
| 159 | for (File file : dateList) { | 163 | for (File file : dateList) { |
| 160 | resultData.add(file.getName()); | 164 | resultData.add(file.getName()); |
| 161 | } | 165 | } |
src/main/java/top/panll/assist/service/FFmpegExecUtils.java
| @@ -52,8 +52,16 @@ public class FFmpegExecUtils implements InitializingBean{ | @@ -52,8 +52,16 @@ public class FFmpegExecUtils implements InitializingBean{ | ||
| 52 | @Autowired | 52 | @Autowired |
| 53 | private RedisUtil redisUtil; | 53 | private RedisUtil redisUtil; |
| 54 | 54 | ||
| 55 | - public FFprobe ffprobe; | ||
| 56 | - public FFmpeg ffmpeg; | 55 | + private FFprobe ffprobe; |
| 56 | + private FFmpeg ffmpeg; | ||
| 57 | + | ||
| 58 | + public FFprobe getFfprobe() { | ||
| 59 | + return ffprobe; | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + public FFmpeg getFfmpeg() { | ||
| 63 | + return ffmpeg; | ||
| 64 | + } | ||
| 57 | 65 | ||
| 58 | @Override | 66 | @Override |
| 59 | public void afterPropertiesSet() throws Exception { | 67 | public void afterPropertiesSet() throws Exception { |
src/main/java/top/panll/assist/service/FileManagerTimer.java
0 → 100644
| 1 | +package top.panll.assist.service; | ||
| 2 | + | ||
| 3 | +import org.apache.commons.io.FileUtils; | ||
| 4 | +import org.slf4j.Logger; | ||
| 5 | +import org.slf4j.LoggerFactory; | ||
| 6 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 7 | +import org.springframework.scheduling.annotation.Scheduled; | ||
| 8 | +import org.springframework.stereotype.Component; | ||
| 9 | +import top.panll.assist.dto.UserSettings; | ||
| 10 | + | ||
| 11 | +import java.io.File; | ||
| 12 | +import java.text.ParseException; | ||
| 13 | +import java.text.SimpleDateFormat; | ||
| 14 | +import java.util.Calendar; | ||
| 15 | +import java.util.Date; | ||
| 16 | +import java.util.List; | ||
| 17 | + | ||
| 18 | +@Component | ||
| 19 | +public class FileManagerTimer { | ||
| 20 | + | ||
| 21 | + private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); | ||
| 22 | + | ||
| 23 | + private final static Logger logger = LoggerFactory.getLogger(FileManagerTimer.class); | ||
| 24 | + | ||
| 25 | + @Autowired | ||
| 26 | + private UserSettings userSettings; | ||
| 27 | + | ||
| 28 | + @Autowired | ||
| 29 | + private VideoFileService videoFileService; | ||
| 30 | + | ||
| 31 | +// @Scheduled(fixedDelay = 20000) //测试 20秒执行一次 | ||
| 32 | + @Scheduled(cron = "0 0 0 * * ?") //每天的0点执行 | ||
| 33 | + public void execute(){ | ||
| 34 | + int recordDay = userSettings.getRecordDay(); | ||
| 35 | + Date date=new Date(); | ||
| 36 | + Calendar calendar = Calendar.getInstance(); | ||
| 37 | + calendar.setTime(date); | ||
| 38 | + calendar.add(Calendar.DAY_OF_MONTH, 0 - recordDay); | ||
| 39 | + date = calendar.getTime(); | ||
| 40 | + logger.info("[录像巡查]移除 {} 之前的文件", formatter.format(date)); | ||
| 41 | + File recordFileDir = new File(userSettings.getRecord()); | ||
| 42 | + if (recordFileDir.canWrite()) { | ||
| 43 | + List<File> appList = videoFileService.getAppList(false); | ||
| 44 | + if (appList != null && appList.size() > 0) { | ||
| 45 | + for (File appFile : appList) { | ||
| 46 | + if ("download.html".equals(appFile.getName())) { | ||
| 47 | + continue; | ||
| 48 | + } | ||
| 49 | + List<File> streamList = videoFileService.getStreamList(appFile, false); | ||
| 50 | + if (streamList != null && streamList.size() > 0) { | ||
| 51 | + for (File streamFile : streamList) { | ||
| 52 | + List<File> dateList = videoFileService.getDateList(streamFile, null, null, false); | ||
| 53 | + if (dateList != null && dateList.size() > 0) { | ||
| 54 | + for (File dateFile : dateList) { | ||
| 55 | + try { | ||
| 56 | + Date parse = formatter.parse(dateFile.getName()); | ||
| 57 | + if (parse.before(date)) { | ||
| 58 | + boolean result = FileUtils.deleteQuietly(dateFile); | ||
| 59 | + if (result) { | ||
| 60 | + logger.info("[录像巡查]成功移除 {} ", dateFile.getAbsolutePath()); | ||
| 61 | + }else { | ||
| 62 | + logger.info("[录像巡查]移除失败 {} ", dateFile.getAbsolutePath()); | ||
| 63 | + } | ||
| 64 | + } | ||
| 65 | + } catch (ParseException e) { | ||
| 66 | + e.printStackTrace(); | ||
| 67 | + } | ||
| 68 | + } | ||
| 69 | + } | ||
| 70 | + if (streamFile.listFiles() == null && streamFile.listFiles().length == 0) { | ||
| 71 | + boolean result = FileUtils.deleteQuietly(streamFile); | ||
| 72 | + if (result) { | ||
| 73 | + logger.info("[录像巡查]成功移除 {} ", streamFile.getAbsolutePath()); | ||
| 74 | + }else { | ||
| 75 | + logger.info("[录像巡查]移除失败 {} ", streamFile.getAbsolutePath()); | ||
| 76 | + } | ||
| 77 | + } | ||
| 78 | + } | ||
| 79 | + } | ||
| 80 | + if (appFile.listFiles() == null || appFile.listFiles().length == 0) { | ||
| 81 | + boolean result = FileUtils.deleteQuietly(appFile); | ||
| 82 | + if (result) { | ||
| 83 | + logger.info("[录像巡查]成功移除 {} ", appFile.getAbsolutePath()); | ||
| 84 | + }else { | ||
| 85 | + logger.info("[录像巡查]移除失败 {} ", appFile.getAbsolutePath()); | ||
| 86 | + } | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + } | ||
| 90 | + } | ||
| 91 | + } | ||
| 92 | + } | ||
| 93 | +} |
src/main/java/top/panll/assist/service/VideoFileService.java
| @@ -40,7 +40,7 @@ public class VideoFileService { | @@ -40,7 +40,7 @@ public class VideoFileService { | ||
| 40 | private RedisTemplate redisTemplate; | 40 | private RedisTemplate redisTemplate; |
| 41 | 41 | ||
| 42 | @Autowired | 42 | @Autowired |
| 43 | - private FFmpegExecUtils fFmpegExecUtils; | 43 | + private FFmpegExecUtils ffmpegExecUtils; |
| 44 | 44 | ||
| 45 | 45 | ||
| 46 | 46 | ||
| @@ -49,12 +49,14 @@ public class VideoFileService { | @@ -49,12 +49,14 @@ public class VideoFileService { | ||
| 49 | 49 | ||
| 50 | private final String keyStr = "MERGEORCUT"; | 50 | private final String keyStr = "MERGEORCUT"; |
| 51 | 51 | ||
| 52 | - public List<File> getAppList() { | 52 | + public List<File> getAppList(Boolean sort) { |
| 53 | File recordFile = new File(userSettings.getRecord()); | 53 | File recordFile = new File(userSettings.getRecord()); |
| 54 | - if (recordFile != null) { | 54 | + if (recordFile != null && recordFile.isDirectory()) { |
| 55 | File[] files = recordFile.listFiles(); | 55 | File[] files = recordFile.listFiles(); |
| 56 | List<File> result = Arrays.asList(files); | 56 | List<File> result = Arrays.asList(files); |
| 57 | - Collections.sort(result); | 57 | + if (sort != null && sort) { |
| 58 | + Collections.sort(result); | ||
| 59 | + } | ||
| 58 | return result; | 60 | return result; |
| 59 | }else { | 61 | }else { |
| 60 | return null; | 62 | return null; |
| @@ -98,12 +100,18 @@ public class VideoFileService { | @@ -98,12 +100,18 @@ public class VideoFileService { | ||
| 98 | // } | 100 | // } |
| 99 | // } | 101 | // } |
| 100 | 102 | ||
| 101 | - public List<File> getStreamList(String app) { | 103 | + public List<File> getStreamList(String app, Boolean sort) { |
| 102 | File appFile = new File(userSettings.getRecord() + File.separator + app); | 104 | File appFile = new File(userSettings.getRecord() + File.separator + app); |
| 103 | - if (appFile != null) { | 105 | + return getStreamList(appFile, sort); |
| 106 | + } | ||
| 107 | + | ||
| 108 | + public List<File> getStreamList(File appFile, Boolean sort) { | ||
| 109 | + if (appFile != null && appFile.isDirectory()) { | ||
| 104 | File[] files = appFile.listFiles(); | 110 | File[] files = appFile.listFiles(); |
| 105 | List<File> result = Arrays.asList(files); | 111 | List<File> result = Arrays.asList(files); |
| 106 | - Collections.sort(result); | 112 | + if (sort != null && sort) { |
| 113 | + Collections.sort(result); | ||
| 114 | + } | ||
| 107 | return result; | 115 | return result; |
| 108 | }else { | 116 | }else { |
| 109 | return null; | 117 | return null; |
| @@ -116,7 +124,7 @@ public class VideoFileService { | @@ -116,7 +124,7 @@ public class VideoFileService { | ||
| 116 | * @throws ParseException | 124 | * @throws ParseException |
| 117 | */ | 125 | */ |
| 118 | public void handFile(File file) { | 126 | public void handFile(File file) { |
| 119 | - FFprobe ffprobe = fFmpegExecUtils.ffprobe; | 127 | + FFprobe ffprobe = ffmpegExecUtils.getFfprobe(); |
| 120 | if(file.exists() && file.isFile() && !file.getName().startsWith(".")&& file.getName().endsWith(".mp4") && file.getName().indexOf(":") < 0) { | 128 | if(file.exists() && file.isFile() && !file.getName().startsWith(".")&& file.getName().endsWith(".mp4") && file.getName().indexOf(":") < 0) { |
| 121 | try { | 129 | try { |
| 122 | FFmpegProbeResult in = null; | 130 | FFmpegProbeResult in = null; |
| @@ -137,7 +145,7 @@ public class VideoFileService { | @@ -137,7 +145,7 @@ public class VideoFileService { | ||
| 137 | String newName = file.getAbsolutePath().replace(file.getName(), | 145 | String newName = file.getAbsolutePath().replace(file.getName(), |
| 138 | simpleDateFormat.format(startTime) + "-" + simpleDateFormat.format(endTime) + "-" + durationLong + ".mp4"); | 146 | simpleDateFormat.format(startTime) + "-" + simpleDateFormat.format(endTime) + "-" + durationLong + ".mp4"); |
| 139 | file.renameTo(new File(newName)); | 147 | file.renameTo(new File(newName)); |
| 140 | - System.out.println(newName); | 148 | + logger.debug("[处理文件] {}", file.getName()); |
| 141 | } catch (IOException e) { | 149 | } catch (IOException e) { |
| 142 | logger.warn("文件可能以损坏[{}]", file.getAbsolutePath()); | 150 | logger.warn("文件可能以损坏[{}]", file.getAbsolutePath()); |
| 143 | // e.printStackTrace(); | 151 | // e.printStackTrace(); |
| @@ -151,11 +159,11 @@ public class VideoFileService { | @@ -151,11 +159,11 @@ public class VideoFileService { | ||
| 151 | 159 | ||
| 152 | List<Map<String, String>> result = new ArrayList<>(); | 160 | List<Map<String, String>> result = new ArrayList<>(); |
| 153 | 161 | ||
| 154 | - List<File> appList = getAppList(); | 162 | + List<File> appList = getAppList(true); |
| 155 | if (appList != null && appList.size() > 0) { | 163 | if (appList != null && appList.size() > 0) { |
| 156 | for (File appFile : appList) { | 164 | for (File appFile : appList) { |
| 157 | if (appFile.isDirectory()) { | 165 | if (appFile.isDirectory()) { |
| 158 | - List<File> streamList = getStreamList(appFile.getName()); | 166 | + List<File> streamList = getStreamList(appFile.getName(), true); |
| 159 | if (streamList != null && streamList.size() > 0) { | 167 | if (streamList != null && streamList.size() > 0) { |
| 160 | for (File streamFile : streamList) { | 168 | for (File streamFile : streamList) { |
| 161 | Map<String, String> data = new HashMap<>(); | 169 | Map<String, String> data = new HashMap<>(); |
| @@ -340,7 +348,7 @@ public class VideoFileService { | @@ -340,7 +348,7 @@ public class VideoFileService { | ||
| 340 | mergeOrCutTaskInfo.setEndTime(endTimeInFile); | 348 | mergeOrCutTaskInfo.setEndTime(endTimeInFile); |
| 341 | } | 349 | } |
| 342 | 350 | ||
| 343 | - fFmpegExecUtils.mergeOrCutFile(filesInTime, recordFile, stream, (status, percentage, result)->{ | 351 | + ffmpegExecUtils.mergeOrCutFile(filesInTime, recordFile, stream, (status, percentage, result)->{ |
| 344 | // 发出redis通知 | 352 | // 发出redis通知 |
| 345 | if (status.equals(Progress.Status.END.name())) { | 353 | if (status.equals(Progress.Status.END.name())) { |
| 346 | mergeOrCutTaskInfo.setPercentage("1"); | 354 | mergeOrCutTaskInfo.setPercentage("1"); |
| @@ -363,11 +371,22 @@ public class VideoFileService { | @@ -363,11 +371,22 @@ public class VideoFileService { | ||
| 363 | return taskId; | 371 | return taskId; |
| 364 | } | 372 | } |
| 365 | 373 | ||
| 366 | - public List<File> getDateList(String app, String stream, Integer year, Integer month) { | 374 | + /** |
| 375 | + * 获取指定时间的日期文件夹 | ||
| 376 | + * @param app | ||
| 377 | + * @param stream | ||
| 378 | + * @param year | ||
| 379 | + * @param month | ||
| 380 | + * @return | ||
| 381 | + */ | ||
| 382 | + public List<File> getDateList(String app, String stream, Integer year, Integer month, Boolean sort) { | ||
| 367 | File recordFile = new File(userSettings.getRecord()); | 383 | File recordFile = new File(userSettings.getRecord()); |
| 368 | File streamFile = new File(recordFile.getAbsolutePath() + File.separator + app + File.separator + stream); | 384 | File streamFile = new File(recordFile.getAbsolutePath() + File.separator + app + File.separator + stream); |
| 369 | - if (!streamFile.exists()) { | ||
| 370 | - logger.warn("获取[app: {}, stream: {}]的视频时未找到目录: {}", app, stream, stream); | 385 | + return getDateList(streamFile, year, month, sort); |
| 386 | + } | ||
| 387 | + public List<File> getDateList(File streamFile, Integer year, Integer month, Boolean sort) { | ||
| 388 | + if (!streamFile.exists() && streamFile.isDirectory()) { | ||
| 389 | + logger.warn("获取[]的视频时未找到目录: {}",streamFile.getName()); | ||
| 371 | return null; | 390 | return null; |
| 372 | } | 391 | } |
| 373 | File[] dateFiles = streamFile.listFiles((File dir, String name)->{ | 392 | File[] dateFiles = streamFile.listFiles((File dir, String name)->{ |
| @@ -393,17 +412,19 @@ public class VideoFileService { | @@ -393,17 +412,19 @@ public class VideoFileService { | ||
| 393 | 412 | ||
| 394 | }); | 413 | }); |
| 395 | List<File> dateFileList = Arrays.asList(dateFiles); | 414 | List<File> dateFileList = Arrays.asList(dateFiles); |
| 415 | + if (sort != null && sort) { | ||
| 416 | + dateFileList.sort((File f1, File f2)->{ | ||
| 417 | + int sortResult = 0; | ||
| 396 | 418 | ||
| 397 | - dateFileList.sort((File f1, File f2)->{ | ||
| 398 | - int sortResult = 0; | 419 | + try { |
| 420 | + sortResult = simpleDateFormat.parse(f1.getName()).compareTo(simpleDateFormat.parse(f2.getName())); | ||
| 421 | + } catch (ParseException e) { | ||
| 422 | + logger.error("格式化时间{}/{}错误", f1.getName(), f2.getName()); | ||
| 423 | + } | ||
| 424 | + return sortResult; | ||
| 425 | + }); | ||
| 426 | + } | ||
| 399 | 427 | ||
| 400 | - try { | ||
| 401 | - sortResult = simpleDateFormat.parse(f1.getName()).compareTo(simpleDateFormat.parse(f2.getName())); | ||
| 402 | - } catch (ParseException e) { | ||
| 403 | - logger.error("格式化时间{}/{}错误", f1.getName(), f2.getName()); | ||
| 404 | - } | ||
| 405 | - return sortResult; | ||
| 406 | - }); | ||
| 407 | return dateFileList; | 428 | return dateFileList; |
| 408 | } | 429 | } |
| 409 | 430 |