Adds ability to force-select specific audio and subtitle streams for the anime converter
All checks were successful
KnarCraft/FFmpegConvert/pipeline/head This commit looks good
All checks were successful
KnarCraft/FFmpegConvert/pipeline/head This commit looks good
This commit is contained in:
parent
388563574f
commit
1323513e46
@ -1,3 +1,2 @@
|
|||||||
Manifest-Version: 1.0
|
Manifest-Version: 1.0
|
||||||
X-COMMENT: Main-Class will be added automatically by build
|
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ import static net.knarcraft.ffmpegconverter.utility.Parser.tokenize;
|
|||||||
* The main class for starting the software
|
* The main class for starting the software
|
||||||
*/
|
*/
|
||||||
class Main {
|
class Main {
|
||||||
|
|
||||||
private static final String FFPROBE_PATH = "ffprobe"; //Can be just ffprobe if it's in the path
|
private static final String FFPROBE_PATH = "ffprobe"; //Can be just ffprobe if it's in the path
|
||||||
private static final String FFMPEG_PATH = "ffmpeg"; //Can be just ffmpeg if it's in the path
|
private static final String FFMPEG_PATH = "ffmpeg"; //Can be just ffmpeg if it's in the path
|
||||||
private static final Scanner READER = new Scanner(System.in, "UTF-8");
|
private static final Scanner READER = new Scanner(System.in, "UTF-8");
|
||||||
@ -107,16 +108,19 @@ class Main {
|
|||||||
*/
|
*/
|
||||||
private static void animeConverter() throws IOException {
|
private static void animeConverter() throws IOException {
|
||||||
OutputUtil.println("[Audio languages jpn,eng,ger,fre] [Subtitle languages eng,ger,fre] [Convert to stereo if " +
|
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]\nYour input: ");
|
"necessary true/false] [Prevent signs&songs subtitles true/false] [Forced audio index 0-n] " +
|
||||||
List<String> input = readInput(4);
|
"[Forced subtitle index 0-n]\nYour input: ");
|
||||||
|
List<String> input = readInput(6);
|
||||||
String[] audioLanguage = new String[]{"jpn", "0"};
|
String[] audioLanguage = new String[]{"jpn", "0"};
|
||||||
String[] subtitleLanguage = new String[]{"eng", "0"};
|
String[] subtitleLanguage = new String[]{"eng", "0"};
|
||||||
boolean toStereo = true;
|
boolean toStereo = true;
|
||||||
boolean preventSigns = true;
|
boolean preventSigns = true;
|
||||||
if (input.size() > 0 && ListUtil.getListFromCommaSeparatedString(input.get(0)) != null) {
|
int forcedAudioIndex = -1;
|
||||||
|
int forcedSubtitleIndex = -1;
|
||||||
|
if (input.size() > 0) {
|
||||||
audioLanguage = ListUtil.getListFromCommaSeparatedString(input.get(0));
|
audioLanguage = ListUtil.getListFromCommaSeparatedString(input.get(0));
|
||||||
}
|
}
|
||||||
if (input.size() > 1 && ListUtil.getListFromCommaSeparatedString(input.get(1)) != null) {
|
if (input.size() > 1) {
|
||||||
subtitleLanguage = ListUtil.getListFromCommaSeparatedString(input.get(1));
|
subtitleLanguage = ListUtil.getListFromCommaSeparatedString(input.get(1));
|
||||||
}
|
}
|
||||||
if (input.size() > 2) {
|
if (input.size() > 2) {
|
||||||
@ -125,7 +129,19 @@ class Main {
|
|||||||
if (input.size() > 3) {
|
if (input.size() > 3) {
|
||||||
preventSigns = Boolean.parseBoolean(input.get(3));
|
preventSigns = Boolean.parseBoolean(input.get(3));
|
||||||
}
|
}
|
||||||
converter = new AnimeConverter(FFPROBE_PATH, FFMPEG_PATH, audioLanguage, subtitleLanguage, toStereo, preventSigns);
|
try {
|
||||||
|
if (input.size() > 4) {
|
||||||
|
forcedAudioIndex = Integer.parseInt(input.get(4));
|
||||||
|
}
|
||||||
|
if (input.size() > 5) {
|
||||||
|
forcedSubtitleIndex = Integer.parseInt(input.get(5));
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException exception) {
|
||||||
|
OutputUtil.println("Forced audio or subtitle index is not a number");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
converter = new AnimeConverter(FFPROBE_PATH, FFMPEG_PATH, audioLanguage, subtitleLanguage, toStereo,
|
||||||
|
preventSigns, forcedAudioIndex, forcedSubtitleIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -184,4 +200,5 @@ class Main {
|
|||||||
} while (choice < min || choice > max);
|
} while (choice < min || choice > max);
|
||||||
return choice;
|
return choice;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ import java.util.List;
|
|||||||
* Implements all methods which can be useful for any implementation of a converter.
|
* Implements all methods which can be useful for any implementation of a converter.
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractConverter implements Converter {
|
public abstract class AbstractConverter implements Converter {
|
||||||
|
|
||||||
final boolean debug = false;
|
final boolean debug = false;
|
||||||
private final String newExtension;
|
private final String newExtension;
|
||||||
String ffprobePath;
|
String ffprobePath;
|
||||||
@ -85,7 +86,7 @@ public abstract class AbstractConverter implements Converter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sorts subtitle streams according to chosen languages and removes non matching languages
|
* Sorts subtitle streams according to chosen languages and removes non-matching languages
|
||||||
*
|
*
|
||||||
* @param streams <p>A list of streams to sort.</p>
|
* @param streams <p>A list of streams to sort.</p>
|
||||||
* @param languages <p>The languages chosen by the user.</p>
|
* @param languages <p>The languages chosen by the user.</p>
|
||||||
@ -115,7 +116,7 @@ public abstract class AbstractConverter implements Converter {
|
|||||||
public abstract String[] getValidFormats();
|
public abstract String[] getValidFormats();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads streams from a file, and converts it to an mp4
|
* Reads streams from a file, and converts it to a mp4 file
|
||||||
*
|
*
|
||||||
* @param folder <p>The folder of the file to process.</p>
|
* @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>
|
||||||
@ -136,15 +137,18 @@ public abstract class AbstractConverter implements Converter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the first audio stream from a list of streams
|
* Gets the n-th 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>
|
||||||
*/
|
*/
|
||||||
AudioStream getFirstAudioSteam(List<StreamObject> streams) {
|
protected AudioStream getNthAudioSteam(List<StreamObject> streams, int n) {
|
||||||
List<AudioStream> audioStreams = filterStreamsByType(streams, AudioStream.class);
|
List<AudioStream> audioStreams = filterStreamsByType(streams, AudioStream.class);
|
||||||
AudioStream audioStream = null;
|
AudioStream audioStream = null;
|
||||||
if (audioStreams.size() > 0) {
|
if (audioStreams.size() > n) {
|
||||||
|
audioStream = audioStreams.get(n);
|
||||||
|
} else if (audioStreams.size() > 0) {
|
||||||
audioStream = audioStreams.get(0);
|
audioStream = audioStreams.get(0);
|
||||||
}
|
}
|
||||||
return audioStream;
|
return audioStream;
|
||||||
@ -154,12 +158,15 @@ public abstract class AbstractConverter implements Converter {
|
|||||||
* Gets the first subtitle stream from a list of streams
|
* Gets the first 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>
|
||||||
*/
|
*/
|
||||||
SubtitleStream getFirstSubtitleStream(List<StreamObject> streams) {
|
protected SubtitleStream getNthSubtitleStream(List<StreamObject> streams, int n) {
|
||||||
List<SubtitleStream> subtitleStreams = filterStreamsByType(streams, SubtitleStream.class);
|
List<SubtitleStream> subtitleStreams = filterStreamsByType(streams, SubtitleStream.class);
|
||||||
SubtitleStream subtitleStream = null;
|
SubtitleStream subtitleStream = null;
|
||||||
if (subtitleStreams.size() > 0) {
|
if (subtitleStreams.size() > n) {
|
||||||
|
subtitleStream = subtitleStreams.get(n);
|
||||||
|
} else if (subtitleStreams.size() > 0) {
|
||||||
subtitleStream = subtitleStreams.get(0);
|
subtitleStream = subtitleStreams.get(0);
|
||||||
}
|
}
|
||||||
return subtitleStream;
|
return subtitleStream;
|
||||||
@ -171,7 +178,7 @@ public abstract class AbstractConverter implements Converter {
|
|||||||
* @param streams <p>A list of all streams.</p>
|
* @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>
|
* @return <p>The first video stream found or null if no video streams were found.</p>
|
||||||
*/
|
*/
|
||||||
VideoStream getFirstVideoStream(List<StreamObject> streams) {
|
protected VideoStream getFirstVideoStream(List<StreamObject> streams) {
|
||||||
List<VideoStream> videoStreams = filterStreamsByType(streams, VideoStream.class);
|
List<VideoStream> videoStreams = filterStreamsByType(streams, VideoStream.class);
|
||||||
VideoStream videoStream = null;
|
VideoStream videoStream = null;
|
||||||
if (videoStreams.size() > 0) {
|
if (videoStreams.size() > 0) {
|
||||||
@ -187,4 +194,5 @@ public abstract class AbstractConverter implements Converter {
|
|||||||
public void convert(File file) throws IOException {
|
public void convert(File file) throws IOException {
|
||||||
processFile(file.getParentFile(), file);
|
processFile(file.getParentFile(), file);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,13 @@ import java.util.List;
|
|||||||
* A converter mainly designed for converting anime to web-playable mp4
|
* A converter mainly designed for converting anime to web-playable mp4
|
||||||
*/
|
*/
|
||||||
public class AnimeConverter extends AbstractConverter {
|
public class AnimeConverter extends AbstractConverter {
|
||||||
|
|
||||||
private final String[] audioLanguages;
|
private final String[] audioLanguages;
|
||||||
private final String[] subtitleLanguages;
|
private final String[] subtitleLanguages;
|
||||||
private final boolean toStereo;
|
private final boolean toStereo;
|
||||||
private final boolean preventSignsAndSongs;
|
private final boolean preventSignsAndSongs;
|
||||||
|
private final int forcedAudioIndex;
|
||||||
|
private final int forcedSubtitleIndex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new anime converter
|
* Instantiates a new anime converter
|
||||||
@ -28,9 +31,11 @@ public class AnimeConverter extends AbstractConverter {
|
|||||||
* @param subtitleLanguages <p>List of wanted subtitle languages in descending order.</p>
|
* @param subtitleLanguages <p>List of wanted subtitle languages in descending order.</p>
|
||||||
* @param toStereo <p>Convert video with several audio channels to stereo.</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>
|
* @param preventSignsAndSongs <p>Prevent subtitles only converting signs and songs (not speech).</p>
|
||||||
|
* @param forcedAudioIndex <p>A specific audio stream to force. 0-indexed from the first audio stream found</p>
|
||||||
|
* @param forcedSubtitleIndex <p>A specific subtitle stream to force. 0-indexed for the first subtitle stream found</p>
|
||||||
*/
|
*/
|
||||||
public AnimeConverter(String ffprobePath, String ffmpegPath, String[] audioLanguages, String[] subtitleLanguages,
|
public AnimeConverter(String ffprobePath, String ffmpegPath, String[] audioLanguages, String[] subtitleLanguages,
|
||||||
boolean toStereo, boolean preventSignsAndSongs) {
|
boolean toStereo, boolean preventSignsAndSongs, int forcedAudioIndex, int forcedSubtitleIndex) {
|
||||||
super("mp4");
|
super("mp4");
|
||||||
this.ffprobePath = ffprobePath;
|
this.ffprobePath = ffprobePath;
|
||||||
this.ffmpegPath = ffmpegPath;
|
this.ffmpegPath = ffmpegPath;
|
||||||
@ -38,6 +43,8 @@ public class AnimeConverter extends AbstractConverter {
|
|||||||
this.subtitleLanguages = subtitleLanguages;
|
this.subtitleLanguages = subtitleLanguages;
|
||||||
this.toStereo = toStereo;
|
this.toStereo = toStereo;
|
||||||
this.preventSignsAndSongs = preventSignsAndSongs;
|
this.preventSignsAndSongs = preventSignsAndSongs;
|
||||||
|
this.forcedAudioIndex = forcedAudioIndex;
|
||||||
|
this.forcedSubtitleIndex = forcedSubtitleIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -49,12 +56,13 @@ public class AnimeConverter extends AbstractConverter {
|
|||||||
|
|
||||||
//Get the first audio stream in accordance with chosen languages
|
//Get the first audio stream in accordance with chosen languages
|
||||||
List<AudioStream> audioStreams = filterAudioStreams(filterStreamsByType(streams, AudioStream.class), audioLanguages);
|
List<AudioStream> audioStreams = filterAudioStreams(filterStreamsByType(streams, AudioStream.class), audioLanguages);
|
||||||
AudioStream audioStream = getFirstAudioSteam(new ArrayList<>(audioStreams));
|
AudioStream audioStream = getNthAudioSteam(new ArrayList<>(audioStreams), Math.max(forcedAudioIndex, 0));
|
||||||
|
|
||||||
//Get the first subtitle stream in accordance with chosen languages and signs and songs prevention
|
//Get the first subtitle stream in accordance with chosen languages and signs and songs prevention
|
||||||
List<SubtitleStream> subtitleStreams = filterSubtitleStreams(filterStreamsByType(streams,
|
List<SubtitleStream> subtitleStreams = filterSubtitleStreams(filterStreamsByType(streams,
|
||||||
SubtitleStream.class), subtitleLanguages, preventSignsAndSongs);
|
SubtitleStream.class), subtitleLanguages, preventSignsAndSongs);
|
||||||
SubtitleStream subtitleStream = getFirstSubtitleStream(new ArrayList<>(subtitleStreams));
|
SubtitleStream subtitleStream = getNthSubtitleStream(new ArrayList<>(subtitleStreams),
|
||||||
|
Math.max(forcedSubtitleIndex, 0));
|
||||||
|
|
||||||
//Get the first video stream
|
//Get the first video stream
|
||||||
VideoStream videoStream = getFirstVideoStream(streams);
|
VideoStream videoStream = getFirstVideoStream(streams);
|
||||||
@ -71,4 +79,5 @@ public class AnimeConverter extends AbstractConverter {
|
|||||||
public String[] getValidFormats() {
|
public String[] getValidFormats() {
|
||||||
return videoFormats;
|
return videoFormats;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ public class AudioConverter extends AbstractConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Gets the first audio stream from the file and adds it to the output file
|
//Gets the first audio stream from the file and adds it to the output file
|
||||||
AudioStream audioStream = getFirstAudioSteam(streams);
|
AudioStream audioStream = getNthAudioSteam(streams, 0);
|
||||||
FFMpegHelper.addAudioStream(command, audioStream, false);
|
FFMpegHelper.addAudioStream(command, audioStream, false);
|
||||||
command.add(outFile);
|
command.add(outFile);
|
||||||
|
|
||||||
@ -44,4 +44,5 @@ public class AudioConverter extends AbstractConverter {
|
|||||||
public String[] getValidFormats() {
|
public String[] getValidFormats() {
|
||||||
return audioFormats;
|
return audioFormats;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -29,4 +29,5 @@ interface Converter {
|
|||||||
* @return <p>A list of commands</p>
|
* @return <p>A list of commands</p>
|
||||||
*/
|
*/
|
||||||
String[] generateConversionCommand(String executable, File file, List<StreamObject> streams, String outFile);
|
String[] generateConversionCommand(String executable, File file, List<StreamObject> streams, String outFile);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,9 @@ import net.knarcraft.ffmpegconverter.utility.FFMpegHelper;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple converter for web-video
|
||||||
|
*/
|
||||||
public class WebVideoConverter extends AbstractConverter {
|
public class WebVideoConverter extends AbstractConverter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,9 +40,9 @@ public class WebVideoConverter extends AbstractConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Get first streams from the file
|
//Get first streams from the file
|
||||||
SubtitleStream subtitleStream = getFirstSubtitleStream(streams);
|
SubtitleStream subtitleStream = getNthSubtitleStream(streams, 0);
|
||||||
VideoStream videoStream = getFirstVideoStream(streams);
|
VideoStream videoStream = getFirstVideoStream(streams);
|
||||||
AudioStream audioStream = getFirstAudioSteam(streams);
|
AudioStream audioStream = getNthAudioSteam(streams, 0);
|
||||||
|
|
||||||
//Add streams to output
|
//Add streams to output
|
||||||
FFMpegHelper.addSubtitleAndVideoStream(command, subtitleStream, videoStream, file);
|
FFMpegHelper.addSubtitleAndVideoStream(command, subtitleStream, videoStream, file);
|
||||||
|
@ -10,16 +10,17 @@ public class ConverterArgument {
|
|||||||
private final String name;
|
private final String name;
|
||||||
private final char shorthand;
|
private final char shorthand;
|
||||||
private final boolean valueRequired;
|
private final boolean valueRequired;
|
||||||
private final ConverterArgumentValue valueType;
|
private final ConverterArgumentValueType valueType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a converter argument
|
* Instantiates a converter argument
|
||||||
|
*
|
||||||
* @param name <p>The name of the argument which users has to type.</p>
|
* @param name <p>The name of the argument which users has to type.</p>
|
||||||
* @param shorthand <p>A single character value for using the command.</p>
|
* @param shorthand <p>A single character value for using the command.</p>
|
||||||
* @param valueRequired <p>Whether the argument must be followed by a valid value.</p>
|
* @param valueRequired <p>Whether the argument must be followed by a valid value.</p>
|
||||||
* @param valueType <p>The type of value the argument requires.</p>
|
* @param valueType <p>The type of value the argument requires.</p>
|
||||||
*/
|
*/
|
||||||
public ConverterArgument(String name, char shorthand, boolean valueRequired, ConverterArgumentValue valueType) {
|
public ConverterArgument(String name, char shorthand, boolean valueRequired, ConverterArgumentValueType valueType) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.shorthand = shorthand;
|
this.shorthand = shorthand;
|
||||||
this.valueRequired = valueRequired;
|
this.valueRequired = valueRequired;
|
||||||
@ -28,6 +29,7 @@ public class ConverterArgument {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the argument name
|
* Gets the argument name
|
||||||
|
*
|
||||||
* @return <p>The argument name.</p>
|
* @return <p>The argument name.</p>
|
||||||
*/
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@ -36,6 +38,7 @@ public class ConverterArgument {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the argument shorthand
|
* Gets the argument shorthand
|
||||||
|
*
|
||||||
* @return <p>The argument shorthand</p>
|
* @return <p>The argument shorthand</p>
|
||||||
*/
|
*/
|
||||||
public char getShorthand() {
|
public char getShorthand() {
|
||||||
@ -44,6 +47,7 @@ public class ConverterArgument {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets whether the argument requires a value
|
* Gets whether the argument requires a value
|
||||||
|
*
|
||||||
* @return <p>Whether the argument requires a value.</p>
|
* @return <p>Whether the argument requires a value.</p>
|
||||||
*/
|
*/
|
||||||
public boolean isValueRequired() {
|
public boolean isValueRequired() {
|
||||||
@ -73,9 +77,14 @@ public class ConverterArgument {
|
|||||||
case STRING:
|
case STRING:
|
||||||
return true;
|
return true;
|
||||||
case INT:
|
case INT:
|
||||||
int ignored = Integer.parseInt(value);
|
try {
|
||||||
|
Integer.parseInt(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
} catch (NumberFormatException exception) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
package net.knarcraft.ffmpegconverter.parser;
|
|
||||||
|
|
||||||
public enum ConverterArgumentValue {
|
|
||||||
BOOLEAN,
|
|
||||||
COMMA_SEPARATED_LIST,
|
|
||||||
STRING,
|
|
||||||
INT
|
|
||||||
}
|
|
@ -0,0 +1,28 @@
|
|||||||
|
package net.knarcraft.ffmpegconverter.parser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value types converter arguments can have
|
||||||
|
*/
|
||||||
|
public enum ConverterArgumentValueType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean value
|
||||||
|
*/
|
||||||
|
BOOLEAN,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list separated by commas
|
||||||
|
*/
|
||||||
|
COMMA_SEPARATED_LIST,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A normal string
|
||||||
|
*/
|
||||||
|
STRING,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An integer
|
||||||
|
*/
|
||||||
|
INT
|
||||||
|
|
||||||
|
}
|
@ -4,6 +4,7 @@ package net.knarcraft.ffmpegconverter.streams;
|
|||||||
* An abstract implementation of a stream object implementing common methods
|
* An abstract implementation of a stream object implementing common methods
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractStream implements StreamObject {
|
public abstract class AbstractStream implements StreamObject {
|
||||||
|
|
||||||
int absoluteIndex;
|
int absoluteIndex;
|
||||||
int relativeIndex;
|
int relativeIndex;
|
||||||
String codecName;
|
String codecName;
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package net.knarcraft.ffmpegconverter.streams;
|
package net.knarcraft.ffmpegconverter.streams;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents an ffmpeg audio stream
|
* This class represents a ffmpeg audio stream
|
||||||
*/
|
*/
|
||||||
public class AudioStream extends AbstractStream implements StreamObject {
|
public class AudioStream extends AbstractStream implements StreamObject {
|
||||||
|
|
||||||
private final int channels;
|
private final int channels;
|
||||||
private final String title;
|
private final String title;
|
||||||
|
|
||||||
@ -38,10 +39,14 @@ public class AudioStream extends AbstractStream implements StreamObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the title of the audio stream
|
* Gets the title of the audio stream
|
||||||
|
* <p>
|
||||||
|
* TODO: While this isn't useful right now, it would be useful if the software allowed first looking at available
|
||||||
|
* steams, and then choose the correct stream based on the name
|
||||||
*
|
*
|
||||||
* @return <p>The title of the audio stream.</p>
|
* @return <p>The title of the audio stream.</p>
|
||||||
*/
|
*/
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return this.title;
|
return this.title;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package net.knarcraft.ffmpegconverter.streams;
|
package net.knarcraft.ffmpegconverter.streams;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object describing a generic video file stream
|
||||||
|
*/
|
||||||
public interface StreamObject {
|
public interface StreamObject {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,9 +27,9 @@ public interface StreamObject {
|
|||||||
int getRelativeIndex();
|
int getRelativeIndex();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the language of the audio stream
|
* Gets the language of the audio or subtitle stream
|
||||||
*
|
*
|
||||||
* @return <p>The language of the audio stream.</p>
|
* @return <p>The language of the audio or subtitle stream.</p>
|
||||||
*/
|
*/
|
||||||
String getLanguage();
|
String getLanguage();
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ package net.knarcraft.ffmpegconverter.streams;
|
|||||||
* An object representation of a subtitle stream in a media file
|
* An object representation of a subtitle stream in a media file
|
||||||
*/
|
*/
|
||||||
public class SubtitleStream extends AbstractStream implements StreamObject {
|
public class SubtitleStream extends AbstractStream implements StreamObject {
|
||||||
|
|
||||||
final private String title;
|
final private String title;
|
||||||
final private String file;
|
final private String file;
|
||||||
final private boolean isFullSubtitle;
|
final private boolean isFullSubtitle;
|
||||||
@ -92,4 +93,5 @@ public class SubtitleStream extends AbstractStream implements StreamObject {
|
|||||||
!titleLowercase.matches(".*forced.*") &&
|
!titleLowercase.matches(".*forced.*") &&
|
||||||
!titleLowercase.matches(".*s&s.*");
|
!titleLowercase.matches(".*s&s.*");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -4,6 +4,7 @@ package net.knarcraft.ffmpegconverter.streams;
|
|||||||
* An object representation of a video stream in a media file
|
* An object representation of a video stream in a media file
|
||||||
*/
|
*/
|
||||||
public class VideoStream extends AbstractStream implements StreamObject {
|
public class VideoStream extends AbstractStream implements StreamObject {
|
||||||
|
|
||||||
private final int width;
|
private final int width;
|
||||||
private final int height;
|
private final int height;
|
||||||
|
|
||||||
@ -41,4 +42,5 @@ public class VideoStream extends AbstractStream implements StreamObject {
|
|||||||
public int getHeight() {
|
public int getHeight() {
|
||||||
return this.height;
|
return this.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -21,6 +21,7 @@ public final class FFMpegHelper {
|
|||||||
private static final String PROBE_SPLIT_CHARACTER = "øæåÆØå";
|
private static final String PROBE_SPLIT_CHARACTER = "øæåÆØå";
|
||||||
|
|
||||||
private FFMpegHelper() {
|
private FFMpegHelper() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -429,4 +430,5 @@ public final class FFMpegHelper {
|
|||||||
}
|
}
|
||||||
return new SubtitleStream(codecName, absoluteIndex, relativeIndex, language, title, file);
|
return new SubtitleStream(codecName, absoluteIndex, relativeIndex, language, title, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import java.io.InputStreamReader;
|
|||||||
public final class FileUtil {
|
public final class FileUtil {
|
||||||
|
|
||||||
private FileUtil() {
|
private FileUtil() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,6 +11,7 @@ import java.util.function.Predicate;
|
|||||||
public final class ListUtil {
|
public final class ListUtil {
|
||||||
|
|
||||||
private ListUtil() {
|
private ListUtil() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,4 +78,5 @@ public final class ListUtil {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,12 @@ import java.io.OutputStreamWriter;
|
|||||||
* A class which helps with outputting information
|
* A class which helps with outputting information
|
||||||
*/
|
*/
|
||||||
public final class OutputUtil {
|
public final class OutputUtil {
|
||||||
|
|
||||||
private static final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
|
private static final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
|
||||||
private static boolean debug;
|
private static boolean debug;
|
||||||
|
|
||||||
private OutputUtil() {
|
private OutputUtil() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,4 +80,5 @@ public final class OutputUtil {
|
|||||||
print(message);
|
print(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,10 +13,12 @@ import java.util.Map;
|
|||||||
public final class Parser {
|
public final class Parser {
|
||||||
|
|
||||||
private Parser() {
|
private Parser() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function parses the input to understandable converter instructions
|
* This function parses the input to understandable converter instructions
|
||||||
|
*
|
||||||
* @param input <p>The input string to parse.</p>
|
* @param input <p>The input string to parse.</p>
|
||||||
* @param validArguments <p>All arguments which are considered valid.</p>
|
* @param validArguments <p>All arguments which are considered valid.</p>
|
||||||
* @return <p>A map with all parsed arguments.</p>
|
* @return <p>A map with all parsed arguments.</p>
|
||||||
@ -193,4 +195,5 @@ public final class Parser {
|
|||||||
private static boolean isNotEmpty(StringBuilder builder) {
|
private static boolean isNotEmpty(StringBuilder builder) {
|
||||||
return !builder.toString().trim().equals("");
|
return !builder.toString().trim().equals("");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ package net.knarcraft.ffmpegconverter.utility;
|
|||||||
final class StringUtil {
|
final class StringUtil {
|
||||||
|
|
||||||
private StringUtil() {
|
private StringUtil() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,4 +30,5 @@ final class StringUtil {
|
|||||||
//Add other occurrences recursively
|
//Add other occurrences recursively
|
||||||
return ListUtil.concatenate(new String[]{outString}, stringBetween(nextString, start, end));
|
return ListUtil.concatenate(new String[]{outString}, stringBetween(nextString, start, end));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,15 +6,17 @@ import org.junit.Test;
|
|||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
public class AnimeConverterTest {
|
public class AnimeConverterTest {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
AnimeConverter converter = new AnimeConverter("ffprobe", "ffmpeg",
|
new AnimeConverter("ffprobe", "ffmpeg",
|
||||||
new String[]{"jpn", "eng", "nor", "swe"}, new String[]{"nor", "eng", "swe", "fin"}, false,
|
new String[]{"jpn", "eng", "nor", "swe"}, new String[]{"nor", "eng", "swe", "fin"}, false,
|
||||||
false);
|
false, -1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void weirdTest() {
|
public void weirdTest() {
|
||||||
assertEquals(0, 0);
|
assertEquals(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.knarcraft.ffmpegconverter.utility;
|
package net.knarcraft.ffmpegconverter.utility;
|
||||||
|
|
||||||
import net.knarcraft.ffmpegconverter.parser.ConverterArgument;
|
import net.knarcraft.ffmpegconverter.parser.ConverterArgument;
|
||||||
import net.knarcraft.ffmpegconverter.parser.ConverterArgumentValue;
|
import net.knarcraft.ffmpegconverter.parser.ConverterArgumentValueType;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -18,9 +18,9 @@ public class ParserTest {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
validArguments = new ArrayList<>();
|
validArguments = new ArrayList<>();
|
||||||
validArguments.add(new ConverterArgument("anargument", 'a', true, ConverterArgumentValue.STRING));
|
validArguments.add(new ConverterArgument("anargument", 'a', true, ConverterArgumentValueType.STRING));
|
||||||
validArguments.add(new ConverterArgument("turnoff", 't', false, ConverterArgumentValue.BOOLEAN));
|
validArguments.add(new ConverterArgument("turnoff", 't', false, ConverterArgumentValueType.BOOLEAN));
|
||||||
validArguments.add(new ConverterArgument("turnon", 'o', false, ConverterArgumentValue.BOOLEAN));
|
validArguments.add(new ConverterArgument("turnon", 'o', false, ConverterArgumentValueType.BOOLEAN));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
Loading…
Reference in New Issue
Block a user