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 | \ No newline at end of file | 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 | \ No newline at end of file | 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 | +} |