Commit 42993a5635367bd057088748c2b8f27695ff3f98
1 parent
add6d0eb
优化多平台的命名规则
Showing
11 changed files
with
410 additions
and
137 deletions
src/main/java/top/panll/assist/config/WebMvcConfig.java
100644 → 100755
src/main/java/top/panll/assist/controller/DownController.java
100644 → 100755
src/main/java/top/panll/assist/controller/RecordController.java
| @@ -14,6 +14,7 @@ import org.springframework.http.ResponseEntity; | @@ -14,6 +14,7 @@ import org.springframework.http.ResponseEntity; | ||
| 14 | import org.springframework.web.bind.annotation.*; | 14 | import org.springframework.web.bind.annotation.*; |
| 15 | import top.panll.assist.controller.bean.ControllerException; | 15 | import top.panll.assist.controller.bean.ControllerException; |
| 16 | import top.panll.assist.controller.bean.ErrorCode; | 16 | import top.panll.assist.controller.bean.ErrorCode; |
| 17 | +import top.panll.assist.controller.bean.RecordFile; | ||
| 17 | import top.panll.assist.controller.bean.WVPResult; | 18 | import top.panll.assist.controller.bean.WVPResult; |
| 18 | import top.panll.assist.dto.*; | 19 | import top.panll.assist.dto.*; |
| 19 | import top.panll.assist.service.VideoFileService; | 20 | import top.panll.assist.service.VideoFileService; |
| @@ -22,6 +23,7 @@ import top.panll.assist.utils.RedisUtil; | @@ -22,6 +23,7 @@ import top.panll.assist.utils.RedisUtil; | ||
| 22 | 23 | ||
| 23 | import javax.servlet.http.HttpServletRequest; | 24 | import javax.servlet.http.HttpServletRequest; |
| 24 | import java.io.File; | 25 | import java.io.File; |
| 26 | +import java.text.DateFormat; | ||
| 25 | import java.text.ParseException; | 27 | import java.text.ParseException; |
| 26 | import java.text.SimpleDateFormat; | 28 | import java.text.SimpleDateFormat; |
| 27 | import java.util.*; | 29 | import java.util.*; |
| @@ -160,7 +162,7 @@ public class RecordController { | @@ -160,7 +162,7 @@ public class RecordController { | ||
| 160 | * 获取视频文件列表 | 162 | * 获取视频文件列表 |
| 161 | * @return | 163 | * @return |
| 162 | */ | 164 | */ |
| 163 | - @Operation(summary ="获取日期文件夹列表") | 165 | + @Operation(summary ="获取视频文件列表") |
| 164 | @Parameter(name = "page", description = "当前页", required = true) | 166 | @Parameter(name = "page", description = "当前页", required = true) |
| 165 | @Parameter(name = "count", description = "每页查询数量", required = true) | 167 | @Parameter(name = "count", description = "每页查询数量", required = true) |
| 166 | @Parameter(name = "app", description = "应用名", required = true) | 168 | @Parameter(name = "app", description = "应用名", required = true) |
| @@ -204,6 +206,54 @@ public class RecordController { | @@ -204,6 +206,54 @@ public class RecordController { | ||
| 204 | } | 206 | } |
| 205 | } | 207 | } |
| 206 | 208 | ||
| 209 | + /** | ||
| 210 | + * 获取视频文件列表 | ||
| 211 | + * @return | ||
| 212 | + */ | ||
| 213 | + @Operation(summary ="获取视频文件列表") | ||
| 214 | + @Parameter(name = "page", description = "当前页", required = true) | ||
| 215 | + @Parameter(name = "count", description = "每页查询数量", required = true) | ||
| 216 | + @Parameter(name = "app", description = "应用名", required = true) | ||
| 217 | + @Parameter(name = "stream", description = "流ID", required = true) | ||
| 218 | + @Parameter(name = "startTime", description = "开始时间(yyyy-MM-dd HH:mm:ss)", required = true) | ||
| 219 | + @Parameter(name = "endTime", description = "结束时间(yyyy-MM-dd HH:mm:ss)", required = true) | ||
| 220 | + @GetMapping(value = "/file/listWithDate") | ||
| 221 | + @ResponseBody | ||
| 222 | + public PageInfo<RecordFile> getRecordListWithDate(@RequestParam int page, | ||
| 223 | + @RequestParam int count, | ||
| 224 | + @RequestParam String app, | ||
| 225 | + @RequestParam String stream, | ||
| 226 | + @RequestParam(required = false) String startTime, | ||
| 227 | + @RequestParam(required = false) String endTime | ||
| 228 | + ){ | ||
| 229 | + | ||
| 230 | + // 开始时间与结束时间可不传或只传其一 | ||
| 231 | + List<RecordFile> recordList = new ArrayList<>(); | ||
| 232 | + try { | ||
| 233 | + Date startTimeDate = null; | ||
| 234 | + Date endTimeDate = null; | ||
| 235 | + if (startTime != null ) { | ||
| 236 | + startTimeDate = formatter.parse(startTime); | ||
| 237 | + } | ||
| 238 | + if (endTime != null ) { | ||
| 239 | + endTimeDate = formatter.parse(endTime); | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + List<File> filesInTime = videoFileService.getFilesInTime(app, stream, startTimeDate, endTimeDate); | ||
| 243 | + if (filesInTime != null && filesInTime.size() > 0) { | ||
| 244 | + for (File file : filesInTime) { | ||
| 245 | + recordList.add(RecordFile.instance(app, stream, file.getName(), file.getParentFile().getName())); | ||
| 246 | + } | ||
| 247 | + } | ||
| 248 | + PageInfo<RecordFile> stringPageInfo = new PageInfo<>(recordList); | ||
| 249 | + stringPageInfo.startPage(page, count); | ||
| 250 | + return stringPageInfo; | ||
| 251 | + } catch (ParseException e) { | ||
| 252 | + logger.error("错误的开始时间[{}]或结束时间[{}]", startTime, endTime); | ||
| 253 | + throw new ControllerException(ErrorCode.ERROR400.getCode(), "错误的开始时间或结束时间, e=" + e.getMessage()); | ||
| 254 | + } | ||
| 255 | + } | ||
| 256 | + | ||
| 207 | 257 | ||
| 208 | /** | 258 | /** |
| 209 | * 添加视频裁剪合并任务 | 259 | * 添加视频裁剪合并任务 |
src/main/java/top/panll/assist/controller/bean/ControllerException.java
100644 → 100755
src/main/java/top/panll/assist/controller/bean/RecordFile.java
0 → 100755
| 1 | +package top.panll.assist.controller.bean; | ||
| 2 | + | ||
| 3 | +public class RecordFile { | ||
| 4 | + private String app; | ||
| 5 | + private String stream; | ||
| 6 | + | ||
| 7 | + private String fileName; | ||
| 8 | + | ||
| 9 | + private String date; | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + public static RecordFile instance(String app, String stream, String fileName, String date) { | ||
| 13 | + RecordFile recordFile = new RecordFile(); | ||
| 14 | + recordFile.setApp(app); | ||
| 15 | + recordFile.setStream(stream); | ||
| 16 | + recordFile.setFileName(fileName); | ||
| 17 | + recordFile.setDate(date); | ||
| 18 | + return recordFile; | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + public String getApp() { | ||
| 23 | + return app; | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + public void setApp(String app) { | ||
| 27 | + this.app = app; | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + public String getStream() { | ||
| 31 | + return stream; | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + public void setStream(String stream) { | ||
| 35 | + this.stream = stream; | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + public String getFileName() { | ||
| 39 | + return fileName; | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + public void setFileName(String fileName) { | ||
| 43 | + this.fileName = fileName; | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + public String getDate() { | ||
| 47 | + return date; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + public void setDate(String date) { | ||
| 51 | + this.date = date; | ||
| 52 | + } | ||
| 53 | +} |
src/main/java/top/panll/assist/dto/AssistConstants.java
100644 → 100755
src/main/java/top/panll/assist/dto/VideoFile.java
0 → 100644
| 1 | +package top.panll.assist.dto; | ||
| 2 | + | ||
| 3 | +import java.io.File; | ||
| 4 | +import java.util.Date; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * 视频文件 | ||
| 8 | + */ | ||
| 9 | +public class VideoFile { | ||
| 10 | + | ||
| 11 | + /** | ||
| 12 | + * 文件对象 | ||
| 13 | + */ | ||
| 14 | + private File file; | ||
| 15 | + | ||
| 16 | + /** | ||
| 17 | + * 文件开始时间 | ||
| 18 | + */ | ||
| 19 | + private Date startTime; | ||
| 20 | + | ||
| 21 | + /** | ||
| 22 | + * 文件结束时间 | ||
| 23 | + */ | ||
| 24 | + private Date endTime; | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + /** | ||
| 28 | + * 时长, 单位:秒 | ||
| 29 | + */ | ||
| 30 | + private long duration; | ||
| 31 | + | ||
| 32 | + | ||
| 33 | + /** | ||
| 34 | + * 是否是目标格式 | ||
| 35 | + */ | ||
| 36 | + private boolean targetFormat; | ||
| 37 | + | ||
| 38 | + public File getFile() { | ||
| 39 | + return file; | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + public void setFile(File file) { | ||
| 43 | + this.file = file; | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + public Date getStartTime() { | ||
| 47 | + return startTime; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + public void setStartTime(Date startTime) { | ||
| 51 | + this.startTime = startTime; | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + public Date getEndTime() { | ||
| 55 | + return endTime; | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + public void setEndTime(Date endTime) { | ||
| 59 | + this.endTime = endTime; | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + public long getDuration() { | ||
| 63 | + return duration; | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + public void setDuration(long duration) { | ||
| 67 | + this.duration = duration; | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + public boolean isTargetFormat() { | ||
| 71 | + return targetFormat; | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + public void setTargetFormat(boolean targetFormat) { | ||
| 75 | + this.targetFormat = targetFormat; | ||
| 76 | + } | ||
| 77 | +} |
src/main/java/top/panll/assist/service/FFmpegExecUtils.java
| @@ -17,6 +17,7 @@ import org.springframework.scheduling.annotation.Async; | @@ -17,6 +17,7 @@ import org.springframework.scheduling.annotation.Async; | ||
| 17 | import org.springframework.stereotype.Component; | 17 | import org.springframework.stereotype.Component; |
| 18 | import org.springframework.util.DigestUtils; | 18 | import org.springframework.util.DigestUtils; |
| 19 | import top.panll.assist.dto.UserSettings; | 19 | import top.panll.assist.dto.UserSettings; |
| 20 | +import top.panll.assist.dto.VideoFile; | ||
| 20 | import top.panll.assist.utils.RedisUtil; | 21 | import top.panll.assist.utils.RedisUtil; |
| 21 | 22 | ||
| 22 | import java.io.BufferedWriter; | 23 | import java.io.BufferedWriter; |
| @@ -93,13 +94,13 @@ public class FFmpegExecUtils implements InitializingBean{ | @@ -93,13 +94,13 @@ public class FFmpegExecUtils implements InitializingBean{ | ||
| 93 | try { | 94 | try { |
| 94 | BufferedWriter bw =new BufferedWriter(new FileWriter(fileListName)); | 95 | BufferedWriter bw =new BufferedWriter(new FileWriter(fileListName)); |
| 95 | for (File file : fils) { | 96 | for (File file : fils) { |
| 96 | - String[] split = file.getName().split("-"); | ||
| 97 | - if (split.length != 3) continue; | ||
| 98 | - String durationStr = split[2].replace(".mp4", ""); | ||
| 99 | - Double duration = Double.parseDouble(durationStr)/1000; | 97 | + VideoFile videoFile = VideoFileFactory.createFile(this, file); |
| 98 | + if (videoFile == null || !videoFile.isTargetFormat()) { | ||
| 99 | + return; | ||
| 100 | + } | ||
| 100 | bw.write("file " + file.getAbsolutePath()); | 101 | bw.write("file " + file.getAbsolutePath()); |
| 101 | bw.newLine(); | 102 | bw.newLine(); |
| 102 | - durationAll += duration; | 103 | + durationAll += videoFile.getDuration(); |
| 103 | } | 104 | } |
| 104 | bw.flush(); | 105 | bw.flush(); |
| 105 | bw.close(); | 106 | bw.close(); |
| @@ -127,16 +128,16 @@ public class FFmpegExecUtils implements InitializingBean{ | @@ -127,16 +128,16 @@ public class FFmpegExecUtils implements InitializingBean{ | ||
| 127 | final double duration_ns = finalDurationAll * TimeUnit.SECONDS.toNanos(1); | 128 | final double duration_ns = finalDurationAll * TimeUnit.SECONDS.toNanos(1); |
| 128 | double percentage = progress.out_time_ns / duration_ns; | 129 | double percentage = progress.out_time_ns / duration_ns; |
| 129 | 130 | ||
| 130 | - // Print out interesting information about the progress | ||
| 131 | -// System.out.println(String.format( | ||
| 132 | -// "[%.0f%%] status:%s frame:%d time:%s ms fps:%.0f speed:%.2fx", | ||
| 133 | -// percentage * 100, | ||
| 134 | -// progress.status, | ||
| 135 | -// progress.frame, | ||
| 136 | -// FFmpegUtils.toTimecode(progress.out_time_ns, TimeUnit.NANOSECONDS), | ||
| 137 | -// progress.fps.doubleValue(), | ||
| 138 | -// progress.speed | ||
| 139 | -// )); | 131 | +// Print out interesting information about the progress |
| 132 | + System.out.println(String.format( | ||
| 133 | + "[%.0f%%] status:%s frame:%d time:%s ms fps:%.0f speed:%.2fx", | ||
| 134 | + percentage * 100, | ||
| 135 | + progress.status, | ||
| 136 | + progress.frame, | ||
| 137 | + FFmpegUtils.toTimecode(progress.out_time_ns, TimeUnit.NANOSECONDS), | ||
| 138 | + progress.fps.doubleValue(), | ||
| 139 | + progress.speed | ||
| 140 | + )); | ||
| 140 | 141 | ||
| 141 | if (progress.status.equals(Progress.Status.END)){ | 142 | if (progress.status.equals(Progress.Status.END)){ |
| 142 | callBack.run(progress.status.name(), percentage, recordFileResultPath); | 143 | callBack.run(progress.status.name(), percentage, recordFileResultPath); |
src/main/java/top/panll/assist/service/VideoFileFactory.java
0 → 100644
| 1 | +package top.panll.assist.service; | ||
| 2 | + | ||
| 3 | +import net.bramp.ffmpeg.probe.FFmpegProbeResult; | ||
| 4 | +import org.slf4j.Logger; | ||
| 5 | +import org.slf4j.LoggerFactory; | ||
| 6 | +import top.panll.assist.dto.VideoFile; | ||
| 7 | + | ||
| 8 | +import java.io.File; | ||
| 9 | +import java.io.IOException; | ||
| 10 | +import java.text.ParseException; | ||
| 11 | +import java.text.SimpleDateFormat; | ||
| 12 | +import java.util.Date; | ||
| 13 | + | ||
| 14 | +public class VideoFileFactory { | ||
| 15 | + | ||
| 16 | + private final static Logger logger = LoggerFactory.getLogger(VideoFileFactory.class); | ||
| 17 | + | ||
| 18 | + public static VideoFile createFile(FFmpegExecUtils ffmpegExecUtils, File file){ | ||
| 19 | + if (!file.exists()) { | ||
| 20 | + return null; | ||
| 21 | + } | ||
| 22 | + if (!file.isFile()){ | ||
| 23 | + return null; | ||
| 24 | + } | ||
| 25 | + if (file.getName().startsWith(".")){ | ||
| 26 | + return null; | ||
| 27 | + } | ||
| 28 | + if (!file.getName().endsWith(".mp4")){ | ||
| 29 | + return null; | ||
| 30 | + } | ||
| 31 | + String date = file.getParentFile().getName(); | ||
| 32 | + if (file.getName().indexOf(":") > 0) { | ||
| 33 | + // 格式为 HH:mm:ss-HH:mm:ss-时长 | ||
| 34 | + | ||
| 35 | + String[] split = file.getName().split("-"); | ||
| 36 | + if (split.length != 3) { | ||
| 37 | + return null; | ||
| 38 | + } | ||
| 39 | + String startTimeStr = date + " " + split[0]; | ||
| 40 | + String endTimeStr = date + " " + split[1]; | ||
| 41 | + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||
| 42 | + VideoFile videoFile = new VideoFile(); | ||
| 43 | + videoFile.setFile(file); | ||
| 44 | + videoFile.setTargetFormat(false); | ||
| 45 | + try { | ||
| 46 | + Date startTimeDate = simpleDateFormat.parse(startTimeStr); | ||
| 47 | + videoFile.setStartTime(startTimeDate); | ||
| 48 | + Date endTimeDate = simpleDateFormat.parse(endTimeStr); | ||
| 49 | + videoFile.setEndTime(endTimeDate); | ||
| 50 | + videoFile.setDuration((endTimeDate.getTime() - startTimeDate.getTime())); | ||
| 51 | + } catch (ParseException e) { | ||
| 52 | + logger.error("[构建视频文件对象] 格式化时间失败, file:{}", file.getAbsolutePath(), e); | ||
| 53 | + return null; | ||
| 54 | + } | ||
| 55 | + return videoFile; | ||
| 56 | + | ||
| 57 | + }else if (getStrCountInStr(file.getName(), "-") == 3){ | ||
| 58 | + | ||
| 59 | + // 格式为zlm的录制格式 HH-mm-ss-序号 | ||
| 60 | + String startStr = file.getName().substring(0, file.getName().lastIndexOf("-")); | ||
| 61 | + String startTimeStr = date + " " + startStr; | ||
| 62 | + VideoFile videoFile = null; | ||
| 63 | + try { | ||
| 64 | + FFmpegProbeResult fFmpegProbeResult = ffmpegExecUtils.getFfprobe().probe(file.getAbsolutePath()); | ||
| 65 | + double duration = fFmpegProbeResult.getFormat().duration * 1000; | ||
| 66 | + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); | ||
| 67 | + Date startTimeDate = simpleDateFormat.parse(startTimeStr); | ||
| 68 | + Date endTimeDate = new Date(startTimeDate.getTime() + new Double(duration).longValue()); | ||
| 69 | + videoFile = new VideoFile(); | ||
| 70 | + videoFile.setTargetFormat(false); | ||
| 71 | + videoFile.setFile(file); | ||
| 72 | + videoFile.setStartTime(startTimeDate); | ||
| 73 | + videoFile.setEndTime(endTimeDate); | ||
| 74 | + videoFile.setDuration((endTimeDate.getTime() - startTimeDate.getTime())/1000); | ||
| 75 | + } catch (IOException e) { | ||
| 76 | + logger.error("[构建视频文件对象] 获取视频时长失败, file:{}", file.getAbsolutePath(), e); | ||
| 77 | + return null; | ||
| 78 | + } catch (ParseException e) { | ||
| 79 | + logger.error("[构建视频文件对象] 格式化时间失败, file:{}", file.getAbsolutePath(), e); | ||
| 80 | + return null; | ||
| 81 | + } | ||
| 82 | + return videoFile; | ||
| 83 | + }else if (getStrCountInStr(file.getName(), "-") == 2 && file.getName().length() == 10 ){ | ||
| 84 | + // 格式为zlm的录制格式 HH-mm-ss | ||
| 85 | + String startTimeStr = date + " " + file.getName(); | ||
| 86 | + VideoFile videoFile = null; | ||
| 87 | + try { | ||
| 88 | + FFmpegProbeResult fFmpegProbeResult = ffmpegExecUtils.getFfprobe().probe(file.getAbsolutePath()); | ||
| 89 | + double duration = fFmpegProbeResult.getFormat().duration * 1000; | ||
| 90 | + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); | ||
| 91 | + Date startTimeDate = simpleDateFormat.parse(startTimeStr); | ||
| 92 | + Date endTimeDate = new Date(startTimeDate.getTime() + new Double(duration).longValue()); | ||
| 93 | + videoFile = new VideoFile(); | ||
| 94 | + videoFile.setTargetFormat(false); | ||
| 95 | + videoFile.setFile(file); | ||
| 96 | + videoFile.setStartTime(startTimeDate); | ||
| 97 | + videoFile.setEndTime(endTimeDate); | ||
| 98 | + videoFile.setDuration((endTimeDate.getTime() - startTimeDate.getTime())/1000); | ||
| 99 | + } catch (IOException e) { | ||
| 100 | + logger.error("[构建视频文件对象] 获取视频时长失败, file:{}", file.getAbsolutePath(), e); | ||
| 101 | + return null; | ||
| 102 | + } catch (ParseException e) { | ||
| 103 | + logger.warn("[构建视频文件对象] 格式化时间失败, file:{}", file.getAbsolutePath(), e); | ||
| 104 | + return null; | ||
| 105 | + } | ||
| 106 | + return videoFile; | ||
| 107 | + }else if (getStrCountInStr(file.getName(), "-") == 1 ){ | ||
| 108 | + // 格式为zlm的录制格式 HH-mm-ss | ||
| 109 | + // 格式为 HH:mm:ss-HH:mm:ss-时长 | ||
| 110 | + | ||
| 111 | + String[] split = file.getName().split("-"); | ||
| 112 | + if (split.length != 2) { | ||
| 113 | + return null; | ||
| 114 | + } | ||
| 115 | + String startTimeStr = date + " " + split[0]; | ||
| 116 | + String endTimeStr = date + " " + split[1]; | ||
| 117 | + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HHmmss"); | ||
| 118 | + VideoFile videoFile = new VideoFile(); | ||
| 119 | + videoFile.setTargetFormat(true); | ||
| 120 | + videoFile.setFile(file); | ||
| 121 | + try { | ||
| 122 | + Date startTimeDate = simpleDateFormat.parse(startTimeStr); | ||
| 123 | + videoFile.setStartTime(startTimeDate); | ||
| 124 | + Date endTimeDate = simpleDateFormat.parse(endTimeStr); | ||
| 125 | + videoFile.setEndTime(endTimeDate); | ||
| 126 | + videoFile.setDuration((endTimeDate.getTime() - startTimeDate.getTime())); | ||
| 127 | + } catch (ParseException e) { | ||
| 128 | + logger.error("[构建视频文件对象] 格式化时间失败, file:{}", file.getAbsolutePath(), e); | ||
| 129 | + return null; | ||
| 130 | + } | ||
| 131 | + return videoFile; | ||
| 132 | + }else { | ||
| 133 | + return null; | ||
| 134 | + } | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + | ||
| 138 | + public static int getStrCountInStr(String sourceStr, String content) { | ||
| 139 | + int index = sourceStr.indexOf(content); | ||
| 140 | + if (index < 0) { | ||
| 141 | + return 0; | ||
| 142 | + } | ||
| 143 | + int count = 1; | ||
| 144 | + int lastIndex = sourceStr.lastIndexOf(content); | ||
| 145 | + while (index != lastIndex) { | ||
| 146 | + index = sourceStr.indexOf(content, index + 1); | ||
| 147 | + count++; | ||
| 148 | + } | ||
| 149 | + return count; | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | +} |
src/main/java/top/panll/assist/service/VideoFileService.java
| @@ -68,35 +68,6 @@ public class VideoFileService { | @@ -68,35 +68,6 @@ public class VideoFileService { | ||
| 68 | return spaceInfo; | 68 | return spaceInfo; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | -// public String getPrintSize(long size) { | ||
| 72 | -// // 如果字节数少于1024,则直接以B为单位,否则先除于1024,后3位因太少无意义 | ||
| 73 | -// if (size < 1024) { | ||
| 74 | -// return String.valueOf(size) + "B"; | ||
| 75 | -// } else { | ||
| 76 | -// size = size / 1024; | ||
| 77 | -// } | ||
| 78 | -// // 如果原字节数除于1024之后,少于1024,则可以直接以KB作为单位 | ||
| 79 | -// // 因为还没有到达要使用另一个单位的时候 | ||
| 80 | -// // 接下去以此类推 | ||
| 81 | -// if (size < 1024) { | ||
| 82 | -// return String.valueOf(size) + "KB"; | ||
| 83 | -// } else { | ||
| 84 | -// size = size / 1024; | ||
| 85 | -// } | ||
| 86 | -// if (size < 1024) { | ||
| 87 | -// // 因为如果以MB为单位的话,要保留最后1位小数, | ||
| 88 | -// // 因此,把此数乘以100之后再取余 | ||
| 89 | -// size = size * 100; | ||
| 90 | -// return String.valueOf((size / 100)) + "." | ||
| 91 | -// + String.valueOf((size % 100)) + "MB"; | ||
| 92 | -// } else { | ||
| 93 | -// // 否则如果要以GB为单位的,先除于1024再作同样的处理 | ||
| 94 | -// size = size * 100 / 1024; | ||
| 95 | -// return String.valueOf((size / 100)) + "." | ||
| 96 | -// + String.valueOf((size % 100)) + "GB"; | ||
| 97 | -// } | ||
| 98 | -// } | ||
| 99 | - | ||
| 100 | public List<File> getStreamList(String app, Boolean sort) { | 71 | public List<File> getStreamList(String app, Boolean sort) { |
| 101 | File appFile = new File(userSettings.getRecord() + File.separator + app); | 72 | File appFile = new File(userSettings.getRecord() + File.separator + app); |
| 102 | return getStreamList(appFile, sort); | 73 | return getStreamList(appFile, sort); |
| @@ -119,47 +90,32 @@ public class VideoFileService { | @@ -119,47 +90,32 @@ public class VideoFileService { | ||
| 119 | } | 90 | } |
| 120 | 91 | ||
| 121 | /** | 92 | /** |
| 122 | - * 对视频文件重命名, 00:00:00-00:00:00 | ||
| 123 | - * @param file | ||
| 124 | - * @throws ParseException | 93 | + * 对视频文件重命名 |
| 125 | */ | 94 | */ |
| 126 | public void handFile(File file,String app, String stream) { | 95 | public void handFile(File file,String app, String stream) { |
| 127 | - FFprobe ffprobe = ffmpegExecUtils.getFfprobe(); | ||
| 128 | - if(file.exists() && file.isFile() && !file.getName().startsWith(".")&& file.getName().endsWith(".mp4") && file.getName().indexOf(":") < 0) { | ||
| 129 | - try { | ||
| 130 | - | ||
| 131 | - FFmpegProbeResult in = ffprobe.probe(file.getAbsolutePath()); | ||
| 132 | - double duration = in.getFormat().duration * 1000; | ||
| 133 | - String endTimeStr = file.getName().replace(".mp4", ""); | ||
| 134 | - | ||
| 135 | - SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); | ||
| 136 | - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss"); | ||
| 137 | - | ||
| 138 | - File dateFile = new File(file.getParent()); | 96 | + VideoFile videoFile = VideoFileFactory.createFile(ffmpegExecUtils, file); |
| 97 | + if (videoFile == null || videoFile.isTargetFormat()) { | ||
| 98 | + return; | ||
| 99 | + } | ||
| 139 | 100 | ||
| 140 | - long startTime = formatter.parse(dateFile.getName() + " " + endTimeStr).getTime(); | ||
| 141 | - long durationLong = new Double(duration).longValue(); | ||
| 142 | - long endTime = startTime + durationLong; | ||
| 143 | - endTime = endTime - endTime%1000; | 101 | + SimpleDateFormat dateFormat = new SimpleDateFormat("HHmmss"); |
| 144 | 102 | ||
| 145 | - String key = AssistConstants.STREAM_CALL_INFO + userSettings.getId() + "_" + app + "_" + stream; | ||
| 146 | - String callId = (String) redisUtil.get(key); | 103 | + String key = AssistConstants.STREAM_CALL_INFO + userSettings.getId() + "_" + app + "_" + stream; |
| 104 | + String callId = (String) redisUtil.get(key); | ||
| 147 | 105 | ||
| 148 | - String streamNew = (callId == null? stream : stream + "_" + callId); | ||
| 149 | - File newPath = new File(userSettings.getRecord() + File.separator + app + File.separator + streamNew + File.separator + DateUtils.getDateStr(new Date(startTime))); | ||
| 150 | - if (!newPath.exists()) { | ||
| 151 | - newPath.mkdirs(); | ||
| 152 | - } | 106 | + String streamNew = (callId == null? stream : stream + "_" + callId); |
| 107 | + File newPath = new File(userSettings.getRecord() + File.separator + app + File.separator + streamNew | ||
| 108 | + + File.separator + DateUtils.getDateStr(videoFile.getStartTime())); | ||
| 109 | + if (!newPath.exists()) { | ||
| 110 | + newPath.mkdirs(); | ||
| 111 | + } | ||
| 153 | 112 | ||
| 154 | - String newName = newPath.getAbsolutePath() + File.separator+ simpleDateFormat.format(startTime) + "-" + simpleDateFormat.format(endTime) + "-" + durationLong + ".mp4"; | ||
| 155 | - file.renameTo(new File(newName)); | ||
| 156 | - System.out.println(file.getAbsolutePath()); | ||
| 157 | - logger.info("[处理文件] {}", file.getName()); | ||
| 158 | - } catch (IOException e) { | ||
| 159 | - logger.warn("文件可能以损坏[{}]", file.getAbsolutePath()); | ||
| 160 | - } catch (ParseException e) { | ||
| 161 | - logger.error("时间格式化失败", e.getMessage()); | ||
| 162 | - } | 113 | + String newName = newPath.getAbsolutePath() + File.separator+ dateFormat.format(videoFile.getStartTime()) |
| 114 | + + "-" + dateFormat.format(videoFile.getEndTime()) + ".mp4"; | ||
| 115 | + logger.info("[处理文件] {}->{}", file.getAbsolutePath(), newName); | ||
| 116 | + boolean renameTo = file.renameTo(new File(newName)); | ||
| 117 | + if (!renameTo) { | ||
| 118 | + logger.info("[处理文件]文件重命名失败 {}->{}", file.getAbsolutePath(), newName); | ||
| 163 | } | 119 | } |
| 164 | } | 120 | } |
| 165 | 121 | ||
| @@ -199,7 +155,7 @@ public class VideoFileService { | @@ -199,7 +155,7 @@ public class VideoFileService { | ||
| 199 | time1 = simpleDateFormatForTime.parse(f1.get("time").toString()); | 155 | time1 = simpleDateFormatForTime.parse(f1.get("time").toString()); |
| 200 | time2 = simpleDateFormatForTime.parse(f2.get("time").toString()); | 156 | time2 = simpleDateFormatForTime.parse(f2.get("time").toString()); |
| 201 | } catch (ParseException e) { | 157 | } catch (ParseException e) { |
| 202 | - logger.error("时间格式化失败", e.getMessage()); | 158 | + logger.error("时间格式化失败", e); |
| 203 | } | 159 | } |
| 204 | return time1.compareTo(time2) * -1; | 160 | return time1.compareTo(time2) * -1; |
| 205 | }); | 161 | }); |
| @@ -221,7 +177,7 @@ public class VideoFileService { | @@ -221,7 +177,7 @@ public class VideoFileService { | ||
| 221 | return result; | 177 | return result; |
| 222 | } | 178 | } |
| 223 | 179 | ||
| 224 | - SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | 180 | + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HHmmss"); |
| 225 | SimpleDateFormat formatterForDate = new SimpleDateFormat("yyyy-MM-dd"); | 181 | SimpleDateFormat formatterForDate = new SimpleDateFormat("yyyy-MM-dd"); |
| 226 | String startTimeStr = null; | 182 | String startTimeStr = null; |
| 227 | String endTimeStr = null; | 183 | String endTimeStr = null; |
| @@ -277,54 +233,50 @@ public class VideoFileService { | @@ -277,54 +233,50 @@ public class VideoFileService { | ||
| 277 | 233 | ||
| 278 | if (dateFiles != null && dateFiles.length > 0) { | 234 | if (dateFiles != null && dateFiles.length > 0) { |
| 279 | for (File dateFile : dateFiles) { | 235 | for (File dateFile : dateFiles) { |
| 280 | - // TODO 按时间获取文件 | ||
| 281 | File[] files = dateFile.listFiles((File dir, String name) ->{ | 236 | File[] files = dateFile.listFiles((File dir, String name) ->{ |
| 282 | - boolean filterResult = true; | ||
| 283 | File currentFile = new File(dir + File.separator + name); | 237 | File currentFile = new File(dir + File.separator + name); |
| 284 | - if (currentFile.isFile() && name.contains(":") && name.endsWith(".mp4") && !name.startsWith(".") && currentFile.length() > 0){ | ||
| 285 | - String[] timeArray = name.split("-"); | ||
| 286 | - if (timeArray.length == 3){ | ||
| 287 | - String fileStartTimeStr = dateFile.getName() + " " + timeArray[0]; | ||
| 288 | - String fileEndTimeStr = dateFile.getName() + " " + timeArray[1]; | ||
| 289 | - try { | ||
| 290 | - if (startTime != null) { | ||
| 291 | - filterResult = filterResult && (formatter.parse(fileStartTimeStr).after(startTime) || (formatter.parse(fileStartTimeStr).before(startTime) && formatter.parse(fileEndTimeStr).after(startTime))); | ||
| 292 | - } | ||
| 293 | - if (endTime != null) { | ||
| 294 | - filterResult = filterResult && (formatter.parse(fileEndTimeStr).before(endTime) || (formatter.parse(fileEndTimeStr).after(endTime) && formatter.parse(fileStartTimeStr).before(endTime))); | ||
| 295 | - } | ||
| 296 | - } catch (ParseException e) { | ||
| 297 | - logger.error("过滤视频文件时异常: {}-{}", name, e.getMessage()); | ||
| 298 | - return false; | ||
| 299 | - } | ||
| 300 | - } | 238 | + VideoFile videoFile = VideoFileFactory.createFile(ffmpegExecUtils, currentFile); |
| 239 | + if (videoFile == null ) { | ||
| 240 | + return false; | ||
| 301 | }else { | 241 | }else { |
| 302 | - filterResult = false; | 242 | + if (!videoFile.isTargetFormat()) { |
| 243 | + return false; | ||
| 244 | + } | ||
| 245 | + if (startTime == null && endTime == null) { | ||
| 246 | + return true; | ||
| 247 | + }else if (startTime == null && endTime != null) { | ||
| 248 | + return videoFile.getEndTime().before(endTime) | ||
| 249 | + || videoFile.getEndTime().equals(endTime) | ||
| 250 | + || (videoFile.getEndTime().after(endTime) && videoFile.getStartTime().before(endTime)); | ||
| 251 | + }else if (startTime != null && endTime == null) { | ||
| 252 | + return videoFile.getStartTime().after(startTime) | ||
| 253 | + || videoFile.getStartTime().equals(startTime) | ||
| 254 | + || (videoFile.getStartTime().before(startTime) && videoFile.getEndTime().after(startTime)); | ||
| 255 | + }else { | ||
| 256 | + return videoFile.getStartTime().after(startTime) | ||
| 257 | + || videoFile.getStartTime().equals(startTime) | ||
| 258 | + || (videoFile.getStartTime().before(startTime) && videoFile.getEndTime().after(startTime)) | ||
| 259 | + || videoFile.getEndTime().before(endTime) | ||
| 260 | + || videoFile.getEndTime().equals(endTime) | ||
| 261 | + || (videoFile.getEndTime().after(endTime) && videoFile.getStartTime().before(endTime)); | ||
| 262 | + } | ||
| 263 | + | ||
| 303 | } | 264 | } |
| 304 | - return filterResult; | ||
| 305 | }); | 265 | }); |
| 306 | - | ||
| 307 | - List<File> fileList = Arrays.asList(files); | ||
| 308 | - result.addAll(fileList); | 266 | + if (files != null && files.length > 0) { |
| 267 | + result.addAll(Arrays.asList(files)); | ||
| 268 | + } | ||
| 309 | } | 269 | } |
| 310 | } | 270 | } |
| 311 | - if (result.size() > 0) { | 271 | + if (!result.isEmpty()) { |
| 312 | result.sort((File f1, File f2) -> { | 272 | result.sort((File f1, File f2) -> { |
| 313 | - int sortResult = 0; | ||
| 314 | - String[] timeArray1 = f1.getName().split("-"); | ||
| 315 | - String[] timeArray2 = f2.getName().split("-"); | ||
| 316 | - if (timeArray1.length == 3 && timeArray2.length == 3){ | ||
| 317 | - File dateFile1 = f1.getParentFile(); | ||
| 318 | - File dateFile2 = f2.getParentFile(); | ||
| 319 | - String fileStartTimeStr1 = dateFile1.getName() + " " + timeArray1[0]; | ||
| 320 | - String fileStartTimeStr2 = dateFile2.getName() + " " + timeArray2[0]; | ||
| 321 | - try { | ||
| 322 | - sortResult = formatter.parse(fileStartTimeStr1).compareTo(formatter.parse(fileStartTimeStr2)); | ||
| 323 | - } catch (ParseException e) { | ||
| 324 | - e.printStackTrace(); | ||
| 325 | - } | 273 | + VideoFile videoFile1 = VideoFileFactory.createFile(ffmpegExecUtils, f1); |
| 274 | + VideoFile videoFile2 = VideoFileFactory.createFile(ffmpegExecUtils, f2); | ||
| 275 | + if (videoFile1 == null || !videoFile1.isTargetFormat() || videoFile2 == null || !videoFile2.isTargetFormat()) { | ||
| 276 | + logger.warn("[根据时间获取视频文件] 排序错误,文件错误: {}/{}", f1.getName(), f2.getName()); | ||
| 277 | + return 0; | ||
| 326 | } | 278 | } |
| 327 | - return sortResult; | 279 | + return videoFile1.getStartTime().compareTo(videoFile2.getStartTime()); |
| 328 | }); | 280 | }); |
| 329 | } | 281 | } |
| 330 | return result; | 282 | return result; |
| @@ -333,7 +285,7 @@ public class VideoFileService { | @@ -333,7 +285,7 @@ public class VideoFileService { | ||
| 333 | 285 | ||
| 334 | public String mergeOrCut(String app, String stream, Date startTime, Date endTime, String remoteHost) { | 286 | public String mergeOrCut(String app, String stream, Date startTime, Date endTime, String remoteHost) { |
| 335 | List<File> filesInTime = this.getFilesInTime(app, stream, startTime, endTime); | 287 | List<File> filesInTime = this.getFilesInTime(app, stream, startTime, endTime); |
| 336 | - if (filesInTime== null || filesInTime.size() == 0){ | 288 | + if (filesInTime== null || filesInTime.isEmpty()){ |
| 337 | logger.info("此时间段未未找到视频文件, {}/{} {}->{}", app, stream, | 289 | logger.info("此时间段未未找到视频文件, {}/{} {}->{}", app, stream, |
| 338 | startTime == null? null:DateUtils.getDateTimeStr(startTime), | 290 | startTime == null? null:DateUtils.getDateTimeStr(startTime), |
| 339 | endTime == null? null:DateUtils.getDateTimeStr(endTime)); | 291 | endTime == null? null:DateUtils.getDateTimeStr(endTime)); |
| @@ -457,6 +409,9 @@ public class VideoFileService { | @@ -457,6 +409,9 @@ public class VideoFileService { | ||
| 457 | } | 409 | } |
| 458 | 410 | ||
| 459 | }); | 411 | }); |
| 412 | + if (dateFiles == null) { | ||
| 413 | + return new ArrayList<>(); | ||
| 414 | + } | ||
| 460 | List<File> dateFileList = Arrays.asList(dateFiles); | 415 | List<File> dateFileList = Arrays.asList(dateFiles); |
| 461 | if (sort != null && sort) { | 416 | if (sort != null && sort) { |
| 462 | dateFileList.sort((File f1, File f2)->{ | 417 | dateFileList.sort((File f1, File f2)->{ |
| @@ -525,21 +480,6 @@ public class VideoFileService { | @@ -525,21 +480,6 @@ public class VideoFileService { | ||
| 525 | return result; | 480 | return result; |
| 526 | } | 481 | } |
| 527 | 482 | ||
| 528 | - public boolean stopTask(String taskId) { | ||
| 529 | -// Runnable task = taskList.get(taskId); | ||
| 530 | -// boolean result = false; | ||
| 531 | -// if (task != null) { | ||
| 532 | -// processThreadPool.remove(task); | ||
| 533 | -// taskList.remove(taskId); | ||
| 534 | -// List<Object> taskCatch = redisUtil.scan(String.format("%S_*_*_%S", keyStr, taskId)); | ||
| 535 | -// if (taskCatch.size() == 1) { | ||
| 536 | -// redisUtil.del((String) taskCatch.get(0)); | ||
| 537 | -// result = true; | ||
| 538 | -// } | ||
| 539 | -// } | ||
| 540 | - return false; | ||
| 541 | - } | ||
| 542 | - | ||
| 543 | public boolean collection(String app, String stream, String type) { | 483 | public boolean collection(String app, String stream, String type) { |
| 544 | File streamFile = new File(userSettings.getRecord() + File.separator + app + File.separator + stream); | 484 | File streamFile = new File(userSettings.getRecord() + File.separator + app + File.separator + stream); |
| 545 | boolean result = false; | 485 | boolean result = false; |
src/main/resources/static/download.html
100644 → 100755