diff --git a/src/main/java/net/knarcraft/ffmpegconverter/converter/AnimeConverter.java b/src/main/java/net/knarcraft/ffmpegconverter/converter/AnimeConverter.java index b800bf5..388550d 100644 --- a/src/main/java/net/knarcraft/ffmpegconverter/converter/AnimeConverter.java +++ b/src/main/java/net/knarcraft/ffmpegconverter/converter/AnimeConverter.java @@ -7,7 +7,6 @@ import net.knarcraft.ffmpegconverter.streams.VideoStream; import java.io.File; import java.io.IOException; -import java.util.Arrays; import java.util.List; public class AnimeConverter extends Converter { @@ -15,17 +14,18 @@ public class AnimeConverter extends Converter { private String[] subtitleLang; private boolean toStereo; private boolean preventSignsAndSongs; - private boolean debug = false; /** - * @param ffprobePath Path/command to ffprobe - * @param ffmpegPath Path/command to ffmpeg - * @param audioLang List of wanted audio languages in descending order - * @param subtitleLang List of wanted subtitle languages in descending order - * @param toStereo Convert video with several audio channels to stereo - * @param preventSignsAndSongs Prevent subtitles only converting signs and songs (not speech) + * Instantiates a new anime converter + * @param ffprobePath
Path/command to ffprobe.
+ * @param ffmpegPathPath/command to ffmpeg.
+ * @param audioLangList of wanted audio languages in descending order.
+ * @param subtitleLangList of wanted subtitle languages in descending order.
+ * @param toStereoConvert video with several audio channels to stereo.
+ * @param preventSignsAndSongsPrevent subtitles only converting signs and songs (not speech).
*/ - public AnimeConverter(String ffprobePath, String ffmpegPath, String[] audioLang, String[] subtitleLang, boolean toStereo, boolean preventSignsAndSongs) { + public AnimeConverter(String ffprobePath, String ffmpegPath, String[] audioLang, String[] subtitleLang, + boolean toStereo, boolean preventSignsAndSongs) { this.ffprobePath = ffprobePath; this.ffmpegPath = ffmpegPath; this.audioLang = audioLang; @@ -34,21 +34,26 @@ public class AnimeConverter extends Converter { this.preventSignsAndSongs = preventSignsAndSongs; } + /** + * Converts the given file + * @param fileThe file to convert.
+ * @throws IOExceptionIf the file cannot be converted.
+ */ public void convert(File file) throws IOException { processFile(file.getParentFile(), file); } /** - * Reads streams from a file, and converts it to an mp4. - * - * @param folder The folder of the file to process - * @param file The file to process - * @throws IOException If the BufferedReader fails + * Reads streams from a file, and converts it to an mp4 + * @param folderThe folder of the file to process.
+ * @param fileThe file to process.
+ * @throws IOExceptionIf the BufferedReader fails.
*/ private void processFile(File folder, File file) throws IOException { ListThe executable file for ffmpeg.
+ * @param fileNameThe input file.
+ * @param streamsA list of ffprobe streams.
+ * @param outFileThe output file.
+ * @returnA list of commands
*/ private String[] builderCommand(String executable, String fileName, ListThe command to add audio to.
+ * @param audioStreamThe audio stream to be added.
+ */ + private void addAudioStreams(ListThe list containing the rest of the command.
+ * @param subtitleStreamThe subtitle stream to be used.
+ * @param videoStreamThe video stream to be used.
+ * @param fileNameThe name of the file which is converted.
+ */ + private void addSubtitles(ListPath/command to ffprobe.
+ * @param ffmpegPathPath/command to ffmpeg.
+ * @param newExtThe extension of the new file.
+ */ public AudioConverter(String ffprobePath, String ffmpegPath, String newExt) { this.ffprobePath = ffprobePath; this.ffmpegPath = ffmpegPath; @@ -17,11 +23,11 @@ public class AudioConverter extends Converter { } /** - * Reads streams from a file, and converts it to an mp4. - * - * @param folder The folder of the file to process - * @param file The file to process - * @throws IOException If the BufferedReader fails + * Processes a file conversion + * @param folderThe work folder containing the file.
+ * @param fileThe file to convert.
+ * @param newExtThe extension of the new file.
+ * @throws IOExceptionIf the file cannot be converted.
*/ private void processFile(File folder, File file, String newExt) throws IOException { ListThe executable file for ffmpeg.
+ * @param fileNameThe input file.
+ * @param streamsA list of ffprobe streams.
+ * @param outFileThe output file.
+ * @returnA list of commands.
*/ private String[] builderCommand(String executable, String fileName, ListThe path/command to ffprobe.
+ * @param fileThe file to probe.
+ * @returnA list of StreamObjects.
+ * @throws IOExceptionIf the process can't be read.
*/ static ListThe path the file should ideally be saved at.
+ * @param extensionThe extension of the target file.
+ * @returnA filename guaranteed not to collide with other files.
+ */ static String fileCollisionPrevention(String targetPath, String extension) { - File file = new File(targetPath); + File newFile = new File(targetPath); + String fileName = stripExtension(targetPath); int i = 1; - while (file.exists()) { - file = new File(stripExtension(file) + "(" + i + ")" + "." + extension); + while (newFile.exists()) { + newFile = new File(fileName + "(" + i++ + ")" + "." + extension); } - return file.toString(); + return newFile.toString(); } /** * Starts and prints output of a process - * @param process The process to run - * @param folder The folder the process should run in - * @throws IOException If the process can't be read + * @param processThe process to run.
+ * @param folderThe folder the process should run in.
+ * @throws IOExceptionIf the process can't be read.
*/ static void convertProcess(ProcessBuilder process, File folder) throws IOException { print("Command to be run: "); @@ -99,15 +107,14 @@ public abstract class Converter { printl(read); } } - printl("FFMPEG is finished."); + printl("Process is finished."); } /** - * Reads from a process reader. - * - * @param reader The reader of a process - * @return The output from the read - * @throws IOException On reader failure + * Reads from a process reader + * @param readerThe reader of a process.
+ * @returnThe output from the read.
+ * @throws IOExceptionOn reader failure.
*/ private static String read(BufferedReader reader, String spacer) throws IOException { String line; @@ -119,7 +126,10 @@ public abstract class Converter { } /** - * @return A base list of ffmpeg commands for converting a video for web + * Creates a list containing all required arguments for converting a video to a web playable video + * @param executableThe executable to use (ffmpeg/ffprobe).
+ * @param fileNameThe name of the file to execute on.
+ * @returnA base list of ffmpeg commands for converting a video for web
*/ static ListThe executable to use (ffmpeg/ffprobe).
+ * @param fileNameThe name of the file to execute on.
+ * @returnA base list of ffmpeg commands for converting a file.
*/ static ListThe list containing the command to run.
+ * @param startThe offset before converting.
+ * @param lengthThe offset for stopping the conversion.
*/ static void addDebug(ListA list of ffprobe indexes.
+ * @returnAn integer list containing just the wanted indexes
*/ private static ListA list.
+ * @param pA predicate
+ * @paramThe type of the list and the predicate.
* @return True if the list have an element for which the predicate is true */ private staticThe string containing the substrings.
+ * @param startThe substring before the wanted substring.
+ * @param endThe substring after the wanted substring.
+ * @returnA list of all occurrences of the substring.
*/ private static String[] stringBetween(String string, String start, String end) { int startPos = string.indexOf(start) + start.length(); @@ -211,12 +222,11 @@ public abstract class Converter { } /** - * Finds a substring between two substrings in a string. - * - * @param string The string containing the substrings - * @param start The substring before the wanted substring - * @param end The substring after the wanted substring - * @return The wanted substring. + * Finds a substring between two substrings in a string + * @param stringThe string containing the substrings.
+ * @param startThe substring before the wanted substring.
+ * @param endThe substring after the wanted substring.
+ * @returnThe wanted substring.
*/ private static String stringBetweenSingle(String string, String start, String end) { int startPos = string.indexOf(start) + start.length(); @@ -228,8 +238,8 @@ public abstract class Converter { /** * Gets filename without extension from File object - * @param file A file object - * @return A filename + * @param fileA file object.
+ * @returnA filename.
*/ static String stripExtension(File file) { return file.getName().substring(0, file.getName().lastIndexOf('.')); @@ -237,8 +247,8 @@ public abstract class Converter { /** * Removes the extension from a file name - * @param file A filename - * @return A filename without its extension + * @param fileA filename.
+ * @returnA filename without its extension.
*/ static String stripExtension(String file) { return file.substring(0, file.lastIndexOf('.')); @@ -246,28 +256,27 @@ public abstract class Converter { /** * Combines two arrays to one - * - * @param a The first array - * @param b The second array - * @paramThe first array.
+ * @param listBThe second array.
+ * @paramThe type of the two lists.
+ * @returnA new array containing all elements from the two arrays.
*/ - public staticA list of stream objects.
+ * @param codecTypeThe codec type of the streams to select.
+ * @paramThe correct object type for the streams with the selected codec type.
+ * @returnA potentially shorter list of streams.
*/ staticA list of audio streams.
+ * @param audioLanguagesA list of languages.
+ * @returnA list containing just audio tracks of chosen languages, sorted in order of languages.
*/ static ListA list of subtitle streams.
+ * @param subtitleLanguagesA list of languages.
+ * @param preventSignsAndSongsWhether partial subtitles should be avoided.
+ * @returnA list containing just subtitles of chosen languages, sorted in order of languages.
*/ static ListA list of all streams for the current file.
+ * @returnA list of StreamObjects.
*/ private static ListA list of parameters belonging to an video stream.
+ * @param relativeIndexThe relative index of the video stream.
+ * @returnA SubtitleStream object.
+ * @throws NumberFormatExceptionIf codec index contains a non-numeric value.
*/ private static VideoStream parseVideoStream(String[] streamParts, int relativeIndex) throws NumberFormatException { String codec = null; @@ -371,10 +380,10 @@ public abstract class Converter { /** * Parses a list of audio stream parameters to an audio stream object - * @param streamParts A list of parameters belonging to an audio stream - * @param relativeIndex The relative index of the audio stream - * @return A SubtitleStream object - * @throws NumberFormatException If codec index contains a non-numeric value + * @param streamPartsA list of parameters belonging to an audio stream.
+ * @param relativeIndexThe relative index of the audio stream.
+ * @returnA SubtitleStream object.
+ * @throws NumberFormatExceptionIf codec index contains a non-numeric value.
*/ private static AudioStream parseAudioStream(String[] streamParts, int relativeIndex) throws NumberFormatException { String codec = null; @@ -400,12 +409,13 @@ public abstract class Converter { /** * Parses a list of subtitle stream parameters to a subtitle stream object - * @param streamParts A list of parameters belonging to a subtitle stream - * @param relativeIndex The relative index of the subtitle - * @return A SubtitleStream object - * @throws NumberFormatException If codec index contains a non-numeric value + * @param streamPartsA list of parameters belonging to a subtitle stream.
+ * @param relativeIndexThe relative index of the subtitle.
+ * @returnA SubtitleStream object.
+ * @throws NumberFormatExceptionIf codec index contains a non-numeric value.
*/ - private static SubtitleStream parseSubtitleStream(String[] streamParts, int relativeIndex) throws NumberFormatException { + private static SubtitleStream parseSubtitleStream(String[] streamParts, int relativeIndex) + throws NumberFormatException { String codecName = null; int absoluteIndex = -1; String language = null; @@ -424,6 +434,11 @@ public abstract class Converter { return new SubtitleStream(codecName, absoluteIndex, relativeIndex, language, title); } + /** + * Escapes special characters which can cause trouble for ffmpeg + * @param fileNameThe filename to escape.
+ * @returnA filename with known special characters escaped.
+ */ static String escapeSpecialCharactersInFileName(String fileName) { return fileName.replace("'", "\\\\\\'") .replace(",", "\\\\\\,") @@ -431,18 +446,36 @@ public abstract class Converter { .replace("]", "\\]") .replace("[", "\\["); } - + + /** + * Prints something to the commandline efficiently + * @param inputThe text to print.
+ * @throws IOExceptionIf a write is not possible.
+ */ static void print(String input) throws IOException { if (!input.equals("")) { writer.write(input); writer.flush(); } } - + + /** + * Prints something and a newline to the commandline efficiently + * @param inputThe text to print.
+ * @throws IOExceptionIf a write is not possible.
+ */ static void printl(String input) throws IOException { if (!input.equals("")) { writer.write(input); } + printl(); + } + + /** + * Prints a newline + * @throws IOExceptionIf a write is not possible.
+ */ + static void printl() throws IOException { writer.newLine(); writer.flush(); } diff --git a/src/main/java/net/knarcraft/ffmpegconverter/converter/VideoConverter.java b/src/main/java/net/knarcraft/ffmpegconverter/converter/VideoConverter.java index 39a70b4..a8a3874 100644 --- a/src/main/java/net/knarcraft/ffmpegconverter/converter/VideoConverter.java +++ b/src/main/java/net/knarcraft/ffmpegconverter/converter/VideoConverter.java @@ -10,8 +10,13 @@ import java.util.List; public class VideoConverter extends Converter { private String newExt; - private boolean debug = false; + /** + * Instantiates a new video converter + * @param ffprobePathPath/command to ffprobe.
+ * @param ffmpegPathPath/command to ffmpeg.
+ * @param newExtThe extension of the new file.
+ */ public VideoConverter(String ffprobePath, String ffmpegPath, String newExt) { this.ffprobePath = ffprobePath; this.ffmpegPath = ffmpegPath; @@ -19,11 +24,10 @@ public class VideoConverter extends Converter { } /** - * Reads streams from a file, and converts it to an mp4. - * - * @param folder The folder of the file to process - * @param file The file to process - * @throws IOException If the BufferedReader fails + * Reads streams from a file, and converts it to an mp4 + * @param folderThe folder of the file to process.
+ * @param fileThe file to process.
+ * @throws IOExceptionIf the BufferedReader fails.
*/ private void processFile(File folder, File file, String newExt) throws IOException { ListThe executable file for ffmpeg.
+ * @param fileNameThe input file.
+ * @param streamsA list of ffprobe streams.
+ * @param outFileThe output file.
+ * @returnA list of commands
*/ private String[] builderCommand(String executable, String fileName, ListThe command to add to.
+ * @param folderThe folder containing the file to be converted.
+ * @param fileNameThe name of the file to be converted.
+ * @param videoStreamThe video stream to be added.
+ * @returnTrue if a video stream was added.
+ */ + private boolean addSubtitles(ListThe command list to add to.
+ */ + private void convertToStereo(ListThe directory containing the file.
+ * @param fileThe file to be converted.
+ * @returnThe extension of the subtitle or empty if no subtitle was found.
+ */ private String hasExternalImageSubtitle(String directory, String file) { String path = stripExtension(file); - for (String s : new String[] {".idx", ".sub"}) { - if (new File(directory + File.separator + path + s).exists()) { - return s; + for (String subtitleExtension : new String[] {".idx", ".sub"}) { + if (new File(directory + File.separator + path + subtitleExtension).exists()) { + return subtitleExtension; } } return ""; } + /** + * Checks whether there exists an external subtitle with the same filename as the file + * @param directoryThe directory containing the file.
+ * @param fileThe file to be converted.
+ * @returnThe extension of the subtitle or empty if no subtitle was found.
+ */ private String hasExternalSubtitle(String directory, String file) { String path = stripExtension(file); - for (String s : new String[] {".srt", ".ass"}) { - if (new File(directory + File.separator + path + s).exists()) { - return s; + for (String subtitleExtension : new String[] {".srt", ".ass"}) { + if (new File(directory + File.separator + path + subtitleExtension).exists()) { + return subtitleExtension; } } return "";