Commit fb7063c400704cf4a379c7701625a2fe9fd2edb0
Merge branch '优化'
Showing
15 changed files
with
299 additions
and
1020 deletions
pom.xml
| @@ -9,7 +9,7 @@ | @@ -9,7 +9,7 @@ | ||
| 9 | </parent> | 9 | </parent> |
| 10 | <groupId>top.panll.assist</groupId> | 10 | <groupId>top.panll.assist</groupId> |
| 11 | <artifactId>wvp-pro-assist</artifactId> | 11 | <artifactId>wvp-pro-assist</artifactId> |
| 12 | - <version>2.6.8</version> | 12 | + <version>2.6.9</version> |
| 13 | <name>wvp-pro-assist</name> | 13 | <name>wvp-pro-assist</name> |
| 14 | <description></description> | 14 | <description></description> |
| 15 | <properties> | 15 | <properties> |
src/main/java/top/panll/assist/config/StartConfig.java deleted
100755 → 0
| 1 | -package top.panll.assist.config; | ||
| 2 | - | ||
| 3 | -import net.bramp.ffmpeg.FFmpeg; | ||
| 4 | -import net.bramp.ffmpeg.FFprobe; | ||
| 5 | -import org.slf4j.Logger; | ||
| 6 | -import org.slf4j.LoggerFactory; | ||
| 7 | -import org.springframework.beans.factory.annotation.Autowired; | ||
| 8 | -import org.springframework.beans.factory.annotation.Value; | ||
| 9 | -import org.springframework.boot.CommandLineRunner; | ||
| 10 | -import org.springframework.core.annotation.Order; | ||
| 11 | -import org.springframework.stereotype.Component; | ||
| 12 | -import top.panll.assist.dto.UserSettings; | ||
| 13 | -import top.panll.assist.service.FFmpegExecUtils; | ||
| 14 | -import top.panll.assist.service.VideoFileService; | ||
| 15 | - | ||
| 16 | -import java.io.*; | ||
| 17 | -import java.nio.charset.StandardCharsets; | ||
| 18 | - | ||
| 19 | -/** | ||
| 20 | - * 用于启动检查环境 | ||
| 21 | - */ | ||
| 22 | -@Component | ||
| 23 | -@Order(value=1) | ||
| 24 | -public class StartConfig implements CommandLineRunner { | ||
| 25 | - | ||
| 26 | - private final static Logger logger = LoggerFactory.getLogger(StartConfig.class); | ||
| 27 | - | ||
| 28 | - @Value("${server.port}") | ||
| 29 | - private String port; | ||
| 30 | - | ||
| 31 | - @Autowired | ||
| 32 | - private UserSettings userSettings; | ||
| 33 | - | ||
| 34 | - @Autowired | ||
| 35 | - private VideoFileService videoFileService; | ||
| 36 | - | ||
| 37 | - | ||
| 38 | - @Override | ||
| 39 | - public void run(String... args) { | ||
| 40 | - String record = userSettings.getRecord(); | ||
| 41 | - if (!record.endsWith(File.separator)) { | ||
| 42 | - userSettings.setRecord(userSettings.getRecord() + File.separator); | ||
| 43 | - } | ||
| 44 | - | ||
| 45 | - File recordFile = new File(record); | ||
| 46 | - if (!recordFile.exists()){ | ||
| 47 | - logger.warn("[userSettings.record]路径不存在,开始创建"); | ||
| 48 | - boolean mkResult = recordFile.mkdirs(); | ||
| 49 | - if (!mkResult) { | ||
| 50 | - logger.info("[userSettings.record]目录创建失败"); | ||
| 51 | - System.exit(1); | ||
| 52 | - } | ||
| 53 | - }else { | ||
| 54 | - if ( !recordFile.isDirectory()) { | ||
| 55 | - logger.warn("[userSettings.record]路径是文件,请修改为目录"); | ||
| 56 | - System.exit(1); | ||
| 57 | - } | ||
| 58 | - if (!recordFile.canRead()) { | ||
| 59 | - logger.error("[userSettings.record]路径无法读取"); | ||
| 60 | - System.exit(1); | ||
| 61 | - } | ||
| 62 | - if (!recordFile.canWrite()) { | ||
| 63 | - logger.error("[userSettings.record]路径无法写入"); | ||
| 64 | - System.exit(1); | ||
| 65 | - } | ||
| 66 | - } | ||
| 67 | - | ||
| 68 | - try { | ||
| 69 | - | ||
| 70 | - // 对目录进行预整理 | ||
| 71 | - File[] appFiles = recordFile.listFiles(); | ||
| 72 | - if (appFiles != null && appFiles.length > 0) { | ||
| 73 | - for (File appFile : appFiles) { | ||
| 74 | - if (appFile.getName().equals("recordTemp")) { | ||
| 75 | - continue; | ||
| 76 | - } | ||
| 77 | - File[] streamFiles = appFile.listFiles(); | ||
| 78 | - if (streamFiles != null && streamFiles.length > 0) { | ||
| 79 | - for (File streamFile : streamFiles) { | ||
| 80 | - File[] dateFiles = streamFile.listFiles(); | ||
| 81 | - if (dateFiles != null && dateFiles.length > 0) { | ||
| 82 | - for (File dateFile : dateFiles) { | ||
| 83 | - File[] files = dateFile.listFiles(); | ||
| 84 | - if (files != null && files.length > 0) { | ||
| 85 | - for (File file : files) { | ||
| 86 | - videoFileService.handFile(file, appFile.getName(), streamFile.getName()); | ||
| 87 | - } | ||
| 88 | - } | ||
| 89 | - } | ||
| 90 | - } | ||
| 91 | - | ||
| 92 | - } | ||
| 93 | - } | ||
| 94 | - | ||
| 95 | - } | ||
| 96 | - } | ||
| 97 | - | ||
| 98 | - } catch (Exception exception){ | ||
| 99 | - exception.printStackTrace(); | ||
| 100 | - logger.error("环境错误: " + exception.getMessage()); | ||
| 101 | - } | ||
| 102 | - } | ||
| 103 | - | ||
| 104 | -// private void writeAssistDownPage(File recordFile) { | ||
| 105 | -// try { | ||
| 106 | -// File file = new File(recordFile.getParentFile().getAbsolutePath(), "download.html"); | ||
| 107 | -// if (file.exists()) { | ||
| 108 | -// file.delete(); | ||
| 109 | -// } | ||
| 110 | -// file.createNewFile(); | ||
| 111 | -// FileOutputStream fs = new FileOutputStream(file); | ||
| 112 | -// StringBuffer stringBuffer = new StringBuffer(); | ||
| 113 | -// String content = "<!DOCTYPE html>\n" + | ||
| 114 | -// "<html lang=\"en\">\n" + | ||
| 115 | -// "<head>\n" + | ||
| 116 | -// " <meta charset=\"UTF-8\">\n" + | ||
| 117 | -// " <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n" + | ||
| 118 | -// " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" + | ||
| 119 | -// " <title>下载</title>\n" + | ||
| 120 | -// "</head>\n" + | ||
| 121 | -// "<body>\n" + | ||
| 122 | -// " <a id=\"download\" download />\n" + | ||
| 123 | -// " <script>\n" + | ||
| 124 | -// " (function(){\n" + | ||
| 125 | -// " let searchParams = new URLSearchParams(location.search);\n" + | ||
| 126 | -// " var download = document.getElementById(\"download\");\n" + | ||
| 127 | -// " download.setAttribute(\"href\", searchParams.get(\"url\"))\n" + | ||
| 128 | -// " download.click()\n" + | ||
| 129 | -// " setTimeout(()=>{\n" + | ||
| 130 | -// " window.location.href=\"about:blank\";\n" + | ||
| 131 | -// "\t\t\t window.close();\n" + | ||
| 132 | -// " },200)\n" + | ||
| 133 | -// " })();\n" + | ||
| 134 | -// " \n" + | ||
| 135 | -// " </script>\n" + | ||
| 136 | -// "</body>\n" + | ||
| 137 | -// "</html>"; | ||
| 138 | -// fs.write(content.getBytes(StandardCharsets.UTF_8)); | ||
| 139 | -// logger.info("已写入html配置页面: " + file.getAbsolutePath()); | ||
| 140 | -// } catch (FileNotFoundException e) { | ||
| 141 | -// logger.error("写入html页面错误", e); | ||
| 142 | -// } catch (IOException e) { | ||
| 143 | -// logger.error("写入html页面错误", e); | ||
| 144 | -// } | ||
| 145 | -// | ||
| 146 | -// | ||
| 147 | -// } | ||
| 148 | -} |
src/main/java/top/panll/assist/config/WebMvcConfig.java
| @@ -17,7 +17,7 @@ public class WebMvcConfig extends WebMvcConfigurerAdapter { | @@ -17,7 +17,7 @@ public class WebMvcConfig extends WebMvcConfigurerAdapter { | ||
| 17 | 17 | ||
| 18 | @Override | 18 | @Override |
| 19 | public void addResourceHandlers(ResourceHandlerRegistry registry) { | 19 | public void addResourceHandlers(ResourceHandlerRegistry registry) { |
| 20 | - File file = new File(userSettings.getRecord()); | 20 | + File file = new File(userSettings.getRecordTempPath()); |
| 21 | registry.addResourceHandler("/download/**").addResourceLocations("file://" + file.getAbsolutePath() + "/"); | 21 | registry.addResourceHandler("/download/**").addResourceLocations("file://" + file.getAbsolutePath() + "/"); |
| 22 | super.addResourceHandlers(registry); | 22 | super.addResourceHandlers(registry); |
| 23 | } | 23 | } |
src/main/java/top/panll/assist/controller/DownController.java deleted
100755 → 0
| 1 | -package top.panll.assist.controller; | ||
| 2 | - | ||
| 3 | - | ||
| 4 | -import org.apache.catalina.connector.ClientAbortException; | ||
| 5 | -import org.mp4parser.BasicContainer; | ||
| 6 | -import org.mp4parser.Container; | ||
| 7 | -import org.mp4parser.muxer.Movie; | ||
| 8 | -import org.mp4parser.muxer.Track; | ||
| 9 | -import org.mp4parser.muxer.builder.DefaultMp4Builder; | ||
| 10 | -import org.mp4parser.muxer.builder.Mp4Builder; | ||
| 11 | -import org.mp4parser.muxer.container.mp4.MovieCreator; | ||
| 12 | -import org.mp4parser.muxer.tracks.AppendTrack; | ||
| 13 | -import org.slf4j.Logger; | ||
| 14 | -import org.slf4j.LoggerFactory; | ||
| 15 | -import org.springframework.beans.factory.annotation.Autowired; | ||
| 16 | -import org.springframework.stereotype.Controller; | ||
| 17 | -import org.springframework.web.bind.annotation.GetMapping; | ||
| 18 | -import org.springframework.web.bind.annotation.RequestMapping; | ||
| 19 | -import org.springframework.web.bind.annotation.ResponseBody; | ||
| 20 | -import top.panll.assist.dto.UserSettings; | ||
| 21 | - | ||
| 22 | -import javax.servlet.http.HttpServletRequest; | ||
| 23 | -import javax.servlet.http.HttpServletResponse; | ||
| 24 | -import java.io.*; | ||
| 25 | -import java.nio.channels.Channels; | ||
| 26 | -import java.nio.channels.WritableByteChannel; | ||
| 27 | -import java.nio.charset.StandardCharsets; | ||
| 28 | -import java.util.ArrayList; | ||
| 29 | -import java.util.LinkedList; | ||
| 30 | -import java.util.List; | ||
| 31 | - | ||
| 32 | -@Controller | ||
| 33 | -@RequestMapping("/down") | ||
| 34 | -public class DownController { | ||
| 35 | - | ||
| 36 | - private final static Logger logger = LoggerFactory.getLogger(DownController.class); | ||
| 37 | - | ||
| 38 | - @Autowired | ||
| 39 | - private UserSettings userSettings; | ||
| 40 | - | ||
| 41 | - /** | ||
| 42 | - * 获取app+stream列表 | ||
| 43 | - * | ||
| 44 | - * @return | ||
| 45 | - */ | ||
| 46 | - @GetMapping(value = "/**") | ||
| 47 | - @ResponseBody | ||
| 48 | - public void download(HttpServletRequest request, HttpServletResponse response) throws IOException { | ||
| 49 | - | ||
| 50 | - List<String> videoList = new ArrayList<>(); | ||
| 51 | - videoList.add("/home/lin/server/test/zlm/Debug/www/record/rtp/34020000002000000003_34020000001310000001/2023-03-20/16-09-07.mp4"); | ||
| 52 | - videoList.add("/home/lin/server/test/zlm/Debug/www/record/rtp/34020000002000000003_34020000001310000001/2023-03-20/17-12-10.mp4"); | ||
| 53 | - videoList.add("/home/lin/server/test/zlm/Debug/www/record/rtp/34020000002000000003_34020000001310000001/2023-03-20/17-38-36.mp4"); | ||
| 54 | - List<Movie> sourceMovies = new ArrayList<>(); | ||
| 55 | - for (String video : videoList) { | ||
| 56 | - sourceMovies.add(MovieCreator.build(video)); | ||
| 57 | - } | ||
| 58 | - | ||
| 59 | - List<Track> videoTracks = new LinkedList<>(); | ||
| 60 | - List<Track> audioTracks = new LinkedList<>(); | ||
| 61 | - for (Movie movie : sourceMovies) { | ||
| 62 | - for (Track track : movie.getTracks()) { | ||
| 63 | - if ("soun".equals(track.getHandler())) { | ||
| 64 | - audioTracks.add(track); | ||
| 65 | - } | ||
| 66 | - | ||
| 67 | - if ("vide".equals(track.getHandler())) { | ||
| 68 | - videoTracks.add(track); | ||
| 69 | - } | ||
| 70 | - } | ||
| 71 | - } | ||
| 72 | - Movie mergeMovie = new Movie(); | ||
| 73 | - if (audioTracks.size() > 0) { | ||
| 74 | - mergeMovie.addTrack(new AppendTrack(audioTracks.toArray(new Track[audioTracks.size()]))); | ||
| 75 | - } | ||
| 76 | - | ||
| 77 | - if (videoTracks.size() > 0) { | ||
| 78 | - mergeMovie.addTrack(new AppendTrack(videoTracks.toArray(new Track[videoTracks.size()]))); | ||
| 79 | - } | ||
| 80 | - | ||
| 81 | - BasicContainer out = (BasicContainer)new DefaultMp4Builder().build(mergeMovie); | ||
| 82 | - | ||
| 83 | - // 文件名 | ||
| 84 | - String fileName = "测试.mp4"; | ||
| 85 | - // 文件类型 | ||
| 86 | - String contentType = request.getServletContext().getMimeType(fileName); | ||
| 87 | - | ||
| 88 | - // 解决下载文件时文件名乱码问题 | ||
| 89 | - byte[] fileNameBytes = fileName.getBytes(StandardCharsets.UTF_8); | ||
| 90 | - fileName = new String(fileNameBytes, 0, fileNameBytes.length, StandardCharsets.ISO_8859_1); | ||
| 91 | - | ||
| 92 | - response.setHeader("Content-Type", contentType); | ||
| 93 | - response.setHeader("Content-Length", String.valueOf(out)); | ||
| 94 | - //inline表示浏览器直接使用,attachment表示下载,fileName表示下载的文件名 | ||
| 95 | - response.setHeader("Content-Disposition", "inline;filename=" + fileName); | ||
| 96 | - response.setContentType(contentType); | ||
| 97 | - | ||
| 98 | - WritableByteChannel writableByteChannel = Channels.newChannel(response.getOutputStream()); | ||
| 99 | - out.writeContainer(writableByteChannel); | ||
| 100 | - writableByteChannel.close(); | ||
| 101 | - | ||
| 102 | - } | ||
| 103 | -} |
src/main/java/top/panll/assist/controller/RecordController.java
| 1 | package top.panll.assist.controller; | 1 | package top.panll.assist.controller; |
| 2 | 2 | ||
| 3 | -import com.alibaba.fastjson.JSON; | ||
| 4 | -import com.alibaba.fastjson.JSONObject; | ||
| 5 | import io.swagger.v3.oas.annotations.Operation; | 3 | import io.swagger.v3.oas.annotations.Operation; |
| 6 | import io.swagger.v3.oas.annotations.Parameter; | 4 | import io.swagger.v3.oas.annotations.Parameter; |
| 7 | import io.swagger.v3.oas.annotations.tags.Tag; | 5 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 8 | -import org.apache.commons.io.FileUtils; | ||
| 9 | import org.slf4j.Logger; | 6 | import org.slf4j.Logger; |
| 10 | import org.slf4j.LoggerFactory; | 7 | import org.slf4j.LoggerFactory; |
| 11 | import org.springframework.beans.factory.annotation.Autowired; | 8 | import org.springframework.beans.factory.annotation.Autowired; |
| 12 | -import org.springframework.http.HttpStatus; | ||
| 13 | -import org.springframework.http.ResponseEntity; | ||
| 14 | import org.springframework.web.bind.annotation.*; | 9 | import org.springframework.web.bind.annotation.*; |
| 15 | -import top.panll.assist.controller.bean.ControllerException; | ||
| 16 | -import top.panll.assist.controller.bean.ErrorCode; | ||
| 17 | -import top.panll.assist.controller.bean.RecordFile; | ||
| 18 | -import top.panll.assist.controller.bean.WVPResult; | 10 | +import top.panll.assist.controller.bean.*; |
| 19 | import top.panll.assist.dto.*; | 11 | import top.panll.assist.dto.*; |
| 20 | import top.panll.assist.service.VideoFileService; | 12 | import top.panll.assist.service.VideoFileService; |
| 21 | -import top.panll.assist.utils.PageInfo; | ||
| 22 | import top.panll.assist.utils.RedisUtil; | 13 | import top.panll.assist.utils.RedisUtil; |
| 23 | 14 | ||
| 24 | -import javax.servlet.http.HttpServletRequest; | ||
| 25 | -import java.io.File; | ||
| 26 | -import java.text.DateFormat; | ||
| 27 | -import java.text.ParseException; | ||
| 28 | import java.text.SimpleDateFormat; | 15 | import java.text.SimpleDateFormat; |
| 29 | import java.util.*; | 16 | import java.util.*; |
| 30 | 17 | ||
| @@ -58,233 +45,19 @@ public class RecordController { | @@ -58,233 +45,19 @@ public class RecordController { | ||
| 58 | return userSettings; | 45 | return userSettings; |
| 59 | } | 46 | } |
| 60 | 47 | ||
| 61 | - /** | ||
| 62 | - * 获取app+stream列表 | ||
| 63 | - * @return | ||
| 64 | - */ | ||
| 65 | - @Operation(summary ="分页获取app+stream的列表") | ||
| 66 | - @Parameter(name = "page", description = "当前页", required = true) | ||
| 67 | - @Parameter(name = "count", description = "每页查询数量", required = true) | ||
| 68 | - @GetMapping(value = "/list") | ||
| 69 | - @ResponseBody | ||
| 70 | - public PageInfo<Map<String, String>> getList(@RequestParam int page, | ||
| 71 | - @RequestParam int count){ | ||
| 72 | - List<Map<String, String>> appList = videoFileService.getList(); | ||
| 73 | - | ||
| 74 | - PageInfo<Map<String, String>> stringPageInfo = new PageInfo<>(appList); | ||
| 75 | - stringPageInfo.startPage(page, count); | ||
| 76 | - return stringPageInfo; | ||
| 77 | - } | ||
| 78 | - | ||
| 79 | - /** | ||
| 80 | - * 分页获取app列表 | ||
| 81 | - * @return | ||
| 82 | - */ | ||
| 83 | - @Operation(summary ="分页获取app列表") | ||
| 84 | - @Parameter(name = "page", description = "当前页", required = true) | ||
| 85 | - @Parameter(name = "count", description = "每页查询数量", required = true) | ||
| 86 | - @GetMapping(value = "/app/list") | ||
| 87 | - @ResponseBody | ||
| 88 | - public PageInfo<String> getAppList(@RequestParam int page, | ||
| 89 | - @RequestParam int count){ | ||
| 90 | - List<String> resultData = new ArrayList<>(); | ||
| 91 | - List<File> appList = videoFileService.getAppList(true); | ||
| 92 | - if (appList.size() > 0) { | ||
| 93 | - for (File file : appList) { | ||
| 94 | - resultData.add(file.getName()); | ||
| 95 | - } | ||
| 96 | - } | ||
| 97 | - Collections.sort(resultData); | ||
| 98 | - | ||
| 99 | - PageInfo<String> stringPageInfo = new PageInfo<>(resultData); | ||
| 100 | - stringPageInfo.startPage(page, count); | ||
| 101 | - return stringPageInfo; | ||
| 102 | - } | ||
| 103 | - | ||
| 104 | - /** | ||
| 105 | - * 分页stream列表 | ||
| 106 | - * @return | ||
| 107 | - */ | ||
| 108 | - @Operation(summary ="分页stream列表") | ||
| 109 | - @Parameter(name = "page", description = "当前页", required = true) | ||
| 110 | - @Parameter(name = "count", description = "每页查询数量", required = true) | ||
| 111 | - @Parameter(name = "app", description = "应用名", required = true) | ||
| 112 | - @GetMapping(value = "/stream/list") | ||
| 113 | - @ResponseBody | ||
| 114 | - public PageInfo<String> getStreamList(@RequestParam int page, | ||
| 115 | - @RequestParam int count, | ||
| 116 | - @RequestParam String app ){ | ||
| 117 | - List<String> resultData = new ArrayList<>(); | ||
| 118 | - if (app == null) { | ||
| 119 | - throw new ControllerException(ErrorCode.ERROR400.getCode(), "app不能为空"); | ||
| 120 | - } | ||
| 121 | - List<File> streamList = videoFileService.getStreamList(app, true); | ||
| 122 | - if (streamList != null) { | ||
| 123 | - for (File file : streamList) { | ||
| 124 | - resultData.add(file.getName()); | ||
| 125 | - } | ||
| 126 | - } | ||
| 127 | - PageInfo<String> stringPageInfo = new PageInfo<>(resultData); | ||
| 128 | - stringPageInfo.startPage(page, count); | ||
| 129 | - return stringPageInfo; | ||
| 130 | - } | ||
| 131 | - | ||
| 132 | - /** | ||
| 133 | - * 获取日期文件夹列表 | ||
| 134 | - * @return | ||
| 135 | - */ | ||
| 136 | - @Operation(summary ="获取日期文件夹列表") | ||
| 137 | - @Parameter(name = "year", description = "月", required = true) | ||
| 138 | - @Parameter(name = "month", description = "年", required = true) | ||
| 139 | - @Parameter(name = "app", description = "应用名", required = true) | ||
| 140 | - @Parameter(name = "stream", description = "流ID", required = true) | ||
| 141 | - @GetMapping(value = "/date/list") | ||
| 142 | - @ResponseBody | ||
| 143 | - public List<String> getDateList( @RequestParam(required = false) Integer year, | ||
| 144 | - @RequestParam(required = false) Integer month, | ||
| 145 | - @RequestParam String app, | ||
| 146 | - @RequestParam String stream ){ | ||
| 147 | - List<String> resultData = new ArrayList<>(); | ||
| 148 | - if (app == null) { | ||
| 149 | - throw new ControllerException(ErrorCode.ERROR400.getCode(), "app不能为空"); | ||
| 150 | - }; | ||
| 151 | - if (stream == null) { | ||
| 152 | - throw new ControllerException(ErrorCode.ERROR400.getCode(), "stream不能为空"); | ||
| 153 | - } | ||
| 154 | - List<File> dateList = videoFileService.getDateList(app, stream, year, month, true); | ||
| 155 | - for (File file : dateList) { | ||
| 156 | - resultData.add(file.getName()); | ||
| 157 | - } | ||
| 158 | - return resultData; | ||
| 159 | - } | ||
| 160 | - | ||
| 161 | - /** | ||
| 162 | - * 获取视频文件列表 | ||
| 163 | - * @return | ||
| 164 | - */ | ||
| 165 | - @Operation(summary ="获取视频文件列表") | ||
| 166 | - @Parameter(name = "page", description = "当前页", required = true) | ||
| 167 | - @Parameter(name = "count", description = "每页查询数量", required = true) | ||
| 168 | - @Parameter(name = "app", description = "应用名", required = true) | ||
| 169 | - @Parameter(name = "stream", description = "流ID", required = true) | ||
| 170 | - @Parameter(name = "startTime", description = "开始时间(yyyy-MM-dd HH:mm:ss)", required = true) | ||
| 171 | - @Parameter(name = "endTime", description = "结束时间(yyyy-MM-dd HH:mm:ss)", required = true) | ||
| 172 | - @GetMapping(value = "/file/list") | ||
| 173 | - @ResponseBody | ||
| 174 | - public PageInfo<String> getRecordList(@RequestParam int page, | ||
| 175 | - @RequestParam int count, | ||
| 176 | - @RequestParam String app, | ||
| 177 | - @RequestParam String stream, | ||
| 178 | - @RequestParam(required = false) String startTime, | ||
| 179 | - @RequestParam(required = false) String endTime | ||
| 180 | - ){ | ||
| 181 | - | ||
| 182 | - // 开始时间与结束时间可不传或只传其一 | ||
| 183 | - List<String> recordList = new ArrayList<>(); | ||
| 184 | - try { | ||
| 185 | - Date startTimeDate = null; | ||
| 186 | - Date endTimeDate = null; | ||
| 187 | - if (startTime != null ) { | ||
| 188 | - startTimeDate = formatter.parse(startTime); | ||
| 189 | - } | ||
| 190 | - if (endTime != null ) { | ||
| 191 | - endTimeDate = formatter.parse(endTime); | ||
| 192 | - } | ||
| 193 | - | ||
| 194 | - List<File> filesInTime = videoFileService.getFilesInTime(app, stream, startTimeDate, endTimeDate); | ||
| 195 | - if (filesInTime != null && filesInTime.size() > 0) { | ||
| 196 | - for (File file : filesInTime) { | ||
| 197 | - recordList.add(file.getName()); | ||
| 198 | - } | ||
| 199 | - } | ||
| 200 | - PageInfo<String> stringPageInfo = new PageInfo<>(recordList); | ||
| 201 | - stringPageInfo.startPage(page, count); | ||
| 202 | - return stringPageInfo; | ||
| 203 | - } catch (ParseException e) { | ||
| 204 | - logger.error("错误的开始时间[{}]或结束时间[{}]", startTime, endTime); | ||
| 205 | - throw new ControllerException(ErrorCode.ERROR400.getCode(), "错误的开始时间或结束时间, e=" + e.getMessage()); | ||
| 206 | - } | ||
| 207 | - } | ||
| 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 | - | ||
| 257 | 48 | ||
| 258 | /** | 49 | /** |
| 259 | * 添加视频裁剪合并任务 | 50 | * 添加视频裁剪合并任务 |
| 260 | */ | 51 | */ |
| 261 | @Operation(summary ="添加视频裁剪合并任务") | 52 | @Operation(summary ="添加视频裁剪合并任务") |
| 262 | - @Parameter(name = "app", description = "应用名", required = true) | ||
| 263 | - @Parameter(name = "stream", description = "流ID", required = true) | ||
| 264 | - @Parameter(name = "startTime", description = "开始时间(yyyy-MM-dd HH:mm:ss)", required = true) | ||
| 265 | - @Parameter(name = "endTime", description = "结束时间(yyyy-MM-dd HH:mm:ss)", required = true) | ||
| 266 | - @Parameter(name = "remoteHost", description = "服务的IP:端口(用于直接返回完整播放地址以及下载地址)", required = true) | ||
| 267 | - @GetMapping(value = "/file/download/task/add") | 53 | + @Parameter(name = "videoTaskInfo", description = "视频合并任务的信息", required = true) |
| 54 | + @PostMapping(value = "/file/download/task/add") | ||
| 268 | @ResponseBody | 55 | @ResponseBody |
| 269 | - public String addTaskForDownload(@RequestParam String app, | ||
| 270 | - @RequestParam String stream, | ||
| 271 | - @RequestParam(required = false) String startTime, | ||
| 272 | - @RequestParam(required = false) String endTime, | ||
| 273 | - @RequestParam(required = false) String remoteHost | ||
| 274 | - ){ | ||
| 275 | - Date startTimeDate = null; | ||
| 276 | - Date endTimeDate = null; | ||
| 277 | - try { | ||
| 278 | - if (startTime != null ) { | ||
| 279 | - startTimeDate = formatter.parse(startTime); | ||
| 280 | - } | ||
| 281 | - if (endTime != null ) { | ||
| 282 | - endTimeDate = formatter.parse(endTime); | ||
| 283 | - } | ||
| 284 | - } catch (ParseException e) { | ||
| 285 | - e.printStackTrace(); | 56 | + public String addTaskForDownload(@RequestBody VideoTaskInfo videoTaskInfo ){ |
| 57 | + if (videoTaskInfo.getFilePathList() == null || videoTaskInfo.getFilePathList().isEmpty()) { | ||
| 58 | + throw new ControllerException(ErrorCode.ERROR100.getCode(), "视频文件列表不可为空"); | ||
| 286 | } | 59 | } |
| 287 | - String id = videoFileService.mergeOrCut(app, stream, startTimeDate, endTimeDate, remoteHost); | 60 | + String id = videoFileService.mergeOrCut(videoTaskInfo); |
| 288 | if (id== null) { | 61 | if (id== null) { |
| 289 | throw new ControllerException(ErrorCode.ERROR100.getCode(), "可能未找到视频文件"); | 62 | throw new ControllerException(ErrorCode.ERROR100.getCode(), "可能未找到视频文件"); |
| 290 | } | 63 | } |
| @@ -295,8 +68,6 @@ public class RecordController { | @@ -295,8 +68,6 @@ public class RecordController { | ||
| 295 | * 查询视频裁剪合并任务列表 | 68 | * 查询视频裁剪合并任务列表 |
| 296 | */ | 69 | */ |
| 297 | @Operation(summary ="查询视频裁剪合并任务列表") | 70 | @Operation(summary ="查询视频裁剪合并任务列表") |
| 298 | - @Parameter(name = "app", description = "应用名", required = true) | ||
| 299 | - @Parameter(name = "stream", description = "流ID", required = true) | ||
| 300 | @Parameter(name = "taskId", description = "任务ID", required = true) | 71 | @Parameter(name = "taskId", description = "任务ID", required = true) |
| 301 | @Parameter(name = "isEnd", description = "是否结束", required = true) | 72 | @Parameter(name = "isEnd", description = "是否结束", required = true) |
| 302 | @GetMapping(value = "/file/download/task/list") | 73 | @GetMapping(value = "/file/download/task/list") |
| @@ -304,9 +75,10 @@ public class RecordController { | @@ -304,9 +75,10 @@ public class RecordController { | ||
| 304 | public List<MergeOrCutTaskInfo> getTaskListForDownload( | 75 | public List<MergeOrCutTaskInfo> getTaskListForDownload( |
| 305 | @RequestParam(required = false) String app, | 76 | @RequestParam(required = false) String app, |
| 306 | @RequestParam(required = false) String stream, | 77 | @RequestParam(required = false) String stream, |
| 78 | + @RequestParam(required = false) String callId, | ||
| 307 | @RequestParam(required = false) String taskId, | 79 | @RequestParam(required = false) String taskId, |
| 308 | @RequestParam(required = false) Boolean isEnd){ | 80 | @RequestParam(required = false) Boolean isEnd){ |
| 309 | - List<MergeOrCutTaskInfo> taskList = videoFileService.getTaskListForDownload(isEnd, app, stream, taskId); | 81 | + List<MergeOrCutTaskInfo> taskList = videoFileService.getTaskListForDownload(app, stream, callId, isEnd, taskId); |
| 310 | if (taskList == null) { | 82 | if (taskList == null) { |
| 311 | throw new ControllerException(ErrorCode.ERROR100); | 83 | throw new ControllerException(ErrorCode.ERROR100); |
| 312 | } | 84 | } |
| @@ -314,64 +86,6 @@ public class RecordController { | @@ -314,64 +86,6 @@ public class RecordController { | ||
| 314 | } | 86 | } |
| 315 | 87 | ||
| 316 | /** | 88 | /** |
| 317 | - * 收藏录像(被收藏的录像不会被清理任务清理) | ||
| 318 | - */ | ||
| 319 | - @Operation(summary ="收藏录像(被收藏的录像不会被清理任务清理)") | ||
| 320 | - @Parameter(name = "type", description = "类型", required = true) | ||
| 321 | - @Parameter(name = "app", description = "应用名", required = true) | ||
| 322 | - @Parameter(name = "stream", description = "流ID", required = true) | ||
| 323 | - @GetMapping(value = "/file/collection/add") | ||
| 324 | - @ResponseBody | ||
| 325 | - public void collection( | ||
| 326 | - @RequestParam(required = true) String type, | ||
| 327 | - @RequestParam(required = true) String app, | ||
| 328 | - @RequestParam(required = true) String stream){ | ||
| 329 | - | ||
| 330 | - boolean collectionResult = videoFileService.collection(app, stream, type); | ||
| 331 | - if (!collectionResult) { | ||
| 332 | - throw new ControllerException(ErrorCode.ERROR100); | ||
| 333 | - } | ||
| 334 | - } | ||
| 335 | - | ||
| 336 | - /** | ||
| 337 | - * 移除收藏录像 | ||
| 338 | - */ | ||
| 339 | - @Operation(summary ="移除收藏录像") | ||
| 340 | - @Parameter(name = "type", description = "类型", required = true) | ||
| 341 | - @Parameter(name = "app", description = "应用名", required = true) | ||
| 342 | - @Parameter(name = "stream", description = "流ID", required = true) | ||
| 343 | - @GetMapping(value = "/file/collection/remove") | ||
| 344 | - @ResponseBody | ||
| 345 | - public void removeCollection( | ||
| 346 | - @RequestParam(required = true) String type, | ||
| 347 | - @RequestParam(required = true) String app, | ||
| 348 | - @RequestParam(required = true) String stream){ | ||
| 349 | - | ||
| 350 | - boolean collectionResult = videoFileService.removeCollection(app, stream, type); | ||
| 351 | - if (!collectionResult) { | ||
| 352 | - throw new ControllerException(ErrorCode.ERROR100); | ||
| 353 | - } | ||
| 354 | - } | ||
| 355 | - | ||
| 356 | - /** | ||
| 357 | - * 收藏录像列表 | ||
| 358 | - */ | ||
| 359 | - @Operation(summary ="收藏录像列表") | ||
| 360 | - @Parameter(name = "type", description = "类型", required = false) | ||
| 361 | - @Parameter(name = "app", description = "应用名", required = false) | ||
| 362 | - @Parameter(name = "stream", description = "流ID", required = false) | ||
| 363 | - @GetMapping(value = "/file/collection/list") | ||
| 364 | - @ResponseBody | ||
| 365 | - public List<SignInfo> collectionList( | ||
| 366 | - @RequestParam(required = false) String type, | ||
| 367 | - @RequestParam(required = false) String app, | ||
| 368 | - @RequestParam(required = false) String stream){ | ||
| 369 | - | ||
| 370 | - List<SignInfo> signInfos = videoFileService.getCollectionList(app, stream, type); | ||
| 371 | - return signInfos; | ||
| 372 | - } | ||
| 373 | - | ||
| 374 | - /** | ||
| 375 | * 中止视频裁剪合并任务列表 | 89 | * 中止视频裁剪合并任务列表 |
| 376 | */ | 90 | */ |
| 377 | @Operation(summary ="中止视频裁剪合并任务列表(暂不支持)") | 91 | @Operation(summary ="中止视频裁剪合并任务列表(暂不支持)") |
| @@ -391,35 +105,6 @@ public class RecordController { | @@ -391,35 +105,6 @@ public class RecordController { | ||
| 391 | } | 105 | } |
| 392 | 106 | ||
| 393 | /** | 107 | /** |
| 394 | - * 录制完成的通知, 对用zlm的hook | ||
| 395 | - * @return | ||
| 396 | - */ | ||
| 397 | - @ResponseBody | ||
| 398 | - @PostMapping(value = "/on_record_mp4", produces = "application/json;charset=UTF-8") | ||
| 399 | - public ResponseEntity<String> onRecordMp4(@RequestBody JSONObject json) { | ||
| 400 | - JSONObject ret = new JSONObject(); | ||
| 401 | - ret.put("code", 0); | ||
| 402 | - ret.put("msg", "success"); | ||
| 403 | - String file_path = json.getString("file_path"); | ||
| 404 | - | ||
| 405 | - String app = json.getString("app"); | ||
| 406 | - String stream = json.getString("stream"); | ||
| 407 | - logger.debug("ZLM 录制完成,文件路径:" + file_path); | ||
| 408 | - | ||
| 409 | - if (file_path == null) { | ||
| 410 | - return new ResponseEntity<String>(ret.toString(), HttpStatus.OK); | ||
| 411 | - } | ||
| 412 | - if (userSettings.getRecordDay() <= 0) { | ||
| 413 | - logger.info("录像保存事件为{}天,直接删除: {}", userSettings.getRecordDay(), file_path); | ||
| 414 | - FileUtils.deleteQuietly(new File(file_path)); | ||
| 415 | - }else { | ||
| 416 | - videoFileService.handFile(new File(file_path), app, stream); | ||
| 417 | - } | ||
| 418 | - | ||
| 419 | - return new ResponseEntity<String>(ret.toString(), HttpStatus.OK); | ||
| 420 | - } | ||
| 421 | - | ||
| 422 | - /** | ||
| 423 | * 磁盘空间查询 | 108 | * 磁盘空间查询 |
| 424 | */ | 109 | */ |
| 425 | @Operation(summary ="磁盘空间查询") | 110 | @Operation(summary ="磁盘空间查询") |
| @@ -430,21 +115,6 @@ public class RecordController { | @@ -430,21 +115,6 @@ public class RecordController { | ||
| 430 | } | 115 | } |
| 431 | 116 | ||
| 432 | /** | 117 | /** |
| 433 | - * 增加推流的鉴权信息,用于录像存储使用 | ||
| 434 | - */ | ||
| 435 | - @Operation(summary ="增加推流的鉴权信息") | ||
| 436 | - @Parameter(name = "app", description = "应用名", required = true) | ||
| 437 | - @Parameter(name = "stream", description = "流ID", required = true) | ||
| 438 | - @Parameter(name = "callId", description = "录像自鉴权ID", required = true) | ||
| 439 | - @ResponseBody | ||
| 440 | - @GetMapping(value = "/addStreamCallInfo", produces = "application/json;charset=UTF-8") | ||
| 441 | - @PostMapping(value = "/addStreamCallInfo", produces = "application/json;charset=UTF-8") | ||
| 442 | - public void addStreamCallInfo(String app, String stream, String callId) { | ||
| 443 | - String key = AssistConstants.STREAM_CALL_INFO + userSettings.getId() + "_" + app + "_" + stream; | ||
| 444 | - redisUtil.set(key, callId, -1); | ||
| 445 | - } | ||
| 446 | - | ||
| 447 | - /** | ||
| 448 | * 录像文件的时长 | 118 | * 录像文件的时长 |
| 449 | */ | 119 | */ |
| 450 | @Operation(summary ="录像文件的时长") | 120 | @Operation(summary ="录像文件的时长") |
src/main/java/top/panll/assist/controller/bean/FileLIstInfo.java
0 → 100644
| 1 | +package top.panll.assist.controller.bean; | ||
| 2 | + | ||
| 3 | +import java.util.List; | ||
| 4 | + | ||
| 5 | +public class FileLIstInfo { | ||
| 6 | + | ||
| 7 | + private List<String> filePathList; | ||
| 8 | + | ||
| 9 | + public List<String> getFilePathList() { | ||
| 10 | + return filePathList; | ||
| 11 | + } | ||
| 12 | + | ||
| 13 | + public void setFilePathList(List<String> filePathList) { | ||
| 14 | + this.filePathList = filePathList; | ||
| 15 | + } | ||
| 16 | +} |
src/main/java/top/panll/assist/dto/MergeOrCutTaskInfo.java
| @@ -3,12 +3,7 @@ package top.panll.assist.dto; | @@ -3,12 +3,7 @@ package top.panll.assist.dto; | ||
| 3 | 3 | ||
| 4 | public class MergeOrCutTaskInfo { | 4 | public class MergeOrCutTaskInfo { |
| 5 | private String id; | 5 | private String id; |
| 6 | - private String app; | ||
| 7 | - private String stream; | ||
| 8 | - private String startTime; | ||
| 9 | - private String endTime; | ||
| 10 | private String createTime; | 6 | private String createTime; |
| 11 | - | ||
| 12 | private String percentage; | 7 | private String percentage; |
| 13 | 8 | ||
| 14 | private String recordFile; | 9 | private String recordFile; |
| @@ -17,6 +12,12 @@ public class MergeOrCutTaskInfo { | @@ -17,6 +12,12 @@ public class MergeOrCutTaskInfo { | ||
| 17 | 12 | ||
| 18 | private String playFile; | 13 | private String playFile; |
| 19 | 14 | ||
| 15 | + private String app; | ||
| 16 | + private String stream; | ||
| 17 | + private String startTime; | ||
| 18 | + private String endTime; | ||
| 19 | + private String callId; | ||
| 20 | + | ||
| 20 | public String getId() { | 21 | public String getId() { |
| 21 | return id; | 22 | return id; |
| 22 | } | 23 | } |
| @@ -25,38 +26,6 @@ public class MergeOrCutTaskInfo { | @@ -25,38 +26,6 @@ public class MergeOrCutTaskInfo { | ||
| 25 | this.id = id; | 26 | this.id = id; |
| 26 | } | 27 | } |
| 27 | 28 | ||
| 28 | - public String getStartTime() { | ||
| 29 | - return startTime; | ||
| 30 | - } | ||
| 31 | - | ||
| 32 | - public void setStartTime(String startTime) { | ||
| 33 | - this.startTime = startTime; | ||
| 34 | - } | ||
| 35 | - | ||
| 36 | - public String getEndTime() { | ||
| 37 | - return endTime; | ||
| 38 | - } | ||
| 39 | - | ||
| 40 | - public void setEndTime(String endTime) { | ||
| 41 | - this.endTime = endTime; | ||
| 42 | - } | ||
| 43 | - | ||
| 44 | - public String getApp() { | ||
| 45 | - return app; | ||
| 46 | - } | ||
| 47 | - | ||
| 48 | - public void setApp(String app) { | ||
| 49 | - this.app = app; | ||
| 50 | - } | ||
| 51 | - | ||
| 52 | - public String getStream() { | ||
| 53 | - return stream; | ||
| 54 | - } | ||
| 55 | - | ||
| 56 | - public void setStream(String stream) { | ||
| 57 | - this.stream = stream; | ||
| 58 | - } | ||
| 59 | - | ||
| 60 | public String getPercentage() { | 29 | public String getPercentage() { |
| 61 | return percentage; | 30 | return percentage; |
| 62 | } | 31 | } |
| @@ -96,4 +65,44 @@ public class MergeOrCutTaskInfo { | @@ -96,4 +65,44 @@ public class MergeOrCutTaskInfo { | ||
| 96 | public void setCreateTime(String createTime) { | 65 | public void setCreateTime(String createTime) { |
| 97 | this.createTime = createTime; | 66 | this.createTime = createTime; |
| 98 | } | 67 | } |
| 68 | + | ||
| 69 | + public String getApp() { | ||
| 70 | + return app; | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + public void setApp(String app) { | ||
| 74 | + this.app = app; | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + public String getStream() { | ||
| 78 | + return stream; | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + public void setStream(String stream) { | ||
| 82 | + this.stream = stream; | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + public String getStartTime() { | ||
| 86 | + return startTime; | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + public void setStartTime(String startTime) { | ||
| 90 | + this.startTime = startTime; | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + public String getEndTime() { | ||
| 94 | + return endTime; | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + public void setEndTime(String endTime) { | ||
| 98 | + this.endTime = endTime; | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + public String getCallId() { | ||
| 102 | + return callId; | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + public void setCallId(String callId) { | ||
| 106 | + this.callId = callId; | ||
| 107 | + } | ||
| 99 | } | 108 | } |
src/main/java/top/panll/assist/dto/UserSettings.java
| @@ -12,13 +12,10 @@ public class UserSettings { | @@ -12,13 +12,10 @@ public class UserSettings { | ||
| 12 | @Value("${userSettings.id}") | 12 | @Value("${userSettings.id}") |
| 13 | private String id; | 13 | private String id; |
| 14 | 14 | ||
| 15 | - @Value("${userSettings.record}") | ||
| 16 | - private String record; | 15 | + @Value("${userSettings.record-temp:./recordTemp}") |
| 16 | + private String recordTempPath; | ||
| 17 | 17 | ||
| 18 | - @Value("${userSettings.recordDay:7}") | ||
| 19 | - private int recordDay; | ||
| 20 | - | ||
| 21 | - @Value("${userSettings.recordTempDay:-1}") | 18 | + @Value("${userSettings.record-temp-day:7}") |
| 22 | private int recordTempDay; | 19 | private int recordTempDay; |
| 23 | 20 | ||
| 24 | @Value("${userSettings.ffmpeg}") | 21 | @Value("${userSettings.ffmpeg}") |
| @@ -38,14 +35,6 @@ public class UserSettings { | @@ -38,14 +35,6 @@ public class UserSettings { | ||
| 38 | this.id = id; | 35 | this.id = id; |
| 39 | } | 36 | } |
| 40 | 37 | ||
| 41 | - public String getRecord() { | ||
| 42 | - return record; | ||
| 43 | - } | ||
| 44 | - | ||
| 45 | - public void setRecord(String record) { | ||
| 46 | - this.record = record; | ||
| 47 | - } | ||
| 48 | - | ||
| 49 | public String getFfmpeg() { | 38 | public String getFfmpeg() { |
| 50 | return ffmpeg; | 39 | return ffmpeg; |
| 51 | } | 40 | } |
| @@ -62,20 +51,9 @@ public class UserSettings { | @@ -62,20 +51,9 @@ public class UserSettings { | ||
| 62 | this.ffprobe = ffprobe; | 51 | this.ffprobe = ffprobe; |
| 63 | } | 52 | } |
| 64 | 53 | ||
| 65 | - public int getRecordDay() { | ||
| 66 | - return recordDay; | ||
| 67 | - } | ||
| 68 | - | ||
| 69 | - public void setRecordDay(int recordDay) { | ||
| 70 | - this.recordDay = recordDay; | ||
| 71 | - } | ||
| 72 | 54 | ||
| 73 | public int getRecordTempDay() { | 55 | public int getRecordTempDay() { |
| 74 | - if (recordTempDay == -1) { | ||
| 75 | - return recordDay; | ||
| 76 | - }else { | ||
| 77 | - return recordTempDay; | ||
| 78 | - } | 56 | + return recordTempDay; |
| 79 | } | 57 | } |
| 80 | 58 | ||
| 81 | public void setRecordTempDay(int recordTempDay) { | 59 | public void setRecordTempDay(int recordTempDay) { |
| @@ -89,4 +67,12 @@ public class UserSettings { | @@ -89,4 +67,12 @@ public class UserSettings { | ||
| 89 | public void setThreads(int threads) { | 67 | public void setThreads(int threads) { |
| 90 | this.threads = threads; | 68 | this.threads = threads; |
| 91 | } | 69 | } |
| 70 | + | ||
| 71 | + public String getRecordTempPath() { | ||
| 72 | + return recordTempPath; | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + public void setRecordTempPath(String recordTempPath) { | ||
| 76 | + this.recordTempPath = recordTempPath; | ||
| 77 | + } | ||
| 92 | } | 78 | } |
src/main/java/top/panll/assist/dto/VideoTaskInfo.java
0 → 100644
| 1 | +package top.panll.assist.dto; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.Parameter; | ||
| 4 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 5 | + | ||
| 6 | +import java.util.List; | ||
| 7 | + | ||
| 8 | +@Schema(description = "视频合并任务的信息") | ||
| 9 | +public class VideoTaskInfo { | ||
| 10 | + | ||
| 11 | + private String app; | ||
| 12 | + private String stream; | ||
| 13 | + private String startTime; | ||
| 14 | + private String endTime; | ||
| 15 | + private String callId; | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + @Schema(description = "视频文件路径列表") | ||
| 19 | + private List<String> filePathList; | ||
| 20 | + | ||
| 21 | + @Schema(description = "返回地址时的远程地址") | ||
| 22 | + private String remoteHost; | ||
| 23 | + | ||
| 24 | + public List<String> getFilePathList() { | ||
| 25 | + return filePathList; | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + public void setFilePathList(List<String> filePathList) { | ||
| 29 | + this.filePathList = filePathList; | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + public String getRemoteHost() { | ||
| 33 | + return remoteHost; | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + public void setRemoteHost(String remoteHost) { | ||
| 37 | + this.remoteHost = remoteHost; | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + public String getApp() { | ||
| 41 | + return app; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + public void setApp(String app) { | ||
| 45 | + this.app = app; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + public String getStream() { | ||
| 49 | + return stream; | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + public void setStream(String stream) { | ||
| 53 | + this.stream = stream; | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + public String getStartTime() { | ||
| 57 | + return startTime; | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + public void setStartTime(String startTime) { | ||
| 61 | + this.startTime = startTime; | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + public String getEndTime() { | ||
| 65 | + return endTime; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + public void setEndTime(String endTime) { | ||
| 69 | + this.endTime = endTime; | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + public String getCallId() { | ||
| 73 | + return callId; | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + public void setCallId(String callId) { | ||
| 77 | + this.callId = callId; | ||
| 78 | + } | ||
| 79 | +} |
src/main/java/top/panll/assist/service/FFmpegExecUtils.java
| @@ -77,7 +77,7 @@ public class FFmpegExecUtils implements InitializingBean{ | @@ -77,7 +77,7 @@ public class FFmpegExecUtils implements InitializingBean{ | ||
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | @Async | 79 | @Async |
| 80 | - public void mergeOrCutFile(List<File> fils, File dest, String destFileName, VideoHandEndCallBack callBack){ | 80 | + public void mergeOrCutFile(List<File> fils, File dest, String destFileName, VideoHandEndCallBack callBack){ |
| 81 | 81 | ||
| 82 | if (fils == null || fils.size() == 0 || ffmpeg == null || ffprobe == null || dest== null || !dest.exists()){ | 82 | if (fils == null || fils.size() == 0 || ffmpeg == null || ffprobe == null || dest== null || !dest.exists()){ |
| 83 | callBack.run("error", 0.0, null); | 83 | callBack.run("error", 0.0, null); |
| @@ -95,7 +95,7 @@ public class FFmpegExecUtils implements InitializingBean{ | @@ -95,7 +95,7 @@ public class FFmpegExecUtils implements InitializingBean{ | ||
| 95 | BufferedWriter bw =new BufferedWriter(new FileWriter(fileListName)); | 95 | BufferedWriter bw =new BufferedWriter(new FileWriter(fileListName)); |
| 96 | for (File file : fils) { | 96 | for (File file : fils) { |
| 97 | VideoFile videoFile = VideoFileFactory.createFile(this, file); | 97 | VideoFile videoFile = VideoFileFactory.createFile(this, file); |
| 98 | - if (videoFile == null || !videoFile.isTargetFormat()) { | 98 | + if (videoFile == null) { |
| 99 | return; | 99 | return; |
| 100 | } | 100 | } |
| 101 | bw.write("file " + file.getAbsolutePath()); | 101 | bw.write("file " + file.getAbsolutePath()); |
| @@ -129,15 +129,15 @@ public class FFmpegExecUtils implements InitializingBean{ | @@ -129,15 +129,15 @@ public class FFmpegExecUtils implements InitializingBean{ | ||
| 129 | double percentage = progress.out_time_ns / duration_ns; | 129 | double percentage = progress.out_time_ns / duration_ns; |
| 130 | 130 | ||
| 131 | // Print out interesting information about the progress | 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 | - )); | 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 | +// )); | ||
| 141 | 141 | ||
| 142 | if (progress.status.equals(Progress.Status.END)){ | 142 | if (progress.status.equals(Progress.Status.END)){ |
| 143 | callBack.run(progress.status.name(), percentage, recordFileResultPath); | 143 | callBack.run(progress.status.name(), percentage, recordFileResultPath); |
src/main/java/top/panll/assist/service/FileManagerTimer.java
| @@ -39,112 +39,47 @@ public class FileManagerTimer { | @@ -39,112 +39,47 @@ public class FileManagerTimer { | ||
| 39 | // @Scheduled(fixedDelay = 2000) //测试 20秒执行一次 | 39 | // @Scheduled(fixedDelay = 2000) //测试 20秒执行一次 |
| 40 | @Scheduled(cron = "0 0 0 * * ?") //每天的0点执行 | 40 | @Scheduled(cron = "0 0 0 * * ?") //每天的0点执行 |
| 41 | public void execute(){ | 41 | public void execute(){ |
| 42 | - if (userSettings.getRecord() == null) { | 42 | + if (userSettings.getRecordTempPath() == null) { |
| 43 | return; | 43 | return; |
| 44 | } | 44 | } |
| 45 | - int recordDay = userSettings.getRecordDay(); | ||
| 46 | - Date lastDate=new Date(); | ||
| 47 | - Calendar lastCalendar = Calendar.getInstance(); | ||
| 48 | - if (recordDay > 0) { | ||
| 49 | - lastCalendar.setTime(lastDate); | ||
| 50 | - lastCalendar.add(Calendar.DAY_OF_MONTH, 0 - recordDay); | ||
| 51 | - lastDate = lastCalendar.getTime(); | ||
| 52 | - } | ||
| 53 | 45 | ||
| 54 | - logger.info("[录像巡查]移除 {} 之前的文件", formatter.format(lastDate)); | ||
| 55 | - File recordFileDir = new File(userSettings.getRecord()); | ||
| 56 | - if (recordFileDir.canWrite()) { | ||
| 57 | - List<File> appList = videoFileService.getAppList(false); | ||
| 58 | - if (appList != null && appList.size() > 0) { | ||
| 59 | - for (File appFile : appList) { | ||
| 60 | - if ("download.html".equals(appFile.getName())) { | ||
| 61 | - continue; | ||
| 62 | - } | ||
| 63 | - List<File> streamList = videoFileService.getStreamList(appFile, false); | ||
| 64 | - if (streamList != null && streamList.size() > 0) { | ||
| 65 | - for (File streamFile : streamList) { | ||
| 66 | - // 带有sig标记文件的为收藏文件,不被自动清理任务移除 | ||
| 67 | - File[] signFiles = streamFile.listFiles((File dir, String name) -> { | ||
| 68 | - File currentFile = new File(dir.getAbsolutePath() + File.separator + name); | ||
| 69 | - return currentFile.isFile() && name.endsWith(".sign"); | ||
| 70 | - }); | ||
| 71 | - if (signFiles != null && signFiles.length > 0) { | ||
| 72 | - continue; | ||
| 73 | - } | ||
| 74 | - List<File> dateList = videoFileService.getDateList(streamFile, null, null, false); | ||
| 75 | - if (dateList != null && dateList.size() > 0) { | ||
| 76 | - for (File dateFile : dateList) { | ||
| 77 | - try { | ||
| 78 | - Date parse = formatter.parse(dateFile.getName()); | ||
| 79 | - if (parse.before(lastDate)) { | ||
| 80 | - boolean result = FileUtils.deleteQuietly(dateFile); | ||
| 81 | - if (result) { | ||
| 82 | - logger.info("[录像巡查]成功移除 {} ", dateFile.getAbsolutePath()); | ||
| 83 | - }else { | ||
| 84 | - logger.info("[录像巡查]移除失败 {} ", dateFile.getAbsolutePath()); | ||
| 85 | - } | ||
| 86 | - } | ||
| 87 | - } catch (ParseException e) { | ||
| 88 | - e.printStackTrace(); | ||
| 89 | - } | ||
| 90 | - } | ||
| 91 | - } | ||
| 92 | - if (streamFile.listFiles() == null || streamFile.listFiles().length == 0) { | ||
| 93 | - boolean result = FileUtils.deleteQuietly(streamFile); | ||
| 94 | - if (result) { | ||
| 95 | - logger.info("[录像巡查]成功移除 {} ", streamFile.getAbsolutePath()); | ||
| 96 | - }else { | ||
| 97 | - logger.info("[录像巡查]移除失败 {} ", streamFile.getAbsolutePath()); | ||
| 98 | - } | ||
| 99 | - } | ||
| 100 | - } | ||
| 101 | - } | ||
| 102 | - if (appFile.listFiles() == null || appFile.listFiles().length == 0) { | ||
| 103 | - boolean result = FileUtils.deleteQuietly(appFile); | ||
| 104 | - if (result) { | ||
| 105 | - logger.info("[录像巡查]成功移除 {} ", appFile.getAbsolutePath()); | ||
| 106 | - }else { | ||
| 107 | - logger.info("[录像巡查]移除失败 {} ", appFile.getAbsolutePath()); | ||
| 108 | - } | ||
| 109 | - } | ||
| 110 | - } | ||
| 111 | - } | ||
| 112 | - } | ||
| 113 | // 清理任务临时文件 | 46 | // 清理任务临时文件 |
| 114 | int recordTempDay = userSettings.getRecordTempDay(); | 47 | int recordTempDay = userSettings.getRecordTempDay(); |
| 115 | Date lastTempDate = new Date(); | 48 | Date lastTempDate = new Date(); |
| 116 | Calendar lastTempCalendar = Calendar.getInstance(); | 49 | Calendar lastTempCalendar = Calendar.getInstance(); |
| 117 | lastTempCalendar.setTime(lastTempDate); | 50 | lastTempCalendar.setTime(lastTempDate); |
| 118 | - lastTempCalendar.add(Calendar.DAY_OF_MONTH, 0 - recordTempDay); | 51 | + lastTempCalendar.add(Calendar.DAY_OF_MONTH, -recordTempDay); |
| 119 | lastTempDate = lastTempCalendar.getTime(); | 52 | lastTempDate = lastTempCalendar.getTime(); |
| 120 | logger.info("[录像巡查]移除合并任务临时文件 {} 之前的文件", formatter.format(lastTempDate)); | 53 | logger.info("[录像巡查]移除合并任务临时文件 {} 之前的文件", formatter.format(lastTempDate)); |
| 121 | - File recordTempFile = new File(userSettings.getRecord() + "recordTemp"); | 54 | + File recordTempFile = new File(userSettings.getRecordTempPath()); |
| 122 | if (recordTempFile.exists() && recordTempFile.isDirectory() && recordTempFile.canWrite()) { | 55 | if (recordTempFile.exists() && recordTempFile.isDirectory() && recordTempFile.canWrite()) { |
| 123 | File[] tempFiles = recordTempFile.listFiles(); | 56 | File[] tempFiles = recordTempFile.listFiles(); |
| 124 | - for (File tempFile : tempFiles) { | ||
| 125 | - if (tempFile.isDirectory() && new Date(tempFile.lastModified()).before(lastTempDate)) { | ||
| 126 | - boolean result = FileUtils.deleteQuietly(tempFile); | ||
| 127 | - if (result) { | ||
| 128 | - logger.info("[录像巡查]成功移除合并任务临时文件 {} ", tempFile.getAbsolutePath()); | ||
| 129 | - }else { | ||
| 130 | - logger.info("[录像巡查]合并任务临时文件移除失败 {} ", tempFile.getAbsolutePath()); | 57 | + if (tempFiles != null) { |
| 58 | + for (File tempFile : tempFiles) { | ||
| 59 | + if (tempFile.isFile() && tempFile.lastModified() < lastTempDate.getTime()) { | ||
| 60 | + boolean result = FileUtils.deleteQuietly(tempFile); | ||
| 61 | + if (result) { | ||
| 62 | + logger.info("[录像巡查]成功移除合并任务临时文件 {} ", tempFile.getAbsolutePath()); | ||
| 63 | + }else { | ||
| 64 | + logger.info("[录像巡查]合并任务临时文件移除失败 {} ", tempFile.getAbsolutePath()); | ||
| 65 | + } | ||
| 131 | } | 66 | } |
| 132 | } | 67 | } |
| 133 | } | 68 | } |
| 134 | } | 69 | } |
| 135 | // 清理redis记录 | 70 | // 清理redis记录 |
| 136 | - String key = String.format("%S_%S_*_*_*", AssistConstants.MERGEORCUT, userSettings.getId()); | 71 | + String key = String.format("%S_%S_*", AssistConstants.MERGEORCUT, userSettings.getId()); |
| 137 | List<Object> taskKeys = redisUtil.scan(key); | 72 | List<Object> taskKeys = redisUtil.scan(key); |
| 138 | for (Object taskKeyObj : taskKeys) { | 73 | for (Object taskKeyObj : taskKeys) { |
| 139 | String taskKey = (String) taskKeyObj; | 74 | String taskKey = (String) taskKeyObj; |
| 140 | MergeOrCutTaskInfo mergeOrCutTaskInfo = (MergeOrCutTaskInfo)redisUtil.get(taskKey); | 75 | MergeOrCutTaskInfo mergeOrCutTaskInfo = (MergeOrCutTaskInfo)redisUtil.get(taskKey); |
| 141 | try { | 76 | try { |
| 142 | - if (StringUtils.isEmpty(mergeOrCutTaskInfo.getCreateTime()) | 77 | + if (StringUtils.hasLength(mergeOrCutTaskInfo.getCreateTime()) |
| 143 | || simpleDateFormatForTime.parse(mergeOrCutTaskInfo.getCreateTime()).before(lastTempDate)) { | 78 | || simpleDateFormatForTime.parse(mergeOrCutTaskInfo.getCreateTime()).before(lastTempDate)) { |
| 144 | redisUtil.del(taskKey); | 79 | redisUtil.del(taskKey); |
| 145 | } | 80 | } |
| 146 | } catch (ParseException e) { | 81 | } catch (ParseException e) { |
| 147 | - e.printStackTrace(); | 82 | + logger.error("[清理过期的redis合并任务信息] 失败", e); |
| 148 | } | 83 | } |
| 149 | } | 84 | } |
| 150 | } | 85 | } |
src/main/java/top/panll/assist/service/VideoFileService.java
| @@ -10,6 +10,9 @@ import org.springframework.beans.factory.annotation.Autowired; | @@ -10,6 +10,9 @@ import org.springframework.beans.factory.annotation.Autowired; | ||
| 10 | import org.springframework.data.redis.core.RedisTemplate; | 10 | import org.springframework.data.redis.core.RedisTemplate; |
| 11 | import org.springframework.stereotype.Service; | 11 | import org.springframework.stereotype.Service; |
| 12 | import org.springframework.util.DigestUtils; | 12 | import org.springframework.util.DigestUtils; |
| 13 | +import org.springframework.util.ObjectUtils; | ||
| 14 | +import top.panll.assist.controller.bean.ControllerException; | ||
| 15 | +import top.panll.assist.controller.bean.ErrorCode; | ||
| 13 | import top.panll.assist.dto.*; | 16 | import top.panll.assist.dto.*; |
| 14 | import top.panll.assist.utils.RedisUtil; | 17 | import top.panll.assist.utils.RedisUtil; |
| 15 | import top.panll.assist.utils.DateUtils; | 18 | import top.panll.assist.utils.DateUtils; |
| @@ -44,7 +47,7 @@ public class VideoFileService { | @@ -44,7 +47,7 @@ public class VideoFileService { | ||
| 44 | private final SimpleDateFormat simpleDateFormatForTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | 47 | private final SimpleDateFormat simpleDateFormatForTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| 45 | 48 | ||
| 46 | public List<File> getAppList(Boolean sort) { | 49 | public List<File> getAppList(Boolean sort) { |
| 47 | - File recordFile = new File(userSettings.getRecord()); | 50 | + File recordFile = new File(userSettings.getRecordTempPath()); |
| 48 | if (recordFile.isDirectory()) { | 51 | if (recordFile.isDirectory()) { |
| 49 | File[] files = recordFile.listFiles((File dir, String name) -> { | 52 | File[] files = recordFile.listFiles((File dir, String name) -> { |
| 50 | File currentFile = new File(dir.getAbsolutePath() + File.separator + name); | 53 | File currentFile = new File(dir.getAbsolutePath() + File.separator + name); |
| @@ -61,17 +64,13 @@ public class VideoFileService { | @@ -61,17 +64,13 @@ public class VideoFileService { | ||
| 61 | } | 64 | } |
| 62 | 65 | ||
| 63 | public SpaceInfo getSpaceInfo(){ | 66 | public SpaceInfo getSpaceInfo(){ |
| 64 | - File recordFile = new File(userSettings.getRecord()); | 67 | + File recordFile = new File(userSettings.getRecordTempPath()); |
| 65 | SpaceInfo spaceInfo = new SpaceInfo(); | 68 | SpaceInfo spaceInfo = new SpaceInfo(); |
| 66 | spaceInfo.setFree(recordFile.getFreeSpace()); | 69 | spaceInfo.setFree(recordFile.getFreeSpace()); |
| 67 | spaceInfo.setTotal(recordFile.getTotalSpace()); | 70 | spaceInfo.setTotal(recordFile.getTotalSpace()); |
| 68 | return spaceInfo; | 71 | return spaceInfo; |
| 69 | } | 72 | } |
| 70 | 73 | ||
| 71 | - public List<File> getStreamList(String app, Boolean sort) { | ||
| 72 | - File appFile = new File(userSettings.getRecord() + File.separator + app); | ||
| 73 | - return getStreamList(appFile, sort); | ||
| 74 | - } | ||
| 75 | 74 | ||
| 76 | public List<File> getStreamList(File appFile, Boolean sort) { | 75 | public List<File> getStreamList(File appFile, Boolean sort) { |
| 77 | if (appFile != null && appFile.isDirectory()) { | 76 | if (appFile != null && appFile.isDirectory()) { |
| @@ -90,79 +89,6 @@ public class VideoFileService { | @@ -90,79 +89,6 @@ public class VideoFileService { | ||
| 90 | } | 89 | } |
| 91 | 90 | ||
| 92 | /** | 91 | /** |
| 93 | - * 对视频文件重命名 | ||
| 94 | - */ | ||
| 95 | - public void handFile(File file,String app, String stream) { | ||
| 96 | - VideoFile videoFile = VideoFileFactory.createFile(ffmpegExecUtils, file); | ||
| 97 | - if (videoFile == null || videoFile.isTargetFormat()) { | ||
| 98 | - return; | ||
| 99 | - } | ||
| 100 | - | ||
| 101 | - SimpleDateFormat dateFormat = new SimpleDateFormat("HHmmss"); | ||
| 102 | - | ||
| 103 | - String key = AssistConstants.STREAM_CALL_INFO + userSettings.getId() + "_" + app + "_" + stream; | ||
| 104 | - String callId = (String) redisUtil.get(key); | ||
| 105 | - | ||
| 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 | - } | ||
| 112 | - | ||
| 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); | ||
| 119 | - } | ||
| 120 | - } | ||
| 121 | - | ||
| 122 | - public List<Map<String, String>> getList() { | ||
| 123 | - | ||
| 124 | - List<Map<String, String>> result = new ArrayList<>(); | ||
| 125 | - | ||
| 126 | - List<File> appList = getAppList(true); | ||
| 127 | - if (appList != null && appList.size() > 0) { | ||
| 128 | - for (File appFile : appList) { | ||
| 129 | - if (appFile.isDirectory()) { | ||
| 130 | - List<File> streamList = getStreamList(appFile.getName(), true); | ||
| 131 | - if (streamList != null && streamList.size() > 0) { | ||
| 132 | - for (File streamFile : streamList) { | ||
| 133 | - Map<String, String> data = new HashMap<>(); | ||
| 134 | - data.put("app", appFile.getName()); | ||
| 135 | - data.put("stream", streamFile.getName()); | ||
| 136 | - | ||
| 137 | - BasicFileAttributes bAttributes = null; | ||
| 138 | - try { | ||
| 139 | - bAttributes = Files.readAttributes(streamFile.toPath(), | ||
| 140 | - BasicFileAttributes.class); | ||
| 141 | - } catch (IOException e) { | ||
| 142 | - e.printStackTrace(); | ||
| 143 | - } | ||
| 144 | - data.put("time", simpleDateFormatForTime.format(new Date(bAttributes.lastModifiedTime().toMillis()))); | ||
| 145 | - result.add(data); | ||
| 146 | - } | ||
| 147 | - } | ||
| 148 | - } | ||
| 149 | - } | ||
| 150 | - } | ||
| 151 | - result.sort((Map f1, Map f2)->{ | ||
| 152 | - Date time1 = null; | ||
| 153 | - Date time2 = null; | ||
| 154 | - try { | ||
| 155 | - time1 = simpleDateFormatForTime.parse(f1.get("time").toString()); | ||
| 156 | - time2 = simpleDateFormatForTime.parse(f2.get("time").toString()); | ||
| 157 | - } catch (ParseException e) { | ||
| 158 | - logger.error("时间格式化失败", e); | ||
| 159 | - } | ||
| 160 | - return time1.compareTo(time2) * -1; | ||
| 161 | - }); | ||
| 162 | - return result; | ||
| 163 | - } | ||
| 164 | - | ||
| 165 | - /** | ||
| 166 | * 获取制定推流的指定时间段内的推流 | 92 | * 获取制定推流的指定时间段内的推流 |
| 167 | * @param app | 93 | * @param app |
| 168 | * @param stream | 94 | * @param stream |
| @@ -191,7 +117,7 @@ public class VideoFileService { | @@ -191,7 +117,7 @@ public class VideoFileService { | ||
| 191 | logger.debug("获取[app: {}, stream: {}, statime: {}, endTime: {}]的视频", app, stream, | 117 | logger.debug("获取[app: {}, stream: {}, statime: {}, endTime: {}]的视频", app, stream, |
| 192 | startTimeStr, endTimeStr); | 118 | startTimeStr, endTimeStr); |
| 193 | 119 | ||
| 194 | - File recordFile = new File(userSettings.getRecord()); | 120 | + File recordFile = new File(userSettings.getRecordTempPath()); |
| 195 | File streamFile = new File(recordFile.getAbsolutePath() + File.separator + app + File.separator + stream + File.separator); | 121 | File streamFile = new File(recordFile.getAbsolutePath() + File.separator + app + File.separator + stream + File.separator); |
| 196 | if (!streamFile.exists()) { | 122 | if (!streamFile.exists()) { |
| 197 | logger.warn("获取[app: {}, stream: {}, statime: {}, endTime: {}]的视频时未找到目录: {}", app, stream, | 123 | logger.warn("获取[app: {}, stream: {}, statime: {}, endTime: {}]的视频时未找到目录: {}", app, stream, |
| @@ -282,80 +208,79 @@ public class VideoFileService { | @@ -282,80 +208,79 @@ public class VideoFileService { | ||
| 282 | } | 208 | } |
| 283 | 209 | ||
| 284 | 210 | ||
| 285 | - public String mergeOrCut(String app, String stream, Date startTime, Date endTime, String remoteHost) { | ||
| 286 | - List<File> filesInTime = this.getFilesInTime(app, stream, startTime, endTime); | ||
| 287 | - if (filesInTime== null || filesInTime.isEmpty()){ | ||
| 288 | - logger.info("此时间段未未找到视频文件, {}/{} {}->{}", app, stream, | ||
| 289 | - startTime == null? null:DateUtils.getDateTimeStr(startTime), | ||
| 290 | - endTime == null? null:DateUtils.getDateTimeStr(endTime)); | ||
| 291 | - return null; | ||
| 292 | - } | 211 | + public String mergeOrCut(VideoTaskInfo videoTaskInfo) { |
| 212 | + assert videoTaskInfo.getFilePathList() != null; | ||
| 213 | + assert !videoTaskInfo.getFilePathList().isEmpty(); | ||
| 293 | String taskId = DigestUtils.md5DigestAsHex(String.valueOf(System.currentTimeMillis()).getBytes()); | 214 | String taskId = DigestUtils.md5DigestAsHex(String.valueOf(System.currentTimeMillis()).getBytes()); |
| 294 | - logger.info("[录像合并] 开始合并,APP:{}, STREAM: {}, 任务ID:{}", app, stream, taskId); | ||
| 295 | - String destDir = "recordTemp" + File.separator + taskId + File.separator + app; | ||
| 296 | - File recordFile = new File(userSettings.getRecord() + destDir ); | 215 | + String logInfo = String.format("app: %S, stream: %S, callId: %S, 任务ID:%S", |
| 216 | + videoTaskInfo.getApp(), videoTaskInfo.getStream(), videoTaskInfo.getCallId(), taskId); | ||
| 217 | + logger.info("[录像合并] 开始合并,{} ", logInfo); | ||
| 218 | + List<File> fileList = new ArrayList<>(); | ||
| 219 | + for (String filePath : videoTaskInfo.getFilePathList()) { | ||
| 220 | + File file = new File(filePath); | ||
| 221 | + if (!file.exists()) { | ||
| 222 | + logger.info("[录像合并] 失败,{} ", logInfo); | ||
| 223 | + throw new ControllerException(ErrorCode.ERROR100.getCode(), filePath + "文件不存在"); | ||
| 224 | + } | ||
| 225 | + logger.info("[录像合并] 添加文件,{}, 文件: {}", logInfo, filePath); | ||
| 226 | + fileList.add(file); | ||
| 227 | + } | ||
| 228 | + | ||
| 229 | + File recordFile = new File(userSettings.getRecordTempPath() ); | ||
| 297 | if (!recordFile.exists()) { | 230 | if (!recordFile.exists()) { |
| 298 | - recordFile.mkdirs(); | 231 | + if (!recordFile.mkdirs()) { |
| 232 | + logger.info("[录像合并] 失败,{}, 创建临时目录失败", logInfo); | ||
| 233 | + throw new ControllerException(ErrorCode.ERROR100.getCode(), "创建临时目录失败"); | ||
| 234 | + } | ||
| 299 | } | 235 | } |
| 300 | MergeOrCutTaskInfo mergeOrCutTaskInfo = new MergeOrCutTaskInfo(); | 236 | MergeOrCutTaskInfo mergeOrCutTaskInfo = new MergeOrCutTaskInfo(); |
| 301 | mergeOrCutTaskInfo.setId(taskId); | 237 | mergeOrCutTaskInfo.setId(taskId); |
| 302 | - mergeOrCutTaskInfo.setApp(app); | ||
| 303 | - mergeOrCutTaskInfo.setStream(stream); | 238 | + mergeOrCutTaskInfo.setApp(videoTaskInfo.getApp()); |
| 239 | + mergeOrCutTaskInfo.setStream(videoTaskInfo.getStream()); | ||
| 240 | + mergeOrCutTaskInfo.setCallId(videoTaskInfo.getCallId()); | ||
| 241 | + mergeOrCutTaskInfo.setStartTime(videoTaskInfo.getStartTime()); | ||
| 242 | + mergeOrCutTaskInfo.setEndTime(videoTaskInfo.getEndTime()); | ||
| 304 | mergeOrCutTaskInfo.setCreateTime(simpleDateFormatForTime.format(System.currentTimeMillis())); | 243 | mergeOrCutTaskInfo.setCreateTime(simpleDateFormatForTime.format(System.currentTimeMillis())); |
| 305 | - if(startTime != null) { | ||
| 306 | - mergeOrCutTaskInfo.setStartTime(simpleDateFormatForTime.format(startTime)); | ||
| 307 | - }else { | ||
| 308 | - String startTimeInFile = filesInTime.get(0).getParentFile().getName() + " " | ||
| 309 | - + filesInTime.get(0).getName().split("-")[0]; | ||
| 310 | - mergeOrCutTaskInfo.setStartTime(startTimeInFile); | ||
| 311 | - } | ||
| 312 | - if(endTime != null) { | ||
| 313 | - mergeOrCutTaskInfo.setEndTime(simpleDateFormatForTime.format(endTime)); | ||
| 314 | - }else { | ||
| 315 | - String endTimeInFile = filesInTime.get(filesInTime.size()- 1).getParentFile().getName() + " " | ||
| 316 | - + filesInTime.get(filesInTime.size()- 1).getName().split("-")[1]; | ||
| 317 | - mergeOrCutTaskInfo.setEndTime(endTimeInFile); | ||
| 318 | - } | ||
| 319 | - if (filesInTime.size() == 1) { | 244 | + String destFileName = videoTaskInfo.getStream() + "_" + videoTaskInfo.getCallId(); |
| 245 | + if (fileList.size() == 1) { | ||
| 320 | 246 | ||
| 321 | // 文件只有一个则不合并,直接复制过去 | 247 | // 文件只有一个则不合并,直接复制过去 |
| 322 | mergeOrCutTaskInfo.setPercentage("1"); | 248 | mergeOrCutTaskInfo.setPercentage("1"); |
| 323 | // 处理文件路径 | 249 | // 处理文件路径 |
| 324 | - String recordFileResultPath = recordFile.getAbsolutePath() + File.separator + stream + ".mp4"; | ||
| 325 | - Path relativize = Paths.get(userSettings.getRecord()).relativize(Paths.get(recordFileResultPath)); | 250 | + |
| 251 | + String recordFileResultPath = recordFile.getAbsolutePath() + File.separator + destFileName + ".mp4"; | ||
| 326 | try { | 252 | try { |
| 327 | - Files.copy(filesInTime.get(0).toPath(), Paths.get(recordFileResultPath)); | 253 | + Files.copy(fileList.get(0).toPath(), Paths.get(recordFileResultPath)); |
| 328 | } catch (IOException e) { | 254 | } catch (IOException e) { |
| 329 | - e.printStackTrace(); | ||
| 330 | - logger.info("[录像合并] 失败,APP:{}, STREAM: {}, 任务ID:{}", app, stream, taskId); | ||
| 331 | - return taskId; | 255 | + logger.info("[录像合并] 失败, {}", logInfo, e); |
| 256 | + throw new ControllerException(ErrorCode.ERROR100.getCode(), e.getMessage()); | ||
| 332 | } | 257 | } |
| 333 | - mergeOrCutTaskInfo.setRecordFile("/download/" + relativize.toString()); | ||
| 334 | - if (remoteHost != null) { | ||
| 335 | - mergeOrCutTaskInfo.setDownloadFile(remoteHost + "/download.html?url=download/" + relativize); | ||
| 336 | - mergeOrCutTaskInfo.setPlayFile(remoteHost + "/download/" + relativize); | 258 | + mergeOrCutTaskInfo.setRecordFile("/download/" + destFileName + ".mp4"); |
| 259 | + if (videoTaskInfo.getRemoteHost() != null) { | ||
| 260 | + mergeOrCutTaskInfo.setDownloadFile(videoTaskInfo.getRemoteHost() + "/download.html?url=download/" + destFileName + ".mp4"); | ||
| 261 | + mergeOrCutTaskInfo.setPlayFile(videoTaskInfo.getRemoteHost() + "/download/" + destFileName + ".mp4"); | ||
| 337 | } | 262 | } |
| 338 | - String key = String.format("%S_%S_%S_%S_%S", AssistConstants.MERGEORCUT , userSettings.getId(), mergeOrCutTaskInfo.getApp(), mergeOrCutTaskInfo.getStream(), mergeOrCutTaskInfo.getId()); | 263 | + String key = String.format("%S_%S_%S", AssistConstants.MERGEORCUT , userSettings.getId(), mergeOrCutTaskInfo.getId()); |
| 339 | redisUtil.set(key, mergeOrCutTaskInfo); | 264 | redisUtil.set(key, mergeOrCutTaskInfo); |
| 340 | - logger.info("[录像合并] 合并完成,APP:{}, STREAM: {}, 任务ID:{}", app, stream, taskId); | 265 | + logger.info("[录像合并] 成功, 任务ID:{}", taskId); |
| 341 | }else { | 266 | }else { |
| 342 | - ffmpegExecUtils.mergeOrCutFile(filesInTime, recordFile, stream, (status, percentage, result)->{ | 267 | + ffmpegExecUtils.mergeOrCutFile(fileList, recordFile, destFileName, (status, percentage, result)->{ |
| 343 | // 发出redis通知 | 268 | // 发出redis通知 |
| 344 | if (status.equals(Progress.Status.END.name())) { | 269 | if (status.equals(Progress.Status.END.name())) { |
| 345 | mergeOrCutTaskInfo.setPercentage("1"); | 270 | mergeOrCutTaskInfo.setPercentage("1"); |
| 346 | 271 | ||
| 347 | // 处理文件路径 | 272 | // 处理文件路径 |
| 348 | - Path relativize = Paths.get(userSettings.getRecord()).relativize(Paths.get(result)); | 273 | + String relativize = new File(result).getName(); |
| 349 | mergeOrCutTaskInfo.setRecordFile(relativize.toString()); | 274 | mergeOrCutTaskInfo.setRecordFile(relativize.toString()); |
| 350 | - if (remoteHost != null) { | ||
| 351 | - mergeOrCutTaskInfo.setDownloadFile(remoteHost + "/download.html?url=download/" + relativize); | ||
| 352 | - mergeOrCutTaskInfo.setPlayFile(remoteHost + "/download/" + relativize); | 275 | + if (videoTaskInfo.getRemoteHost() != null) { |
| 276 | + mergeOrCutTaskInfo.setDownloadFile(videoTaskInfo.getRemoteHost() + "/download.html?url=download/" + relativize); | ||
| 277 | + mergeOrCutTaskInfo.setPlayFile(videoTaskInfo.getRemoteHost() + "/download/" + relativize); | ||
| 353 | } | 278 | } |
| 354 | - logger.info("[录像合并] 合并完成,APP:{}, STREAM: {}, 任务ID:{}", app, stream, taskId); | 279 | + logger.info("[录像合并] 成功, {}", logInfo); |
| 355 | }else { | 280 | }else { |
| 356 | mergeOrCutTaskInfo.setPercentage(percentage + ""); | 281 | mergeOrCutTaskInfo.setPercentage(percentage + ""); |
| 357 | } | 282 | } |
| 358 | - String key = String.format("%S_%S_%S_%S_%S", AssistConstants.MERGEORCUT, userSettings.getId(), mergeOrCutTaskInfo.getApp(), mergeOrCutTaskInfo.getStream(), mergeOrCutTaskInfo.getId()); | 283 | + String key = String.format("%S_%S_%S", AssistConstants.MERGEORCUT, userSettings.getId(), mergeOrCutTaskInfo.getId()); |
| 359 | redisUtil.set(key, mergeOrCutTaskInfo); | 284 | redisUtil.set(key, mergeOrCutTaskInfo); |
| 360 | }); | 285 | }); |
| 361 | } | 286 | } |
| @@ -363,19 +288,6 @@ public class VideoFileService { | @@ -363,19 +288,6 @@ public class VideoFileService { | ||
| 363 | return taskId; | 288 | return taskId; |
| 364 | } | 289 | } |
| 365 | 290 | ||
| 366 | - /** | ||
| 367 | - * 获取指定时间的日期文件夹 | ||
| 368 | - * @param app | ||
| 369 | - * @param stream | ||
| 370 | - * @param year | ||
| 371 | - * @param month | ||
| 372 | - * @return | ||
| 373 | - */ | ||
| 374 | - public List<File> getDateList(String app, String stream, Integer year, Integer month, Boolean sort) { | ||
| 375 | - File recordFile = new File(userSettings.getRecord()); | ||
| 376 | - File streamFile = new File(recordFile.getAbsolutePath() + File.separator + app + File.separator + stream); | ||
| 377 | - return getDateList(streamFile, year, month, sort); | ||
| 378 | - } | ||
| 379 | public List<File> getDateList(File streamFile, Integer year, Integer month, Boolean sort) { | 291 | public List<File> getDateList(File streamFile, Integer year, Integer month, Boolean sort) { |
| 380 | if (!streamFile.exists() && streamFile.isDirectory()) { | 292 | if (!streamFile.exists() && streamFile.isDirectory()) { |
| 381 | logger.warn("获取[]的视频时未找到目录: {}",streamFile.getName()); | 293 | logger.warn("获取[]的视频时未找到目录: {}",streamFile.getName()); |
| @@ -428,35 +340,39 @@ public class VideoFileService { | @@ -428,35 +340,39 @@ public class VideoFileService { | ||
| 428 | return dateFileList; | 340 | return dateFileList; |
| 429 | } | 341 | } |
| 430 | 342 | ||
| 431 | - public List<MergeOrCutTaskInfo> getTaskListForDownload(Boolean idEnd, String app, String stream, String taskId) { | 343 | + public List<MergeOrCutTaskInfo> getTaskListForDownload(String app, String stream, String callId, Boolean isEnd, String taskId) { |
| 344 | + logger.info("[查询录像合成列表] app: {}, stream: {}, callId: {}, isEnd: {}, taskId: {}", | ||
| 345 | + app, stream, callId, isEnd, taskId); | ||
| 432 | ArrayList<MergeOrCutTaskInfo> result = new ArrayList<>(); | 346 | ArrayList<MergeOrCutTaskInfo> result = new ArrayList<>(); |
| 433 | - if (app == null) { | ||
| 434 | - app = "*"; | ||
| 435 | - } | ||
| 436 | - if (stream == null) { | ||
| 437 | - stream = "*"; | ||
| 438 | - } | ||
| 439 | if (taskId == null) { | 347 | if (taskId == null) { |
| 440 | taskId = "*"; | 348 | taskId = "*"; |
| 441 | } | 349 | } |
| 442 | - List<Object> taskCatch = redisUtil.scan(String.format("%S_%S_%S_%S_%S", AssistConstants.MERGEORCUT, | ||
| 443 | - userSettings.getId(), app, stream, taskId)); | 350 | + List<Object> taskCatch = redisUtil.scan(String.format("%S_%S_%S", AssistConstants.MERGEORCUT, |
| 351 | + userSettings.getId(), taskId)); | ||
| 444 | for (int i = 0; i < taskCatch.size(); i++) { | 352 | for (int i = 0; i < taskCatch.size(); i++) { |
| 445 | String keyItem = taskCatch.get(i).toString(); | 353 | String keyItem = taskCatch.get(i).toString(); |
| 446 | MergeOrCutTaskInfo mergeOrCutTaskInfo = (MergeOrCutTaskInfo)redisUtil.get(keyItem); | 354 | MergeOrCutTaskInfo mergeOrCutTaskInfo = (MergeOrCutTaskInfo)redisUtil.get(keyItem); |
| 447 | - if (mergeOrCutTaskInfo != null && mergeOrCutTaskInfo.getPercentage() != null){ | ||
| 448 | - if (idEnd != null ) { | ||
| 449 | - if (idEnd) { | ||
| 450 | - if (Double.parseDouble(mergeOrCutTaskInfo.getPercentage()) == 1){ | ||
| 451 | - result.add(mergeOrCutTaskInfo); | 355 | + if (mergeOrCutTaskInfo != null){ |
| 356 | + if ((!ObjectUtils.isEmpty(app) && !mergeOrCutTaskInfo.getApp().equals(app)) | ||
| 357 | + || (!ObjectUtils.isEmpty(stream) && !mergeOrCutTaskInfo.getStream().equals(stream)) | ||
| 358 | + || (!ObjectUtils.isEmpty(callId) && !mergeOrCutTaskInfo.getCallId().equals(callId)) | ||
| 359 | + ) { | ||
| 360 | + continue; | ||
| 361 | + } | ||
| 362 | + if (mergeOrCutTaskInfo.getPercentage() != null){ | ||
| 363 | + if (isEnd != null ) { | ||
| 364 | + if (isEnd) { | ||
| 365 | + if (Double.parseDouble(mergeOrCutTaskInfo.getPercentage()) == 1){ | ||
| 366 | + result.add(mergeOrCutTaskInfo); | ||
| 367 | + } | ||
| 368 | + }else { | ||
| 369 | + if (Double.parseDouble(mergeOrCutTaskInfo.getPercentage()) < 1){ | ||
| 370 | + result.add((MergeOrCutTaskInfo)redisUtil.get(keyItem)); | ||
| 371 | + } | ||
| 452 | } | 372 | } |
| 453 | }else { | 373 | }else { |
| 454 | - if (Double.parseDouble(mergeOrCutTaskInfo.getPercentage()) < 1){ | ||
| 455 | - result.add((MergeOrCutTaskInfo)redisUtil.get(keyItem)); | ||
| 456 | - } | 374 | + result.add((MergeOrCutTaskInfo)redisUtil.get(keyItem)); |
| 457 | } | 375 | } |
| 458 | - }else { | ||
| 459 | - result.add((MergeOrCutTaskInfo)redisUtil.get(keyItem)); | ||
| 460 | } | 376 | } |
| 461 | } | 377 | } |
| 462 | } | 378 | } |
| @@ -465,10 +381,10 @@ public class VideoFileService { | @@ -465,10 +381,10 @@ public class VideoFileService { | ||
| 465 | try { | 381 | try { |
| 466 | sortResult = simpleDateFormatForTime.parse(m1.getCreateTime()).compareTo(simpleDateFormatForTime.parse(m2.getCreateTime())); | 382 | sortResult = simpleDateFormatForTime.parse(m1.getCreateTime()).compareTo(simpleDateFormatForTime.parse(m2.getCreateTime())); |
| 467 | if (sortResult == 0) { | 383 | if (sortResult == 0) { |
| 468 | - sortResult = simpleDateFormatForTime.parse(m1.getStartTime()).compareTo(simpleDateFormatForTime.parse(m2.getStartTime())); | 384 | + sortResult = simpleDateFormatForTime.parse(m1.getCreateTime()).compareTo(simpleDateFormatForTime.parse(m2.getCreateTime())); |
| 469 | } | 385 | } |
| 470 | if (sortResult == 0) { | 386 | if (sortResult == 0) { |
| 471 | - sortResult = simpleDateFormatForTime.parse(m1.getEndTime()).compareTo(simpleDateFormatForTime.parse(m2.getEndTime())); | 387 | + sortResult = simpleDateFormatForTime.parse(m1.getCreateTime()).compareTo(simpleDateFormatForTime.parse(m2.getCreateTime())); |
| 472 | } | 388 | } |
| 473 | } catch (ParseException e) { | 389 | } catch (ParseException e) { |
| 474 | e.printStackTrace(); | 390 | e.printStackTrace(); |
| @@ -480,7 +396,7 @@ public class VideoFileService { | @@ -480,7 +396,7 @@ public class VideoFileService { | ||
| 480 | } | 396 | } |
| 481 | 397 | ||
| 482 | public boolean collection(String app, String stream, String type) { | 398 | public boolean collection(String app, String stream, String type) { |
| 483 | - File streamFile = new File(userSettings.getRecord() + File.separator + app + File.separator + stream); | 399 | + File streamFile = new File(userSettings.getRecordTempPath() + File.separator + app + File.separator + stream); |
| 484 | boolean result = false; | 400 | boolean result = false; |
| 485 | if (streamFile.exists() && streamFile.isDirectory() && streamFile.canWrite()) { | 401 | if (streamFile.exists() && streamFile.isDirectory() && streamFile.canWrite()) { |
| 486 | File signFile = new File(streamFile.getAbsolutePath() + File.separator + type + ".sign"); | 402 | File signFile = new File(streamFile.getAbsolutePath() + File.separator + type + ".sign"); |
| @@ -494,7 +410,7 @@ public class VideoFileService { | @@ -494,7 +410,7 @@ public class VideoFileService { | ||
| 494 | } | 410 | } |
| 495 | 411 | ||
| 496 | public boolean removeCollection(String app, String stream, String type) { | 412 | public boolean removeCollection(String app, String stream, String type) { |
| 497 | - File signFile = new File(userSettings.getRecord() + File.separator + app + File.separator + stream + File.separator + type + ".sign"); | 413 | + File signFile = new File(userSettings.getRecordTempPath() + File.separator + app + File.separator + stream + File.separator + type + ".sign"); |
| 498 | boolean result = false; | 414 | boolean result = false; |
| 499 | if (signFile.exists() && signFile.isFile()) { | 415 | if (signFile.exists() && signFile.isFile()) { |
| 500 | result = signFile.delete(); | 416 | result = signFile.delete(); |
| @@ -565,4 +481,24 @@ public class VideoFileService { | @@ -565,4 +481,24 @@ public class VideoFileService { | ||
| 565 | } | 481 | } |
| 566 | return durationResult; | 482 | return durationResult; |
| 567 | } | 483 | } |
| 484 | + | ||
| 485 | + public int deleteFile(List<String> filePathList) { | ||
| 486 | + assert filePathList != null; | ||
| 487 | + assert filePathList.isEmpty(); | ||
| 488 | + int deleteResult = 0; | ||
| 489 | + for (String filePath : filePathList) { | ||
| 490 | + File file = new File(filePath); | ||
| 491 | + if (file.exists()) { | ||
| 492 | + if (file.delete()) { | ||
| 493 | + deleteResult ++; | ||
| 494 | + } | ||
| 495 | + }else { | ||
| 496 | + logger.warn("[删除文件] 文件不存在,{}", filePath); | ||
| 497 | + } | ||
| 498 | + } | ||
| 499 | + if (deleteResult == 0) { | ||
| 500 | + throw new ControllerException(ErrorCode.ERROR100.getCode(), "未删除任何文件"); | ||
| 501 | + } | ||
| 502 | + return deleteResult; | ||
| 503 | + } | ||
| 568 | } | 504 | } |
src/main/java/top/panll/assist/utils/PageInfo.java deleted
100755 → 0
| 1 | -package top.panll.assist.utils; | ||
| 2 | - | ||
| 3 | -import java.util.ArrayList; | ||
| 4 | -import java.util.List; | ||
| 5 | - | ||
| 6 | -public class PageInfo<T> { | ||
| 7 | - //当前页 | ||
| 8 | - private int pageNum; | ||
| 9 | - //每页的数量 | ||
| 10 | - private int pageSize; | ||
| 11 | - //当前页的数量 | ||
| 12 | - private int size; | ||
| 13 | - //总页数 | ||
| 14 | - private int pages; | ||
| 15 | - //总数 | ||
| 16 | - private int total; | ||
| 17 | - | ||
| 18 | - private List<T> resultData; | ||
| 19 | - | ||
| 20 | - private List<T> list; | ||
| 21 | - | ||
| 22 | - public PageInfo(List<T> resultData) { | ||
| 23 | - this.resultData = resultData; | ||
| 24 | - } | ||
| 25 | - | ||
| 26 | - public void startPage(int page, int count) { | ||
| 27 | - if (count <= 0) count = 10; | ||
| 28 | - if (page <= 0) page = 1; | ||
| 29 | - this.pageNum = page; | ||
| 30 | - this.pageSize = count; | ||
| 31 | - this.total = resultData.size(); | ||
| 32 | - | ||
| 33 | - this.pages = total%count == 0 ? total/count : total/count + 1; | ||
| 34 | - int fromIndx = (page - 1) * count; | ||
| 35 | - if ( fromIndx > this.total - 1) { | ||
| 36 | - this.list = new ArrayList<>(); | ||
| 37 | - this.size = 0; | ||
| 38 | - return; | ||
| 39 | - } | ||
| 40 | - | ||
| 41 | - int toIndx = page * count; | ||
| 42 | - if (toIndx > this.total) { | ||
| 43 | - toIndx = this.total; | ||
| 44 | - } | ||
| 45 | - this.list = this.resultData.subList(fromIndx, toIndx); | ||
| 46 | - this.size = this.list.size(); | ||
| 47 | - } | ||
| 48 | - | ||
| 49 | - public int getPageNum() { | ||
| 50 | - return pageNum; | ||
| 51 | - } | ||
| 52 | - | ||
| 53 | - public void setPageNum(int pageNum) { | ||
| 54 | - this.pageNum = pageNum; | ||
| 55 | - } | ||
| 56 | - | ||
| 57 | - public int getPageSize() { | ||
| 58 | - return pageSize; | ||
| 59 | - } | ||
| 60 | - | ||
| 61 | - public void setPageSize(int pageSize) { | ||
| 62 | - this.pageSize = pageSize; | ||
| 63 | - } | ||
| 64 | - | ||
| 65 | - public int getSize() { | ||
| 66 | - return size; | ||
| 67 | - } | ||
| 68 | - | ||
| 69 | - public void setSize(int size) { | ||
| 70 | - this.size = size; | ||
| 71 | - } | ||
| 72 | - | ||
| 73 | - public int getPages() { | ||
| 74 | - return pages; | ||
| 75 | - } | ||
| 76 | - | ||
| 77 | - public void setPages(int pages) { | ||
| 78 | - this.pages = pages; | ||
| 79 | - } | ||
| 80 | - | ||
| 81 | - public int getTotal() { | ||
| 82 | - return total; | ||
| 83 | - } | ||
| 84 | - | ||
| 85 | - public void setTotal(int total) { | ||
| 86 | - this.total = total; | ||
| 87 | - } | ||
| 88 | - | ||
| 89 | - public List<T> getList() { | ||
| 90 | - return list; | ||
| 91 | - } | ||
| 92 | - | ||
| 93 | - public void setList(List<T> list) { | ||
| 94 | - this.list = list; | ||
| 95 | - } | ||
| 96 | -} |
src/main/resources/all-application.yml
| @@ -28,10 +28,10 @@ server: | @@ -28,10 +28,10 @@ server: | ||
| 28 | 28 | ||
| 29 | # [根据业务需求配置] | 29 | # [根据业务需求配置] |
| 30 | user-settings: | 30 | user-settings: |
| 31 | - # [可选 ] zlm配置的录像路径,不配置则使用当前目录下的record目录 即: ./record | ||
| 32 | - record: /media/lin/Server/ZLMediaKit/dev/ZLMediaKit/release/linux/Debug/www/record | 31 | + # [可选 ] 临时录像路径 |
| 32 | + record-temp-path: ./recordTemp | ||
| 33 | # [可选 ] 录像保存时长(单位: 天)每天晚12点自动对过期文件执行清理, 不配置则不删除 | 33 | # [可选 ] 录像保存时长(单位: 天)每天晚12点自动对过期文件执行清理, 不配置则不删除 |
| 34 | - recordDay: 7 | 34 | + record-temp-day: 7 |
| 35 | # [可选 ] 录像下载合成临时文件保存时长, 不配置默认取值recordDay(单位: 天)每天晚12点自动对过期文件执行清理 | 35 | # [可选 ] 录像下载合成临时文件保存时长, 不配置默认取值recordDay(单位: 天)每天晚12点自动对过期文件执行清理 |
| 36 | # recordTempDay: 7 | 36 | # recordTempDay: 7 |
| 37 | # [必选 ] ffmpeg路径 | 37 | # [必选 ] ffmpeg路径 |
src/main/resources/application-local.yml
| @@ -11,7 +11,7 @@ spring: | @@ -11,7 +11,7 @@ spring: | ||
| 11 | # [可选] 数据库 DB | 11 | # [可选] 数据库 DB |
| 12 | database: 1 | 12 | database: 1 |
| 13 | # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 | 13 | # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 |
| 14 | - password: adminadmin123. | 14 | + password: |
| 15 | # 以下为集群配置 | 15 | # 以下为集群配置 |
| 16 | # cluster: | 16 | # cluster: |
| 17 | # nodes: 192.168.1.242:7001 | 17 | # nodes: 192.168.1.242:7001 |
| @@ -33,18 +33,13 @@ server: | @@ -33,18 +33,13 @@ server: | ||
| 33 | 33 | ||
| 34 | # [根据业务需求配置] | 34 | # [根据业务需求配置] |
| 35 | userSettings: | 35 | userSettings: |
| 36 | - # [必选 ] 服务ID | ||
| 37 | - id: 334533 | ||
| 38 | - # [必选 ] 录像路径 | ||
| 39 | - record: /home/lin/record/ | ||
| 40 | - # [可选 ] 录像保存时长(单位: 天)每天晚12点自动对过期文件执行清理 | ||
| 41 | - recordDay: 10 | ||
| 42 | - # [可选 ] 录像下载合成临时文件保存时长, 不配置默认取值recordDay(单位: 天)每天晚12点自动对过期文件执行清理 | ||
| 43 | - # recordTempDay: 7 | 36 | + id: 111 |
| 37 | + # [可选 ] 录像保存时长(单位: 天)每天晚12点自动对过期文件执行清理, 不配置则不删除 | ||
| 38 | + record-temp-day: 7 | ||
| 44 | # [必选 ] ffmpeg路径 | 39 | # [必选 ] ffmpeg路径 |
| 45 | - ffmpeg: /home/lin/IdeaProjects/wvp-pro-assist/lib/ffmpeg | 40 | + ffmpeg: ./lib/ffmpeg |
| 46 | # [必选 ] ffprobe路径, 一般安装ffmpeg就会自带, 一般跟ffmpeg在同一目录,用于查询文件的信息, | 41 | # [必选 ] ffprobe路径, 一般安装ffmpeg就会自带, 一般跟ffmpeg在同一目录,用于查询文件的信息, |
| 47 | - ffprobe: /home/lin/IdeaProjects/wvp-pro-assist/lib/ffprobe | 42 | + ffprobe: ./lib/ffprobe |
| 48 | # [可选 ] 限制 ffmpeg 合并文件使用的线程数,间接限制cpu使用率, 默认2 限制到50% | 43 | # [可选 ] 限制 ffmpeg 合并文件使用的线程数,间接限制cpu使用率, 默认2 限制到50% |
| 49 | threads: 2 | 44 | threads: 2 |
| 50 | 45 |