Improves comments for converters

This commit is contained in:
2020-03-20 12:47:11 +01:00
parent 0f9fbc06c7
commit bf6542c22a
4 changed files with 274 additions and 178 deletions

View File

@ -23,6 +23,7 @@ import java.util.function.Predicate;
public abstract class Converter {
String ffprobePath;
String ffmpegPath;
boolean DEBUG = false;
private static final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
@ -41,10 +42,10 @@ public abstract class Converter {
/**
* Gets streams from a file
* @param ffprobePath The path/command to ffprobe
* @param file The file to probe
* @return A list of StreamObjects
* @throws IOException If the process can't be read
* @param ffprobePath <p>The path/command to ffprobe.</p>
* @param file <p>The file to probe.</p>
* @return <p>A list of StreamObjects.</p>
* @throws IOException <p>If the process can't be read.</p>
*/
static List<StreamObject> probeFile(String ffprobePath, File file) throws IOException {
ProcessBuilder builderProbe = new ProcessBuilder(
@ -71,20 +72,27 @@ public abstract class Converter {
return parseStreams(stringBetween(output.toString(), "[STREAM]", "[/STREAM]"));
}
/**
* Adds parentheses with an integer if the output file already exists
* @param targetPath <p>The path the file should ideally be saved at.</p>
* @param extension <p>The extension of the target file.</p>
* @return <p>A filename guaranteed not to collide with other files.</p>
*/
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 process <p>The process to run.</p>
* @param folder <p>The folder the process should run in.</p>
* @throws IOException <p>If the process can't be read.</p>
*/
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 reader <p>The reader of a process.</p>
* @return <p>The output from the read.</p>
* @throws IOException <p>On reader failure.</p>
*/
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 executable <p>The executable to use (ffmpeg/ffprobe).</p>
* @param fileName <p>The name of the file to execute on.</p>
* @return <p>A base list of ffmpeg commands for converting a video for web</p>
*/
static List<String> ffmpegWebVideo(String executable, String fileName) {
List<String> command = generalFile(executable, fileName);
@ -135,7 +145,10 @@ public abstract class Converter {
}
/**
* @return A base list of ffmpeg commands for converting a file
* Creates a list containing command line arguments for a general file
* @param executable <p>The executable to use (ffmpeg/ffprobe).</p>
* @param fileName <p>The name of the file to execute on.</p>
* @return <p>A base list of ffmpeg commands for converting a file.</p>
*/
static List<String> generalFile(String executable, String fileName) {
List<String> command = new ArrayList<>();
@ -148,9 +161,9 @@ public abstract class Converter {
/**
* Adds debugging parameters for only converting parts of a file
* @param command The list containing the command to run
* @param start The offset before converting
* @param length The offset for stopping the conversion
* @param command <p>The list containing the command to run.</p>
* @param start <p>The offset before converting.</p>
* @param length <p>The offset for stopping the conversion.</p>
*/
static void addDebug(List<String> command, int start, int length) {
command.add("-ss");
@ -160,10 +173,9 @@ public abstract class Converter {
}
/**
* Lists all indexes fulfilling a predicate.
*
* @param list A list of ffprobe indexes
* @return An integer list containing just the wanted indexes
* Lists all indexes fulfilling a predicate
* @param list <p>A list of ffprobe indexes.</p>
* @return <p>An integer list containing just the wanted indexes</p>
*/
private static List<Integer> listIndexes(String[] list, Predicate<String> p) {
List<Integer> indexes = new ArrayList<>();
@ -177,9 +189,9 @@ public abstract class Converter {
/**
* Tests a predicate on a list
* @param list A list
* @param p A predicate
* @param <T> Any type
* @param list <p>A list.</p>
* @param p <p>A predicate</p>
* @param <T> <p>The type of the list and the predicate.</p>
* @return True if the list have an element for which the predicate is true
*/
private static <T> boolean testPredicate(T[] list, Predicate<T> p) {
@ -192,12 +204,11 @@ public abstract class Converter {
}
/**
* Finds all substrings 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 A list of all occurrences of the substring
* Finds all substrings between two substrings in a string
* @param string <p>The string containing the substrings.</p>
* @param start <p>The substring before the wanted substring.</p>
* @param end <p>The substring after the wanted substring.</p>
* @return <p>A list of all occurrences of the substring.</p>
*/
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 string <p>The string containing the substrings.</p>
* @param start <p>The substring before the wanted substring.</p>
* @param end <p>The substring after the wanted substring.</p>
* @return <p>The wanted substring.</p>
*/
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 file <p>A file object.</p>
* @return <p>A filename.</p>
*/
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 file <p>A filename.</p>
* @return <p>A filename without its extension.</p>
*/
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
* @param <T> Any type
* @return A new array containing all elements from the two arrays
* @param listA <p>The first array.</p>
* @param listB <p>The second array.</p>
* @param <T> <p>The type of the two lists.</p>
* @return <p>A new array containing all elements from the two arrays.</p>
*/
public static <T> T[] concatenate(T[] a, T[] b) {
int aLen = a.length;
int bLen = b.length;
public static <T> T[] concatenate(T[] listA, T[] listB) {
int listALength = listA.length;
int listBLength = listB.length;
@SuppressWarnings("unchecked")
T[] c = (T[]) Array.newInstance(a.getClass().getComponentType(), aLen + bLen);
System.arraycopy(a, 0, c, 0, aLen);
System.arraycopy(b, 0, c, aLen, bLen);
return c;
T[] resultList = (T[]) Array.newInstance(listA.getClass().getComponentType(), listALength + listBLength);
System.arraycopy(listA, 0, resultList, 0, listALength);
System.arraycopy(listB, 0, resultList, listALength, listBLength);
return resultList;
}
/**
* Filters parsed streams into one of the stream types
* @param streams A list of stream objects
* @param codecType The codec type of the streams to select
* @param <G> The correct object type for the streams with the selected codec type
* @return A potentially shorter list of streams
* @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>
* @return <p>A potentially shorter list of streams.</p>
*/
static <G extends StreamObject> List<G> filterStreamsByType(List<StreamObject> streams, String codecType) {
Iterator<StreamObject> i = streams.iterator();
@ -283,9 +292,9 @@ public abstract class Converter {
/**
* Filters and sorts audio streams according to chosen languages
* @param audioStreams A list of audio streams
* @param audioLanguages A list of languages
* @return A list containing just audio tracks of chosen languages, sorted in order of languages
* @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>
*/
static List<AudioStream> filterAudioStreams(List<AudioStream> audioStreams, String[] audioLanguages) {
List<AudioStream> filtered = new ArrayList<>();
@ -303,10 +312,10 @@ public abstract class Converter {
/**
* Filters and sorts subtitle streams according to chosen languages
* @param subtitleStreams A list of subtitle streams
* @param subtitleLanguages A list of languages
* @param preventSignsAndSongs Whether partial subtitles should be avoided
* @return A list containing just subtitles of chosen languages, sorted in order of languages
* @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>
*/
static List<SubtitleStream> filterSubtitleStreams(List<SubtitleStream> subtitleStreams, String[] subtitleLanguages,
boolean preventSignsAndSongs) {
@ -328,8 +337,8 @@ public abstract class Converter {
/**
* Takes a list of all streams and parses each stream into one of three objects
* @param streams A list of all streams for the current file
* @return A list of StreamObjects
* @param streams <p>A list of all streams for the current file.</p>
* @return <p>A list of StreamObjects.</p>
*/
private static List<StreamObject> parseStreams(String[] streams) {
List<StreamObject> parsedStreams = new ArrayList<>();
@ -351,10 +360,10 @@ public abstract class Converter {
/**
* Parses a list of video stream parameters to a video stream object
* @param streamParts A list of parameters belonging to an video stream
* @param relativeIndex The relative index of the video stream
* @return A SubtitleStream object
* @throws NumberFormatException If codec index contains a non-numeric value
* @param streamParts <p>A list of parameters belonging to an video stream.</p>
* @param relativeIndex <p>The relative index of the video stream.</p>
* @return <p>A SubtitleStream object.</p>
* @throws NumberFormatException <p>If codec index contains a non-numeric value.</p>
*/
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 streamParts <p>A list of parameters belonging to an audio stream.</p>
* @param relativeIndex <p>The relative index of the audio stream.</p>
* @return <p>A SubtitleStream object.</p>
* @throws NumberFormatException <p>If codec index contains a non-numeric value.</p>
*/
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 streamParts <p>A list of parameters belonging to a subtitle stream.</p>
* @param relativeIndex <p>The relative index of the subtitle.</p>
* @return <p>A SubtitleStream object.</p>
* @throws NumberFormatException <p>If codec index contains a non-numeric value.</p>
*/
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 fileName <p>The filename to escape.</p>
* @return <p>A filename with known special characters escaped.</p>
*/
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 input <p>The text to print.</p>
* @throws IOException <p>If a write is not possible.</p>
*/
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 input <p>The text to print.</p>
* @throws IOException <p>If a write is not possible.</p>
*/
static void printl(String input) throws IOException {
if (!input.equals("")) {
writer.write(input);
}
printl();
}
/**
* Prints a newline
* @throws IOException <p>If a write is not possible.</p>
*/
static void printl() throws IOException {
writer.newLine();
writer.flush();
}