feat: adding get files

This commit is contained in:
wzp 2023-04-26 18:53:17 +08:00
parent f0e4366d23
commit e3508ad65d
13 changed files with 453 additions and 69 deletions

124
.idea/uiDesigner.xml generated Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

88
.idea/workspace.xml generated
View File

@ -5,44 +5,19 @@
</component>
<component name="ChangeListManager">
<list default="true" id="b1988503-f417-4c69-ad49-94239747bbea" name="变更" comment="feat: adding get files">
<change afterPath="$PROJECT_DIR$/.idea/modules/FFMpegJ/FileManager.FFMpegJ.main.iml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/modules/FFMpegJ/FileManager.FFMpegJ.test.iml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/FFMpegJ/src/main/java/cn/wzpmc/filemanager/ffmpeg/FFMpegRuntime.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/FileManager/src/entities/FileDetailsInfo.ts" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/uiDesigner.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/FFMpegJ/src/main/java/cn/wzpmc/filemanager/ffmpeg/enums/VideoEncoder.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/FFMpegJ/src/main/java/cn/wzpmc/filemanager/ffmpeg/threads/TranscodingFileThread.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/application.properties" afterDir="false" />
<change afterPath="$PROJECT_DIR$/gradle.properties" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/entities/CountableList.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/entities/ResponseResult.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/enums/SearchType.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/utils/JwtUtils.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.gitignore" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/compiler.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/compiler.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/dataSources.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/gradle.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/gradle.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/jarRepositories.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/jarRepositories.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/modules.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/modules.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/modules/FileManager.main.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/modules/FileManager.main.iml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/vcs.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/FileManager.iml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/FileManager/components.d.ts" beforeDir="false" afterPath="$PROJECT_DIR$/FileManager/components.d.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/FileManager/package-lock.json" beforeDir="false" afterPath="$PROJECT_DIR$/FileManager/package-lock.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/FileManager/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/FileManager/package.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/FileManager/src/App.vue" beforeDir="false" afterPath="$PROJECT_DIR$/FileManager/src/App.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/FileManager/src/requester/Requester.ts" beforeDir="false" afterPath="$PROJECT_DIR$/FileManager/src/requester/Requester.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/build.gradle.kts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/settings.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/settings.gradle.kts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/config/GlobalWebMvcConfig.java" beforeDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/entities/EncodingThreadInfo.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/enums/EncodingStatus.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/FFMpegJ/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/FFMpegJ/build.gradle.kts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/FFMpegJ/src/main/java/cn/wzpmc/filemanager/ffmpeg/FFMpegRuntime.java" beforeDir="false" afterPath="$PROJECT_DIR$/FFMpegJ/src/main/java/cn/wzpmc/filemanager/ffmpeg/FFMpegRuntime.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/FileManagerApplication.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/FileManagerApplication.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/controller/FileController.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/controller/FileController.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/controller/UserController.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/controller/UserController.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/dao/FileDao.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/dao/FileDao.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/dao/UserDao.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/dao/UserDao.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/service/FileService.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/service/FileService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/service/UserService.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/cn/wzpmc/filemanager/service/UserService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/resources/application.properties" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/resources/application.properties" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/resources/cn/wzpmc/filemanager/dao/FileDao.xml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/resources/cn/wzpmc/filemanager/dao/FileDao.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/resources/cn/wzpmc/filemanager/dao/UserDao.xml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/resources/cn/wzpmc/filemanager/dao/UserDao.xml" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -88,8 +63,8 @@
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Class" />
<option value="TypeScript File" />
<option value="Class" />
</list>
</option>
</component>
@ -97,7 +72,9 @@
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="HighlightingSettingsPerFile">
<setting file="jar:///server/JAVA_HOME/17/lib/src.zip!/java.base/java/util/regex/Pattern.java" root0="SKIP_INSPECTION" />
<setting file="jar:///server/JAVA_HOME/20/lib/src.zip!/java.base/java/util/Date.java" root0="SKIP_INSPECTION" />
<setting file="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.projectlombok/lombok/1.18.26/f43db6c43d481ab766a496c86dc43c145e3c9df4/lombok-1.18.26-sources.jar!/lombok/extern/slf4j/XSlf4j.java" root0="SKIP_INSPECTION" />
</component>
<component name="HttpClientSelectedEnvironments">
<file url="jar://$APPLICATION_HOME_DIR$/plugins/restClient/lib/restClient.jar!/com/intellij/ws/rest/client/requests/collection/post-requests.http" environment="test" />
@ -151,28 +128,29 @@
<window_info id="Commit_Guest" show_stripe_button="false" />
<window_info id="Pull Requests" />
<window_info id="Learn" />
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.32734376" />
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.23818277" />
<window_info id="Commit" order="1" weight="0.32734376" />
<window_info id="Structure" order="2" weight="0.25" />
<window_info anchor="bottom" id="Database Changes" />
<window_info anchor="bottom" id="TypeScript" />
<window_info anchor="bottom" id="Profiler" />
<window_info active="true" anchor="bottom" id="Messages" visible="true" weight="0.32994187" />
<window_info anchor="bottom" id="Profiler" weight="0.32994187" />
<window_info anchor="bottom" id="Messages" weight="0.32994187" />
<window_info anchor="bottom" id="Java Enterprise" weight="0.33251953" />
<window_info anchor="bottom" id="File Transfer" />
<window_info anchor="bottom" id="Run" weight="0.32994187" />
<window_info anchor="bottom" id="Dependency Checker" />
<window_info anchor="bottom" id="Version Control" order="0" weight="0.32994187" />
<window_info anchor="bottom" id="Problems View" order="1" weight="0.33284885" />
<window_info anchor="bottom" id="Terminal" order="2" weight="0.32994187" />
<window_info anchor="bottom" id="Build" order="3" weight="0.33284885" />
<window_info anchor="bottom" id="Services" order="4" weight="0.32994187" />
<window_info active="true" anchor="bottom" id="Version Control" order="0" visible="true" weight="0.34228516" />
<window_info anchor="bottom" id="Problems View" order="1" weight="0.3396318" />
<window_info anchor="bottom" id="Terminal" order="2" weight="0.34190106" />
<window_info anchor="bottom" id="Build" order="3" weight="0.32994187" />
<window_info anchor="bottom" id="Debug" order="4" show_stripe_button="false" weight="0.32994187" />
<window_info anchor="bottom" id="Services" order="5" weight="0.34228516" />
<window_info anchor="right" id="Endpoints" />
<window_info anchor="right" id="Beans" />
<window_info anchor="right" id="Meet New UI" show_stripe_button="false" side_tool="true" />
<window_info anchor="right" content_ui="combo" id="Notifications" order="0" weight="0.25" />
<window_info anchor="right" id="Database" order="1" weight="0.25" />
<window_info anchor="right" id="Gradle" order="2" visible="true" weight="0.32734376" />
<window_info anchor="right" id="Gradle" order="2" weight="0.23619792" />
</layout>
</component>
<component name="RecentsManager">
@ -346,8 +324,8 @@
</list>
<recent_temporary>
<list>
<item itemvalue="Gradle.FileManager [clean]" />
<item itemvalue="Gradle.CheckTest.onTest" />
<item itemvalue="Gradle.FileManager [clean]" />
<item itemvalue="Gradle.CheckTest" />
<item itemvalue="Gradle.FileManager [nativeRun]" />
</list>
@ -378,7 +356,9 @@
<workItem from="1680618003149" duration="219000" />
<workItem from="1680932900587" duration="28000" />
<workItem from="1681528254816" duration="55000" />
<workItem from="1681825747684" duration="988000" />
<workItem from="1681825747684" duration="2853000" />
<workItem from="1682258664381" duration="2743000" />
<workItem from="1682426315842" duration="7659000" />
</task>
<task id="LOCAL-00001" summary="feat: adding get files">
<created>1679928730544</created>
@ -387,7 +367,21 @@
<option name="project" value="LOCAL" />
<updated>1679928730544</updated>
</task>
<option name="localTasksCounter" value="2" />
<task id="LOCAL-00002" summary="feat: adding get files">
<created>1681826752728</created>
<option name="number" value="00002" />
<option name="presentableId" value="LOCAL-00002" />
<option name="project" value="LOCAL" />
<updated>1681826752728</updated>
</task>
<task id="LOCAL-00003" summary="feat: adding get files">
<created>1681826809345</created>
<option name="number" value="00003" />
<option name="presentableId" value="LOCAL-00003" />
<option name="project" value="LOCAL" />
<updated>1681826809345</updated>
</task>
<option name="localTasksCounter" value="4" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">

View File

@ -21,7 +21,9 @@ dependencies {
annotationProcessor("org.projectlombok:lombok:1.18.26")
// https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2
implementation("com.alibaba.fastjson2:fastjson2:2.0.26")
implementation("org.apache.tika:tika-core:2.7.0")
implementation(
"org.apache.tika:tika-core:2.7.0")
}
tasks.withType<Test> {

View File

@ -40,7 +40,7 @@ public class FFMpegRuntime {
if (contentType == null || !contentType.startsWith("video")) {
return null;
}
ProcessBuilder processBuilder = new ProcessBuilder("ffprobe", "-v", "quiet", "-print_format", "json", "-show_streams", file.getAbsolutePath());
ProcessBuilder processBuilder = new ProcessBuilder(this.ffprobePath, "-v", "quiet", "-print_format", "json", "-show_streams", file.getAbsolutePath());
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();

View File

@ -0,0 +1,20 @@
package cn.wzpmc.filemanager.ffmpeg.enums;
public enum VideoEncoder {
H264("h264", "h264_nvenc", "h264_cuvid"),
HEVC("h265", "hevc_nvenc", "hevc_cuvid");
public final String name;
public final String encoderName;
public final String decoderName;
VideoEncoder(String name, String encoderName, String decoderName){
this.name = name;
this.encoderName = encoderName;
this.decoderName = decoderName;
}
public static VideoEncoder getEncoder(String name){
if (name.equals("h264")){
return H264;
}
return HEVC;
}
}

View File

@ -0,0 +1,128 @@
package cn.wzpmc.filemanager.ffmpeg.threads;
import cn.wzpmc.filemanager.ffmpeg.FFMpegRuntime;
import cn.wzpmc.filemanager.ffmpeg.enums.VideoEncoder;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j
public class TranscodingFileThread extends Thread{
private final static Pattern getDataPattern = Pattern.compile("frame=\\s*(\\d+)\\s+fps=([\\d\\.]+)\\s+q=([\\d\\.]+)\\s+size=\\s*(\\d+kB)\\s+time=([\\d:.]+)\\s+bitrate=([\\d\\.]+kbits/s)\\s+speed=([\\d\\.]+x)\\s*");
private final File input;
@Getter
private final VideoEncoder outputEncoder;
@Getter
private final File output;
private final Callback callback;
private final FFMpegRuntime ffMpegRuntime;
private VideoEncoder inputEncoder;
@Getter
private long totalFrames;
@Getter
private float progress;
@Getter
private long frames;
@Getter
private float fps;
@SneakyThrows
public TranscodingFileThread(File input, VideoEncoder outputEncoder, File output, Callback callback, FFMpegRuntime ffMpegRuntime){
this.input = input;
this.outputEncoder = outputEncoder;
this.output = output;
this.callback = callback;
this.ffMpegRuntime = ffMpegRuntime;
ProcessBuilder probeProcessBuilder = new ProcessBuilder();
probeProcessBuilder.command(
this.ffMpegRuntime.getFfprobePath(),
"-v",
"quiet",
"-print_format",
"json",
"-show_streams",
this.input.getAbsolutePath()
);
Process probeProcess = probeProcessBuilder.start();
probeProcess.waitFor();
String fileProbeResult = new String(probeProcess.getInputStream().readAllBytes());
JSONObject probeResultObject = JSONObject.parseObject(fileProbeResult);
JSONArray streams = probeResultObject.getJSONArray("streams");
for (int i = 0; i < streams.size(); i++) {
JSONObject stream = streams.getJSONObject(i);
if (stream.getString("codec_type").equals("video")) {
this.inputEncoder = VideoEncoder.getEncoder(stream.getString("codec_name"));
this.totalFrames = Long.parseLong(stream.getString("nb_frames"));
}
}
if (this.inputEncoder == null){
throw new RuntimeException(new IOException("The input file isn't video file!"));
}
super.setName("Transcoding-File-Thread-" + input.getName());
}
@Override
public void run() {
try{
if (this.output.exists()){
boolean delete = this.output.delete();
if (!delete){
return;
}
}
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command(
this.ffMpegRuntime.getFfmpegPath(),
"-hide_banner",
"-vsync",
"0",
"-hwaccel",
"cuvid",
"-hwaccel_output_format",
"cuda",
"-c:v",
this.inputEncoder.decoderName,
"-i",
this.input.getAbsolutePath(),
"-c:v",
this.outputEncoder.encoderName,
"-c:a",
"copy",
this.output.getAbsolutePath()
);
System.out.println(String.join(" ", processBuilder.command()));
Process start = processBuilder.start();
BufferedInputStream in = new BufferedInputStream(start.getErrorStream());
BufferedReader inBr = new BufferedReader(new InputStreamReader(in));
String lineStr;
while (start.isAlive()) {
lineStr = inBr.readLine();
if (lineStr == null){
this.frames = totalFrames;
progress = 1.0f;
return;
}
Matcher matcher = getDataPattern.matcher(lineStr);
if (matcher.find()) {
this.frames = Long.parseLong(matcher.group(1));
this.fps = Float.parseFloat(matcher.group(2));
progress = (float) this.frames / totalFrames;
}
}
}catch (Throwable throwable){
throwable.printStackTrace();
}finally {
this.callback.onDone(this);
}
}
@FunctionalInterface
public interface Callback{
void onDone(TranscodingFileThread thread);
}
}

8
application.properties Normal file
View File

@ -0,0 +1,8 @@
server.port=8080
spring.datasource.url=jdbc:mysql://192.168.1.2:3306/fs
spring.datasource.username=FS
spring.datasource.password=JiGSnWrwpPFnrthM
save-path=/main/files
hmac-key=rsnIkOKV,8#5Ex>B
spring.servlet.multipart.max-request-size=20GB
spring.servlet.multipart.max-file-size=20GB

View File

@ -10,5 +10,4 @@ public class FileManagerApplication {
public static void main(String[] args) {
SpringApplication.run(FileManagerApplication.class, args);
}
}

View File

@ -1,10 +1,14 @@
package cn.wzpmc.filemanager.controller;
import cn.wzpmc.filemanager.entities.CountableList;
import cn.wzpmc.filemanager.entities.EncodingThreadInfo;
import cn.wzpmc.filemanager.entities.FileObject;
import cn.wzpmc.filemanager.enums.SearchType;
import cn.wzpmc.filemanager.ffmpeg.enums.VideoEncoder;
import cn.wzpmc.filemanager.service.FileService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@ -14,21 +18,22 @@ import java.util.Map;
@RestController
@CrossOrigin
@RequestMapping("/api/file")
public class FileController {
private final FileService service;
@Autowired
public FileController(FileService service){
this.service = service;
}
@GetMapping("/api/file/count")
@GetMapping("/count")
public Long getFileCount(){
return service.getFileCount();
}
@GetMapping("/api/file/get")
@GetMapping("/get")
public List<FileObject> getFiles(@RequestParam("page") int page){
return service.getFiles(page);
}
@GetMapping("/api/file/search")
@GetMapping("/search")
public CountableList<FileObject> searchFiles(@RequestParam("type") SearchType type, @RequestParam("keywords") String keywords, @RequestParam("page") int page){
return switch (type){
case NAME -> service.searchFilesByName(keywords, page);
@ -37,20 +42,28 @@ public class FileController {
case FORMAT -> service.searchFilesByFormat(keywords, page);
};
}
@GetMapping("/api/file")
@GetMapping("/")
public void downloadFile(@RequestParam("id") int id, HttpServletResponse response){
service.downloadFile(id, response);
}
@PostMapping("/api/file/upload")
@PostMapping("/upload")
public FileObject uploadFile(@RequestHeader("Authorization") String token, @RequestBody MultipartFile file){
return service.uploadFile(token, file);
}
@PostMapping("/api/file/remove")
@PostMapping("/remove")
public boolean removeFile(@RequestHeader("Authorization") String token, @RequestBody FileObject file){
return service.removeFile(token, file);
}
@GetMapping("/api/file/details")
@GetMapping("/details")
public Map<String, Object> getFileDetails(@RequestParam("id") int id){
return service.getFileDetails(id);
}
@PostMapping("/encoding")
public Object transEncoding(@RequestBody FileObject object, @RequestParam("enc") String encoder, @RequestHeader("Authorization") String token){
return service.encoding(object, VideoEncoder.getEncoder(encoder), token);
}
@GetMapping("/getEncodingInfo")
public List<EncodingThreadInfo> getEncodingInfo(){
return service.getEncodingInfo();
}
}

View File

@ -6,24 +6,22 @@ import cn.wzpmc.filemanager.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
@RestController
@CrossOrigin
@RequestMapping("/api/user/")
public class UserController {
private final UserService service;
@Autowired
public UserController(UserService service){
this.service = service;
}
@PostMapping("/api/user/login")
@PostMapping("/login")
public ResponseResult<User> login(@RequestBody User user, HttpServletRequest request, HttpServletResponse response){
return new ResponseResult<>(this.service.login(user, request.getRemoteAddr(), response));
}
@PostMapping("/api/user/register")
@PostMapping("/register")
public User register(@RequestBody User user, HttpServletRequest request, HttpServletResponse response){
return this.service.register(user, request.getRemoteAddr(), response);
}

View File

@ -0,0 +1,16 @@
package cn.wzpmc.filemanager.entities;
import cn.wzpmc.filemanager.enums.EncodingStatus;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class EncodingThreadInfo {
private EncodingStatus status;
private FileObject file;
private float progress;
private long totalFrame;
private long nowFrame;
private float fps;
}

View File

@ -0,0 +1,5 @@
package cn.wzpmc.filemanager.enums;
public enum EncodingStatus {
WAITING, RUNNING, END
}

View File

@ -2,9 +2,13 @@ package cn.wzpmc.filemanager.service;
import cn.wzpmc.filemanager.dao.FileDao;
import cn.wzpmc.filemanager.entities.CountableList;
import cn.wzpmc.filemanager.entities.EncodingThreadInfo;
import cn.wzpmc.filemanager.entities.FileObject;
import cn.wzpmc.filemanager.entities.User;
import cn.wzpmc.filemanager.enums.EncodingStatus;
import cn.wzpmc.filemanager.ffmpeg.FFMpegRuntime;
import cn.wzpmc.filemanager.ffmpeg.enums.VideoEncoder;
import cn.wzpmc.filemanager.ffmpeg.threads.TranscodingFileThread;
import cn.wzpmc.filemanager.utils.JwtUtils;
import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
@ -19,6 +23,8 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
@ -44,6 +50,8 @@ public class FileService {
log.info("成功创建保存文件夹!");
}
this.runtime = new FFMpegRuntime();
DaemonThread daemonThread = new DaemonThread();
daemonThread.start();
}
public Long getFileCount() {
@ -88,12 +96,21 @@ public class FileService {
}
@SneakyThrows
public FileObject uploadFile(String token, MultipartFile file) {
String fullName = file.getOriginalFilename();
assert fullName != null;
File tempFile = File.createTempFile(fullName, "");
FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
StreamUtils.copy(file.getInputStream(), fileOutputStream);
fileOutputStream.close();
return uploadFile(token, tempFile, fullName);
}
public FileObject uploadFile(String token, File file, String fullName){
Optional<User> user = jwtUtils.getUser(token);
if (user.isEmpty()) {
return null;
}
User requestUser = user.get();
String fullName = file.getOriginalFilename();
assert fullName != null;
int i = fullName.lastIndexOf('.');
String name = fullName.substring(0, i);
@ -102,20 +119,26 @@ public class FileService {
FileObject fileObject = new FileObject();
fileObject.setFileName(name);
fileObject.setFileFormat(format);
fileObject.setFileSize(file.getSize());
fileObject.setFileSize(file.length());
fileObject.setUploader(requestUser.getUsername());
fileObject.setMd5(md5);
File saveFile = new File(this.savePath, md5);
if (!saveFile.exists()) {
StreamUtils.copy(file.getInputStream(), new FileOutputStream(saveFile));
try {
Files.move(file.toPath(), saveFile.toPath());
} catch (IOException e) {
e.printStackTrace();
log.warn("移动文件失败!, File={}", fileObject);
return null;
}
dao.uploadFile(fileObject);
return fileObject;
}
@SneakyThrows
private static String getFileMd5(MultipartFile file){
private static String getFileMd5(File file){
MessageDigest MD5 = MessageDigest.getInstance("MD5");
MD5.digest(file.getBytes());
FileInputStream fileInputStream = new FileInputStream(file);
MD5.digest(fileInputStream.readAllBytes());
fileInputStream.close();
return new String(Hex.encodeHex(MD5.digest()));
}
@ -166,4 +189,58 @@ public class FileService {
}
return result;
}
private final Map<Integer, TranscodingFileThread> transcodingFileThreadMap = new Hashtable<>();
private final Map<String, EncodingStatus> statusMap = new Hashtable<>();
@SneakyThrows
public Object encoding(FileObject fileObject, VideoEncoder outputEnc, String token){
if (!runtime.check()) {
log.warn("服务端缺少FFMpeg环境FFMpeg和FFProbe会影响某些功能使用");
}
if (transcodingFileThreadMap.containsKey(fileObject.getId())){
return "文件存在,无法转码!";
}
File outputTempFile = File.createTempFile("video-encoding-" + fileObject.getMd5(), ".mp4");
File inputFile = new File(savePath, fileObject.getMd5());
TranscodingFileThread transcodingFileThread = new TranscodingFileThread(inputFile, outputEnc, outputTempFile, (thread) -> {
statusMap.put(thread.getName(), EncodingStatus.END);
this.uploadFile(token, thread.getOutput(), fileObject.getFileName() + "-" + thread.getOutputEncoder().name + ".mp4");
}, runtime);
statusMap.put(transcodingFileThread.getName(), EncodingStatus.WAITING);
transcodingFileThreadMap.put(fileObject.getId(), transcodingFileThread);
return transcodingFileThreadMap.hashCode();
}
public List<EncodingThreadInfo> getEncodingInfo() {
List<EncodingThreadInfo> result = new ArrayList<>();
for (Map.Entry<Integer, TranscodingFileThread> entry : transcodingFileThreadMap.entrySet()) {
Integer fileId = entry.getKey();
TranscodingFileThread value = entry.getValue();
FileObject fullFileInfo = dao.getFullFileInfo(fileId);
result.add(new EncodingThreadInfo(statusMap.get(value.getName()), fullFileInfo, value.getProgress(), value.getTotalFrames(), value.getFrames(), value.getFps()));
}
return result;
}
private class DaemonThread extends Thread {
@SneakyThrows
@Override
public void run() {
while (true){
for (TranscodingFileThread value : FileService.this.transcodingFileThreadMap.values()) {
String name = value.getName();
EncodingStatus status = FileService.this.statusMap.get(name);
if (status.equals(EncodingStatus.RUNNING)){
break;
}
if (status.equals(EncodingStatus.END)){
continue;
}
value.start();
FileService.this.statusMap.put(name, EncodingStatus.RUNNING);
break;
}
Thread.sleep(1000);
}
}
}
}