Commit f3e2bf1e24548b30d0d0471b769cd74fe88fe921

Authored by panlinlin
1 parent 43c6122d

添加接口

.gitignore 0 → 100644
  1 +/.idea/
... ...
... ... @@ -14,6 +14,7 @@
14 14 <description></description>
15 15 <properties>
16 16 <java.version>1.8</java.version>
  17 +<!-- <pagehelper.version>5.2.0</pagehelper.version>-->
17 18 </properties>
18 19  
19 20 <repositories>
... ... @@ -60,6 +61,12 @@
60 61 <version>1.2.73</version>
61 62 </dependency>
62 63  
  64 +<!-- <dependency>-->
  65 +<!-- <groupId>com.github.pagehelper</groupId>-->
  66 +<!-- <artifactId>pagehelper-spring-boot-starter</artifactId>-->
  67 +<!-- <version>1.2.10</version>-->
  68 +<!-- </dependency>-->
  69 +
63 70 <dependency>
64 71 <groupId>org.springframework.boot</groupId>
65 72 <artifactId>spring-boot-starter-test</artifactId>
... ...
src/main/java/top/panll/assist/config/TaskConfig.java 0 → 100644
  1 +package top.panll.assist.config;
  2 +
  3 +import org.slf4j.Logger;
  4 +import org.slf4j.LoggerFactory;
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.context.annotation.Configuration;
  7 +import org.springframework.scheduling.annotation.EnableScheduling;
  8 +import org.springframework.scheduling.annotation.Scheduled;
  9 +import top.panll.assist.service.VideoFileService;
  10 +
  11 +import java.io.File;
  12 +import java.text.ParseException;
  13 +import java.text.SimpleDateFormat;
  14 +import java.time.LocalDateTime;
  15 +import java.util.Calendar;
  16 +import java.util.Date;
  17 +import java.util.List;
  18 +
  19 +@Configuration
  20 +@EnableScheduling
  21 +public class TaskConfig {
  22 +
  23 + private final static Logger logger = LoggerFactory.getLogger(TaskConfig.class);
  24 +
  25 + @Autowired
  26 + private VideoFileService videoFileService;
  27 +
  28 + private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
  29 +
  30 + @Scheduled(cron = "0 0 0 * * ?")
  31 + private void configureTasks() {
  32 + logger.info("录像过期自检任务执行");
  33 + List<File> appList = videoFileService.getAppList();
  34 + Calendar calendar = Calendar.getInstance();
  35 + calendar.add(Calendar.DATE, - 7);
  36 + Date monday = calendar.getTime();
  37 + if (appList != null && appList.size() > 0) {
  38 + for (File appFile : appList) {
  39 + List<File> streamList = videoFileService.getStreamList(appFile.getName());
  40 + if (streamList != null && streamList.size() > 0) {
  41 + for (File streamFile : streamList) {
  42 + File[] recordDateFileList = streamFile.listFiles();
  43 + if (recordDateFileList != null && recordDateFileList.length > 0) {
  44 + for (File recordDateFile : recordDateFileList) {
  45 + try {
  46 + Date fileDaye = simpleDateFormat.parse(recordDateFile.getName());
  47 + if (fileDaye.before(monday)){
  48 + logger.debug("移除文件[{}]", recordDateFile.getAbsolutePath());
  49 + recordDateFile.delete();
  50 + }
  51 + } catch (ParseException e) {
  52 + logger.error("无法格式化[{}]为日期, 直接移除", recordDateFile.getName());
  53 + recordDateFile.delete();
  54 + }
  55 + }
  56 + }
  57 + if (streamFile.listFiles().length == 0) {
  58 + streamFile.delete();
  59 + }
  60 + }
  61 + }
  62 + if (appFile.listFiles().length == 0) {
  63 + appFile.delete();
  64 + }
  65 + }
  66 + }
  67 + }
  68 +}
... ...
src/main/java/top/panll/assist/controller/RecordController.java
... ... @@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired;
6 6 import org.springframework.web.bind.annotation.*;
7 7 import top.panll.assist.controller.bean.WVPResult;
8 8 import top.panll.assist.service.VideoFileService;
  9 +import top.panll.assist.utils.PageInfo;
9 10  
10 11 import java.io.File;
11 12 import java.text.ParseException;
... ... @@ -13,6 +14,7 @@ import java.text.SimpleDateFormat;
13 14 import java.util.ArrayList;
14 15 import java.util.Date;
15 16 import java.util.List;
  17 +import java.util.Map;
16 18  
17 19 @CrossOrigin
18 20 @RestController
... ... @@ -26,14 +28,35 @@ public class RecordController {
26 28  
27 29 private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
28 30  
  31 +
  32 + /**
  33 + * 获取app文件夹列表
  34 + * @return
  35 + */
  36 + @GetMapping(value = "/list")
  37 + @ResponseBody
  38 + public WVPResult<PageInfo<Map<String, String>>> getList(@RequestParam int page,
  39 + @RequestParam int count){
  40 + WVPResult<PageInfo<Map<String, String>>> result = new WVPResult<>();
  41 + List<Map<String, String>> appList = videoFileService.getList();
  42 + result.setCode(0);
  43 + result.setMsg("success");
  44 +
  45 + PageInfo<Map<String, String>> stringPageInfo = new PageInfo<>(appList);
  46 + stringPageInfo.startPage(page, count);
  47 + result.setData(stringPageInfo);
  48 + return result;
  49 + }
  50 +
29 51 /**
30 52 * 获取app文件夹列表
31 53 * @return
32 54 */
33 55 @GetMapping(value = "/app/list")
34 56 @ResponseBody
35   - public WVPResult<List<String>> getAppList(){
36   - WVPResult<List<String>> result = new WVPResult<>();
  57 + public WVPResult<PageInfo<String>> getAppList(@RequestParam int page,
  58 + @RequestParam int count){
  59 + WVPResult<PageInfo<String>> result = new WVPResult<>();
37 60 List<String> resultData = new ArrayList<>();
38 61 List<File> appList = videoFileService.getAppList();
39 62 for (File file : appList) {
... ... @@ -41,7 +64,10 @@ public class RecordController {
41 64 }
42 65 result.setCode(0);
43 66 result.setMsg("success");
44   - result.setData(resultData);
  67 +
  68 + PageInfo<String> stringPageInfo = new PageInfo<>(resultData);
  69 + stringPageInfo.startPage(page, count);
  70 + result.setData(stringPageInfo);
45 71 return result;
46 72 }
47 73  
... ... @@ -51,8 +77,10 @@ public class RecordController {
51 77 */
52 78 @GetMapping(value = "/stream/list")
53 79 @ResponseBody
54   - public WVPResult<List<String>> getStreamList(@RequestParam String app ){
55   - WVPResult<List<String>> result = new WVPResult<>();
  80 + public WVPResult<PageInfo<String>> getStreamList(@RequestParam int page,
  81 + @RequestParam int count,
  82 + @RequestParam String app ){
  83 + WVPResult<PageInfo<String>> result = new WVPResult<>();
56 84 List<String> resultData = new ArrayList<>();
57 85 if (app == null) {
58 86 result.setCode(400);
... ... @@ -65,7 +93,43 @@ public class RecordController {
65 93 }
66 94 result.setCode(0);
67 95 result.setMsg("success");
68   - result.setData(resultData);
  96 + PageInfo<String> stringPageInfo = new PageInfo<>(resultData);
  97 + stringPageInfo.startPage(page, count);
  98 + result.setData(stringPageInfo);
  99 + return result;
  100 + }
  101 +
  102 + /**
  103 + * 获取日期文件夹列表
  104 + * @return
  105 + */
  106 + @GetMapping(value = "/date/list")
  107 + @ResponseBody
  108 + public WVPResult<PageInfo<String>> getDateList(@RequestParam int page,
  109 + @RequestParam int count,
  110 + @RequestParam String app,
  111 + @RequestParam String stream ){
  112 + WVPResult<PageInfo<String>> result = new WVPResult<>();
  113 + List<String> resultData = new ArrayList<>();
  114 + if (app == null) {
  115 + result.setCode(400);
  116 + result.setMsg("app不能为空");
  117 + return result;
  118 + };
  119 + if (stream == null) {
  120 + result.setCode(400);
  121 + result.setMsg("stream不能为空");
  122 + return result;
  123 + }
  124 + List<File> dateList = videoFileService.getDateList(app, stream);
  125 + for (File file : dateList) {
  126 + resultData.add(file.getName());
  127 + }
  128 + result.setCode(0);
  129 + result.setMsg("success");
  130 + PageInfo<String> stringPageInfo = new PageInfo<>(resultData);
  131 + stringPageInfo.startPage(page, count);
  132 + result.setData(stringPageInfo);
69 133 return result;
70 134 }
71 135  
... ... @@ -75,13 +139,15 @@ public class RecordController {
75 139 */
76 140 @GetMapping(value = "/file/list")
77 141 @ResponseBody
78   - public WVPResult<List<String>> getRecordList(@RequestParam String app,
79   - @RequestParam String stream,
80   - @RequestParam String startTime,
81   - @RequestParam String endTime
  142 + public WVPResult<PageInfo<String>> getRecordList(@RequestParam int page,
  143 + @RequestParam int count,
  144 + @RequestParam String app,
  145 + @RequestParam String stream,
  146 + @RequestParam String startTime,
  147 + @RequestParam String endTime
82 148 ){
83 149  
84   - WVPResult<List<String>> result = new WVPResult<>();
  150 + WVPResult<PageInfo<String>> result = new WVPResult<>();
85 151 // TODO 暂时开始时间与结束时间为必传, 后续可不传或只传其一
86 152 List<String> recordList = new ArrayList<>();
87 153 try {
... ... @@ -102,7 +168,9 @@ public class RecordController {
102 168 }
103 169 result.setCode(0);
104 170 result.setMsg("success");
105   - result.setData(recordList);
  171 + PageInfo<String> stringPageInfo = new PageInfo<>(recordList);
  172 + stringPageInfo.startPage(page, count);
  173 + result.setData(stringPageInfo);
106 174 } catch (ParseException e) {
107 175 logger.error("错误的开始时间[{}]或结束时间[{}]", startTime, endTime);
108 176 result.setCode(400);
... ...
src/main/java/top/panll/assist/dto/UserSettings.java
... ... @@ -9,6 +9,9 @@ public class UserSettings {
9 9 @Value("${userSettings.record}")
10 10 private String record;
11 11  
  12 + @Value("${userSettings.recordDay}")
  13 + private int recordDay;
  14 +
12 15 @Value("${userSettings.ffmpeg}")
13 16 private String ffmpeg;
14 17  
... ... @@ -38,4 +41,12 @@ public class UserSettings {
38 41 public void setFfprobe(String ffprobe) {
39 42 this.ffprobe = ffprobe;
40 43 }
  44 +
  45 + public int getRecordDay() {
  46 + return recordDay;
  47 + }
  48 +
  49 + public void setRecordDay(int recordDay) {
  50 + this.recordDay = recordDay;
  51 + }
41 52 }
... ...
src/main/java/top/panll/assist/service/VideoFileService.java
1 1 package top.panll.assist.service;
2 2  
  3 +import com.alibaba.fastjson.JSON;
3 4 import net.bramp.ffmpeg.FFprobe;
4 5 import net.bramp.ffmpeg.probe.FFmpegProbeResult;
5 6 import net.bramp.ffmpeg.progress.Progress;
... ... @@ -8,7 +9,6 @@ import org.slf4j.LoggerFactory;
8 9 import org.springframework.beans.factory.annotation.Autowired;
9 10 import org.springframework.context.annotation.Bean;
10 11 import org.springframework.data.redis.core.StringRedisTemplate;
11   -import org.springframework.data.redis.listener.RedisMessageListenerContainer;
12 12 import org.springframework.stereotype.Service;
13 13 import org.springframework.util.DigestUtils;
14 14 import top.panll.assist.config.RedisUtil;
... ... @@ -40,8 +40,10 @@ public class VideoFileService {
40 40  
41 41 private ThreadPoolExecutor processThreadPool;
42 42  
  43 + private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
43 44  
44   - @Bean("iniThreadPool")
  45 +
  46 + @Bean("threadPoolExecutor")
45 47 private ThreadPoolExecutor iniThreadPool() {
46 48  
47 49 int processThreadNum = Runtime.getRuntime().availableProcessors() * 10;
... ... @@ -57,7 +59,9 @@ public class VideoFileService {
57 59 File recordFile = new File(userSettings.getRecord());
58 60 if (recordFile != null) {
59 61 File[] files = recordFile.listFiles();
60   - return Arrays.asList(files);
  62 + List<File> result = Arrays.asList(files);
  63 + Collections.sort(result);
  64 + return result;
61 65 }else {
62 66 return null;
63 67 }
... ... @@ -67,7 +71,9 @@ public class VideoFileService {
67 71 File appFile = new File(userSettings.getRecord() + File.separator + app);
68 72 if (appFile != null) {
69 73 File[] files = appFile.listFiles();
70   - return Arrays.asList(files);
  74 + List<File> result = Arrays.asList(files);
  75 + Collections.sort(result);
  76 + return result;
71 77 }else {
72 78 return null;
73 79 }
... ... @@ -107,6 +113,36 @@ public class VideoFileService {
107 113 }
108 114 }
109 115  
  116 + public List<Map<String, String>> getList() {
  117 +
  118 + List<Map<String, String>> result = new ArrayList<>();
  119 +
  120 + List<File> appList = getAppList();
  121 + if (appList != null && appList.size() > 0) {
  122 + for (File appFile : appList) {
  123 + List<File> streamList = getStreamList(appFile.getName());
  124 + if (streamList != null && streamList.size() > 0) {
  125 + for (File streamFile : streamList) {
  126 + Map<String, String> data = new HashMap<>();
  127 + data.put("app", appFile.getName());
  128 + data.put("stream", streamFile.getName());
  129 +
  130 +// BasicFileAttributes bAttributes = null;
  131 +// try {
  132 +// bAttributes = Files.readAttributes(streamFile.toPath(),
  133 +// BasicFileAttributes.class);
  134 +// } catch (IOException e) {
  135 +// e.printStackTrace();
  136 +// }
  137 +// data.put("time", simpleDateFormat.format(new Date(bAttributes.lastModifiedTime().toMillis())));
  138 + result.add(data);
  139 + }
  140 + }
  141 + }
  142 + }
  143 + return result;
  144 + }
  145 +
110 146 /**
111 147 * 获取制定推流的指定时间段内的推流
112 148 * @param app
... ... @@ -212,14 +248,37 @@ public class VideoFileService {
212 248 data.put("percentage", "1");
213 249 data.put("recordFile", result);
214 250 redisUtil.set(app + "_" + stream + "_" + temp, data, 3*60*60);
215   - stringRedisTemplate.convertAndSend("topic_mergeorcut_end", data);
  251 + stringRedisTemplate.convertAndSend("topic_mergeorcut_end", JSON.toJSONString(data));
216 252 }else {
217 253 data.put("percentage", percentage + "");
218 254 redisUtil.set(app + "_" + stream + "_" + temp, data, 3*60*60);
219   - stringRedisTemplate.convertAndSend("topic_mergeorcut_continue", data);
  255 + stringRedisTemplate.convertAndSend("topic_mergeorcut_continue", JSON.toJSONString(data));
220 256 }
221 257 });
222 258 });
223 259 return temp;
224 260 }
  261 +
  262 +
  263 + public List<File> getDateList(String app, String stream) {
  264 + File recordFile = new File(userSettings.getRecord());
  265 + File streamFile = new File(recordFile.getAbsolutePath() + File.separator + app + File.separator + stream);
  266 + if (!streamFile.exists()) {
  267 + logger.warn("获取[app: {}, stream: {}]的视频时未找到目录: {}", app, stream, stream);
  268 + return null;
  269 + }
  270 + File[] dateFiles = streamFile.listFiles();
  271 + List<File> dateFileList = Arrays.asList(dateFiles);
  272 + dateFileList.sort((File f1, File f2)->{
  273 + int sortResult = 0;
  274 + SimpleDateFormat formatterForDate = new SimpleDateFormat("yyyy-MM-dd");
  275 + try {
  276 + sortResult = formatterForDate.parse(f1.getName()).compareTo(formatterForDate.parse(f2.getName()));
  277 + } catch (ParseException e) {
  278 + e.printStackTrace();
  279 + }
  280 + return sortResult;
  281 + });
  282 + return dateFileList;
  283 + }
225 284 }
... ...
src/main/java/top/panll/assist/utils/PageInfo.java 0 → 100644
  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 (page <= 0) page = 1;
  28 + this.pageNum = page;
  29 + this.pageSize = count;
  30 + this.total = resultData.size();
  31 +
  32 + this.pages = total%count == 0 ? total/count : total/count + 1;
  33 + int fromIndx = (page - 1) * count;
  34 + if ( fromIndx > this.total - 1) {
  35 + this.list = new ArrayList<>();
  36 + this.size = 0;
  37 + return;
  38 + }
  39 +
  40 + int toIndx = page * count;
  41 + if (toIndx > this.total) {
  42 + toIndx = this.total;
  43 + }
  44 + this.list = this.resultData.subList(fromIndx, toIndx);
  45 + this.size = this.list.size();
  46 + }
  47 +
  48 + public int getPageNum() {
  49 + return pageNum;
  50 + }
  51 +
  52 + public void setPageNum(int pageNum) {
  53 + this.pageNum = pageNum;
  54 + }
  55 +
  56 + public int getPageSize() {
  57 + return pageSize;
  58 + }
  59 +
  60 + public void setPageSize(int pageSize) {
  61 + this.pageSize = pageSize;
  62 + }
  63 +
  64 + public int getSize() {
  65 + return size;
  66 + }
  67 +
  68 + public void setSize(int size) {
  69 + this.size = size;
  70 + }
  71 +
  72 + public int getPages() {
  73 + return pages;
  74 + }
  75 +
  76 + public void setPages(int pages) {
  77 + this.pages = pages;
  78 + }
  79 +
  80 + public int getTotal() {
  81 + return total;
  82 + }
  83 +
  84 + public void setTotal(int total) {
  85 + this.total = total;
  86 + }
  87 +
  88 + public List<T> getList() {
  89 + return list;
  90 + }
  91 +
  92 + public void setList(List<T> list) {
  93 + this.list = list;
  94 + }
  95 +}
... ...
src/main/resources/application-dev.yml
... ... @@ -30,11 +30,14 @@ server:
30 30 userSettings:
31 31 # [必选 ] zlm配置的录像路径
32 32 record: /media/lin/Server/ZLMediaKit/dev/ZLMediaKit/release/linux/Debug/www/record
  33 + # [可选 ] 录像保存时长(单位: 天)每天晚12点自动对过期文件执行清理
  34 + recordDay: 7
33 35 # [必选 ] ffmpeg路径
34 36 ffmpeg: /usr/bin/ffmpeg
35 37 # [必选 ] ffprobe路径, 一般安装ffmpeg就会自带, 一般跟ffmpeg在同一目录,用于查询文件的信息
36 38 ffprobe: /usr/bin/ffprobe
37 39  
  40 +
38 41 # [可选] 日志配置, 一般不需要改
39 42 logging:
40 43 file:
... ...
src/main/resources/application-local.yml
... ... @@ -30,6 +30,8 @@ server:
30 30 userSettings:
31 31 # [必选 ] zlm配置的录像路径
32 32 record: /media/lin/Server/ZLMediaKit/dev/ZLMediaKit/release/linux/Debug/www/record
  33 + # [可选 ] 录像保存时长(单位: 天)每天晚12点自动对过期文件执行清理
  34 + recordDay: 7
33 35 # [必选 ] ffmpeg路径
34 36 ffmpeg: /usr/bin/ffmpeg
35 37 # [必选 ] ffprobe路径, 一般安装ffmpeg就会自带, 一般跟ffmpeg在同一目录,用于查询文件的信息
... ...