diff --git a/src/main/java/net/knarcraft/ffmpegconverter/Main.java b/src/main/java/net/knarcraft/ffmpegconverter/Main.java
index 6561d8b..bc22a4e 100644
--- a/src/main/java/net/knarcraft/ffmpegconverter/Main.java
+++ b/src/main/java/net/knarcraft/ffmpegconverter/Main.java
@@ -3,6 +3,7 @@ package net.knarcraft.ffmpegconverter;
import net.knarcraft.ffmpegconverter.converter.AnimeConverter;
import net.knarcraft.ffmpegconverter.converter.AudioConverter;
import net.knarcraft.ffmpegconverter.converter.Converter;
+import net.knarcraft.ffmpegconverter.converter.DownScaleConverter;
import net.knarcraft.ffmpegconverter.converter.MKVToMP4Transcoder;
import net.knarcraft.ffmpegconverter.converter.MkvH264Converter;
import net.knarcraft.ffmpegconverter.converter.MkvH265ReducedConverter;
@@ -65,7 +66,7 @@ class Main {
private static Converter loadConverter() throws IOException {
int choice = getChoice("Which converter do you want do use?\n1. Anime to web mp4\n2. Audio converter\n" +
"3. Video converter\n4. Web video converter\n5. MKV to h264 converter\n6. MKV to h265 reduced " +
- "converter\n7. MKV to MP4 transcoder", 1, 7);
+ "converter\n7. MKV to MP4 transcoder\n8. DownScaleConverter", 1, 8);
switch (choice) {
case 1:
@@ -82,6 +83,8 @@ class Main {
return new MkvH265ReducedConverter(FFPROBE_PATH, FFMPEG_PATH);
case 7:
return generateMKVToMP4Transcoder();
+ case 8:
+ return generateDownScaleConverter();
}
return null;
}
@@ -117,6 +120,28 @@ class Main {
}
}
+ /**
+ * Initializes and returns the downscale converter
+ *
+ * @return
The initialized downscale converter
+ * @throws IOException If unable to print to output
+ */
+ private static Converter generateDownScaleConverter() throws IOException {
+ OutputUtil.println("(New width e.x. 1920) (New height e.x. 1080)\nYour input: ");
+ List input = readInput(3);
+ int newWidth;
+ int newHeight;
+
+ try {
+ newWidth = Integer.parseInt(input.get(0));
+ newHeight = Integer.parseInt(input.get(1));
+ return new DownScaleConverter(FFPROBE_PATH, FFMPEG_PATH, newWidth, newHeight);
+ } catch (NumberFormatException exception) {
+ OutputUtil.println("Width or height is not a number");
+ return null;
+ }
+ }
+
/**
* Initializes and returns the MKV to MP4 transcoder
*
diff --git a/src/main/java/net/knarcraft/ffmpegconverter/converter/AbstractConverter.java b/src/main/java/net/knarcraft/ffmpegconverter/converter/AbstractConverter.java
index c34d50c..d95c4dd 100644
--- a/src/main/java/net/knarcraft/ffmpegconverter/converter/AbstractConverter.java
+++ b/src/main/java/net/knarcraft/ffmpegconverter/converter/AbstractConverter.java
@@ -30,7 +30,7 @@ public abstract class AbstractConverter implements Converter {
/**
* Initializes variables used by the abstract converter
*/
- AbstractConverter(String newExtension) {
+ AbstractConverter(@Nullable String newExtension) {
this.newExtension = newExtension;
OutputUtil.setDebug(this.debug);
try {
@@ -128,11 +128,19 @@ public abstract class AbstractConverter implements Converter {
throw new IllegalArgumentException("The file has no valid streams. Please make sure the file exists and" +
" is not corrupt.");
}
- String newPath = FileUtil.getNonCollidingPath(folder, file, newExtension);
+ String outExtension = newExtension != null ? newExtension : FileUtil.getExtension(file.getName());
+ String newPath = FileUtil.getNonCollidingPath(folder, file, outExtension);
OutputUtil.println();
OutputUtil.println("Preparing to start process...");
OutputUtil.println("Converting " + file);
- ProcessBuilder processBuilder = new ProcessBuilder(generateConversionCommand(ffmpegPath, file, streams, newPath));
+
+ String[] command = generateConversionCommand(ffmpegPath, file, streams, newPath);
+ // If no commands were given, no conversion is necessary
+ if (command.length == 0) {
+ return;
+ }
+
+ ProcessBuilder processBuilder = new ProcessBuilder(command);
FFMpegHelper.runProcess(processBuilder, folder, "\n", true);
}
diff --git a/src/main/java/net/knarcraft/ffmpegconverter/converter/DownScaleConverter.java b/src/main/java/net/knarcraft/ffmpegconverter/converter/DownScaleConverter.java
new file mode 100644
index 0000000..cea1490
--- /dev/null
+++ b/src/main/java/net/knarcraft/ffmpegconverter/converter/DownScaleConverter.java
@@ -0,0 +1,69 @@
+package net.knarcraft.ffmpegconverter.converter;
+
+import net.knarcraft.ffmpegconverter.streams.StreamObject;
+import net.knarcraft.ffmpegconverter.streams.VideoStream;
+import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * A converter for converting video files
+ */
+public class DownScaleConverter extends AbstractConverter {
+
+ private final int newWidth;
+ private final int newHeight;
+
+ /**
+ * Instantiates a new video converter
+ *
+ * @param ffprobePath Path/command to ffprobe.
+ * @param ffmpegPath Path/command to ffmpeg.
+ * @param newWidth The new width of the video
+ * @param newHeight The new height of the video
+ */
+ public DownScaleConverter(String ffprobePath, String ffmpegPath, int newWidth, int newHeight) {
+ super(null);
+ this.ffprobePath = ffprobePath;
+ this.ffmpegPath = ffmpegPath;
+ this.newHeight = newHeight;
+ this.newWidth = newWidth;
+ }
+
+ @Override
+ public String[] generateConversionCommand(String executable, File file, List streams, String outFile) {
+ VideoStream videoStream = getNthVideoStream(streams, 0);
+ if (videoStream == null || (videoStream.getWidth() <= newWidth && videoStream.getHeight() <= newHeight)) {
+ return new String[0];
+ }
+
+ List command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, file.getName());
+ if (this.debug) {
+ FFMpegHelper.addDebugArguments(command, 50, 120);
+ }
+
+ //Add all streams without re-encoding
+ command.add("-map");
+ command.add("0");
+ command.add("-c:a");
+ command.add("copy");
+ command.add("-c:s");
+ command.add("copy");
+ command.add("-vf");
+ command.add("scale=" + newWidth + ":" + newHeight);
+ command.add("-crf");
+ command.add("20");
+ command.add("-preset");
+ command.add("slow");
+
+ command.add(outFile);
+ return command.toArray(new String[0]);
+ }
+
+ @Override
+ public String[] getValidFormats() {
+ return videoFormats;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/knarcraft/ffmpegconverter/utility/FileUtil.java b/src/main/java/net/knarcraft/ffmpegconverter/utility/FileUtil.java
index 99ce46a..f8d1c13 100644
--- a/src/main/java/net/knarcraft/ffmpegconverter/utility/FileUtil.java
+++ b/src/main/java/net/knarcraft/ffmpegconverter/utility/FileUtil.java
@@ -25,17 +25,7 @@ public final class FileUtil {
*/
public static String getNonCollidingPath(File folder, File file, String outExtension) {
return FileUtil.getNonCollidingFilename(folder.getAbsolutePath() + File.separator +
- FileUtil.stripExtension(file) + "." + outExtension, outExtension);
- }
-
- /**
- * Removes the extension from a file name
- *
- * @param file A filename.
- * @return A filename without its extension.
- */
- static String stripExtension(String file) {
- return file.substring(0, file.lastIndexOf('.'));
+ FileUtil.stripExtension(file.getName()) + "." + outExtension, outExtension);
}
/**
@@ -117,7 +107,7 @@ public final class FileUtil {
*/
private static String getNonCollidingFilename(String targetPath, String extension) {
File newFile = new File(targetPath);
- String fileName = stripExtension(targetPath);
+ String fileName = stripExtension(targetPath).replaceAll("\\([0-9]+\\)$", "");
int i = 1;
while (newFile.exists()) {
newFile = new File(fileName + "(" + i++ + ")" + "." + extension);
@@ -126,13 +116,27 @@ public final class FileUtil {
}
/**
- * Gets filename without extension from File object
+ * Gets the extension of the given filename
*
- * @param file A file object.
- * @return A filename.
+ * @param file The filename to check
+ * @return The file's extension
*/
- private static String stripExtension(File file) {
- return file.getName().substring(0, file.getName().lastIndexOf('.'));
+ public static String getExtension(String file) {
+ if (file.contains(".")) {
+ return file.substring(file.lastIndexOf('.') + 1);
+ } else {
+ return "";
+ }
+ }
+
+ /**
+ * Removes the extension from a file name
+ *
+ * @param file A filename.
+ * @return A filename without its extension.
+ */
+ public static String stripExtension(String file) {
+ return file.substring(0, file.lastIndexOf('.'));
}
}