Adds new converters
Adds a MKV to HEVC converter which aims to reduce file-sizes Adds a MKV to MP4 transcoder which allows selection of each type of stream
This commit is contained in:
		@@ -3,7 +3,9 @@ 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.MKVToMP4Transcoder;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.converter.MkvH264Converter;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.converter.MkvH265ReducedConverter;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.converter.VideoConverter;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.converter.WebVideoConverter;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.utility.FileUtil;
 | 
			
		||||
@@ -12,6 +14,7 @@ import net.knarcraft.ffmpegconverter.utility.OutputUtil;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Scanner;
 | 
			
		||||
 | 
			
		||||
@@ -61,11 +64,12 @@ 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", 1, 5);
 | 
			
		||||
                "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);
 | 
			
		||||
 | 
			
		||||
        switch (choice) {
 | 
			
		||||
            case 1:
 | 
			
		||||
                return animeConverter();
 | 
			
		||||
                return generateAnimeConverter();
 | 
			
		||||
            case 2:
 | 
			
		||||
                return new AudioConverter(FFPROBE_PATH, FFMPEG_PATH, getChoice("<output extension>"));
 | 
			
		||||
            case 3:
 | 
			
		||||
@@ -74,6 +78,10 @@ class Main {
 | 
			
		||||
                return new WebVideoConverter(FFPROBE_PATH, FFMPEG_PATH, getChoice("<output extension>"));
 | 
			
		||||
            case 5:
 | 
			
		||||
                return new MkvH264Converter(FFPROBE_PATH, FFMPEG_PATH);
 | 
			
		||||
            case 6:
 | 
			
		||||
                return new MkvH265ReducedConverter(FFPROBE_PATH, FFMPEG_PATH);
 | 
			
		||||
            case 7:
 | 
			
		||||
                return generateMKVToMP4Transcoder();
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
@@ -96,18 +104,56 @@ class Main {
 | 
			
		||||
                OutputUtil.println("No valid files found in folder.");
 | 
			
		||||
            }
 | 
			
		||||
        } else if (fileOrFolder.exists()) {
 | 
			
		||||
            converter.convert(fileOrFolder);
 | 
			
		||||
            String path = fileOrFolder.getPath();
 | 
			
		||||
            if (Arrays.stream(converter.getValidFormats()).anyMatch((format) -> format.equalsIgnoreCase(
 | 
			
		||||
                    path.substring(path.lastIndexOf('.') + 1)))) {
 | 
			
		||||
                converter.convert(fileOrFolder);
 | 
			
		||||
            } else {
 | 
			
		||||
                OutputUtil.println("The specified file " + fileOrFolder.getAbsolutePath() + " is not supported for " +
 | 
			
		||||
                        "the selected converter.");
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            OutputUtil.println("Path " + fileOrFolder.getAbsolutePath() + " does not point to any file or folder.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Initializes the anime converter
 | 
			
		||||
     * Initializes and returns the MKV to MP4 transcoder
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>The initialized transcoder</p>
 | 
			
		||||
     * @throws IOException <p>If unable to print to output</p>
 | 
			
		||||
     */
 | 
			
		||||
    private static Converter generateMKVToMP4Transcoder() throws IOException {
 | 
			
		||||
        OutputUtil.println("[Audio stream index 0-n] [Subtitle stream index 0-n] [Video stream index 0-n]\nYour input: ");
 | 
			
		||||
        List<String> input = readInput(3);
 | 
			
		||||
        int audioStreamIndex = -1;
 | 
			
		||||
        int subtitleStreamIndex = -1;
 | 
			
		||||
        int videoStreamIndex = -1;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            if (input.size() > 0) {
 | 
			
		||||
                audioStreamIndex = Integer.parseInt(input.get(0));
 | 
			
		||||
            }
 | 
			
		||||
            if (input.size() > 1) {
 | 
			
		||||
                subtitleStreamIndex = Integer.parseInt(input.get(1));
 | 
			
		||||
            }
 | 
			
		||||
            if (input.size() > 2) {
 | 
			
		||||
                videoStreamIndex = Integer.parseInt(input.get(2));
 | 
			
		||||
            }
 | 
			
		||||
            return new MKVToMP4Transcoder(FFPROBE_PATH, FFMPEG_PATH, audioStreamIndex, subtitleStreamIndex, videoStreamIndex);
 | 
			
		||||
        } catch (NumberFormatException exception) {
 | 
			
		||||
            OutputUtil.println("Audio, Subtitle or Video stream index is not a number");
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Initializes and returns the anime converter
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>The initialized anime converter</p>
 | 
			
		||||
     * @throws IOException <p>If reading or writing fails.</p>
 | 
			
		||||
     */
 | 
			
		||||
    private static Converter animeConverter() throws IOException {
 | 
			
		||||
    private static Converter generateAnimeConverter() throws IOException {
 | 
			
		||||
        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] " +
 | 
			
		||||
                "[Forced subtitle index 0-n] [Subtitle name filter]\nYour input: ");
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,8 @@ import net.knarcraft.ffmpegconverter.streams.VideoStream;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.utility.FileUtil;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.utility.OutputUtil;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
import org.jetbrains.annotations.Nullable;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
@@ -135,13 +137,16 @@ public abstract class AbstractConverter implements Converter {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the n-th audio stream from a list of streams
 | 
			
		||||
     * Gets the nth audio stream from a list of streams
 | 
			
		||||
     *
 | 
			
		||||
     * @param streams <p>A list of all streams.</p>
 | 
			
		||||
     * @param streams <p>A list of all streams</p>
 | 
			
		||||
     * @param n       <p>The index of the audio stream to get</p>
 | 
			
		||||
     * @return <p>The first audio stream found or null if no audio streams were found.</p>
 | 
			
		||||
     * @return <p>The first audio stream found or null if no audio streams were found</p>
 | 
			
		||||
     */
 | 
			
		||||
    protected AudioStream getNthAudioSteam(List<StreamObject> streams, int n) {
 | 
			
		||||
        if (n < 0) {
 | 
			
		||||
            throw new IllegalArgumentException("N cannot be negative!");
 | 
			
		||||
        }
 | 
			
		||||
        List<AudioStream> audioStreams = filterStreamsByType(streams, AudioStream.class);
 | 
			
		||||
        AudioStream audioStream = null;
 | 
			
		||||
        if (audioStreams.size() > n) {
 | 
			
		||||
@@ -153,13 +158,16 @@ public abstract class AbstractConverter implements Converter {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the first subtitle stream from a list of streams
 | 
			
		||||
     * Gets the nth subtitle stream from a list of streams
 | 
			
		||||
     *
 | 
			
		||||
     * @param streams <p>A list of all streams.</p>
 | 
			
		||||
     * @param streams <p>A list of all streams</p>
 | 
			
		||||
     * @param n       <p>The index of the subtitle stream to get</p>
 | 
			
		||||
     * @return <p>The first subtitle stream found or null if no subtitle streams were found.</p>
 | 
			
		||||
     * @return <p>The first subtitle stream found or null if no subtitle streams were found</p>
 | 
			
		||||
     */
 | 
			
		||||
    protected SubtitleStream getNthSubtitleStream(List<StreamObject> streams, int n) {
 | 
			
		||||
        if (n < 0) {
 | 
			
		||||
            throw new IllegalArgumentException("N cannot be negative!");
 | 
			
		||||
        }
 | 
			
		||||
        List<SubtitleStream> subtitleStreams = filterStreamsByType(streams, SubtitleStream.class);
 | 
			
		||||
        SubtitleStream subtitleStream = null;
 | 
			
		||||
        if (subtitleStreams.size() > n) {
 | 
			
		||||
@@ -171,25 +179,28 @@ public abstract class AbstractConverter implements Converter {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the first video stream from a list of streams
 | 
			
		||||
     * Gets the nth video stream from a list of streams
 | 
			
		||||
     *
 | 
			
		||||
     * @param streams <p>A list of all streams.</p>
 | 
			
		||||
     * @return <p>The first video stream found or null if no video streams were found.</p>
 | 
			
		||||
     * @param streams <p>A list of all streams</p>
 | 
			
		||||
     * @param n       <p>The index of the video stream to get</p>
 | 
			
		||||
     * @return <p>The nth video stream, or null if no video streams were found</p>
 | 
			
		||||
     */
 | 
			
		||||
    protected VideoStream getFirstVideoStream(List<StreamObject> streams) {
 | 
			
		||||
    protected @Nullable VideoStream getNthVideoStream(@NotNull List<StreamObject> streams, int n) {
 | 
			
		||||
        if (n < 0) {
 | 
			
		||||
            throw new IllegalArgumentException("N cannot be negative!");
 | 
			
		||||
        }
 | 
			
		||||
        List<VideoStream> videoStreams = filterStreamsByType(streams, VideoStream.class);
 | 
			
		||||
        VideoStream videoStream = null;
 | 
			
		||||
        if (videoStreams.size() > 0) {
 | 
			
		||||
        if (videoStreams.size() > n) {
 | 
			
		||||
            videoStream = videoStreams.get(n);
 | 
			
		||||
        } else if (videoStreams.size() > 0) {
 | 
			
		||||
            videoStream = videoStreams.get(0);
 | 
			
		||||
        }
 | 
			
		||||
        if (videoStream == null) {
 | 
			
		||||
            throw new IllegalArgumentException("The file does not have any valid video streams.");
 | 
			
		||||
        }
 | 
			
		||||
        return videoStream;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void convert(File file) throws IOException {
 | 
			
		||||
    public void convert(@NotNull File file) throws IOException {
 | 
			
		||||
        processFile(file.getParentFile(), file);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -70,7 +70,7 @@ public class AnimeConverter extends AbstractConverter {
 | 
			
		||||
                Math.max(this.forcedSubtitleIndex, 0));
 | 
			
		||||
 | 
			
		||||
        //Get the first video stream
 | 
			
		||||
        VideoStream videoStream = getFirstVideoStream(streams);
 | 
			
		||||
        VideoStream videoStream = getNthVideoStream(streams, 0);
 | 
			
		||||
 | 
			
		||||
        //Add streams to output file
 | 
			
		||||
        FFMpegHelper.addAudioStream(command, audioStream, this.toStereo);
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,81 @@
 | 
			
		||||
package net.knarcraft.ffmpegconverter.converter;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.ffmpegconverter.streams.AudioStream;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.streams.StreamObject;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.streams.SubtitleStream;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.streams.VideoStream;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A transcoder which takes one of each stream from an MKV file and produces an MP4 file
 | 
			
		||||
 */
 | 
			
		||||
public class MKVToMP4Transcoder extends AbstractConverter {
 | 
			
		||||
 | 
			
		||||
    private final int videoStreamIndex;
 | 
			
		||||
    private final int audioStreamIndex;
 | 
			
		||||
    private final int subtitleStreamIndex;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiates a new mkv to mp4 transcoder
 | 
			
		||||
     *
 | 
			
		||||
     * @param ffprobePath         <p>Path/command to ffprobe.</p>
 | 
			
		||||
     * @param ffmpegPath          <p>Path/command to ffmpeg.</p>
 | 
			
		||||
     * @param audioStreamIndex    <p>The relative index of the audio stream to use (0 or below selects the first)</p>
 | 
			
		||||
     * @param subtitleStreamIndex <p>The relative index of the subtitle stream to use (0 or below selects the first)</p>
 | 
			
		||||
     * @param videoStreamIndex    <p>The relative index of the video stream to use (0 or below selects the first)</p>
 | 
			
		||||
     */
 | 
			
		||||
    public MKVToMP4Transcoder(String ffprobePath, String ffmpegPath, int audioStreamIndex, int subtitleStreamIndex,
 | 
			
		||||
                              int videoStreamIndex) {
 | 
			
		||||
        super("mp4");
 | 
			
		||||
        this.ffprobePath = ffprobePath;
 | 
			
		||||
        this.ffmpegPath = ffmpegPath;
 | 
			
		||||
        this.videoStreamIndex = videoStreamIndex;
 | 
			
		||||
        this.audioStreamIndex = audioStreamIndex;
 | 
			
		||||
        this.subtitleStreamIndex = subtitleStreamIndex;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String[] getValidFormats() {
 | 
			
		||||
        return new String[]{"mkv"};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String[] generateConversionCommand(String executable, File file, List<StreamObject> streams, String outFile) {
 | 
			
		||||
        List<String> command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, file.getName());
 | 
			
		||||
        if (this.debug) {
 | 
			
		||||
            FFMpegHelper.addDebugArguments(command, 50, 120);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Get the nth audio stream
 | 
			
		||||
        List<AudioStream> audioStreams = filterStreamsByType(streams, AudioStream.class);
 | 
			
		||||
        AudioStream audioStream = getNthAudioSteam(new ArrayList<>(audioStreams), Math.max(this.audioStreamIndex, 0));
 | 
			
		||||
 | 
			
		||||
        //Get the nth subtitle stream
 | 
			
		||||
        List<SubtitleStream> allSubtitleStreams = filterStreamsByType(streams, SubtitleStream.class);
 | 
			
		||||
        SubtitleStream subtitleStream = getNthSubtitleStream(new ArrayList<>(allSubtitleStreams),
 | 
			
		||||
                Math.max(this.subtitleStreamIndex, 0));
 | 
			
		||||
 | 
			
		||||
        //Get the nth video stream
 | 
			
		||||
        VideoStream videoStream = getNthVideoStream(streams, Math.max(this.videoStreamIndex, 0));
 | 
			
		||||
 | 
			
		||||
        // Copy stream info
 | 
			
		||||
        command.add("-map_metadata");
 | 
			
		||||
        command.add("0");
 | 
			
		||||
        command.add("-movflags");
 | 
			
		||||
        command.add("use_metadata_tags");
 | 
			
		||||
        command.add("-c");
 | 
			
		||||
        command.add("copy");
 | 
			
		||||
 | 
			
		||||
        //Add streams to output file
 | 
			
		||||
        FFMpegHelper.addAudioStream(command, audioStream, false);
 | 
			
		||||
        FFMpegHelper.addSubtitleAndVideoStream(command, subtitleStream, videoStream, file);
 | 
			
		||||
 | 
			
		||||
        command.add(outFile);
 | 
			
		||||
        return command.toArray(new String[0]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -7,6 +7,7 @@ import net.knarcraft.ffmpegconverter.streams.VideoStream;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -34,7 +35,14 @@ public class MkvH264Converter extends AbstractConverter {
 | 
			
		||||
    @Override
 | 
			
		||||
    public String[] generateConversionCommand(String executable, File file, List<StreamObject> streams,
 | 
			
		||||
                                              String outFile) {
 | 
			
		||||
        List<String> command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, file.getName());
 | 
			
		||||
        List<String> command = new ArrayList<>();
 | 
			
		||||
        command.add(executable);
 | 
			
		||||
        command.add("-hwaccel");
 | 
			
		||||
        command.add("cuda");
 | 
			
		||||
        command.add("-hwaccel_output_format");
 | 
			
		||||
        command.add("cuda");
 | 
			
		||||
        command.add("-i");
 | 
			
		||||
        command.add(file.getName());
 | 
			
		||||
        if (this.debug) {
 | 
			
		||||
            FFMpegHelper.addDebugArguments(command, 50, 120);
 | 
			
		||||
        }
 | 
			
		||||
@@ -43,8 +51,14 @@ public class MkvH264Converter extends AbstractConverter {
 | 
			
		||||
        if (!filterStreamsByType(streams, VideoStream.class).isEmpty()) {
 | 
			
		||||
            command.add("-map");
 | 
			
		||||
            command.add("0:v");
 | 
			
		||||
            command.add("-vcodec");
 | 
			
		||||
            command.add("h264");
 | 
			
		||||
            command.add("-crf");
 | 
			
		||||
            command.add("28");
 | 
			
		||||
            command.add("-codec:v");
 | 
			
		||||
            command.add("h264_nvenc");
 | 
			
		||||
            command.add("-preset");
 | 
			
		||||
            command.add("slow");
 | 
			
		||||
            command.add("-movflags");
 | 
			
		||||
            command.add("+faststart");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Map audio if present
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,108 @@
 | 
			
		||||
package net.knarcraft.ffmpegconverter.converter;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.ffmpegconverter.streams.AudioStream;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.streams.StreamObject;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.streams.SubtitleStream;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.streams.VideoStream;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A converter solely for the purpose of converting video streams of MKV files into h264
 | 
			
		||||
 */
 | 
			
		||||
public class MkvH265ReducedConverter extends AbstractConverter {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Initializes variables used by the abstract converter
 | 
			
		||||
     *
 | 
			
		||||
     * @param ffprobePath <p>Path/command to ffprobe.</p>
 | 
			
		||||
     * @param ffmpegPath  <p>Path/command to ffmpeg.</p>
 | 
			
		||||
     */
 | 
			
		||||
    public MkvH265ReducedConverter(String ffprobePath, String ffmpegPath) {
 | 
			
		||||
        super("mkv");
 | 
			
		||||
        this.ffprobePath = ffprobePath;
 | 
			
		||||
        this.ffmpegPath = ffmpegPath;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String[] getValidFormats() {
 | 
			
		||||
        return new String[]{"mkv"};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String[] generateConversionCommand(String executable, File file, List<StreamObject> streams,
 | 
			
		||||
                                              String outFile) {
 | 
			
		||||
        List<String> command = new ArrayList<>();
 | 
			
		||||
        command.add(executable);
 | 
			
		||||
        command.add("-hwaccel");
 | 
			
		||||
        command.add("cuda");
 | 
			
		||||
        command.add("-hwaccel_output_format");
 | 
			
		||||
        command.add("cuda");
 | 
			
		||||
        command.add("-i");
 | 
			
		||||
        command.add(file.getName());
 | 
			
		||||
 | 
			
		||||
        if (this.debug) {
 | 
			
		||||
            FFMpegHelper.addDebugArguments(command, 50, 120);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Map video if present
 | 
			
		||||
        if (!filterStreamsByType(streams, VideoStream.class).isEmpty()) {
 | 
			
		||||
            command.add("-map");
 | 
			
		||||
            command.add("0:v");
 | 
			
		||||
            command.add("-codec:v");
 | 
			
		||||
            command.add("hevc_nvenc");
 | 
			
		||||
            command.add("-crf");
 | 
			
		||||
            command.add("28");
 | 
			
		||||
            command.add("-preset");
 | 
			
		||||
            command.add("slow");
 | 
			
		||||
            command.add("-tag:v");
 | 
			
		||||
            command.add("hvc1");
 | 
			
		||||
            command.add("-movflags");
 | 
			
		||||
            command.add("+faststart");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Map audio if present
 | 
			
		||||
        if (!filterStreamsByType(streams, AudioStream.class).isEmpty()) {
 | 
			
		||||
            command.add("-map");
 | 
			
		||||
            command.add("0:a");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Map subtitles if present
 | 
			
		||||
        if (hasInternalStreams(streams)) {
 | 
			
		||||
            command.add("-map");
 | 
			
		||||
            command.add("0:s");
 | 
			
		||||
            command.add("-c:s");
 | 
			
		||||
            command.add("copy");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        command.add("-map_metadata");
 | 
			
		||||
        command.add("0");
 | 
			
		||||
        command.add("-movflags");
 | 
			
		||||
        command.add("use_metadata_tags");
 | 
			
		||||
        command.add("-f");
 | 
			
		||||
        command.add("matroska");
 | 
			
		||||
 | 
			
		||||
        command.add(outFile);
 | 
			
		||||
        return command.toArray(new String[0]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks whether the processed file has any internal subtitle streams
 | 
			
		||||
     *
 | 
			
		||||
     * @param streams <p>All parsed streams for the video file</p>
 | 
			
		||||
     * @return <p>True if the file has at least one internal subtitle stream</p>
 | 
			
		||||
     */
 | 
			
		||||
    private boolean hasInternalStreams(List<StreamObject> streams) {
 | 
			
		||||
        for (StreamObject subtitleStream : filterStreamsByType(streams, SubtitleStream.class)) {
 | 
			
		||||
            if (((SubtitleStream) subtitleStream).isInternalSubtitle()) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -41,7 +41,7 @@ public class WebVideoConverter extends AbstractConverter {
 | 
			
		||||
 | 
			
		||||
        //Get first streams from the file
 | 
			
		||||
        SubtitleStream subtitleStream = getNthSubtitleStream(streams, 0);
 | 
			
		||||
        VideoStream videoStream = getFirstVideoStream(streams);
 | 
			
		||||
        VideoStream videoStream = getNthVideoStream(streams, 0);
 | 
			
		||||
        AudioStream audioStream = getNthAudioSteam(streams, 0);
 | 
			
		||||
 | 
			
		||||
        //Add streams to output
 | 
			
		||||
 
 | 
			
		||||
@@ -103,7 +103,9 @@ public class SubtitleStream extends AbstractStream implements StreamObject {
 | 
			
		||||
        return !titleLowercase.matches(".*si(ng|gn)s?[ &/a-z]+songs?.*") &&
 | 
			
		||||
                !titleLowercase.matches(".*songs?[ &/a-z]+si(gn|ng)s?.*") &&
 | 
			
		||||
                !titleLowercase.matches(".*forced.*") &&
 | 
			
		||||
                !titleLowercase.matches(".*s&s.*");
 | 
			
		||||
                !titleLowercase.matches(".*s&s.*") &&
 | 
			
		||||
                !titleLowercase.matches("signs?") &&
 | 
			
		||||
                !titleLowercase.matches("songs?");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user