Adds a de-interlace module and stuff
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				KnarCraft/FFmpegConvert/pipeline/head This commit looks good
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	KnarCraft/FFmpegConvert/pipeline/head This commit looks good
				
			Adds a module to de-interlace when converting a video. It's enabled by a new configuration option. Fixes some bugs in the letterbox cropper Adds mpeg4 to video formats
This commit is contained in:
		@@ -52,6 +52,11 @@ public class ConfigKey<T> {
 | 
			
		||||
     */
 | 
			
		||||
    public static final ConfigKey<String> MINIMAL_SUBTITLE_PREFERENCE = createKey("minimal-subtitle-preference", String.class, "AVOID");
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The configuration key for whether to de-interlace video streams
 | 
			
		||||
     */
 | 
			
		||||
    public static final ConfigKey<Boolean> DE_INTERLACE_VIDEO = createKey("de-interlace-video", Boolean.class, false);
 | 
			
		||||
 | 
			
		||||
    private final String configKey;
 | 
			
		||||
    private final T defaultValue;
 | 
			
		||||
    private final Class<T> type;
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ public class Configuration {
 | 
			
		||||
    private List<String> animeAudioLanguages;
 | 
			
		||||
    private List<String> animeSubtitleLanguages;
 | 
			
		||||
    private MinimalSubtitlePreference minimalSubtitlePreference;
 | 
			
		||||
    private boolean deInterlaceVideo;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiates and loads a new configuration
 | 
			
		||||
@@ -53,6 +54,7 @@ public class Configuration {
 | 
			
		||||
        alwaysEncodeFlac = ConfigHelper.asBoolean(configHandler.getValue(ConfigKey.ENCODE_FLAC_ALWAYS));
 | 
			
		||||
        animeAudioLanguages = ConfigHelper.asStringList(configHandler.getValue(ConfigKey.AUDIO_LANGUAGES_ANIME));
 | 
			
		||||
        animeSubtitleLanguages = ConfigHelper.asStringList(configHandler.getValue(ConfigKey.SUBTITLE_LANGUAGES_ANIME));
 | 
			
		||||
        deInterlaceVideo = ConfigHelper.asBoolean(configHandler.getValue(ConfigKey.DE_INTERLACE_VIDEO));
 | 
			
		||||
        try {
 | 
			
		||||
            minimalSubtitlePreference = MinimalSubtitlePreference.valueOf(String.valueOf(configHandler.getValue(
 | 
			
		||||
                    ConfigKey.MINIMAL_SUBTITLE_PREFERENCE)));
 | 
			
		||||
@@ -147,4 +149,13 @@ public class Configuration {
 | 
			
		||||
        return this.minimalSubtitlePreference;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets whether video streams should be de-interlaced
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>Whether to de-interlace streams</p>
 | 
			
		||||
     */
 | 
			
		||||
    public boolean deInterlaceVideo() {
 | 
			
		||||
        return this.deInterlaceVideo;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,8 @@ package net.knarcraft.ffmpegconverter.converter;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.FFMpegConvert;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.container.FFMpegCommand;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.container.StreamProbeResult;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.converter.module.DeInterlaceModule;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.converter.module.ModuleExecutor;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.handler.AvailableHardwareEncoderHandler;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.streams.StreamObject;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
 | 
			
		||||
@@ -68,6 +70,12 @@ public abstract class AbstractConverter implements Converter {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // De-interlace the video if enabled
 | 
			
		||||
        if (FFMpegConvert.getConfiguration().deInterlaceVideo() &&
 | 
			
		||||
                (outExtension.equalsIgnoreCase("mkv") || outExtension.equalsIgnoreCase("mp4"))) {
 | 
			
		||||
            new ModuleExecutor(ffMpegCommand, List.of(new DeInterlaceModule())).execute();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String[] command = ffMpegCommand.getResult();
 | 
			
		||||
        // If no commands were given, no conversion is necessary
 | 
			
		||||
        if (command.length == 0) {
 | 
			
		||||
 
 | 
			
		||||
@@ -90,7 +90,7 @@ public class AnimeConverter extends AbstractConverter {
 | 
			
		||||
        FFMpegCommand command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, probeResult.parsedFiles());
 | 
			
		||||
        List<ConverterModule> modules = new ArrayList<>();
 | 
			
		||||
        if (this.debug) {
 | 
			
		||||
            modules.add(new DebugModule(90, 120));
 | 
			
		||||
            modules.add(new DebugModule());
 | 
			
		||||
        }
 | 
			
		||||
        modules.add(new FastStartModule());
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ public class AudioConverter extends AbstractConverter {
 | 
			
		||||
        List<ConverterModule> modules = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        if (this.debug) {
 | 
			
		||||
            modules.add(new DebugModule(0, 0));
 | 
			
		||||
            modules.add(new DebugModule());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Gets the first audio stream from the file and adds it to the output file
 | 
			
		||||
 
 | 
			
		||||
@@ -64,7 +64,7 @@ public class DownScaleConverter extends AbstractConverter {
 | 
			
		||||
 | 
			
		||||
        FFMpegCommand command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, probeResult.parsedFiles());
 | 
			
		||||
        if (this.debug) {
 | 
			
		||||
            modules.add(new DebugModule(0, 0));
 | 
			
		||||
            modules.add(new DebugModule());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Add all streams without re-encoding
 | 
			
		||||
 
 | 
			
		||||
@@ -112,7 +112,7 @@ public class LetterboxCropper extends AbstractConverter {
 | 
			
		||||
 | 
			
		||||
        FFMpegCommand convertCommand = new FFMpegCommand(ffmpegPath);
 | 
			
		||||
 | 
			
		||||
        convertCommand.addInputFileOption(inputFile.getName());
 | 
			
		||||
        convertCommand.addInputFile(inputFile.getName());
 | 
			
		||||
        convertCommand.addOutputFileOption("-vf", "crop=" + crop);
 | 
			
		||||
        convertCommand.addOutputFileOption("-c:v", "libx265");
 | 
			
		||||
        convertCommand.addOutputFileOption("-crf", "22");
 | 
			
		||||
@@ -142,7 +142,7 @@ public class LetterboxCropper extends AbstractConverter {
 | 
			
		||||
        Map<String, Integer> cropValues = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
        if (this.debug) {
 | 
			
		||||
            modules.add(new DebugModule(0, 0));
 | 
			
		||||
            modules.add(new DebugModule());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        FFMpegCommand probeCommand = new FFMpegCommand(ffmpegPath);
 | 
			
		||||
@@ -166,7 +166,7 @@ public class LetterboxCropper extends AbstractConverter {
 | 
			
		||||
            FFMpegCommand clone = probeCommand.clone();
 | 
			
		||||
            clone.addInputFileOption("-ss", String.valueOf(i));
 | 
			
		||||
 | 
			
		||||
            ProcessBuilder processBuilder = new ProcessBuilder(probeCommand.getResult());
 | 
			
		||||
            ProcessBuilder processBuilder = new ProcessBuilder(clone.getResult());
 | 
			
		||||
            ProcessResult result = null;
 | 
			
		||||
            try {
 | 
			
		||||
                result = FFMpegHelper.runProcess(processBuilder, inputFile.getParentFile(), SPACER, false);
 | 
			
		||||
 
 | 
			
		||||
@@ -60,7 +60,7 @@ public class MKVToMP4Transcoder extends AbstractConverter {
 | 
			
		||||
        List<ConverterModule> modules = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        if (this.debug) {
 | 
			
		||||
            modules.add(new DebugModule(0, 0));
 | 
			
		||||
            modules.add(new DebugModule());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Copy stream info
 | 
			
		||||
 
 | 
			
		||||
@@ -52,7 +52,7 @@ public class MkvH264Converter extends AbstractConverter {
 | 
			
		||||
        List<ConverterModule> modules = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        if (this.debug) {
 | 
			
		||||
            modules.add(new DebugModule(0, 0));
 | 
			
		||||
            modules.add(new DebugModule());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Map video if present
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,7 @@ public class MkvH265ReducedConverter extends AbstractConverter {
 | 
			
		||||
        List<ConverterModule> modules = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        if (this.debug) {
 | 
			
		||||
            modules.add(new DebugModule(0, 0));
 | 
			
		||||
            modules.add(new DebugModule());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Map video if present
 | 
			
		||||
 
 | 
			
		||||
@@ -73,7 +73,7 @@ public class StreamOrderConverter extends AbstractConverter {
 | 
			
		||||
        FFMpegCommand command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, probeResult.parsedFiles());
 | 
			
		||||
        List<ConverterModule> modules = new ArrayList<>();
 | 
			
		||||
        if (this.debug) {
 | 
			
		||||
            modules.add(new DebugModule(90, 120));
 | 
			
		||||
            modules.add(new DebugModule());
 | 
			
		||||
        }
 | 
			
		||||
        modules.add(new FastStartModule());
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -50,7 +50,7 @@ public class SubtitleEmbed extends AbstractConverter {
 | 
			
		||||
        List<ConverterModule> modules = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        if (this.debug) {
 | 
			
		||||
            modules.add(new DebugModule(0, 0));
 | 
			
		||||
            modules.add(new DebugModule());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        modules.add(new MapAllModule<>(probeResult.parsedStreams()));
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,7 @@ public class VideoConverter extends AbstractConverter {
 | 
			
		||||
 | 
			
		||||
        List<StreamObject> streams = probeResult.parsedStreams();
 | 
			
		||||
        if (this.debug) {
 | 
			
		||||
            modules.add(new DebugModule(0, 0));
 | 
			
		||||
            modules.add(new DebugModule());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Add all streams without re-encoding
 | 
			
		||||
 
 | 
			
		||||
@@ -76,7 +76,7 @@ public class WebAnimeConverter extends AbstractConverter {
 | 
			
		||||
        FFMpegCommand command = FFMpegHelper.getFFMpegWebVideoCommand(executable, probeResult.parsedFiles());
 | 
			
		||||
        List<ConverterModule> modules = new ArrayList<>();
 | 
			
		||||
        if (this.debug) {
 | 
			
		||||
            modules.add(new DebugModule(0, 0));
 | 
			
		||||
            modules.add(new DebugModule());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Get the first audio stream in accordance with chosen languages
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,7 @@ public class WebVideoConverter extends AbstractConverter {
 | 
			
		||||
        List<ConverterModule> modules = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        if (this.debug) {
 | 
			
		||||
            modules.add(new DebugModule(0, 0));
 | 
			
		||||
            modules.add(new DebugModule());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Get first streams from the file
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,16 @@
 | 
			
		||||
package net.knarcraft.ffmpegconverter.converter.module;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.ffmpegconverter.container.FFMpegCommand;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A converter module for adding de-interlacing
 | 
			
		||||
 */
 | 
			
		||||
public class DeInterlaceModule implements ConverterModule {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addArguments(@NotNull FFMpegCommand command) {
 | 
			
		||||
        command.addOutputFileOption("-filter:v", "bwdif=mode=send_field");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -11,6 +11,13 @@ public class DebugModule implements ConverterModule {
 | 
			
		||||
    private double startTime = 50;
 | 
			
		||||
    private double duration = 120;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiates a new debug module that starts at 50 seconds, and lasts until 120 seconds
 | 
			
		||||
     */
 | 
			
		||||
    public DebugModule() {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiates a new debug module
 | 
			
		||||
     *
 | 
			
		||||
 
 | 
			
		||||
@@ -184,8 +184,8 @@ public final class FFMpegHelper {
 | 
			
		||||
     * @param stream  <p>The stream to map</p>
 | 
			
		||||
     */
 | 
			
		||||
    public static void mapStream(@NotNull FFMpegCommand command, @NotNull StreamObject stream) {
 | 
			
		||||
        command.addOutputFileOption("-map", String.format("%d:%d",
 | 
			
		||||
                stream.getInputIndex(), stream.getAbsoluteIndex()));
 | 
			
		||||
        command.addOutputFileOption("-map", String.format("%d:%d", stream.getInputIndex(),
 | 
			
		||||
                stream.getAbsoluteIndex()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -15,4 +15,6 @@ audio-languages-anime=jpn,eng,*
 | 
			
		||||
# The preference for subtitle languages when converting anime (0 = undefined, * = any)
 | 
			
		||||
subtitle-languages-anime=eng,*
 | 
			
		||||
# The preference for minimal subtitles, AKA Signs & Songs (REQUIRE/PREFER/NO_PREFERENCE/AVOID/REJECT)
 | 
			
		||||
minimal-subtitle-preference=AVOID
 | 
			
		||||
minimal-subtitle-preference=AVOID
 | 
			
		||||
# The preference for whether video streams should be de-interlaced. It is recommended to only enable this when you notice that a video file is interlaced.
 | 
			
		||||
de-interlace-video=false
 | 
			
		||||
@@ -28,4 +28,5 @@ m2v
 | 
			
		||||
svi
 | 
			
		||||
3g2
 | 
			
		||||
roq
 | 
			
		||||
nsv
 | 
			
		||||
nsv
 | 
			
		||||
mpeg4
 | 
			
		||||
		Reference in New Issue
	
	Block a user