Commit aad3e404578d60923eed3346e72048d62e2c9d20
0 parents
初始提交
Showing
10 changed files
with
414 additions
and
0 deletions
pom.xml
0 → 100644
| 1 | +++ a/pom.xml | |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
| 3 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
| 4 | + <modelVersion>4.0.0</modelVersion> | |
| 5 | + <parent> | |
| 6 | + <groupId>org.springframework.boot</groupId> | |
| 7 | + <artifactId>spring-boot-starter-parent</artifactId> | |
| 8 | + <version>2.4.5</version> | |
| 9 | + <relativePath/> <!-- lookup parent from repository --> | |
| 10 | + </parent> | |
| 11 | + <groupId>top.panll.assist</groupId> | |
| 12 | + <artifactId>wvp-pro-assist</artifactId> | |
| 13 | + <version>2.0.0</version> | |
| 14 | + <name>wvp-pro-assist</name> | |
| 15 | + <description>Demo project for Spring Boot</description> | |
| 16 | + <properties> | |
| 17 | + <java.version>1.8</java.version> | |
| 18 | + </properties> | |
| 19 | + <dependencies> | |
| 20 | + <dependency> | |
| 21 | + <groupId>org.springframework.boot</groupId> | |
| 22 | + <artifactId>spring-boot-starter-web</artifactId> | |
| 23 | + </dependency> | |
| 24 | + | |
| 25 | + <dependency> | |
| 26 | + <groupId>log4j</groupId> | |
| 27 | + <artifactId>log4j</artifactId> | |
| 28 | + <version>1.2.17</version> | |
| 29 | + </dependency> | |
| 30 | + | |
| 31 | + <dependency> | |
| 32 | + <groupId>net.bramp.ffmpeg</groupId> | |
| 33 | + <artifactId>ffmpeg</artifactId> | |
| 34 | + <version>0.6.2</version> | |
| 35 | + </dependency> | |
| 36 | + | |
| 37 | + <dependency> | |
| 38 | + <groupId>org.springframework.boot</groupId> | |
| 39 | + <artifactId>spring-boot-starter-test</artifactId> | |
| 40 | + <scope>test</scope> | |
| 41 | + </dependency> | |
| 42 | + </dependencies> | |
| 43 | + | |
| 44 | + <build> | |
| 45 | + <finalName>${project.artifactId}-${project.version}-${maven.build.timestamp}</finalName> | |
| 46 | + <plugins> | |
| 47 | + <plugin> | |
| 48 | + <groupId>org.springframework.boot</groupId> | |
| 49 | + <artifactId>spring-boot-maven-plugin</artifactId> | |
| 50 | + </plugin> | |
| 51 | + </plugins> | |
| 52 | + </build> | |
| 53 | + | |
| 54 | +</project> | ... | ... |
src/main/java/top/panll/assist/WvpProAssistApplication.java
0 → 100644
| 1 | +++ a/src/main/java/top/panll/assist/WvpProAssistApplication.java | |
| 1 | +package top.panll.assist; | |
| 2 | + | |
| 3 | +import org.springframework.boot.SpringApplication; | |
| 4 | +import org.springframework.boot.autoconfigure.SpringBootApplication; | |
| 5 | + | |
| 6 | +@SpringBootApplication | |
| 7 | +public class WvpProAssistApplication { | |
| 8 | + | |
| 9 | + public static void main(String[] args) { | |
| 10 | + SpringApplication.run(WvpProAssistApplication.class, args); | |
| 11 | + } | |
| 12 | + | |
| 13 | +} | ... | ... |
src/main/java/top/panll/assist/config/StartConfig.java
0 → 100644
| 1 | +++ a/src/main/java/top/panll/assist/config/StartConfig.java | |
| 1 | +package top.panll.assist.config; | |
| 2 | + | |
| 3 | +import net.bramp.ffmpeg.FFmpeg; | |
| 4 | +import net.bramp.ffmpeg.FFprobe; | |
| 5 | +import net.bramp.ffmpeg.probe.FFmpegProbeResult; | |
| 6 | +import org.slf4j.Logger; | |
| 7 | +import org.slf4j.LoggerFactory; | |
| 8 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 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.File; | |
| 17 | +import java.io.IOException; | |
| 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 | + @Autowired | |
| 29 | + private UserSettings userSettings; | |
| 30 | + | |
| 31 | + @Autowired | |
| 32 | + private VideoFileService videoFileService; | |
| 33 | + | |
| 34 | + @Override | |
| 35 | + public void run(String... args) { | |
| 36 | + String record = userSettings.getRecord(); | |
| 37 | + File recordFile = new File(record); | |
| 38 | + if (!recordFile.exists() || !recordFile.isDirectory()) { | |
| 39 | + logger.error("[userSettings.record]配置错误,请检查路径是否存在"); | |
| 40 | + System.exit(1); | |
| 41 | + } | |
| 42 | + try { | |
| 43 | + String ffmpegPath = userSettings.getFfmpeg(); | |
| 44 | + String ffprobePath = userSettings.getFfprobe(); | |
| 45 | + FFmpeg ffmpeg = new FFmpeg(ffmpegPath); | |
| 46 | + FFprobe ffprobe = new FFprobe(ffprobePath); | |
| 47 | + logger.info("wvp-pro辅助程序启动成功"); | |
| 48 | + FFmpegExecUtils.getInstance().ffmpeg = ffmpeg; | |
| 49 | + FFmpegExecUtils.getInstance().ffprobe = ffprobe; | |
| 50 | + // 对目录进行预整理 | |
| 51 | + File[] appFiles = recordFile.listFiles(); | |
| 52 | + for (File appFile : appFiles) { | |
| 53 | + File[] streamFiles = appFile.listFiles(); | |
| 54 | + for (File streamFile : streamFiles) { | |
| 55 | + File[] dateFiles = streamFile.listFiles(); | |
| 56 | + for (File dateFile : dateFiles) { | |
| 57 | + File[] files = dateFile.listFiles(); | |
| 58 | + for (File file : files) { | |
| 59 | + videoFileService.handFile(file); | |
| 60 | + } | |
| 61 | + } | |
| 62 | + } | |
| 63 | + } | |
| 64 | + }catch (IOException exception){ | |
| 65 | + System.out.println(exception.getMessage()); | |
| 66 | + if (exception.getMessage().indexOf("ffmpeg") > 0 ) { | |
| 67 | + logger.error("[userSettings.ffmpeg]配置错误,请检查是否已安装ffmpeg并正确配置"); | |
| 68 | + System.exit(1); | |
| 69 | + } | |
| 70 | + if (exception.getMessage().indexOf("ffprobe") > 0 ) { | |
| 71 | + logger.error("[userSettings.ffprobe]配置错误,请检查是否已安装ffprobe并正确配置"); | |
| 72 | + System.exit(1); | |
| 73 | + } | |
| 74 | + }catch (Exception exception){ | |
| 75 | + logger.error("环境错误: " + exception.getMessage()); | |
| 76 | + } | |
| 77 | + } | |
| 78 | +} | ... | ... |
src/main/java/top/panll/assist/dto/UserSettings.java
0 → 100644
| 1 | +++ a/src/main/java/top/panll/assist/dto/UserSettings.java | |
| 1 | +package top.panll.assist.dto; | |
| 2 | + | |
| 3 | +import org.springframework.beans.factory.annotation.Value; | |
| 4 | +import org.springframework.stereotype.Component; | |
| 5 | + | |
| 6 | +@Component | |
| 7 | +public class UserSettings { | |
| 8 | + | |
| 9 | + @Value("${userSettings.record}") | |
| 10 | + private String record; | |
| 11 | + | |
| 12 | + @Value("${userSettings.ffmpeg}") | |
| 13 | + private String ffmpeg; | |
| 14 | + | |
| 15 | + @Value("${userSettings.ffprobe}") | |
| 16 | + private String ffprobe; | |
| 17 | + | |
| 18 | + public String getRecord() { | |
| 19 | + return record; | |
| 20 | + } | |
| 21 | + | |
| 22 | + public void setRecord(String record) { | |
| 23 | + this.record = record; | |
| 24 | + } | |
| 25 | + | |
| 26 | + public String getFfmpeg() { | |
| 27 | + return ffmpeg; | |
| 28 | + } | |
| 29 | + | |
| 30 | + public void setFfmpeg(String ffmpeg) { | |
| 31 | + this.ffmpeg = ffmpeg; | |
| 32 | + } | |
| 33 | + | |
| 34 | + public String getFfprobe() { | |
| 35 | + return ffprobe; | |
| 36 | + } | |
| 37 | + | |
| 38 | + public void setFfprobe(String ffprobe) { | |
| 39 | + this.ffprobe = ffprobe; | |
| 40 | + } | |
| 41 | +} | ... | ... |
src/main/java/top/panll/assist/service/FFmpegExecUtils.java
0 → 100644
| 1 | +++ a/src/main/java/top/panll/assist/service/FFmpegExecUtils.java | |
| 1 | +package top.panll.assist.service; | |
| 2 | + | |
| 3 | +import net.bramp.ffmpeg.FFmpeg; | |
| 4 | +import net.bramp.ffmpeg.FFprobe; | |
| 5 | + | |
| 6 | +public class FFmpegExecUtils { | |
| 7 | + | |
| 8 | + private static FFmpegExecUtils instance; | |
| 9 | + | |
| 10 | + public FFmpegExecUtils() { | |
| 11 | + } | |
| 12 | + | |
| 13 | + public static FFmpegExecUtils getInstance(){ | |
| 14 | + if(instance==null){ | |
| 15 | + synchronized (FFmpegExecUtils.class){ | |
| 16 | + if(instance==null){ | |
| 17 | + instance=new FFmpegExecUtils(); | |
| 18 | + } | |
| 19 | + } | |
| 20 | + } | |
| 21 | + return instance; | |
| 22 | + } | |
| 23 | + | |
| 24 | + public FFprobe ffprobe; | |
| 25 | + public FFmpeg ffmpeg; | |
| 26 | + | |
| 27 | +} | ... | ... |
src/main/java/top/panll/assist/service/VideoFileService.java
0 → 100644
| 1 | +++ a/src/main/java/top/panll/assist/service/VideoFileService.java | |
| 1 | +package top.panll.assist.service; | |
| 2 | + | |
| 3 | +import net.bramp.ffmpeg.FFprobe; | |
| 4 | +import net.bramp.ffmpeg.probe.FFmpegProbeResult; | |
| 5 | +import org.slf4j.Logger; | |
| 6 | +import org.slf4j.LoggerFactory; | |
| 7 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 8 | +import org.springframework.stereotype.Service; | |
| 9 | +import top.panll.assist.config.StartConfig; | |
| 10 | +import top.panll.assist.dto.UserSettings; | |
| 11 | + | |
| 12 | +import java.io.File; | |
| 13 | +import java.io.FilenameFilter; | |
| 14 | +import java.io.IOException; | |
| 15 | +import java.text.ParseException; | |
| 16 | +import java.text.SimpleDateFormat; | |
| 17 | +import java.util.ArrayList; | |
| 18 | +import java.util.Date; | |
| 19 | +import java.util.List; | |
| 20 | + | |
| 21 | +@Service | |
| 22 | +public class VideoFileService { | |
| 23 | + | |
| 24 | + private final static Logger logger = LoggerFactory.getLogger(VideoFileService.class); | |
| 25 | + | |
| 26 | + @Autowired | |
| 27 | + private UserSettings userSettings; | |
| 28 | + | |
| 29 | + | |
| 30 | + public void handFile(File file) throws ParseException { | |
| 31 | + FFprobe ffprobe = FFmpegExecUtils.getInstance().ffprobe; | |
| 32 | + if(file.isFile() && !file.getName().startsWith(".") && file.getName().indexOf(":") < 0) { | |
| 33 | + try { | |
| 34 | + FFmpegProbeResult in = null; | |
| 35 | + in = ffprobe.probe(file.getAbsolutePath()); | |
| 36 | + double duration = in.getFormat().duration * 1000; | |
| 37 | + String endTimeStr = file.getName().replace(".mp4", ""); | |
| 38 | + | |
| 39 | + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); | |
| 40 | + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss"); | |
| 41 | + | |
| 42 | + File dateFile = new File(file.getParent()); | |
| 43 | + | |
| 44 | + long endTime = formatter.parse(dateFile.getName() + " " + endTimeStr).getTime(); | |
| 45 | + long startTime = endTime - new Double(duration).longValue(); | |
| 46 | + | |
| 47 | + String newName = file.getAbsolutePath().replace(file.getName(), | |
| 48 | + simpleDateFormat.format(startTime) + "-" + simpleDateFormat.format(endTime) + ".mp4"); | |
| 49 | + file.renameTo(new File(newName)); | |
| 50 | + System.out.println(newName); | |
| 51 | + } catch (IOException exception) { | |
| 52 | + exception.printStackTrace(); | |
| 53 | + } | |
| 54 | + } | |
| 55 | + } | |
| 56 | + | |
| 57 | + public List<File> getFilesInTime(String app, String stream, Date startTime, Date endTime){ | |
| 58 | + | |
| 59 | + List<File> result = new ArrayList<>(); | |
| 60 | + | |
| 61 | + if (app == null || stream == null) { | |
| 62 | + return result; | |
| 63 | + } | |
| 64 | + | |
| 65 | + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |
| 66 | + String startTimeStr = formatter.format(startTime); | |
| 67 | + String endTimeStr = formatter.format(endTime); | |
| 68 | + logger.debug("获取[app: {}, stream: {}, statime: {}, endTime: {}]的视频", app, stream, | |
| 69 | + startTimeStr, endTimeStr); | |
| 70 | + | |
| 71 | + File file = new File(userSettings.getRecord()); | |
| 72 | + File[] appFiles = file.listFiles(new FilenameFilter() { | |
| 73 | + @Override | |
| 74 | + public boolean accept(File dir, String name) { | |
| 75 | + return app.equals(name); | |
| 76 | + } | |
| 77 | + }); | |
| 78 | + if (appFiles.length == 0) { | |
| 79 | + logger.warn("获取[app: {}, stream: {}, statime: {}, endTime: {}]的视频时未找到目录: {}", app, stream, | |
| 80 | + startTimeStr, endTimeStr, app); | |
| 81 | + return result; | |
| 82 | + } | |
| 83 | + File appFile = appFiles[0]; | |
| 84 | + File[] streamFiles = appFile.listFiles(new FilenameFilter() { | |
| 85 | + @Override | |
| 86 | + public boolean accept(File dir, String name) { | |
| 87 | + return stream.equals(name); | |
| 88 | + } | |
| 89 | + }); | |
| 90 | + if (streamFiles.length == 0) { | |
| 91 | + logger.warn("获取[app: {}, stream: {}, statime: {}, endTime: {}]的视频时未找到目录: {}", app, stream, | |
| 92 | + startTimeStr, endTimeStr, stream); | |
| 93 | + return result; | |
| 94 | + } | |
| 95 | + File streamFile = streamFiles[0]; | |
| 96 | + // TODO 按时间获取文件 | |
| 97 | + | |
| 98 | + | |
| 99 | + return result; | |
| 100 | + } | |
| 101 | + | |
| 102 | +} | ... | ... |
src/main/resources/application-dev.yml
0 → 100644
| 1 | +++ a/src/main/resources/application-dev.yml | |
| 1 | +# [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 | |
| 2 | +server: | |
| 3 | + port: 18081 | |
| 4 | + # [可选] HTTPS配置, 默认不开启 | |
| 5 | + ssl: | |
| 6 | + # [可选] 是否开启HTTPS访问 | |
| 7 | + enabled: false | |
| 8 | + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 | |
| 9 | + key-store: classpath:xxx.jks | |
| 10 | + # [可选] 证书密码 | |
| 11 | + key-password: password | |
| 12 | + # [可选] 证书类型, 默认为jks,根据实际修改 | |
| 13 | + key-store-type: JKS | |
| 14 | + | |
| 15 | +# [根据业务需求配置] | |
| 16 | +userSettings: | |
| 17 | + # [必选 ] zlm配置的录像路径 | |
| 18 | + record: /media/lin/Server/ZLMediaKit/dev/ZLMediaKit/release/linux/Debug/www/record | |
| 19 | + # [必选 ] ffmpeg路径 | |
| 20 | + ffmpeg: /usr/bin/ffmpeg | |
| 21 | + # [必选 ] ffprobe路径, 一般安装ffmpeg就会自带, 一般跟ffmpeg在同一目录,用于查询文件的信息 | |
| 22 | + ffprobe: /usr/bin/ffprobe | |
| 23 | + | |
| 24 | +# [可选] 日志配置, 一般不需要改 | |
| 25 | +logging: | |
| 26 | + file: | |
| 27 | + name: logs/wvp.log | |
| 28 | + max-history: 30 | |
| 29 | + max-size: 10MB | |
| 30 | + total-size-cap: 300MB | |
| 31 | + level: | |
| 32 | + com: | |
| 33 | + genersoft: | |
| 34 | + iot: info | |
| 35 | + net: | |
| 36 | + bramp: warning | |
| 0 | 37 | \ No newline at end of file | ... | ... |
src/main/resources/application-local.yml
0 → 100644
| 1 | +++ a/src/main/resources/application-local.yml | |
| 1 | +# [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 | |
| 2 | +server: | |
| 3 | + port: 18081 | |
| 4 | + # [可选] HTTPS配置, 默认不开启 | |
| 5 | + ssl: | |
| 6 | + # [可选] 是否开启HTTPS访问 | |
| 7 | + enabled: false | |
| 8 | + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 | |
| 9 | + key-store: classpath:xxx.jks | |
| 10 | + # [可选] 证书密码 | |
| 11 | + key-password: password | |
| 12 | + # [可选] 证书类型, 默认为jks,根据实际修改 | |
| 13 | + key-store-type: JKS | |
| 14 | + | |
| 15 | +# [根据业务需求配置] | |
| 16 | +userSettings: | |
| 17 | + # [必选 ] zlm配置的录像路径 | |
| 18 | + record: /media/lin/Server/ZLMediaKit/dev/ZLMediaKit/release/linux/Debug/www/record | |
| 19 | + # [必选 ] ffmpeg路径 | |
| 20 | + ffmpeg: /usr/bin/ffmpeg | |
| 21 | + # [必选 ] ffprobe路径, 一般安装ffmpeg就会自带, 一般跟ffmpeg在同一目录,用于查询文件的信息 | |
| 22 | + ffprobe: /usr/bin/ffprobe | |
| 23 | + | |
| 24 | +# [可选] 日志配置, 一般不需要改 | |
| 25 | +logging: | |
| 26 | + file: | |
| 27 | + name: logs/wvp.log | |
| 28 | + max-history: 30 | |
| 29 | + max-size: 10MB | |
| 30 | + total-size-cap: 300MB | |
| 31 | + level: | |
| 32 | + com: | |
| 33 | + genersoft: | |
| 34 | + iot: INFO | |
| 35 | + net: | |
| 36 | + bramp: | |
| 37 | + ffmpeg: WARN | |
| 0 | 38 | \ No newline at end of file | ... | ... |
src/main/resources/application.yml
0 → 100644
src/test/java/top/panll/assist/WvpProAssistApplicationTests.java
0 → 100644
| 1 | +++ a/src/test/java/top/panll/assist/WvpProAssistApplicationTests.java | |
| 1 | +package top.panll.assist; | |
| 2 | + | |
| 3 | +import org.junit.jupiter.api.Test; | |
| 4 | +import org.springframework.boot.test.context.SpringBootTest; | |
| 5 | + | |
| 6 | +@SpringBootTest | |
| 7 | +class WvpProAssistApplicationTests { | |
| 8 | + | |
| 9 | + @Test | |
| 10 | + void contextLoads() { | |
| 11 | + } | |
| 12 | + | |
| 13 | +} | ... | ... |