Makes it possible to enable debug mode
Some checks failed
KnarCraft/FFmpegConvert/pipeline/head There was a failure building this commit
Some checks failed
KnarCraft/FFmpegConvert/pipeline/head There was a failure building this commit
Debug mode is now enabled if the property `debug = true` is set in `conf/config.properties` Changes code for reading internal configurations Changes many primitive lists to List<> Adds some missing annotations Renames the main class
This commit is contained in:
parent
f0e75eb440
commit
4ebd29b358
2
pom.xml
2
pom.xml
@ -86,7 +86,7 @@
|
|||||||
<transformer
|
<transformer
|
||||||
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||||
<manifestEntries>
|
<manifestEntries>
|
||||||
<Main-Class>net.knarcraft.ffmpegconverter.Main</Main-Class>
|
<Main-Class>net.knarcraft.ffmpegconverter.FFMpegConvert</Main-Class>
|
||||||
</manifestEntries>
|
</manifestEntries>
|
||||||
</transformer>
|
</transformer>
|
||||||
</transformers>
|
</transformers>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.knarcraft.ffmpegconverter;
|
package net.knarcraft.ffmpegconverter;
|
||||||
|
|
||||||
|
import net.knarcraft.ffmpegconverter.config.ConfigHandler;
|
||||||
import net.knarcraft.ffmpegconverter.converter.AnimeConverter;
|
import net.knarcraft.ffmpegconverter.converter.AnimeConverter;
|
||||||
import net.knarcraft.ffmpegconverter.converter.AudioConverter;
|
import net.knarcraft.ffmpegconverter.converter.AudioConverter;
|
||||||
import net.knarcraft.ffmpegconverter.converter.Converter;
|
import net.knarcraft.ffmpegconverter.converter.Converter;
|
||||||
@ -15,11 +16,13 @@ import net.knarcraft.ffmpegconverter.property.MinimalSubtitlePreference;
|
|||||||
import net.knarcraft.ffmpegconverter.utility.FileUtil;
|
import net.knarcraft.ffmpegconverter.utility.FileUtil;
|
||||||
import net.knarcraft.ffmpegconverter.utility.ListUtil;
|
import net.knarcraft.ffmpegconverter.utility.ListUtil;
|
||||||
import net.knarcraft.ffmpegconverter.utility.OutputUtil;
|
import net.knarcraft.ffmpegconverter.utility.OutputUtil;
|
||||||
|
import org.apache.commons.configuration2.Configuration;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
@ -28,15 +31,23 @@ import static net.knarcraft.ffmpegconverter.utility.Parser.tokenize;
|
|||||||
/**
|
/**
|
||||||
* The main class for starting the software
|
* The main class for starting the software
|
||||||
*/
|
*/
|
||||||
class Main {
|
public class FFMpegConvert {
|
||||||
|
|
||||||
private static final String FFPROBE_PATH = "ffprobe"; //Can be just ffprobe if it's in the path
|
private static final String FFPROBE_PATH = "ffprobe"; //Can be just ffprobe if it's in the path
|
||||||
private static final String FFMPEG_PATH = "ffmpeg"; //Can be just ffmpeg if it's in the path
|
private static final String FFMPEG_PATH = "ffmpeg"; //Can be just ffmpeg if it's in the path
|
||||||
private static final Scanner READER = new Scanner(System.in, StandardCharsets.UTF_8);
|
private static final Scanner READER = new Scanner(System.in, StandardCharsets.UTF_8);
|
||||||
private static Converter converter = null;
|
private static Converter converter = null;
|
||||||
|
private static final ConfigHandler configHandler = new ConfigHandler();
|
||||||
|
private static boolean debug = false;
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(@NotNull String[] arguments) throws IOException {
|
||||||
|
Configuration configuration = configHandler.load();
|
||||||
|
if (configuration.containsKey("debug")) {
|
||||||
|
debug = configuration.getBoolean("debug");
|
||||||
|
}
|
||||||
|
OutputUtil.setDebug(debug);
|
||||||
converter = loadConverter();
|
converter = loadConverter();
|
||||||
|
|
||||||
if (converter == null) {
|
if (converter == null) {
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
return;
|
return;
|
||||||
@ -62,9 +73,29 @@ class Main {
|
|||||||
OutputUtil.close();
|
OutputUtil.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the configuration handler
|
||||||
|
*
|
||||||
|
* @return <p>The configuration handler</p>
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static ConfigHandler getConfigHandler() {
|
||||||
|
return configHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether debug mode is enabled
|
||||||
|
*
|
||||||
|
* @return <p>True if debug mode is enabled</p>
|
||||||
|
*/
|
||||||
|
public static boolean isDebugEnabled() {
|
||||||
|
return debug;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asks the user which converter they want, and assigns a converter instance to the converter variable
|
* Asks the user which converter they want, and assigns a converter instance to the converter variable
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
private static Converter loadConverter() {
|
private static Converter loadConverter() {
|
||||||
int choice = getChoice("""
|
int choice = getChoice("""
|
||||||
Which converter do you want do use?
|
Which converter do you want do use?
|
||||||
@ -101,7 +132,7 @@ class Main {
|
|||||||
* @param recursionSteps <p>The depth to recurse if a folder is given.</p>
|
* @param recursionSteps <p>The depth to recurse if a folder is given.</p>
|
||||||
* @throws IOException <p>If conversion or writing fails.</p>
|
* @throws IOException <p>If conversion or writing fails.</p>
|
||||||
*/
|
*/
|
||||||
private static void convertAllFiles(File fileOrFolder, int recursionSteps) throws IOException {
|
private static void convertAllFiles(@NotNull File fileOrFolder, int recursionSteps) throws IOException {
|
||||||
if (fileOrFolder.isDirectory()) {
|
if (fileOrFolder.isDirectory()) {
|
||||||
File[] files = FileUtil.listFilesRecursive(fileOrFolder, converter.getValidFormats(), recursionSteps);
|
File[] files = FileUtil.listFilesRecursive(fileOrFolder, converter.getValidFormats(), recursionSteps);
|
||||||
if (files != null && files.length > 0) {
|
if (files != null && files.length > 0) {
|
||||||
@ -113,7 +144,7 @@ class Main {
|
|||||||
}
|
}
|
||||||
} else if (fileOrFolder.exists()) {
|
} else if (fileOrFolder.exists()) {
|
||||||
String path = fileOrFolder.getPath();
|
String path = fileOrFolder.getPath();
|
||||||
if (Arrays.stream(converter.getValidFormats()).anyMatch((format) -> format.equalsIgnoreCase(
|
if (converter.getValidFormats().stream().anyMatch((format) -> format.equalsIgnoreCase(
|
||||||
path.substring(path.lastIndexOf('.') + 1)))) {
|
path.substring(path.lastIndexOf('.') + 1)))) {
|
||||||
converter.convert(fileOrFolder);
|
converter.convert(fileOrFolder);
|
||||||
} else {
|
} else {
|
||||||
@ -130,6 +161,7 @@ class Main {
|
|||||||
*
|
*
|
||||||
* @return <p>The initialized downscale converter</p>
|
* @return <p>The initialized downscale converter</p>
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
private static Converter generateDownScaleConverter() {
|
private static Converter generateDownScaleConverter() {
|
||||||
OutputUtil.println("(New width e.x. 1920) (New height e.x. 1080)\nYour input: ");
|
OutputUtil.println("(New width e.x. 1920) (New height e.x. 1080)\nYour input: ");
|
||||||
List<String> input = readInput(3);
|
List<String> input = readInput(3);
|
||||||
@ -151,6 +183,7 @@ class Main {
|
|||||||
*
|
*
|
||||||
* @return <p>The initialized transcoder</p>
|
* @return <p>The initialized transcoder</p>
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
private static Converter generateMKVToMP4Transcoder() {
|
private static Converter generateMKVToMP4Transcoder() {
|
||||||
OutputUtil.println("[Audio stream index 0-n] [Subtitle stream index 0-n] [Video stream index 0-n]\nYour input: ");
|
OutputUtil.println("[Audio stream index 0-n] [Subtitle stream index 0-n] [Video stream index 0-n]\nYour input: ");
|
||||||
List<String> input = readInput(3);
|
List<String> input = readInput(3);
|
||||||
@ -180,6 +213,7 @@ class Main {
|
|||||||
*
|
*
|
||||||
* @return <p>The initialized anime converter</p>
|
* @return <p>The initialized anime converter</p>
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
private static Converter generateAnimeConverter() {
|
private static Converter generateAnimeConverter() {
|
||||||
OutputUtil.println("[Audio languages jpn,eng,ger,fre] [Subtitle languages eng,ger,fre] [Minimal subtitle " +
|
OutputUtil.println("[Audio languages jpn,eng,ger,fre] [Subtitle languages eng,ger,fre] [Minimal subtitle " +
|
||||||
"preference REQUIRE/PREFER/NO_PREFERENCE/AVOID/REJECT] [Forced audio index 0-n] " +
|
"preference REQUIRE/PREFER/NO_PREFERENCE/AVOID/REJECT] [Forced audio index 0-n] " +
|
||||||
@ -224,6 +258,7 @@ class Main {
|
|||||||
*
|
*
|
||||||
* @return <p>The initialized anime converter</p>
|
* @return <p>The initialized anime converter</p>
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
private static Converter generateWebAnimeConverter() {
|
private static Converter generateWebAnimeConverter() {
|
||||||
OutputUtil.println("[Audio languages jpn,eng,ger,fre] [Subtitle languages eng,ger,fre] [Convert to stereo if " +
|
OutputUtil.println("[Audio languages jpn,eng,ger,fre] [Subtitle languages eng,ger,fre] [Convert to stereo if " +
|
||||||
"necessary true/false] [Prevent signs&songs subtitles true/false] [Forced audio index 0-n] " +
|
"necessary true/false] [Prevent signs&songs subtitles true/false] [Forced audio index 0-n] " +
|
||||||
@ -274,6 +309,7 @@ class Main {
|
|||||||
* @param max <p>The number of tokens expected.</p>
|
* @param max <p>The number of tokens expected.</p>
|
||||||
* @return <p>A list of tokens.</p>
|
* @return <p>A list of tokens.</p>
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
private static List<String> readInput(int max) {
|
private static List<String> readInput(int max) {
|
||||||
List<String> tokens = tokenize(READER.nextLine());
|
List<String> tokens = tokenize(READER.nextLine());
|
||||||
if (max < tokens.size()) {
|
if (max < tokens.size()) {
|
||||||
@ -289,7 +325,8 @@ class Main {
|
|||||||
* @param prompt <p>The prompt shown to the user.</p>
|
* @param prompt <p>The prompt shown to the user.</p>
|
||||||
* @return <p>The non-empty choice given by the user.</p>
|
* @return <p>The non-empty choice given by the user.</p>
|
||||||
*/
|
*/
|
||||||
private static String getChoice(String prompt) {
|
@NotNull
|
||||||
|
private static String getChoice(@NotNull String prompt) {
|
||||||
OutputUtil.println(prompt);
|
OutputUtil.println(prompt);
|
||||||
String choice = "";
|
String choice = "";
|
||||||
while (choice.isEmpty()) {
|
while (choice.isEmpty()) {
|
||||||
@ -307,7 +344,7 @@ class Main {
|
|||||||
* @param max The maximum allowed value
|
* @param max The maximum allowed value
|
||||||
* @return The value given by the user
|
* @return The value given by the user
|
||||||
*/
|
*/
|
||||||
private static int getChoice(String prompt, int min, int max) {
|
private static int getChoice(@NotNull String prompt, int min, int max) {
|
||||||
OutputUtil.println(prompt);
|
OutputUtil.println(prompt);
|
||||||
int choice = Integer.MIN_VALUE;
|
int choice = Integer.MIN_VALUE;
|
||||||
do {
|
do {
|
@ -0,0 +1,92 @@
|
|||||||
|
package net.knarcraft.ffmpegconverter.config;
|
||||||
|
|
||||||
|
import net.knarcraft.ffmpegconverter.utility.FileHelper;
|
||||||
|
import net.knarcraft.ffmpegconverter.utility.OutputUtil;
|
||||||
|
import org.apache.commons.configuration2.Configuration;
|
||||||
|
import org.apache.commons.configuration2.PropertiesConfiguration;
|
||||||
|
import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
|
||||||
|
import org.apache.commons.configuration2.builder.fluent.Configurations;
|
||||||
|
import org.apache.commons.configuration2.ex.ConfigurationException;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A handler for dealing with configurations
|
||||||
|
*/
|
||||||
|
public class ConfigHandler {
|
||||||
|
|
||||||
|
private final File configFolder = new File("conf").getAbsoluteFile();
|
||||||
|
private final Configurations configurations = new Configurations();
|
||||||
|
private final File settingsFile = new File(configFolder, "config.properties");
|
||||||
|
private FileBasedConfigurationBuilder<PropertiesConfiguration> builder = configurations.propertiesBuilder(settingsFile);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a writable configuration used for changing settings
|
||||||
|
*
|
||||||
|
* @return <p>A writable properties configuration</p>
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public PropertiesConfiguration getWritableConfiguration() {
|
||||||
|
try {
|
||||||
|
return builder.getConfiguration();
|
||||||
|
} catch (ConfigurationException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the writable configuration to disk
|
||||||
|
*/
|
||||||
|
public void writeConfiguration() {
|
||||||
|
OutputUtil.printDebug("Preparing to save config");
|
||||||
|
if (!configFolder.exists() && !configFolder.mkdir()) {
|
||||||
|
throw new RuntimeException("Unable to create config folder. Make sure to run this .jar file from a " +
|
||||||
|
"writable directory!");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (!settingsFile.exists() && !settingsFile.createNewFile()) {
|
||||||
|
OutputUtil.println("Failed to create configuration file.");
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
OutputUtil.println("Failed to create configuration file.");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
builder.save();
|
||||||
|
} catch (ConfigurationException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
OutputUtil.printDebug("Saved available hardware encoder handler");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the saved configuration file
|
||||||
|
*
|
||||||
|
* @return <p>The loaded configuration</p>
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public Configuration load() throws IOException {
|
||||||
|
Configuration configuration;
|
||||||
|
if (!settingsFile.exists()) {
|
||||||
|
configuration = new PropertiesConfiguration();
|
||||||
|
BufferedReader reader = FileHelper.getBufferedReaderForInternalFile("/conf/config.properties");
|
||||||
|
Map<String, String> entries = FileHelper.readKeyValuePairs(reader, "=");
|
||||||
|
for (Map.Entry<String, String> entry : entries.entrySet()) {
|
||||||
|
configuration.setProperty(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
configuration = configurations.properties(settingsFile);
|
||||||
|
} catch (ConfigurationException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Reload contents in the builder
|
||||||
|
builder = configurations.propertiesBuilder(settingsFile);
|
||||||
|
return configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,12 +1,13 @@
|
|||||||
package net.knarcraft.ffmpegconverter.converter;
|
package net.knarcraft.ffmpegconverter.converter;
|
||||||
|
|
||||||
|
import net.knarcraft.ffmpegconverter.FFMpegConvert;
|
||||||
import net.knarcraft.ffmpegconverter.container.FFMpegCommand;
|
import net.knarcraft.ffmpegconverter.container.FFMpegCommand;
|
||||||
import net.knarcraft.ffmpegconverter.container.StreamProbeResult;
|
import net.knarcraft.ffmpegconverter.container.StreamProbeResult;
|
||||||
import net.knarcraft.ffmpegconverter.handler.AvailableHardwareEncoderHandler;
|
import net.knarcraft.ffmpegconverter.handler.AvailableHardwareEncoderHandler;
|
||||||
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
||||||
|
import net.knarcraft.ffmpegconverter.utility.FileHelper;
|
||||||
import net.knarcraft.ffmpegconverter.utility.FileUtil;
|
import net.knarcraft.ffmpegconverter.utility.FileUtil;
|
||||||
import net.knarcraft.ffmpegconverter.utility.OutputUtil;
|
import net.knarcraft.ffmpegconverter.utility.OutputUtil;
|
||||||
import org.apache.commons.configuration2.ex.ConfigurationException;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@ -20,12 +21,13 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractConverter implements Converter {
|
public abstract class AbstractConverter implements Converter {
|
||||||
|
|
||||||
final boolean debug = false;
|
final boolean debug = FFMpegConvert.isDebugEnabled();
|
||||||
private final String newExtension;
|
private final String newExtension;
|
||||||
protected String ffprobePath;
|
protected String ffprobePath;
|
||||||
protected String ffmpegPath;
|
protected String ffmpegPath;
|
||||||
protected String[] audioFormats;
|
protected List<String> audioFormats;
|
||||||
protected String[] videoFormats;
|
protected List<String> videoFormats;
|
||||||
|
protected List<String> subtitleFormats;
|
||||||
protected AvailableHardwareEncoderHandler encoderHandler = null;
|
protected AvailableHardwareEncoderHandler encoderHandler = null;
|
||||||
|
|
||||||
|
|
||||||
@ -34,31 +36,31 @@ public abstract class AbstractConverter implements Converter {
|
|||||||
*/
|
*/
|
||||||
AbstractConverter(@Nullable String newExtension) {
|
AbstractConverter(@Nullable String newExtension) {
|
||||||
this.newExtension = newExtension;
|
this.newExtension = newExtension;
|
||||||
OutputUtil.setDebug(this.debug);
|
|
||||||
try {
|
try {
|
||||||
audioFormats = FileUtil.readFileLines("audio_formats.txt");
|
this.audioFormats = FileHelper.readLines(FileHelper.getBufferedReaderForInternalFile("/audio_formats.txt"));
|
||||||
videoFormats = FileUtil.readFileLines("video_formats.txt");
|
this.videoFormats = FileHelper.readLines(FileHelper.getBufferedReaderForInternalFile("/video_formats.txt"));
|
||||||
|
this.subtitleFormats = FileHelper.readLines(FileHelper.getBufferedReaderForInternalFile("/subtitle_formats.txt"));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
System.out.println("Unable to read audio and/or video formats from internal files.");
|
OutputUtil.println("Unable to read audio and/or video formats from internal files.");
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void convert(@NotNull File file) throws IOException {
|
public void convert(@NotNull File file) throws IOException {
|
||||||
StreamProbeResult probeResult = FFMpegHelper.probeFile(ffprobePath, file);
|
StreamProbeResult probeResult = FFMpegHelper.probeFile(this.ffprobePath, file, this.subtitleFormats);
|
||||||
if (probeResult.parsedStreams().isEmpty()) {
|
if (probeResult.parsedStreams().isEmpty()) {
|
||||||
throw new IllegalArgumentException("The file has no valid streams. Please make sure the file exists and" +
|
throw new IllegalArgumentException("The file has no valid streams. Please make sure the file exists and" +
|
||||||
" is not corrupt.");
|
" is not corrupt.");
|
||||||
}
|
}
|
||||||
|
|
||||||
String outExtension = newExtension != null ? newExtension : FileUtil.getExtension(file.getName());
|
String outExtension = this.newExtension != null ? this.newExtension : FileUtil.getExtension(file.getName());
|
||||||
String newPath = FileUtil.getNonCollidingPath(file.getParentFile(), file, outExtension);
|
String newPath = FileUtil.getNonCollidingPath(file.getParentFile(), file, outExtension);
|
||||||
OutputUtil.println();
|
OutputUtil.println();
|
||||||
OutputUtil.println("Preparing to start process...");
|
OutputUtil.println("Preparing to start process...");
|
||||||
OutputUtil.println("Converting " + file);
|
OutputUtil.println("Converting " + file);
|
||||||
|
|
||||||
FFMpegCommand ffMpegCommand = generateConversionCommand(ffmpegPath, probeResult, newPath);
|
FFMpegCommand ffMpegCommand = generateConversionCommand(this.ffmpegPath, probeResult, newPath);
|
||||||
// If the command is null, that means the file does not need conversion
|
// If the command is null, that means the file does not need conversion
|
||||||
if (ffMpegCommand == null) {
|
if (ffMpegCommand == null) {
|
||||||
return;
|
return;
|
||||||
@ -73,11 +75,7 @@ public abstract class AbstractConverter implements Converter {
|
|||||||
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
||||||
int exitCode = FFMpegHelper.runProcess(processBuilder, file.getParentFile(), "\n", true).exitCode();
|
int exitCode = FFMpegHelper.runProcess(processBuilder, file.getParentFile(), "\n", true).exitCode();
|
||||||
if (exitCode != 0) {
|
if (exitCode != 0) {
|
||||||
try {
|
handleError(ffMpegCommand, file, newPath);
|
||||||
handleError(ffMpegCommand, file, newPath);
|
|
||||||
} catch (ConfigurationException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,11 +85,10 @@ public abstract class AbstractConverter implements Converter {
|
|||||||
* @param ffMpegCommand <p>The failed ffmpeg command</p>
|
* @param ffMpegCommand <p>The failed ffmpeg command</p>
|
||||||
* @param file <p>The file that was to be converted</p>
|
* @param file <p>The file that was to be converted</p>
|
||||||
* @param newPath <p>The path of the output file</p>
|
* @param newPath <p>The path of the output file</p>
|
||||||
* @throws IOException <p>If unable to produce output</p>
|
* @throws IOException <p>If unable to produce output</p>
|
||||||
* @throws ConfigurationException <p>If unable </p>
|
|
||||||
*/
|
*/
|
||||||
private void handleError(@NotNull FFMpegCommand ffMpegCommand, @NotNull File file,
|
private void handleError(@NotNull FFMpegCommand ffMpegCommand, @NotNull File file,
|
||||||
@NotNull String newPath) throws IOException, ConfigurationException {
|
@NotNull String newPath) throws IOException {
|
||||||
File outputFile = new File(newPath);
|
File outputFile = new File(newPath);
|
||||||
if (outputFile.exists() && !outputFile.delete()) {
|
if (outputFile.exists() && !outputFile.delete()) {
|
||||||
OutputUtil.println("Failed to remove failed output file. Please remove it manually");
|
OutputUtil.println("Failed to remove failed output file. Please remove it manually");
|
||||||
@ -118,23 +115,24 @@ public abstract class AbstractConverter implements Converter {
|
|||||||
*
|
*
|
||||||
* @return <p>Available hardware encoding methods</p>
|
* @return <p>Available hardware encoding methods</p>
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
protected List<String> getAvailableHardwareEncodingMethods() {
|
protected List<String> getAvailableHardwareEncodingMethods() {
|
||||||
try {
|
if (encoderHandler == null) {
|
||||||
if (encoderHandler == null) {
|
encoderHandler = AvailableHardwareEncoderHandler.load();
|
||||||
encoderHandler = AvailableHardwareEncoderHandler.load();
|
if (encoderHandler.availableHardwareEncodings().isEmpty()) {
|
||||||
if (encoderHandler.availableHardwareEncodings().isEmpty()) {
|
List<String> hardwareEncoding;
|
||||||
List<String> hardwareEncoding = new ArrayList<>(FFMpegHelper.getHWAcceleration(ffmpegPath));
|
try {
|
||||||
hardwareEncoding.remove(0);
|
hardwareEncoding = new ArrayList<>(FFMpegHelper.getHWAcceleration(ffmpegPath));
|
||||||
encoderHandler = new AvailableHardwareEncoderHandler(hardwareEncoding);
|
} catch (IOException e) {
|
||||||
encoderHandler.save();
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
hardwareEncoding.remove(0);
|
||||||
|
encoderHandler = new AvailableHardwareEncoderHandler(hardwareEncoding);
|
||||||
|
encoderHandler.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
return encoderHandler.availableHardwareEncodings();
|
|
||||||
} catch (ConfigurationException | IOException exception) {
|
|
||||||
OutputUtil.println("Unable to get available hardware encoders: " + exception.getMessage());
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return encoderHandler.availableHardwareEncodings();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import net.knarcraft.ffmpegconverter.streams.AudioStream;
|
|||||||
import net.knarcraft.ffmpegconverter.streams.SubtitleStream;
|
import net.knarcraft.ffmpegconverter.streams.SubtitleStream;
|
||||||
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -69,6 +70,7 @@ public class AnimeConverter extends AbstractConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public FFMpegCommand generateConversionCommand(@NotNull String executable,
|
public FFMpegCommand generateConversionCommand(@NotNull String executable,
|
||||||
@NotNull StreamProbeResult probeResult,
|
@NotNull StreamProbeResult probeResult,
|
||||||
@NotNull String outFile) {
|
@NotNull String outFile) {
|
||||||
@ -118,7 +120,8 @@ public class AnimeConverter extends AbstractConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull String[] getValidFormats() {
|
@NotNull
|
||||||
|
public List<String> getValidFormats() {
|
||||||
return this.videoFormats;
|
return this.videoFormats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import net.knarcraft.ffmpegconverter.converter.module.mapping.NthAudioStreamModu
|
|||||||
import net.knarcraft.ffmpegconverter.converter.module.output.SetOutputFileModule;
|
import net.knarcraft.ffmpegconverter.converter.module.output.SetOutputFileModule;
|
||||||
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -25,13 +26,14 @@ public class AudioConverter extends AbstractConverter {
|
|||||||
* @param ffmpegPath <p>Path/command to ffmpeg.</p>
|
* @param ffmpegPath <p>Path/command to ffmpeg.</p>
|
||||||
* @param newExtension <p>The extension of the new file.</p>
|
* @param newExtension <p>The extension of the new file.</p>
|
||||||
*/
|
*/
|
||||||
public AudioConverter(String ffprobePath, String ffmpegPath, String newExtension) {
|
public AudioConverter(@NotNull String ffprobePath, @NotNull String ffmpegPath, @NotNull String newExtension) {
|
||||||
super(newExtension);
|
super(newExtension);
|
||||||
this.ffprobePath = ffprobePath;
|
this.ffprobePath = ffprobePath;
|
||||||
this.ffmpegPath = ffmpegPath;
|
this.ffmpegPath = ffmpegPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
||||||
@NotNull String outFile) {
|
@NotNull String outFile) {
|
||||||
FFMpegCommand command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, probeResult.parsedFiles());
|
FFMpegCommand command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, probeResult.parsedFiles());
|
||||||
@ -50,7 +52,8 @@ public class AudioConverter extends AbstractConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getValidFormats() {
|
@NotNull
|
||||||
|
public List<String> getValidFormats() {
|
||||||
return audioFormats;
|
return audioFormats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,9 +3,11 @@ package net.knarcraft.ffmpegconverter.converter;
|
|||||||
import net.knarcraft.ffmpegconverter.container.FFMpegCommand;
|
import net.knarcraft.ffmpegconverter.container.FFMpegCommand;
|
||||||
import net.knarcraft.ffmpegconverter.container.StreamProbeResult;
|
import net.knarcraft.ffmpegconverter.container.StreamProbeResult;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface describes a file converter
|
* This interface describes a file converter
|
||||||
@ -18,7 +20,7 @@ public interface Converter {
|
|||||||
* @return <p>A list of valid input formats</p>
|
* @return <p>A list of valid input formats</p>
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
String[] getValidFormats();
|
List<String> getValidFormats();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the given file
|
* Converts the given file
|
||||||
@ -36,6 +38,7 @@ public interface Converter {
|
|||||||
* @param outFile <p>The output file</p>
|
* @param outFile <p>The output file</p>
|
||||||
* @return <p>A list of commands</p>
|
* @return <p>A list of commands</p>
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
||||||
@NotNull String outFile);
|
@NotNull String outFile);
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ import net.knarcraft.ffmpegconverter.streams.StreamObject;
|
|||||||
import net.knarcraft.ffmpegconverter.streams.VideoStream;
|
import net.knarcraft.ffmpegconverter.streams.VideoStream;
|
||||||
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -36,7 +37,7 @@ public class DownScaleConverter extends AbstractConverter {
|
|||||||
* @param newWidth <p>The new width of the video</p>
|
* @param newWidth <p>The new width of the video</p>
|
||||||
* @param newHeight <p>The new height of the video</p>
|
* @param newHeight <p>The new height of the video</p>
|
||||||
*/
|
*/
|
||||||
public DownScaleConverter(String ffprobePath, String ffmpegPath, int newWidth, int newHeight) {
|
public DownScaleConverter(@NotNull String ffprobePath, @NotNull String ffmpegPath, int newWidth, int newHeight) {
|
||||||
super(null);
|
super(null);
|
||||||
this.ffprobePath = ffprobePath;
|
this.ffprobePath = ffprobePath;
|
||||||
this.ffmpegPath = ffmpegPath;
|
this.ffmpegPath = ffmpegPath;
|
||||||
@ -45,6 +46,7 @@ public class DownScaleConverter extends AbstractConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
||||||
@NotNull String outFile) {
|
@NotNull String outFile) {
|
||||||
List<StreamObject> streams = probeResult.parsedStreams();
|
List<StreamObject> streams = probeResult.parsedStreams();
|
||||||
@ -78,7 +80,8 @@ public class DownScaleConverter extends AbstractConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getValidFormats() {
|
@NotNull
|
||||||
|
public List<String> getValidFormats() {
|
||||||
return videoFormats;
|
return videoFormats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import net.knarcraft.ffmpegconverter.converter.module.output.CopyAllModule;
|
|||||||
import net.knarcraft.ffmpegconverter.converter.module.output.SetOutputFileModule;
|
import net.knarcraft.ffmpegconverter.converter.module.output.SetOutputFileModule;
|
||||||
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -46,11 +47,13 @@ public class MKVToMP4Transcoder extends AbstractConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getValidFormats() {
|
@NotNull
|
||||||
return new String[]{"mkv"};
|
public List<String> getValidFormats() {
|
||||||
|
return List.of("mkv");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
||||||
@NotNull String outFile) {
|
@NotNull String outFile) {
|
||||||
FFMpegCommand command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, probeResult.parsedFiles());
|
FFMpegCommand command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, probeResult.parsedFiles());
|
||||||
|
@ -15,6 +15,7 @@ import net.knarcraft.ffmpegconverter.converter.module.output.SetOutputFileModule
|
|||||||
import net.knarcraft.ffmpegconverter.streams.StreamObject;
|
import net.knarcraft.ffmpegconverter.streams.StreamObject;
|
||||||
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -37,11 +38,13 @@ public class MkvH264Converter extends AbstractConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getValidFormats() {
|
@NotNull
|
||||||
return new String[]{"mkv"};
|
public List<String> getValidFormats() {
|
||||||
|
return List.of("mkv");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
||||||
@NotNull String outFile) {
|
@NotNull String outFile) {
|
||||||
FFMpegCommand command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, probeResult.parsedFiles());
|
FFMpegCommand command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, probeResult.parsedFiles());
|
||||||
|
@ -16,6 +16,7 @@ import net.knarcraft.ffmpegconverter.streams.SubtitleStream;
|
|||||||
import net.knarcraft.ffmpegconverter.streams.VideoStream;
|
import net.knarcraft.ffmpegconverter.streams.VideoStream;
|
||||||
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -38,11 +39,13 @@ public class MkvH265ReducedConverter extends AbstractConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getValidFormats() {
|
@NotNull
|
||||||
return new String[]{"mkv"};
|
public List<String> getValidFormats() {
|
||||||
|
return List.of("mkv");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
||||||
@NotNull String outFile) {
|
@NotNull String outFile) {
|
||||||
FFMpegCommand command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, probeResult.parsedFiles());
|
FFMpegCommand command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, probeResult.parsedFiles());
|
||||||
|
@ -12,6 +12,7 @@ import net.knarcraft.ffmpegconverter.converter.module.output.MovTextModule;
|
|||||||
import net.knarcraft.ffmpegconverter.converter.module.output.SetOutputFileModule;
|
import net.knarcraft.ffmpegconverter.converter.module.output.SetOutputFileModule;
|
||||||
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -34,11 +35,13 @@ public class SubtitleEmbed extends AbstractConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getValidFormats() {
|
@NotNull
|
||||||
return new String[]{"mp4"};
|
public List<String> getValidFormats() {
|
||||||
|
return List.of("mp4");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
||||||
@NotNull String outFile) {
|
@NotNull String outFile) {
|
||||||
FFMpegCommand command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, probeResult.parsedFiles());
|
FFMpegCommand command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, probeResult.parsedFiles());
|
||||||
|
@ -12,6 +12,7 @@ import net.knarcraft.ffmpegconverter.converter.module.output.SetOutputFileModule
|
|||||||
import net.knarcraft.ffmpegconverter.streams.StreamObject;
|
import net.knarcraft.ffmpegconverter.streams.StreamObject;
|
||||||
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -35,6 +36,7 @@ public class VideoConverter extends AbstractConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
||||||
@NotNull String outFile) {
|
@NotNull String outFile) {
|
||||||
FFMpegCommand command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, probeResult.parsedFiles());
|
FFMpegCommand command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, probeResult.parsedFiles());
|
||||||
@ -57,7 +59,8 @@ public class VideoConverter extends AbstractConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getValidFormats() {
|
@NotNull
|
||||||
|
public List<String> getValidFormats() {
|
||||||
return videoFormats;
|
return videoFormats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import net.knarcraft.ffmpegconverter.streams.SubtitleStream;
|
|||||||
import net.knarcraft.ffmpegconverter.streams.VideoStream;
|
import net.knarcraft.ffmpegconverter.streams.VideoStream;
|
||||||
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -69,6 +70,7 @@ public class WebAnimeConverter extends AbstractConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
||||||
@NotNull String outFile) {
|
@NotNull String outFile) {
|
||||||
FFMpegCommand command = FFMpegHelper.getFFMpegWebVideoCommand(executable, probeResult.parsedFiles());
|
FFMpegCommand command = FFMpegHelper.getFFMpegWebVideoCommand(executable, probeResult.parsedFiles());
|
||||||
@ -114,7 +116,8 @@ public class WebAnimeConverter extends AbstractConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getValidFormats() {
|
@NotNull
|
||||||
|
public List<String> getValidFormats() {
|
||||||
return this.videoFormats;
|
return this.videoFormats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ import net.knarcraft.ffmpegconverter.streams.SubtitleStream;
|
|||||||
import net.knarcraft.ffmpegconverter.streams.VideoStream;
|
import net.knarcraft.ffmpegconverter.streams.VideoStream;
|
||||||
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -39,11 +40,13 @@ public class WebVideoConverter extends AbstractConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getValidFormats() {
|
@NotNull
|
||||||
|
public List<String> getValidFormats() {
|
||||||
return videoFormats;
|
return videoFormats;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
public FFMpegCommand generateConversionCommand(@NotNull String executable, @NotNull StreamProbeResult probeResult,
|
||||||
@NotNull String outFile) {
|
@NotNull String outFile) {
|
||||||
FFMpegCommand command = FFMpegHelper.getFFMpegWebVideoCommand(executable, probeResult.parsedFiles());
|
FFMpegCommand command = FFMpegHelper.getFFMpegWebVideoCommand(executable, probeResult.parsedFiles());
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
package net.knarcraft.ffmpegconverter.handler;
|
package net.knarcraft.ffmpegconverter.handler;
|
||||||
|
|
||||||
|
import net.knarcraft.ffmpegconverter.FFMpegConvert;
|
||||||
|
import net.knarcraft.ffmpegconverter.config.ConfigHandler;
|
||||||
import net.knarcraft.ffmpegconverter.utility.OutputUtil;
|
import net.knarcraft.ffmpegconverter.utility.OutputUtil;
|
||||||
import org.apache.commons.configuration2.Configuration;
|
import org.apache.commons.configuration2.Configuration;
|
||||||
import org.apache.commons.configuration2.PropertiesConfiguration;
|
import org.apache.commons.configuration2.PropertiesConfiguration;
|
||||||
import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
|
|
||||||
import org.apache.commons.configuration2.builder.fluent.Configurations;
|
|
||||||
import org.apache.commons.configuration2.ex.ConfigurationException;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -18,8 +16,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public record AvailableHardwareEncoderHandler(@NotNull List<String> availableHardwareEncodings) {
|
public record AvailableHardwareEncoderHandler(@NotNull List<String> availableHardwareEncodings) {
|
||||||
|
|
||||||
private static final File configFolder = new File("conf").getAbsoluteFile();
|
private static final ConfigHandler configHandler = FFMpegConvert.getConfigHandler();
|
||||||
private static final Configurations configurations = new Configurations();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all hardware encodings
|
* Gets all hardware encodings
|
||||||
@ -42,30 +39,12 @@ public record AvailableHardwareEncoderHandler(@NotNull List<String> availableHar
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves settings fro this available hardware encoder handler
|
* Saves settings for this available hardware encoder handler
|
||||||
*
|
|
||||||
* @throws ConfigurationException <p>If the configuration file cannot be saved</p>
|
|
||||||
*/
|
*/
|
||||||
public void save() throws ConfigurationException {
|
public void save() {
|
||||||
OutputUtil.printDebug("Preparing to save config");
|
PropertiesConfiguration configuration = configHandler.getWritableConfiguration();
|
||||||
if (!configFolder.exists() && !configFolder.mkdir()) {
|
configuration.setProperty("encoder.hardware", this.availableHardwareEncodings);
|
||||||
throw new RuntimeException("Unable to create config folder. Make sure to run this .jar file from a " +
|
configHandler.writeConfiguration();
|
||||||
"writable directory!");
|
|
||||||
}
|
|
||||||
File settingsFile = new File(configFolder, "config.properties");
|
|
||||||
try {
|
|
||||||
if (!settingsFile.exists() && !settingsFile.createNewFile()) {
|
|
||||||
OutputUtil.println("Failed to create configuration file.");
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
OutputUtil.println("Failed to create configuration file.");
|
|
||||||
}
|
|
||||||
|
|
||||||
FileBasedConfigurationBuilder<PropertiesConfiguration> builder =
|
|
||||||
configurations.propertiesBuilder(settingsFile);
|
|
||||||
PropertiesConfiguration config = builder.getConfiguration();
|
|
||||||
config.setProperty("encoder.hardware", this.availableHardwareEncodings);
|
|
||||||
builder.save();
|
|
||||||
OutputUtil.printDebug("Saved available hardware encoder handler");
|
OutputUtil.printDebug("Saved available hardware encoder handler");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,14 +52,15 @@ public record AvailableHardwareEncoderHandler(@NotNull List<String> availableHar
|
|||||||
* Loads saved settings for an available hardware encoder handler
|
* Loads saved settings for an available hardware encoder handler
|
||||||
*
|
*
|
||||||
* @return <p>The loaded available hardware encoder handler, or a new one if no data has been saved</p>
|
* @return <p>The loaded available hardware encoder handler, or a new one if no data has been saved</p>
|
||||||
* @throws ConfigurationException <p>If the configuration file cannot be loaded</p>
|
|
||||||
*/
|
*/
|
||||||
public static AvailableHardwareEncoderHandler load() throws ConfigurationException {
|
@NotNull
|
||||||
File settingsFile = new File(configFolder, "config.properties");
|
public static AvailableHardwareEncoderHandler load() {
|
||||||
if (!settingsFile.exists()) {
|
Configuration configuration;
|
||||||
return new AvailableHardwareEncoderHandler(new ArrayList<>());
|
try {
|
||||||
|
configuration = configHandler.load();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
Configuration configuration = configurations.properties(settingsFile);
|
|
||||||
List<String> getEncodings = configuration.getList(String.class, "encoder.hardware");
|
List<String> getEncodings = configuration.getList(String.class, "encoder.hardware");
|
||||||
return new AvailableHardwareEncoderHandler(getEncodings);
|
return new AvailableHardwareEncoderHandler(getEncodings);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.knarcraft.ffmpegconverter.parser;
|
package net.knarcraft.ffmpegconverter.parser;
|
||||||
|
|
||||||
import net.knarcraft.ffmpegconverter.utility.ListUtil;
|
import net.knarcraft.ffmpegconverter.utility.ListUtil;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class representing a command argument
|
* A class representing a command argument
|
||||||
@ -20,7 +21,8 @@ public class ConverterArgument {
|
|||||||
* @param valueRequired <p>Whether the argument must be followed by a valid value.</p>
|
* @param valueRequired <p>Whether the argument must be followed by a valid value.</p>
|
||||||
* @param valueType <p>The type of value the argument requires.</p>
|
* @param valueType <p>The type of value the argument requires.</p>
|
||||||
*/
|
*/
|
||||||
public ConverterArgument(String name, char shorthand, boolean valueRequired, ConverterArgumentValueType valueType) {
|
public ConverterArgument(@NotNull String name, char shorthand, boolean valueRequired,
|
||||||
|
@NotNull ConverterArgumentValueType valueType) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.shorthand = shorthand;
|
this.shorthand = shorthand;
|
||||||
this.valueRequired = valueRequired;
|
this.valueRequired = valueRequired;
|
||||||
@ -60,7 +62,7 @@ public class ConverterArgument {
|
|||||||
* @param value <p>The value to test.</p>
|
* @param value <p>The value to test.</p>
|
||||||
* @return <p>True if the argument is valid. False otherwise.</p>
|
* @return <p>True if the argument is valid. False otherwise.</p>
|
||||||
*/
|
*/
|
||||||
public boolean testArgumentValue(String value) {
|
public boolean testArgumentValue(@NotNull String value) {
|
||||||
if (value.isEmpty()) {
|
if (value.isEmpty()) {
|
||||||
return !valueRequired;
|
return !valueRequired;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,8 @@ public abstract class AbstractStream implements StreamObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull String getCodecName() {
|
@NotNull
|
||||||
|
public String getCodecName() {
|
||||||
return this.codecName;
|
return this.codecName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +52,8 @@ public abstract class AbstractStream implements StreamObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull String getLanguage() {
|
@NotNull
|
||||||
|
public String getLanguage() {
|
||||||
return this.language;
|
return this.language;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@ import java.util.Map;
|
|||||||
public final class FFMpegHelper {
|
public final class FFMpegHelper {
|
||||||
|
|
||||||
private static final String PROBE_SPLIT_CHARACTER = "øæåÆØå";
|
private static final String PROBE_SPLIT_CHARACTER = "øæåÆØå";
|
||||||
private static String[] subtitleFormats = null;
|
|
||||||
|
|
||||||
private FFMpegHelper() {
|
private FFMpegHelper() {
|
||||||
|
|
||||||
@ -70,14 +69,16 @@ public final class FFMpegHelper {
|
|||||||
/**
|
/**
|
||||||
* Gets streams from a file
|
* Gets streams from a file
|
||||||
*
|
*
|
||||||
* @param ffprobePath <p>The path/command to ffprobe.</p>
|
* @param ffprobePath <p>The path/command to ffprobe</p>
|
||||||
* @param file <p>The file to probe.</p>
|
* @param file <p>The file to probe</p>
|
||||||
* @return <p>A list of StreamObjects.</p>
|
* @param subtitleFormats <p>The extensions to accept for external subtitles</p>
|
||||||
* @throws IOException <p>If the process can't be readProcess.</p>
|
* @return <p>A list of StreamObjects</p>
|
||||||
|
* @throws IOException <p>If the process can't be readProcess</p>
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public static StreamProbeResult probeFile(@NotNull String ffprobePath, @NotNull File file) throws IOException {
|
public static StreamProbeResult probeFile(@NotNull String ffprobePath, @NotNull File file,
|
||||||
return parseStreams(ffprobePath, probeForStreams(ffprobePath, file), file);
|
@NotNull List<String> subtitleFormats) throws IOException {
|
||||||
|
return parseStreams(ffprobePath, probeForStreams(ffprobePath, file), file, subtitleFormats);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -223,7 +224,8 @@ public final class FFMpegHelper {
|
|||||||
* @param fileName <p>The filename to escape.</p>
|
* @param fileName <p>The filename to escape.</p>
|
||||||
* @return <p>A filename with known special characters escaped.</p>
|
* @return <p>A filename with known special characters escaped.</p>
|
||||||
*/
|
*/
|
||||||
public static String escapeSpecialCharactersInFileName(String fileName) {
|
@NotNull
|
||||||
|
public static String escapeSpecialCharactersInFileName(@NotNull String fileName) {
|
||||||
return fileName.replaceAll("\\\\", "\\\\\\\\\\\\\\\\")
|
return fileName.replaceAll("\\\\", "\\\\\\\\\\\\\\\\")
|
||||||
.replaceAll("'", "'\\\\\\\\\\\\\''")
|
.replaceAll("'", "'\\\\\\\\\\\\\''")
|
||||||
.replaceAll("%", "\\\\\\\\\\\\%")
|
.replaceAll("%", "\\\\\\\\\\\\%")
|
||||||
@ -260,7 +262,8 @@ public final class FFMpegHelper {
|
|||||||
* @return <p>A list of streams.</p>
|
* @return <p>A list of streams.</p>
|
||||||
* @throws IOException <p>If something goes wrong while probing.</p>
|
* @throws IOException <p>If something goes wrong while probing.</p>
|
||||||
*/
|
*/
|
||||||
private static List<String> probeForStreams(String ffprobePath, File file) throws IOException {
|
@NotNull
|
||||||
|
private static List<String> probeForStreams(@NotNull String ffprobePath, @NotNull File file) throws IOException {
|
||||||
FFMpegCommand probeCommand = new FFMpegCommand(ffprobePath);
|
FFMpegCommand probeCommand = new FFMpegCommand(ffprobePath);
|
||||||
probeCommand.addGlobalOption("-v", "error", "-show_streams");
|
probeCommand.addGlobalOption("-v", "error", "-show_streams");
|
||||||
probeCommand.addInputFile(file.toString());
|
probeCommand.addInputFile(file.toString());
|
||||||
@ -276,13 +279,15 @@ public final class FFMpegHelper {
|
|||||||
/**
|
/**
|
||||||
* Takes a list of all streams and parses each stream into one of three objects
|
* Takes a list of all streams and parses each stream into one of three objects
|
||||||
*
|
*
|
||||||
* @param streams <p>A list of all streams for the current file.</p>
|
* @param ffprobePath <p>The path to the ffprobe executable</p>
|
||||||
* @param file <p>The file currently being converted.</p>
|
* @param streams <p>A list of all streams for the current file.</p>
|
||||||
|
* @param file <p>The file currently being converted.</p>
|
||||||
|
* @param subtitleFormats <p>The extensions to accept for external subtitles</p>
|
||||||
* @return <p>A list of StreamObjects.</p>
|
* @return <p>A list of StreamObjects.</p>
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
private static StreamProbeResult parseStreams(@NotNull String ffprobePath, @NotNull List<String> streams,
|
private static StreamProbeResult parseStreams(@NotNull String ffprobePath, @NotNull List<String> streams,
|
||||||
@NotNull File file) throws IOException {
|
@NotNull File file, @NotNull List<String> subtitleFormats) throws IOException {
|
||||||
List<StreamObject> parsedStreams = new ArrayList<>();
|
List<StreamObject> parsedStreams = new ArrayList<>();
|
||||||
int relativeAudioIndex = 0;
|
int relativeAudioIndex = 0;
|
||||||
int relativeVideoIndex = 0;
|
int relativeVideoIndex = 0;
|
||||||
@ -306,7 +311,7 @@ public final class FFMpegHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
StreamProbeResult probeResult = new StreamProbeResult(List.of(file), parsedStreams);
|
StreamProbeResult probeResult = new StreamProbeResult(List.of(file), parsedStreams);
|
||||||
getExternalSubtitles(probeResult, ffprobePath, file.getParentFile(), file.getName());
|
getExternalSubtitles(probeResult, ffprobePath, file.getParentFile(), file.getName(), subtitleFormats);
|
||||||
return probeResult;
|
return probeResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,17 +340,16 @@ public final class FFMpegHelper {
|
|||||||
/**
|
/**
|
||||||
* Tries to find any external subtitles adjacent to the first input file, and appends it to the given probe result
|
* Tries to find any external subtitles adjacent to the first input file, and appends it to the given probe result
|
||||||
*
|
*
|
||||||
* @param ffprobePath <p>The path/command to ffprobe</p>
|
* @param streamProbeResult <p>The stream probe result to append to</p>
|
||||||
* @param directory <p>The directory containing the file</p>
|
* @param ffprobePath <p>The path/command to ffprobe</p>
|
||||||
* @param convertingFile <p>The first/main file to be converted</p>
|
* @param directory <p>The directory containing the file</p>
|
||||||
|
* @param convertingFile <p>The first/main file to be converted</p>
|
||||||
|
* @param subtitleFormats <p>The extensions to accept for external subtitles</p>
|
||||||
*/
|
*/
|
||||||
private static void getExternalSubtitles(@NotNull StreamProbeResult streamProbeResult,
|
private static void getExternalSubtitles(@NotNull StreamProbeResult streamProbeResult,
|
||||||
@NotNull String ffprobePath, @NotNull File directory,
|
@NotNull String ffprobePath, @NotNull File directory,
|
||||||
@NotNull String convertingFile) throws IOException {
|
@NotNull String convertingFile, @NotNull List<String> subtitleFormats) throws IOException {
|
||||||
//Find all files in the same directory with external subtitle formats
|
//Find all files in the same directory with external subtitle formats
|
||||||
if (subtitleFormats == null) {
|
|
||||||
subtitleFormats = FileUtil.readFileLines("subtitle_formats.txt");
|
|
||||||
}
|
|
||||||
File[] subtitleFiles = FileUtil.listFilesRecursive(directory, subtitleFormats, 1);
|
File[] subtitleFiles = FileUtil.listFilesRecursive(directory, subtitleFormats, 1);
|
||||||
// TODO: Generalize this for external audio tracks
|
// TODO: Generalize this for external audio tracks
|
||||||
|
|
||||||
@ -382,7 +386,8 @@ public final class FFMpegHelper {
|
|||||||
* @return <p>The output from the readProcess.</p>
|
* @return <p>The output from the readProcess.</p>
|
||||||
* @throws IOException <p>On reader failure.</p>
|
* @throws IOException <p>On reader failure.</p>
|
||||||
*/
|
*/
|
||||||
private static String readProcess(BufferedReader reader, String spacer) throws IOException {
|
@NotNull
|
||||||
|
private static String readProcess(@NotNull BufferedReader reader, @NotNull String spacer) throws IOException {
|
||||||
String line;
|
String line;
|
||||||
StringBuilder text = new StringBuilder();
|
StringBuilder text = new StringBuilder();
|
||||||
while (reader.ready() && (line = reader.readLine()) != null && !line.isEmpty() && !line.equals("\n")) {
|
while (reader.ready() && (line = reader.readLine()) != null && !line.isEmpty() && !line.equals("\n")) {
|
||||||
@ -398,6 +403,7 @@ public final class FFMpegHelper {
|
|||||||
* @return <p>The available hardware acceleration methods</p>
|
* @return <p>The available hardware acceleration methods</p>
|
||||||
* @throws IOException <p>If the process fails</p>
|
* @throws IOException <p>If the process fails</p>
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
public static List<String> getHWAcceleration(@NotNull String ffmpegPath) throws IOException {
|
public static List<String> getHWAcceleration(@NotNull String ffmpegPath) throws IOException {
|
||||||
FFMpegCommand probeCommand = new FFMpegCommand(ffmpegPath);
|
FFMpegCommand probeCommand = new FFMpegCommand(ffmpegPath);
|
||||||
probeCommand.addGlobalOption("-v", "error", "-hwaccels");
|
probeCommand.addGlobalOption("-v", "error", "-hwaccels");
|
||||||
|
@ -0,0 +1,178 @@
|
|||||||
|
package net.knarcraft.ffmpegconverter.utility;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper class for dealing with files
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public final class FileHelper {
|
||||||
|
|
||||||
|
private FileHelper() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a buffered reader for an internal file
|
||||||
|
*
|
||||||
|
* @param file <p>The name of the file to get a buffered reader for (start with a '/'). The file should reside in
|
||||||
|
* the resources directory.</p>
|
||||||
|
* @return <p>A buffered read for reading the file</p>
|
||||||
|
* @throws FileNotFoundException <p>If unable to get an input stream for the given file</p>
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static BufferedReader getBufferedReaderForInternalFile(@NotNull String file) throws FileNotFoundException {
|
||||||
|
InputStream inputStream = getInputStreamForInternalFile(file);
|
||||||
|
if (inputStream == null) {
|
||||||
|
throw new FileNotFoundException("Unable to read the given file");
|
||||||
|
}
|
||||||
|
return getBufferedReaderFromInputStream(inputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an input stream from a string pointing to an internal file
|
||||||
|
*
|
||||||
|
* <p>This is used for getting an input stream for reading a file contained within the compiled .jar file. The file
|
||||||
|
* should be in the resources directory, and the file path should start with a forward slash ("/") character.</p>
|
||||||
|
*
|
||||||
|
* @param file <p>The file to read</p>
|
||||||
|
* @return <p>An input stream for the file</p>
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static InputStream getInputStreamForInternalFile(@NotNull String file) {
|
||||||
|
return FileHelper.class.getResourceAsStream(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a buffered reader from a string pointing to a file
|
||||||
|
*
|
||||||
|
* @param file <p>The file to read</p>
|
||||||
|
* @return <p>A buffered reader reading the file</p>
|
||||||
|
* @throws FileNotFoundException <p>If the given file does not exist</p>
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
|
||||||
|
public static BufferedReader getBufferedReaderFromString(@NotNull String file) throws FileNotFoundException {
|
||||||
|
FileInputStream fileInputStream = new FileInputStream(file);
|
||||||
|
return getBufferedReaderFromInputStream(fileInputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a buffered reader given an input stream
|
||||||
|
*
|
||||||
|
* @param inputStream <p>The input stream to read</p>
|
||||||
|
* @return <p>A buffered reader reading the input stream</p>
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static BufferedReader getBufferedReaderFromInputStream(@NotNull InputStream inputStream) {
|
||||||
|
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
|
||||||
|
return new BufferedReader(inputStreamReader);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a buffered writer from a string pointing to a file
|
||||||
|
*
|
||||||
|
* @param file <p>The file to write to</p>
|
||||||
|
* @return <p>A buffered writer writing to the file</p>
|
||||||
|
* @throws FileNotFoundException <p>If the file does not exist</p>
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static BufferedWriter getBufferedWriterFromString(@NotNull String file) throws FileNotFoundException {
|
||||||
|
FileOutputStream fileOutputStream = new FileOutputStream(file);
|
||||||
|
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8);
|
||||||
|
return new BufferedWriter(outputStreamWriter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads key/value pairs from a buffered reader
|
||||||
|
*
|
||||||
|
* @param bufferedReader <p>The buffered reader to read</p>
|
||||||
|
* @param separator <p>The separator separating a key from a value</p>
|
||||||
|
* @return <p>A map containing the read pairs</p>
|
||||||
|
* @throws IOException <p>If unable to read from the stream</p>
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static Map<String, String> readKeyValuePairs(@NotNull BufferedReader bufferedReader,
|
||||||
|
@NotNull String separator) throws IOException {
|
||||||
|
Map<String, String> readPairs = new HashMap<>();
|
||||||
|
List<String> lines = readLines(bufferedReader);
|
||||||
|
|
||||||
|
for (String line : lines) {
|
||||||
|
int separatorIndex = line.indexOf(separator);
|
||||||
|
if (separatorIndex == -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Read the line
|
||||||
|
String key = line.substring(0, separatorIndex);
|
||||||
|
String value = line.substring(separatorIndex + 1);
|
||||||
|
readPairs.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return readPairs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a list from a buffered reader
|
||||||
|
*
|
||||||
|
* @param bufferedReader <p>The buffered reader to read</p>
|
||||||
|
* @return <p>A list of the read strings</p>
|
||||||
|
* @throws IOException <p>If unable to read from the stream</p>
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static List<String> readLines(@NotNull BufferedReader bufferedReader) throws IOException {
|
||||||
|
List<String> readLines = new ArrayList<>();
|
||||||
|
|
||||||
|
String line = bufferedReader.readLine();
|
||||||
|
boolean firstLine = true;
|
||||||
|
while (line != null) {
|
||||||
|
//Strip UTF BOM from the first line
|
||||||
|
if (firstLine) {
|
||||||
|
line = removeUTF8BOM(line);
|
||||||
|
firstLine = false;
|
||||||
|
}
|
||||||
|
//Split at first separator
|
||||||
|
if (line.isEmpty()) {
|
||||||
|
line = bufferedReader.readLine();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
readLines.add(line);
|
||||||
|
line = bufferedReader.readLine();
|
||||||
|
}
|
||||||
|
bufferedReader.close();
|
||||||
|
|
||||||
|
return readLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the UTF-8 Byte Order Mark if present
|
||||||
|
*
|
||||||
|
* @param string <p>The string to remove the BOM from</p>
|
||||||
|
* @return <p>A string guaranteed without a BOM</p>
|
||||||
|
*/
|
||||||
|
private static @NotNull String removeUTF8BOM(@NotNull String string) {
|
||||||
|
String UTF8_BOM = "\uFEFF";
|
||||||
|
if (string.startsWith(UTF8_BOM)) {
|
||||||
|
string = string.substring(1);
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,10 +1,10 @@
|
|||||||
package net.knarcraft.ffmpegconverter.utility;
|
package net.knarcraft.ffmpegconverter.utility;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.util.List;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class which helps with file handling
|
* A class which helps with file handling
|
||||||
@ -23,7 +23,8 @@ public final class FileUtil {
|
|||||||
* @param outExtension <p>The extension of the output file.</p>
|
* @param outExtension <p>The extension of the output file.</p>
|
||||||
* @return <p>A file name with the new extension and without any collisions.</p>
|
* @return <p>A file name with the new extension and without any collisions.</p>
|
||||||
*/
|
*/
|
||||||
public static String getNonCollidingPath(File folder, File file, String outExtension) {
|
@NotNull
|
||||||
|
public static String getNonCollidingPath(@NotNull File folder, @NotNull File file, @NotNull String outExtension) {
|
||||||
return FileUtil.getNonCollidingFilename(folder.getAbsolutePath() + File.separator +
|
return FileUtil.getNonCollidingFilename(folder.getAbsolutePath() + File.separator +
|
||||||
FileUtil.stripExtension(file.getName()) + "." + outExtension, outExtension);
|
FileUtil.stripExtension(file.getName()) + "." + outExtension, outExtension);
|
||||||
}
|
}
|
||||||
@ -35,7 +36,8 @@ public final class FileUtil {
|
|||||||
* @param maxRecursions <p>Maximum number of recursions</p>
|
* @param maxRecursions <p>Maximum number of recursions</p>
|
||||||
* @return A list of files
|
* @return A list of files
|
||||||
*/
|
*/
|
||||||
public static File[] listFilesRecursive(File folder, String[] extensions, int maxRecursions) {
|
@Nullable
|
||||||
|
public static File[] listFilesRecursive(@NotNull File folder, @NotNull List<String> extensions, int maxRecursions) {
|
||||||
//Return if the target depth has been reached
|
//Return if the target depth has been reached
|
||||||
if (maxRecursions == 0) {
|
if (maxRecursions == 0) {
|
||||||
return null;
|
return null;
|
||||||
@ -43,6 +45,7 @@ public final class FileUtil {
|
|||||||
//Get a list of all files which are folders and has one of the extensions specified
|
//Get a list of all files which are folders and has one of the extensions specified
|
||||||
File[] foundFiles = folder.listFiles((file) -> file.isFile() &&
|
File[] foundFiles = folder.listFiles((file) -> file.isFile() &&
|
||||||
ListUtil.listContains(extensions, (item) -> file.getName().toLowerCase().endsWith(item)));
|
ListUtil.listContains(extensions, (item) -> file.getName().toLowerCase().endsWith(item)));
|
||||||
|
|
||||||
//Return if recursion is finished
|
//Return if recursion is finished
|
||||||
if (maxRecursions == 1) {
|
if (maxRecursions == 1) {
|
||||||
return foundFiles;
|
return foundFiles;
|
||||||
@ -68,36 +71,6 @@ public final class FileUtil {
|
|||||||
return foundFiles;
|
return foundFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a file's contents to a string list
|
|
||||||
*
|
|
||||||
* <p>The file must contain the number of lines to read in the first line.</p>
|
|
||||||
*
|
|
||||||
* @param fileName <p>The file to read.</p>
|
|
||||||
* @return <p>A string list where each element is one line of the file.</p>
|
|
||||||
* @throws IOException <p>If the file cannot be read.</p>
|
|
||||||
*/
|
|
||||||
public static String[] readFileLines(String fileName) throws IOException {
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(getResourceAsStream(fileName)));
|
|
||||||
int numberOfLines = Integer.parseInt(reader.readLine());
|
|
||||||
String[] lines = new String[numberOfLines];
|
|
||||||
for (int i = 0; i < lines.length; i++) {
|
|
||||||
lines[i] = reader.readLine();
|
|
||||||
}
|
|
||||||
return lines;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a resource as an InputStream
|
|
||||||
*
|
|
||||||
* @param resourceName <p>The name of the resource you want to read.</p>
|
|
||||||
* @return <p>An input stream which can be used to access the resource.</p>
|
|
||||||
*/
|
|
||||||
private static InputStream getResourceAsStream(String resourceName) {
|
|
||||||
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
|
|
||||||
return classloader.getResourceAsStream(resourceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds parentheses with an integer if the output file already exists
|
* Adds parentheses with an integer if the output file already exists
|
||||||
*
|
*
|
||||||
@ -105,7 +78,8 @@ public final class FileUtil {
|
|||||||
* @param extension <p>The extension of the target file.</p>
|
* @param extension <p>The extension of the target file.</p>
|
||||||
* @return <p>A filename guaranteed not to collide with other files.</p>
|
* @return <p>A filename guaranteed not to collide with other files.</p>
|
||||||
*/
|
*/
|
||||||
private static String getNonCollidingFilename(String targetPath, String extension) {
|
@NotNull
|
||||||
|
private static String getNonCollidingFilename(@NotNull String targetPath, @NotNull String extension) {
|
||||||
File newFile = new File(targetPath);
|
File newFile = new File(targetPath);
|
||||||
String fileName = stripExtension(targetPath).replaceAll("\\([0-9]+\\)$", "");
|
String fileName = stripExtension(targetPath).replaceAll("\\([0-9]+\\)$", "");
|
||||||
int i = 1;
|
int i = 1;
|
||||||
@ -121,7 +95,8 @@ public final class FileUtil {
|
|||||||
* @param file <p>The filename to check</p>
|
* @param file <p>The filename to check</p>
|
||||||
* @return <p>The file's extension</p>
|
* @return <p>The file's extension</p>
|
||||||
*/
|
*/
|
||||||
public static String getExtension(String file) {
|
@NotNull
|
||||||
|
public static String getExtension(@NotNull String file) {
|
||||||
if (file.contains(".")) {
|
if (file.contains(".")) {
|
||||||
return file.substring(file.lastIndexOf('.') + 1);
|
return file.substring(file.lastIndexOf('.') + 1);
|
||||||
} else {
|
} else {
|
||||||
@ -135,7 +110,8 @@ public final class FileUtil {
|
|||||||
* @param file <p>A filename.</p>
|
* @param file <p>A filename.</p>
|
||||||
* @return <p>A filename without its extension.</p>
|
* @return <p>A filename without its extension.</p>
|
||||||
*/
|
*/
|
||||||
public static String stripExtension(String file) {
|
@NotNull
|
||||||
|
public static String stripExtension(@NotNull String file) {
|
||||||
return file.substring(0, file.lastIndexOf('.'));
|
return file.substring(0, file.lastIndexOf('.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package net.knarcraft.ffmpegconverter.utility;
|
package net.knarcraft.ffmpegconverter.utility;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -22,7 +24,8 @@ public final class ListUtil {
|
|||||||
* @param <T> <p>The type of the two lists.</p>
|
* @param <T> <p>The type of the two lists.</p>
|
||||||
* @return <p>A new array containing all elements from the two arrays.</p>
|
* @return <p>A new array containing all elements from the two arrays.</p>
|
||||||
*/
|
*/
|
||||||
static <T> T[] concatenate(T[] listA, T[] listB) {
|
@NotNull
|
||||||
|
public static <T> T[] concatenate(@NotNull T[] listA, @NotNull T[] listB) {
|
||||||
int listALength = listA.length;
|
int listALength = listA.length;
|
||||||
int listBLength = listB.length;
|
int listBLength = listB.length;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@ -40,7 +43,7 @@ public final class ListUtil {
|
|||||||
* @param <T> <p>The type of the list.</p>
|
* @param <T> <p>The type of the list.</p>
|
||||||
* @return <p>A new list containing all matching elements.</p>
|
* @return <p>A new list containing all matching elements.</p>
|
||||||
*/
|
*/
|
||||||
static <T> List<T> getMatching(List<T> list, Predicate<T> predicate) {
|
public static <T> List<T> getMatching(List<T> list, Predicate<T> predicate) {
|
||||||
List<T> matching = new ArrayList<>(list);
|
List<T> matching = new ArrayList<>(list);
|
||||||
matching.removeIf(predicate.negate());
|
matching.removeIf(predicate.negate());
|
||||||
return matching;
|
return matching;
|
||||||
@ -54,7 +57,7 @@ public final class ListUtil {
|
|||||||
* @param <T> Anything which can be stored in a list
|
* @param <T> Anything which can be stored in a list
|
||||||
* @return True if at least one element fulfills the predicate
|
* @return True if at least one element fulfills the predicate
|
||||||
*/
|
*/
|
||||||
static <T> boolean listContains(T[] list, Predicate<T> predicate) {
|
public static <T> boolean listContains(@NotNull List<T> list, @NotNull Predicate<T> predicate) {
|
||||||
for (T item : list) {
|
for (T item : list) {
|
||||||
if (predicate.test(item)) {
|
if (predicate.test(item)) {
|
||||||
return true;
|
return true;
|
||||||
@ -69,7 +72,8 @@ public final class ListUtil {
|
|||||||
* @param string <p>A string which may include commas.</p>
|
* @param string <p>A string which may include commas.</p>
|
||||||
* @return <p>A string list.</p>
|
* @return <p>A string list.</p>
|
||||||
*/
|
*/
|
||||||
public static String[] getListFromCommaSeparatedString(String string) {
|
@NotNull
|
||||||
|
public static String[] getListFromCommaSeparatedString(@NotNull String string) {
|
||||||
String[] result;
|
String[] result;
|
||||||
if (string.contains(",")) {
|
if (string.contains(",")) {
|
||||||
result = string.split(",");
|
result = string.split(",");
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package net.knarcraft.ffmpegconverter.utility;
|
package net.knarcraft.ffmpegconverter.utility;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
@ -30,7 +32,7 @@ public final class OutputUtil {
|
|||||||
*
|
*
|
||||||
* @param input <p>The text to print.</p>
|
* @param input <p>The text to print.</p>
|
||||||
*/
|
*/
|
||||||
public static void println(String input) {
|
public static void println(@NotNull String input) {
|
||||||
if (!input.isEmpty()) {
|
if (!input.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
writer.write(input);
|
writer.write(input);
|
||||||
@ -46,7 +48,7 @@ public final class OutputUtil {
|
|||||||
*
|
*
|
||||||
* @param input <p>The string to print.</p>
|
* @param input <p>The string to print.</p>
|
||||||
*/
|
*/
|
||||||
public static void print(String input) {
|
public static void print(@NotNull String input) {
|
||||||
try {
|
try {
|
||||||
writer.write(input);
|
writer.write(input);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
@ -82,7 +84,7 @@ public final class OutputUtil {
|
|||||||
*
|
*
|
||||||
* @param message <p>The debug message to show.</p>
|
* @param message <p>The debug message to show.</p>
|
||||||
*/
|
*/
|
||||||
public static void printDebug(String message) {
|
public static void printDebug(@NotNull String message) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
println(message);
|
println(message);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.knarcraft.ffmpegconverter.utility;
|
package net.knarcraft.ffmpegconverter.utility;
|
||||||
|
|
||||||
import net.knarcraft.ffmpegconverter.parser.ConverterArgument;
|
import net.knarcraft.ffmpegconverter.parser.ConverterArgument;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -23,7 +24,8 @@ public final class Parser {
|
|||||||
* @param validArguments <p>All arguments which are considered valid.</p>
|
* @param validArguments <p>All arguments which are considered valid.</p>
|
||||||
* @return <p>A map with all parsed arguments.</p>
|
* @return <p>A map with all parsed arguments.</p>
|
||||||
*/
|
*/
|
||||||
static Map<String, String> parse(String input, List<ConverterArgument> validArguments) {
|
@NotNull
|
||||||
|
static Map<String, String> parse(@NotNull String input, @NotNull List<ConverterArgument> validArguments) {
|
||||||
return parse(tokenize(input), validArguments);
|
return parse(tokenize(input), validArguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,7 +36,8 @@ public final class Parser {
|
|||||||
* @param validArguments <p>A list of arguments which are considered valid.</p>
|
* @param validArguments <p>A list of arguments which are considered valid.</p>
|
||||||
* @return <p>A map with all parsed arguments.</p>
|
* @return <p>A map with all parsed arguments.</p>
|
||||||
*/
|
*/
|
||||||
private static Map<String, String> parse(List<String> tokens, List<ConverterArgument> validArguments) {
|
@NotNull
|
||||||
|
private static Map<String, String> parse(@NotNull List<String> tokens, @NotNull List<ConverterArgument> validArguments) {
|
||||||
Map<String, String> parsedArguments = new HashMap<>();
|
Map<String, String> parsedArguments = new HashMap<>();
|
||||||
|
|
||||||
while (!tokens.isEmpty()) {
|
while (!tokens.isEmpty()) {
|
||||||
@ -50,7 +53,8 @@ public final class Parser {
|
|||||||
* @param converterArguments <p>A list of all the valid arguments in existence.</p>
|
* @param converterArguments <p>A list of all the valid arguments in existence.</p>
|
||||||
* @param parsedArguments <p>The map to store the parsed argument to.</p>
|
* @param parsedArguments <p>The map to store the parsed argument to.</p>
|
||||||
*/
|
*/
|
||||||
private static void parseArgument(List<String> tokens, List<ConverterArgument> converterArguments, Map<String, String> parsedArguments) {
|
private static void parseArgument(@NotNull List<String> tokens, @NotNull List<ConverterArgument> converterArguments,
|
||||||
|
@NotNull Map<String, String> parsedArguments) {
|
||||||
String currentToken = tokens.remove(0);
|
String currentToken = tokens.remove(0);
|
||||||
List<ConverterArgument> foundArguments;
|
List<ConverterArgument> foundArguments;
|
||||||
|
|
||||||
@ -79,7 +83,8 @@ public final class Parser {
|
|||||||
* @param foundArgument <p>The found argument to store.</p>
|
* @param foundArgument <p>The found argument to store.</p>
|
||||||
* @param parsedArguments <p>The map to store parsed arguments to.</p>
|
* @param parsedArguments <p>The map to store parsed arguments to.</p>
|
||||||
*/
|
*/
|
||||||
private static void storeArgumentValue(List<String> tokens, ConverterArgument foundArgument, Map<String, String> parsedArguments) {
|
private static void storeArgumentValue(@NotNull List<String> tokens, @NotNull ConverterArgument foundArgument,
|
||||||
|
@NotNull Map<String, String> parsedArguments) {
|
||||||
String argumentValue;
|
String argumentValue;
|
||||||
if (tokens.isEmpty()) {
|
if (tokens.isEmpty()) {
|
||||||
argumentValue = "";
|
argumentValue = "";
|
||||||
@ -114,7 +119,8 @@ public final class Parser {
|
|||||||
* @param input <p>A string.</p>
|
* @param input <p>A string.</p>
|
||||||
* @return <p>A list of tokens.</p>
|
* @return <p>A list of tokens.</p>
|
||||||
*/
|
*/
|
||||||
public static List<String> tokenize(String input) {
|
@NotNull
|
||||||
|
public static List<String> tokenize(@NotNull String input) {
|
||||||
List<String> tokens = new ArrayList<>();
|
List<String> tokens = new ArrayList<>();
|
||||||
boolean startedQuote = false;
|
boolean startedQuote = false;
|
||||||
StringBuilder currentToken = new StringBuilder();
|
StringBuilder currentToken = new StringBuilder();
|
||||||
@ -157,8 +163,8 @@ public final class Parser {
|
|||||||
* @param index <p>The index of the read character.</p>
|
* @param index <p>The index of the read character.</p>
|
||||||
* @param tokens <p>The list of processed tokens.</p>
|
* @param tokens <p>The list of processed tokens.</p>
|
||||||
*/
|
*/
|
||||||
private static void tokenizeNormalCharacter(StringBuilder currentToken, char character, int inputLength, int index,
|
private static void tokenizeNormalCharacter(@NotNull StringBuilder currentToken, char character, int inputLength,
|
||||||
List<String> tokens) {
|
int index, @NotNull List<String> tokens) {
|
||||||
currentToken.append(character);
|
currentToken.append(character);
|
||||||
if (index == inputLength - 1) {
|
if (index == inputLength - 1) {
|
||||||
tokens.add(currentToken.toString());
|
tokens.add(currentToken.toString());
|
||||||
@ -173,7 +179,8 @@ public final class Parser {
|
|||||||
* @param tokens <p>The list of processed tokens.</p>
|
* @param tokens <p>The list of processed tokens.</p>
|
||||||
* @return <p>True if the token is finished.</p>
|
* @return <p>True if the token is finished.</p>
|
||||||
*/
|
*/
|
||||||
private static boolean tokenizeSpace(boolean startedQuote, StringBuilder currentToken, List<String> tokens) {
|
private static boolean tokenizeSpace(boolean startedQuote, @NotNull StringBuilder currentToken,
|
||||||
|
@NotNull List<String> tokens) {
|
||||||
if (!startedQuote) {
|
if (!startedQuote) {
|
||||||
//If not inside "", a space marks the end of a parameter
|
//If not inside "", a space marks the end of a parameter
|
||||||
if (isNotEmpty(currentToken)) {
|
if (isNotEmpty(currentToken)) {
|
||||||
@ -192,7 +199,7 @@ public final class Parser {
|
|||||||
* @param builder <p>The string builder to check.</p>
|
* @param builder <p>The string builder to check.</p>
|
||||||
* @return <p>True if the string builder is non empty.</p>
|
* @return <p>True if the string builder is non empty.</p>
|
||||||
*/
|
*/
|
||||||
private static boolean isNotEmpty(StringBuilder builder) {
|
private static boolean isNotEmpty(@NotNull StringBuilder builder) {
|
||||||
return !builder.toString().trim().isEmpty();
|
return !builder.toString().trim().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
39
|
|
||||||
3gp
|
3gp
|
||||||
aa
|
aa
|
||||||
aac
|
aac
|
||||||
|
1
src/main/resources/conf/config.properties
Normal file
1
src/main/resources/conf/config.properties
Normal file
@ -0,0 +1 @@
|
|||||||
|
debug=false
|
@ -1,4 +1,3 @@
|
|||||||
5
|
|
||||||
idx
|
idx
|
||||||
sub
|
sub
|
||||||
srt
|
srt
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
31
|
|
||||||
avi
|
avi
|
||||||
mpg
|
mpg
|
||||||
mpeg
|
mpeg
|
||||||
|
@ -13,7 +13,7 @@ import static org.junit.Assert.assertFalse;
|
|||||||
|
|
||||||
public class ListUtilTest {
|
public class ListUtilTest {
|
||||||
private static List<Integer> matchesList;
|
private static List<Integer> matchesList;
|
||||||
private static Integer[] containsList;
|
private static List<Integer> containsList;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUp() {
|
public static void setUp() {
|
||||||
@ -28,7 +28,7 @@ public class ListUtilTest {
|
|||||||
matchesList.add(19);
|
matchesList.add(19);
|
||||||
matchesList.add(21);
|
matchesList.add(21);
|
||||||
matchesList.add(23);
|
matchesList.add(23);
|
||||||
containsList = new Integer[]{1, 3, 5, 7, 234, 23, 45};
|
containsList = List.of(1, 3, 5, 7, 234, 23, 45);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
Loading…
Reference in New Issue
Block a user