diff --git a/src/main/java/net/knarcraft/ffmpegconverter/converter/Converter.java b/src/main/java/net/knarcraft/ffmpegconverter/converter/Converter.java index 8c0aba7..8fab2dd 100644 --- a/src/main/java/net/knarcraft/ffmpegconverter/converter/Converter.java +++ b/src/main/java/net/knarcraft/ffmpegconverter/converter/Converter.java @@ -1,515 +1,17 @@ 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 java.io.BufferedReader; -import java.io.BufferedWriter; import java.io.File; import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.function.Predicate; /** - * Implements all methods which can be usefull for any implementation of a converter. + * This interface describes a file converter */ -public abstract class Converter { - String ffprobePath; - String ffmpegPath; - boolean DEBUG = false; - - private static final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); - - private static final String PROBE_SPLIT_CHARACTER = "øæåÆØå"; - - public abstract String[] getValidFormats(); - public abstract void convert(File file) throws IOException; - - final String[] AUDIO_FORMATS = new String[] {".3gp", ".aa", ".aac", ".aax", ".act", ".aiff", ".amr", ".ape", ".au", - ".awb", ".dct", ".dss", ".dvf", ".flac", ".gsm", ".iklax", ".ivs", ".m4a", ".m4b", ".m4p", ".mmf", ".mp3", - ".mpc", ".msv", ".ogg", ".oga", ".mogg", ".opus", ".ra", ".rm", ".raw", ".sln", ".tta", ".vox", ".wav", - ".wma", ".wv", ".webm", ".8svx"}; - final String[] VIDEO_FORMATS = new String[] {".avi", ".mpg", ".mpeg", ".mkv", ".wmv", ".flv", ".webm", ".3gp", - ".rmvb", ".3gpp", ".mts", ".m4v", ".mov", ".rm", ".asf", ".mp4", ".vob", ".ogv", ".drc", ".qt", ".yuv", - ".asm", ".m4p", ".mp2", ".mpe", ".mpv", ".m2v", ".svi", ".3g2", ".roq", ".nsv"}; +public interface Converter { /** - * Gets streams from a file - * @param ffprobePath
The path/command to ffprobe.
- * @param fileThe file to probe.
- * @returnA list of StreamObjects.
- * @throws IOExceptionIf the process can't be read.
+ * Converts the given file + * @param fileThe file to convert.
+ * @throws IOExceptionIf the file cannot be converted.
*/ - 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 newFile = new File(targetPath); - String fileName = stripExtension(targetPath); - int i = 1; - while (newFile.exists()) { - newFile = new File(fileName + "(" + i++ + ")" + "." + extension); - } - return newFile.toString(); - } - - /** - * Starts and prints output of a process - * @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: "); - printl(process.command().toString()); - process.directory(folder); - process.redirectErrorStream(true); - Process processConvert = process.start(); - BufferedReader readerConvert = new BufferedReader(new InputStreamReader(processConvert.getInputStream())); - while (processConvert.isAlive()) { - String read = read(readerConvert, "\n"); - if (!read.equals("")) { - printl(read); - } - } - printl("Process is finished."); - } - - /** - * 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; - StringBuilder text = new StringBuilder(); - while (reader.ready() && (line = reader.readLine()) != null && !line.equals("") && !line.equals("\n")) { - text.append(line).append(spacer); - } - return text.toString().trim(); - } - - /** - * 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(); - if (!string.contains(start) || string.indexOf(end, startPos) < startPos) { - return new String[]{}; - } - int endPos = string.indexOf(end, startPos); - String outString = string.substring(startPos, endPos).trim(); - String nextString = string.substring(endPos + end.length()); - return concatenate(new String[]{outString}, stringBetween(nextString, start, end)); - } - - /** - * 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(); - if (!string.contains(start) || string.indexOf(end, startPos) < startPos) { - return ""; - } - return string.substring(startPos, string.indexOf(end, startPos)); - } - - /** - * Gets filename without extension from File object - * @param fileA file object.
- * @returnA filename.
- */ - static String stripExtension(File file) { - return file.getName().substring(0, file.getName().lastIndexOf('.')); - } - - /** - * Removes the extension from a file name - * @param fileA filename.
- * @returnA filename without its extension.
- */ - static String stripExtension(String file) { - return file.substring(0, file.lastIndexOf('.')); - } - - /** - * Combines two arrays to one - * @param listAThe 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; - int absoluteIndex = -1; - for (String streamPart : streamParts) { - if (streamPart.contains("codec_name=")) { - codec = streamPart.replace("codec_name=", ""); - } else if (streamPart.contains("index=")) { - absoluteIndex = Integer.parseInt(streamPart.replace("index=", "")); - } - } - return new VideoStream(codec, absoluteIndex, relativeIndex); - } - - /** - * Parses a list of audio stream parameters to an audio stream object - * @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; - int absoluteIndex = -1; - String language = null; - int channels = 0; - String title = ""; - for (String streamPart : streamParts) { - if (streamPart.contains("codec_name=")) { - codec = streamPart.replace("codec_name=", ""); - } else if (streamPart.contains("index=")) { - absoluteIndex = Integer.parseInt(streamPart.replace("index=", "")); - } else if (streamPart.contains("TAG:language=")) { - language = streamPart.replace("TAG:language=", ""); - } else if (streamPart.contains("channels=")) { - channels = Integer.parseInt(streamPart.replace("channels=", "")); - } else if (streamPart.contains("TAG:title=")) { - title = streamPart.replace("TAG:title=", ""); - } - } - return new AudioStream(codec, absoluteIndex, relativeIndex, language, title, channels); - } - - /** - * Parses a list of subtitle stream parameters to a subtitle stream object - * @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 { - String codecName = null; - int absoluteIndex = -1; - String language = null; - String title = ""; - for (String streamPart : streamParts) { - if (streamPart.contains("codec_name=")) { - codecName = streamPart.replace("codec_name=", ""); - } else if (streamPart.contains("index=")) { - absoluteIndex = Integer.parseInt(streamPart.replace("index=", "")); - } else if (streamPart.contains("TAG:language=")) { - language = streamPart.replace("TAG:language=", ""); - } else if (streamPart.contains("TAG:title=")) { - title = streamPart.replace("TAG:title=", ""); - } - } - 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(",", "\\\\\\,") - .replace(";", "\\;") - .replace("]", "\\]") - .replace("[", "\\["); - } - - /** - * Prints something to the commandline efficiently - * @param inputThe text to print.
- * @throws IOExceptionIf a write is not possible.
- */ - private 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(); - } - - /** - * Checks whether there exists an external image 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.
- */ - String hasExternalImageSubtitle(String directory, String file) { - String path = stripExtension(file); - for (String subtitleExtension : new String[] {".idx", ".sub"}) { - if (new File(directory + File.separator + path + subtitleExtension).exists()) { - return path + 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.
- */ - String hasExternalSubtitle(String directory, String file) { - String path = stripExtension(file); - for (String subtitleExtension : new String[] {".srt", ".ass"}) { - System.out.println(directory + File.separator + path + subtitleExtension); - if (new File(directory + File.separator + path + subtitleExtension).exists()) { - return path + subtitleExtension; - } - } - return ""; - } + void convert(File file) throws IOException; }