Updates converters to use the new utility classes
This commit is contained in:
		@@ -16,9 +16,9 @@ import java.util.List;
 | 
			
		||||
 * Implements all methods which can be useful for any implementation of a converter.
 | 
			
		||||
 */
 | 
			
		||||
public abstract class AbstractConverter implements Converter {
 | 
			
		||||
    final boolean DEBUG = false;
 | 
			
		||||
    String ffprobePath;
 | 
			
		||||
    String ffmpegPath;
 | 
			
		||||
    final boolean DEBUG = false;
 | 
			
		||||
    String[] audioFormats;
 | 
			
		||||
    String[] videoFormats;
 | 
			
		||||
 | 
			
		||||
@@ -35,17 +35,12 @@ public abstract class AbstractConverter implements Converter {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets all valid input formats for the converter
 | 
			
		||||
     * @return <p>A list of valid input formats</p>
 | 
			
		||||
     */
 | 
			
		||||
    public abstract String[] getValidFormats();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Filters parsed streams into one of the stream types
 | 
			
		||||
     * @param streams <p>A list of stream objects.</p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param streams   <p>A list of stream objects.</p>
 | 
			
		||||
     * @param codecType <p>The codec type of the streams to select.</p>
 | 
			
		||||
     * @param <G> <p>The correct object type for the streams with the selected codec type.</p>
 | 
			
		||||
     * @param <G>       <p>The correct object type for the streams with the selected codec type.</p>
 | 
			
		||||
     * @return <p>A potentially shorter list of streams.</p>
 | 
			
		||||
     */
 | 
			
		||||
    @SuppressWarnings("unchecked")
 | 
			
		||||
@@ -63,7 +58,8 @@ public abstract class AbstractConverter implements Converter {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Filters and sorts audio streams according to chosen languages
 | 
			
		||||
     * @param audioStreams <p>A list of audio streams.</p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param audioStreams   <p>A list of audio streams.</p>
 | 
			
		||||
     * @param audioLanguages <p>A list of languages.</p>
 | 
			
		||||
     * @return <p>A list containing just audio tracks of chosen languages, sorted in order of languages.</p>
 | 
			
		||||
     */
 | 
			
		||||
@@ -83,8 +79,9 @@ public abstract class AbstractConverter implements Converter {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Filters and sorts subtitle streams according to chosen languages
 | 
			
		||||
     * @param subtitleStreams <p>A list of subtitle streams.</p>
 | 
			
		||||
     * @param subtitleLanguages <p>A list of languages.</p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param subtitleStreams      <p>A list of subtitle streams.</p>
 | 
			
		||||
     * @param subtitleLanguages    <p>A list of languages.</p>
 | 
			
		||||
     * @param preventSignsAndSongs <p>Whether partial subtitles should be avoided.</p>
 | 
			
		||||
     * @return <p>A list containing just subtitles of chosen languages, sorted in order of languages.</p>
 | 
			
		||||
     */
 | 
			
		||||
@@ -108,6 +105,7 @@ public abstract class AbstractConverter implements Converter {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Escapes special characters which can cause trouble for ffmpeg
 | 
			
		||||
     *
 | 
			
		||||
     * @param fileName <p>The filename to escape.</p>
 | 
			
		||||
     * @return <p>A filename with known special characters escaped.</p>
 | 
			
		||||
     */
 | 
			
		||||
@@ -120,13 +118,19 @@ public abstract class AbstractConverter implements Converter {
 | 
			
		||||
                .replace("[", "\\[");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets all valid input formats for the converter
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>A list of valid input formats</p>
 | 
			
		||||
     */
 | 
			
		||||
    public abstract String[] getValidFormats();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds audio to a command
 | 
			
		||||
     * @param command <p>The command to add audio to.</p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param command     <p>The command to add audio to.</p>
 | 
			
		||||
     * @param audioStream <p>The audio stream to be added.</p>
 | 
			
		||||
     * @param toStereo <p>Whether to convert the audio stream to stereo.</p>
 | 
			
		||||
     * @param toStereo    <p>Whether to convert the audio stream to stereo.</p>
 | 
			
		||||
     */
 | 
			
		||||
    void addAudioStreams(List<String> command, AudioStream audioStream, boolean toStereo) {
 | 
			
		||||
        if (audioStream != null) {
 | 
			
		||||
@@ -141,10 +145,11 @@ public abstract class AbstractConverter implements Converter {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds subtitles and video mapping to a command
 | 
			
		||||
     * @param command <p>The list containing the rest of the command.</p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param command        <p>The list containing the rest of the command.</p>
 | 
			
		||||
     * @param subtitleStream <p>The subtitle stream to be used.</p>
 | 
			
		||||
     * @param videoStream <p>The video stream to be used.</p>
 | 
			
		||||
     * @param file <p>The file to convert.</p>
 | 
			
		||||
     * @param videoStream    <p>The video stream to be used.</p>
 | 
			
		||||
     * @param file           <p>The file to convert.</p>
 | 
			
		||||
     */
 | 
			
		||||
    void addSubtitles(List<String> command, SubtitleStream subtitleStream, VideoStream videoStream, File file) {
 | 
			
		||||
        //No appropriate subtitle was found. Just add the video stream.
 | 
			
		||||
@@ -165,9 +170,10 @@ public abstract class AbstractConverter implements Converter {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds subtitle commands to a command list
 | 
			
		||||
     * @param command <p>The list containing the FFmpeg commands.</p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param command        <p>The list containing the FFmpeg commands.</p>
 | 
			
		||||
     * @param subtitleStream <p>The subtitle stream to add.</p>
 | 
			
		||||
     * @param videoStream <p>The video stream to burn the subtitle into.</p>
 | 
			
		||||
     * @param videoStream    <p>The video stream to burn the subtitle into.</p>
 | 
			
		||||
     */
 | 
			
		||||
    private void addSubtitle(List<String> command, SubtitleStream subtitleStream, VideoStream videoStream) {
 | 
			
		||||
        command.add("-map");
 | 
			
		||||
@@ -181,9 +187,10 @@ public abstract class AbstractConverter implements Converter {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds image subtitle commands to a command list
 | 
			
		||||
     * @param command <p>The list containing the FFmpeg commands.</p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param command        <p>The list containing the FFmpeg commands.</p>
 | 
			
		||||
     * @param subtitleStream <p>The subtitle stream to add.</p>
 | 
			
		||||
     * @param videoStream <p>The video stream to burn the subtitle into.</p>
 | 
			
		||||
     * @param videoStream    <p>The video stream to burn the subtitle into.</p>
 | 
			
		||||
     */
 | 
			
		||||
    private void addInternalImageSubtitle(List<String> command, SubtitleStream subtitleStream, VideoStream videoStream) {
 | 
			
		||||
        command.add("-filter_complex");
 | 
			
		||||
@@ -194,9 +201,10 @@ public abstract class AbstractConverter implements Converter {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds external image subtitle commands to a command list
 | 
			
		||||
     * @param command <p>The list containing the FFmpeg commands.</p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param command               <p>The list containing the FFmpeg commands.</p>
 | 
			
		||||
     * @param externalImageSubtitle <p>The external image subtitle stream to add.</p>
 | 
			
		||||
     * @param videoStream <p>The video stream to burn the subtitle into.</p>
 | 
			
		||||
     * @param videoStream           <p>The video stream to burn the subtitle into.</p>
 | 
			
		||||
     */
 | 
			
		||||
    private void addExternalImageSubtitle(List<String> command, SubtitleStream externalImageSubtitle,
 | 
			
		||||
                                          VideoStream videoStream) {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,24 +4,31 @@ 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 net.knarcraft.ffmpegconverter.utility.FileUtil;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.utility.OutputUtil;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public class AnimeConverter extends Converter {
 | 
			
		||||
    private String[] audioLang;
 | 
			
		||||
    private String[] subtitleLang;
 | 
			
		||||
    private boolean toStereo;
 | 
			
		||||
    private boolean preventSignsAndSongs;
 | 
			
		||||
/**
 | 
			
		||||
 * A converter mainly designed for converting anime to web-playable mp4
 | 
			
		||||
 */
 | 
			
		||||
public class AnimeConverter extends AbstractConverter {
 | 
			
		||||
    private final String[] audioLang;
 | 
			
		||||
    private final String[] subtitleLang;
 | 
			
		||||
    private final boolean toStereo;
 | 
			
		||||
    private final boolean preventSignsAndSongs;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiates a new anime converter
 | 
			
		||||
     * @param ffprobePath <p>Path/command to ffprobe.</p>
 | 
			
		||||
     * @param ffmpegPath <p>Path/command to ffmpeg.</p>
 | 
			
		||||
     * @param audioLang <p>List of wanted audio languages in descending order.</p>
 | 
			
		||||
     * @param subtitleLang <p>List of wanted subtitle languages in descending order.</p>
 | 
			
		||||
     * @param toStereo <p>Convert video with several audio channels to stereo.</p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param ffprobePath          <p>Path/command to ffprobe.</p>
 | 
			
		||||
     * @param ffmpegPath           <p>Path/command to ffmpeg.</p>
 | 
			
		||||
     * @param audioLang            <p>List of wanted audio languages in descending order.</p>
 | 
			
		||||
     * @param subtitleLang         <p>List of wanted subtitle languages in descending order.</p>
 | 
			
		||||
     * @param toStereo             <p>Convert video with several audio channels to stereo.</p>
 | 
			
		||||
     * @param preventSignsAndSongs <p>Prevent subtitles only converting signs and songs (not speech).</p>
 | 
			
		||||
     */
 | 
			
		||||
    public AnimeConverter(String ffprobePath, String ffmpegPath, String[] audioLang, String[] subtitleLang,
 | 
			
		||||
@@ -34,51 +41,49 @@ public class AnimeConverter extends Converter {
 | 
			
		||||
        this.preventSignsAndSongs = preventSignsAndSongs;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Converts the given file
 | 
			
		||||
     * @param file <p>The file to convert.</p>
 | 
			
		||||
     * @throws IOException <p>If the file cannot be converted.</p>
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public void convert(File file) throws IOException {
 | 
			
		||||
        processFile(file.getParentFile(), file);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reads streams from a file, and converts it to an mp4
 | 
			
		||||
     *
 | 
			
		||||
     * @param folder <p>The folder of the file to process.</p>
 | 
			
		||||
     * @param file <p>The file to process.</p>
 | 
			
		||||
     * @param file   <p>The file to process.</p>
 | 
			
		||||
     * @throws IOException <p>If the BufferedReader fails.</p>
 | 
			
		||||
     */
 | 
			
		||||
    private void processFile(File folder, File file) throws IOException {
 | 
			
		||||
        List<StreamObject> streams = probeFile(ffprobePath, file);
 | 
			
		||||
        List<StreamObject> streams = FFMpegHelper.probeFile(ffprobePath, file);
 | 
			
		||||
        if (streams.isEmpty()) {
 | 
			
		||||
            throw new IllegalArgumentException("The file has no valid streams. Please make sure the file exists and" +
 | 
			
		||||
                    " is not corrupt.");
 | 
			
		||||
        }
 | 
			
		||||
        String newPath = fileCollisionPrevention(folder.getAbsolutePath() + File.separator +
 | 
			
		||||
                stripExtension(file) + ".mp4", "mp4");
 | 
			
		||||
        printl();
 | 
			
		||||
        printl("Preparing to start process...");
 | 
			
		||||
        printl("Converting " + file);
 | 
			
		||||
        String newPath = FileUtil.getNonCollidingFilename(folder.getAbsolutePath() + File.separator +
 | 
			
		||||
                FileUtil.stripExtension(file) + ".mp4", "mp4");
 | 
			
		||||
        OutputUtil.println();
 | 
			
		||||
        OutputUtil.println("Preparing to start process...");
 | 
			
		||||
        OutputUtil.println("Converting " + file);
 | 
			
		||||
        String[] command = builderCommand(ffmpegPath, file.getName(), streams, newPath, file);
 | 
			
		||||
        ProcessBuilder processBuilder = new ProcessBuilder(command);
 | 
			
		||||
        convertProcess(processBuilder, folder);
 | 
			
		||||
        FFMpegHelper.convertProcess(processBuilder, folder);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Generates a command for a ProcessBuilder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param executable <p>The executable file for ffmpeg.</p>
 | 
			
		||||
     * @param fileName <p>The input file.</p>
 | 
			
		||||
     * @param streams <p>A list of ffprobe streams.</p>
 | 
			
		||||
     * @param outFile <p>The output file.</p>
 | 
			
		||||
     * @param fileName   <p>The input file.</p>
 | 
			
		||||
     * @param streams    <p>A list of ffprobe streams.</p>
 | 
			
		||||
     * @param outFile    <p>The output file.</p>
 | 
			
		||||
     * @return <p>A list of commands</p>
 | 
			
		||||
     */
 | 
			
		||||
    private String[] builderCommand(String executable, String fileName, List<StreamObject> streams, String outFile,
 | 
			
		||||
                                    File file) {
 | 
			
		||||
        List<String> command = ffmpegWebVideo(executable, fileName);
 | 
			
		||||
        List<String> command = FFMpegHelper.getFFMpegWebVideoCommand(executable, fileName);
 | 
			
		||||
 | 
			
		||||
        if (this.DEBUG) {
 | 
			
		||||
            addDebug(command, 50, 120);
 | 
			
		||||
            FFMpegHelper.addDebugArguments(command, 50, 120);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<AudioStream> audioStreams = filterAudioStreams(filterStreamsByType(streams, "audio"), audioLang);
 | 
			
		||||
@@ -102,77 +107,15 @@ public class AnimeConverter extends Converter {
 | 
			
		||||
            subtitleStream = subtitleStreams.get(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        addAudioStreams(command, audioStream);
 | 
			
		||||
        addSubtitles(command, subtitleStream, videoStream, fileName, file);
 | 
			
		||||
        addAudioStreams(command, audioStream, toStereo);
 | 
			
		||||
        addSubtitles(command, subtitleStream, videoStream, file);
 | 
			
		||||
 | 
			
		||||
        command.add(outFile);
 | 
			
		||||
        return command.toArray(new String[0]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds audio to a command
 | 
			
		||||
     * @param command <p>The command to add audio to.</p>
 | 
			
		||||
     * @param audioStream <p>The audio stream to be added.</p>
 | 
			
		||||
     */
 | 
			
		||||
    private void addAudioStreams(List<String> command, AudioStream audioStream) {
 | 
			
		||||
        if (audioStream != null) {
 | 
			
		||||
            command.add("-map");
 | 
			
		||||
            command.add("0:" + audioStream.getAbsoluteIndex());
 | 
			
		||||
            if (toStereo && audioStream.getChannels() > 2) {
 | 
			
		||||
                command.add("-af");
 | 
			
		||||
                command.add("pan=stereo|FL=FC+0.30*FL+0.30*BL|FR=FC+0.30*FR+0.30*BR");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds subtitles and video mapping to a command
 | 
			
		||||
     * @param command <p>The list containing the rest of the command.</p>
 | 
			
		||||
     * @param subtitleStream <p>The subtitle stream to be used.</p>
 | 
			
		||||
     * @param videoStream <p>The video stream to be used.</p>
 | 
			
		||||
     * @param fileName <p>The name of the file which is converted.</p>
 | 
			
		||||
     * @param file <p>The file to convert.</p>
 | 
			
		||||
     */
 | 
			
		||||
    private void addSubtitles(List<String> command, SubtitleStream subtitleStream, VideoStream videoStream,
 | 
			
		||||
                              String fileName, File file) {
 | 
			
		||||
        File folder = file.getParentFile();
 | 
			
		||||
        String externalImageSubtitle = hasExternalImageSubtitle(folder.getAbsolutePath(), fileName);
 | 
			
		||||
        String externalSubtitle = hasExternalSubtitle(folder.getAbsolutePath(), fileName);
 | 
			
		||||
        if (subtitleStream != null && subtitleStream.getIsImageSubtitle()) {
 | 
			
		||||
            command.add("-filter_complex");
 | 
			
		||||
            String filter = String.format("[0:v:%d][0:%d]overlay", videoStream.getAbsoluteIndex(),
 | 
			
		||||
                    subtitleStream.getAbsoluteIndex());
 | 
			
		||||
            command.add(filter);
 | 
			
		||||
        } else if (subtitleStream != null) {
 | 
			
		||||
            command.add("-map");
 | 
			
		||||
            command.add(String.format("0:%d", videoStream.getAbsoluteIndex()));
 | 
			
		||||
            command.add("-vf");
 | 
			
		||||
            String safeFileName = escapeSpecialCharactersInFileName(fileName);
 | 
			
		||||
            String subtitleCommand = String.format("subtitles='%s':si=%d", safeFileName,
 | 
			
		||||
                    subtitleStream.getRelativeIndex());
 | 
			
		||||
            command.add(subtitleCommand);
 | 
			
		||||
        } else if (!externalSubtitle.equals("")) {
 | 
			
		||||
            command.add("-map");
 | 
			
		||||
            command.add(String.format("0:%d", videoStream.getAbsoluteIndex()));
 | 
			
		||||
            command.add("-vf");
 | 
			
		||||
            String subtitleCommand = String.format("subtitles='%s'", escapeSpecialCharactersInFileName(externalSubtitle));
 | 
			
		||||
            command.add(subtitleCommand);
 | 
			
		||||
        } else if (!externalImageSubtitle.equals("")) {
 | 
			
		||||
                command.add("-i");
 | 
			
		||||
                command.add(stripExtension(fileName) + externalImageSubtitle);
 | 
			
		||||
                command.add("-filter_complex");
 | 
			
		||||
                command.add(String.format("[1:s]scale=width=1272:height=720,crop=w=1272:h=720:x=0:y=out_h[sub];[%d:v]" +
 | 
			
		||||
                                "[sub]overlay", videoStream.getAbsoluteIndex()));
 | 
			
		||||
                command.add("-profile:v");
 | 
			
		||||
                command.add("baseline");
 | 
			
		||||
        } else {
 | 
			
		||||
            command.add("-map");
 | 
			
		||||
            command.add(String.format("0:%d", videoStream.getAbsoluteIndex()));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String[] getValidFormats() {
 | 
			
		||||
        return VIDEO_FORMATS;
 | 
			
		||||
        return videoFormats;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,19 +2,25 @@ package net.knarcraft.ffmpegconverter.converter;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.ffmpegconverter.streams.AudioStream;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.streams.StreamObject;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
 | 
			
		||||
import net.knarcraft.ffmpegconverter.utility.FileUtil;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public class AudioConverter extends Converter {
 | 
			
		||||
    private String newExt;
 | 
			
		||||
/**
 | 
			
		||||
 * A converter for converting audio files
 | 
			
		||||
 */
 | 
			
		||||
public class AudioConverter extends AbstractConverter {
 | 
			
		||||
    private final String newExt;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiates a new audio converter
 | 
			
		||||
     *
 | 
			
		||||
     * @param ffprobePath <p>Path/command to ffprobe.</p>
 | 
			
		||||
     * @param ffmpegPath <p>Path/command to ffmpeg.</p>
 | 
			
		||||
     * @param newExt <p>The extension of the new file.</p>
 | 
			
		||||
     * @param ffmpegPath  <p>Path/command to ffmpeg.</p>
 | 
			
		||||
     * @param newExt      <p>The extension of the new file.</p>
 | 
			
		||||
     */
 | 
			
		||||
    public AudioConverter(String ffprobePath, String ffmpegPath, String newExt) {
 | 
			
		||||
        this.ffprobePath = ffprobePath;
 | 
			
		||||
@@ -24,30 +30,32 @@ public class AudioConverter extends Converter {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Processes a file conversion
 | 
			
		||||
     *
 | 
			
		||||
     * @param folder <p>The work folder containing the file.</p>
 | 
			
		||||
     * @param file <p>The file to convert.</p>
 | 
			
		||||
     * @param file   <p>The file to convert.</p>
 | 
			
		||||
     * @param newExt <p>The extension of the new file.</p>
 | 
			
		||||
     * @throws IOException <p>If the file cannot be converted.</p>
 | 
			
		||||
     */
 | 
			
		||||
    private void processFile(File folder, File file, String newExt) throws IOException {
 | 
			
		||||
        List<StreamObject> streams = probeFile(ffprobePath, file);
 | 
			
		||||
        List<StreamObject> streams = FFMpegHelper.probeFile(ffprobePath, file);
 | 
			
		||||
        if (streams.size() == 0) {
 | 
			
		||||
            throw new IllegalArgumentException("The file has no streams");
 | 
			
		||||
        }
 | 
			
		||||
        String newPath = stripExtension(file) + "." + newExt;
 | 
			
		||||
        convertProcess(new ProcessBuilder(builderCommand(ffmpegPath, file.getName(), streams, newPath)), folder);
 | 
			
		||||
        String newPath = FileUtil.stripExtension(file) + "." + newExt;
 | 
			
		||||
        FFMpegHelper.convertProcess(new ProcessBuilder(builderCommand(ffmpegPath, file.getName(), streams, newPath)), folder);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Generates a command for a ProcessBuilder.
 | 
			
		||||
     *
 | 
			
		||||
     * @param executable <p>The executable file for ffmpeg.</p>
 | 
			
		||||
     * @param fileName <p>The input file.</p>
 | 
			
		||||
     * @param streams <p>A list of ffprobe streams.</p>
 | 
			
		||||
     * @param outFile <p>The output file.</p>
 | 
			
		||||
     * @param fileName   <p>The input file.</p>
 | 
			
		||||
     * @param streams    <p>A list of ffprobe streams.</p>
 | 
			
		||||
     * @param outFile    <p>The output file.</p>
 | 
			
		||||
     * @return <p>A list of commands.</p>
 | 
			
		||||
     */
 | 
			
		||||
    private String[] builderCommand(String executable, String fileName, List<StreamObject> streams, String outFile) {
 | 
			
		||||
        List<String> command = generalFile(executable, fileName);
 | 
			
		||||
        List<String> command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, fileName);
 | 
			
		||||
        List<AudioStream> audioStreams = filterStreamsByType(streams, "audio");
 | 
			
		||||
        AudioStream audioStream = null;
 | 
			
		||||
        if (audioStreams.size() > 0) {
 | 
			
		||||
@@ -63,7 +71,7 @@ public class AudioConverter extends Converter {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String[] getValidFormats() {
 | 
			
		||||
        return AUDIO_FORMATS;
 | 
			
		||||
        return audioFormats;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@ public interface Converter {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Converts the given file
 | 
			
		||||
     *
 | 
			
		||||
     * @param file <p>The file to convert.</p>
 | 
			
		||||
     * @throws IOException <p>If the file cannot be converted.</p>
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -2,20 +2,27 @@ 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 net.knarcraft.ffmpegconverter.utility.FileUtil;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public class VideoConverter extends Converter {
 | 
			
		||||
    private String newExt;
 | 
			
		||||
/**
 | 
			
		||||
 * A converter for converting video files
 | 
			
		||||
 */
 | 
			
		||||
public class VideoConverter extends AbstractConverter {
 | 
			
		||||
    private final String newExt;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiates a new video converter
 | 
			
		||||
     *
 | 
			
		||||
     * @param ffprobePath <p>Path/command to ffprobe.</p>
 | 
			
		||||
     * @param ffmpegPath <p>Path/command to ffmpeg.</p>
 | 
			
		||||
     * @param newExt <p>The extension of the new file.</p>
 | 
			
		||||
     * @param ffmpegPath  <p>Path/command to ffmpeg.</p>
 | 
			
		||||
     * @param newExt      <p>The extension of the new file.</p>
 | 
			
		||||
     */
 | 
			
		||||
    public VideoConverter(String ffprobePath, String ffmpegPath, String newExt) {
 | 
			
		||||
        this.ffprobePath = ffprobePath;
 | 
			
		||||
@@ -25,52 +32,56 @@ public class VideoConverter extends Converter {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reads streams from a file, and converts it to an mp4
 | 
			
		||||
     *
 | 
			
		||||
     * @param folder <p>The folder of the file to process.</p>
 | 
			
		||||
     * @param file <p>The file to process.</p>
 | 
			
		||||
     * @param file   <p>The file to process.</p>
 | 
			
		||||
     * @throws IOException <p>If the BufferedReader fails.</p>
 | 
			
		||||
     */
 | 
			
		||||
    private void processFile(File folder, File file, String newExt) throws IOException {
 | 
			
		||||
        List<StreamObject> streams = probeFile(ffprobePath, file);
 | 
			
		||||
        List<StreamObject> streams = FFMpegHelper.probeFile(ffprobePath, file);
 | 
			
		||||
        if (streams.size() == 0) {
 | 
			
		||||
            throw new IllegalArgumentException("The file has no streams");
 | 
			
		||||
        }
 | 
			
		||||
        String newPath = fileCollisionPrevention(folder.getAbsolutePath() + File.separator + stripExtension(file) + "." + newExt, newExt);
 | 
			
		||||
        convertProcess(new ProcessBuilder(builderCommand(ffmpegPath, file.getName(), streams, newPath, folder)), folder);
 | 
			
		||||
        String newPath = FileUtil.getNonCollidingFilename(folder.getAbsolutePath() + File.separator +
 | 
			
		||||
                FileUtil.stripExtension(file) + "." + newExt, newExt);
 | 
			
		||||
        FFMpegHelper.convertProcess(new ProcessBuilder(builderCommand(ffmpegPath, file, streams, newPath)), folder);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Generates a command for a ProcessBuilder
 | 
			
		||||
     *
 | 
			
		||||
     * @param executable <p>The executable file for ffmpeg.</p>
 | 
			
		||||
     * @param fileName <p>The input file.</p>
 | 
			
		||||
     * @param streams <p>A list of ffprobe streams.</p>
 | 
			
		||||
     * @param outFile <p>The output file.</p>
 | 
			
		||||
     * @param file       <p>The input file.</p>
 | 
			
		||||
     * @param streams    <p>A list of ffprobe streams.</p>
 | 
			
		||||
     * @param outFile    <p>The output file.</p>
 | 
			
		||||
     * @return <p>A list of commands</p>
 | 
			
		||||
     */
 | 
			
		||||
    private String[] builderCommand(String executable, String fileName, List<StreamObject> streams, String outFile, File folder) {
 | 
			
		||||
        List<String> command = generalFile(executable, fileName);
 | 
			
		||||
    private String[] builderCommand(String executable, File file, List<StreamObject> streams, String outFile) {
 | 
			
		||||
        List<String> command = FFMpegHelper.getFFMpegGeneralFileCommand(executable, file.getName());
 | 
			
		||||
 | 
			
		||||
        if (this.DEBUG) {
 | 
			
		||||
            addDebug(command, 50, 120);
 | 
			
		||||
            FFMpegHelper.addDebugArguments(command, 50, 120);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<AudioStream> audioStreams = filterStreamsByType(streams, "audio");
 | 
			
		||||
        List<VideoStream> videoStreams = filterStreamsByType(streams, "video");
 | 
			
		||||
        List<SubtitleStream> subtitleStreams = filterStreamsByType(streams, "subtitle");
 | 
			
		||||
 | 
			
		||||
        VideoStream videoStream = null;
 | 
			
		||||
        AudioStream audioStream = null;
 | 
			
		||||
        SubtitleStream subtitleStream = null;
 | 
			
		||||
        if (videoStreams.size() > 0) {
 | 
			
		||||
            videoStream = videoStreams.get(0);
 | 
			
		||||
        }
 | 
			
		||||
        if (audioStreams.size() > 0) {
 | 
			
		||||
            audioStream = audioStreams.get(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        boolean videoAdded = addSubtitles(command, folder, fileName, videoStream);
 | 
			
		||||
 | 
			
		||||
        if (!videoAdded && videoStreams.size() > 0) {
 | 
			
		||||
            command.add("-map");
 | 
			
		||||
            command.add("0:" + videoStream);
 | 
			
		||||
        if (subtitleStreams.size() > 0) {
 | 
			
		||||
            subtitleStream = subtitleStreams.get(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        addSubtitles(command, subtitleStream, videoStream, file);
 | 
			
		||||
 | 
			
		||||
        if (audioStreams.size() > 0) {
 | 
			
		||||
            command.add("-map");
 | 
			
		||||
            command.add("0:" + audioStream);
 | 
			
		||||
@@ -82,39 +93,9 @@ public class VideoConverter extends Converter {
 | 
			
		||||
        return command.toArray(new String[0]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds subtitles to a command
 | 
			
		||||
     * @param command <p>The command to add to.</p>
 | 
			
		||||
     * @param folder <p>The folder containing the file to be converted.</p>
 | 
			
		||||
     * @param fileName <p>The name of the file to be converted.</p>
 | 
			
		||||
     * @param videoStream <p>The video stream to be added.</p>
 | 
			
		||||
     * @return <p>True if a video stream was added.</p>
 | 
			
		||||
     */
 | 
			
		||||
    private boolean addSubtitles(List<String> command, File folder, String fileName, VideoStream videoStream) {
 | 
			
		||||
        String externalSubtitle = hasExternalSubtitle(folder.getAbsolutePath(), fileName);
 | 
			
		||||
        String externalImageSubtitle = hasExternalImageSubtitle(folder.getAbsolutePath(), fileName);
 | 
			
		||||
        if (!externalSubtitle.equals("")) {
 | 
			
		||||
            command.add("-vf");
 | 
			
		||||
            command.add("subtitles=" + externalSubtitle);
 | 
			
		||||
        } else if (!externalImageSubtitle.equals("")) {
 | 
			
		||||
            command.add("-i");
 | 
			
		||||
            command.add(externalImageSubtitle);
 | 
			
		||||
            if (this.DEBUG) {
 | 
			
		||||
                addDebug(command, 50, 120);
 | 
			
		||||
            }
 | 
			
		||||
            //TODO: Scale subtitles to video
 | 
			
		||||
            command.add("-filter_complex");
 | 
			
		||||
            command.add("[1:s]scale=width=1920:height=800,crop=w=1920:h=800:x=0:y=out_h[sub];[" + videoStream +
 | 
			
		||||
                    ":v][sub]overlay");
 | 
			
		||||
            command.add("-profile:v");
 | 
			
		||||
            command.add("baseline");
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Converts the audio of a video to stereo
 | 
			
		||||
     *
 | 
			
		||||
     * @param command <p>The command list to add to.</p>
 | 
			
		||||
     */
 | 
			
		||||
    private void convertToStereo(List<String> command) {
 | 
			
		||||
@@ -124,7 +105,7 @@ public class VideoConverter extends Converter {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String[] getValidFormats() {
 | 
			
		||||
        return VIDEO_FORMATS;
 | 
			
		||||
        return videoFormats;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user