Adds a video downscaler
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				KnarCraft/FFmpegConvert/pipeline/head This commit looks good
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	KnarCraft/FFmpegConvert/pipeline/head This commit looks good
				
			This commit is contained in:
		@@ -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 <p>The initialized downscale converter</p>
 | 
			
		||||
     * @throws IOException <p>If unable to print to output</p>
 | 
			
		||||
     */
 | 
			
		||||
    private static Converter generateDownScaleConverter() throws IOException {
 | 
			
		||||
        OutputUtil.println("(New width e.x. 1920) (New height e.x. 1080)\nYour input: ");
 | 
			
		||||
        List<String> 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
 | 
			
		||||
     *
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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 <p>Path/command to ffprobe.</p>
 | 
			
		||||
     * @param ffmpegPath  <p>Path/command to ffmpeg.</p>
 | 
			
		||||
     * @param newWidth    <p>The new width of the video</p>
 | 
			
		||||
     * @param newHeight   <p>The new height of the video</p>
 | 
			
		||||
     */
 | 
			
		||||
    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<StreamObject> streams, String outFile) {
 | 
			
		||||
        VideoStream videoStream = getNthVideoStream(streams, 0);
 | 
			
		||||
        if (videoStream == null || (videoStream.getWidth() <= newWidth && videoStream.getHeight() <= newHeight)) {
 | 
			
		||||
            return new String[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<String> 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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <p>A filename.</p>
 | 
			
		||||
     * @return <p>A filename without its extension.</p>
 | 
			
		||||
     */
 | 
			
		||||
    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 <p>A file object.</p>
 | 
			
		||||
     * @return <p>A filename.</p>
 | 
			
		||||
     * @param file <p>The filename to check</p>
 | 
			
		||||
     * @return <p>The file's extension</p>
 | 
			
		||||
     */
 | 
			
		||||
    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 <p>A filename.</p>
 | 
			
		||||
     * @return <p>A filename without its extension.</p>
 | 
			
		||||
     */
 | 
			
		||||
    public static String stripExtension(String file) {
 | 
			
		||||
        return file.substring(0, file.lastIndexOf('.'));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user