Adds ability to filter subtitle streams based on the title
All checks were successful
KnarCraft/FFmpegConvert/pipeline/head This commit looks good

This commit is contained in:
Kristian Knarvik 2022-10-11 23:13:45 +02:00
parent 1323513e46
commit 3c298f623e
6 changed files with 31 additions and 16 deletions

View File

@ -109,14 +109,16 @@ 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] [Forced audio index 0-n] " + "necessary true/false] [Prevent signs&songs subtitles true/false] [Forced audio index 0-n] " +
"[Forced subtitle index 0-n]\nYour input: "); "[Forced subtitle index 0-n] [Subtitle name filter]\nYour input: ");
List<String> input = readInput(6); List<String> input = readInput(7);
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;
int forcedAudioIndex = -1; int forcedAudioIndex = -1;
int forcedSubtitleIndex = -1; int forcedSubtitleIndex = -1;
String subtitleNameFilter = "";
if (input.size() > 0) { if (input.size() > 0) {
audioLanguage = ListUtil.getListFromCommaSeparatedString(input.get(0)); audioLanguage = ListUtil.getListFromCommaSeparatedString(input.get(0));
} }
@ -140,8 +142,11 @@ class Main {
OutputUtil.println("Forced audio or subtitle index is not a number"); OutputUtil.println("Forced audio or subtitle index is not a number");
return; return;
} }
if (input.size() > 6) {
subtitleNameFilter = input.get(6);
}
converter = new AnimeConverter(FFPROBE_PATH, FFMPEG_PATH, audioLanguage, subtitleLanguage, toStereo, converter = new AnimeConverter(FFPROBE_PATH, FFMPEG_PATH, audioLanguage, subtitleLanguage, toStereo,
preventSigns, forcedAudioIndex, forcedSubtitleIndex); preventSigns, forcedAudioIndex, forcedSubtitleIndex, subtitleNameFilter);
} }

View File

@ -76,12 +76,17 @@ public abstract class AbstractConverter implements Converter {
* @param subtitleStreams <p>A list of subtitle streams.</p> * @param subtitleStreams <p>A list of subtitle streams.</p>
* @param subtitleLanguages <p>A list of languages.</p> * @param subtitleLanguages <p>A list of languages.</p>
* @param preventSignsAndSongs <p>Whether partial subtitles should be avoided.</p> * @param preventSignsAndSongs <p>Whether partial subtitles should be avoided.</p>
* @param subtitleNameFilter <p>The filter to use for forcing streams of a given subtitle group</p>
* @return <p>A list containing just subtitles of chosen languages, sorted in order of languages.</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, static List<SubtitleStream> filterSubtitleStreams(List<SubtitleStream> subtitleStreams, String[] subtitleLanguages,
boolean preventSignsAndSongs) { boolean preventSignsAndSongs, String subtitleNameFilter) {
List<SubtitleStream> sorted = sortStreamsByLanguage(subtitleStreams, subtitleLanguages); List<SubtitleStream> sorted = sortStreamsByLanguage(subtitleStreams, subtitleLanguages);
sorted.removeIf((stream) -> preventSignsAndSongs && !stream.getIsFullSubtitle()); sorted.removeIf((stream) -> preventSignsAndSongs && !stream.getIsFullSubtitle());
//Filter by name of subtitle group, PGS or similar
if (!subtitleNameFilter.trim().isEmpty()) {
sorted.removeIf((stream) -> !stream.getTitle().contains(subtitleNameFilter));
}
return sorted; return sorted;
} }

View File

@ -21,6 +21,7 @@ public class AnimeConverter extends AbstractConverter {
private final boolean preventSignsAndSongs; private final boolean preventSignsAndSongs;
private final int forcedAudioIndex; private final int forcedAudioIndex;
private final int forcedSubtitleIndex; private final int forcedSubtitleIndex;
private final String subtitleNameFilter;
/** /**
* Instantiates a new anime converter * Instantiates a new anime converter
@ -35,7 +36,8 @@ public class AnimeConverter extends AbstractConverter {
* @param forcedSubtitleIndex <p>A specific subtitle stream to force. 0-indexed for the first subtitle 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, int forcedAudioIndex, int forcedSubtitleIndex) { boolean toStereo, boolean preventSignsAndSongs, int forcedAudioIndex, int forcedSubtitleIndex,
String subtitleNameFilter) {
super("mp4"); super("mp4");
this.ffprobePath = ffprobePath; this.ffprobePath = ffprobePath;
this.ffmpegPath = ffmpegPath; this.ffmpegPath = ffmpegPath;
@ -45,6 +47,7 @@ public class AnimeConverter extends AbstractConverter {
this.preventSignsAndSongs = preventSignsAndSongs; this.preventSignsAndSongs = preventSignsAndSongs;
this.forcedAudioIndex = forcedAudioIndex; this.forcedAudioIndex = forcedAudioIndex;
this.forcedSubtitleIndex = forcedSubtitleIndex; this.forcedSubtitleIndex = forcedSubtitleIndex;
this.subtitleNameFilter = subtitleNameFilter;
} }
@Override @Override
@ -55,20 +58,22 @@ 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),
AudioStream audioStream = getNthAudioSteam(new ArrayList<>(audioStreams), Math.max(forcedAudioIndex, 0)); this.audioLanguages);
AudioStream audioStream = getNthAudioSteam(new ArrayList<>(audioStreams), Math.max(this.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> allSubtitleStreams = filterStreamsByType(streams, SubtitleStream.class);
SubtitleStream.class), subtitleLanguages, preventSignsAndSongs); List<SubtitleStream> subtitleStreams = filterSubtitleStreams(allSubtitleStreams, this.subtitleLanguages,
this.preventSignsAndSongs, this.subtitleNameFilter);
SubtitleStream subtitleStream = getNthSubtitleStream(new ArrayList<>(subtitleStreams), SubtitleStream subtitleStream = getNthSubtitleStream(new ArrayList<>(subtitleStreams),
Math.max(forcedSubtitleIndex, 0)); Math.max(this.forcedSubtitleIndex, 0));
//Get the first video stream //Get the first video stream
VideoStream videoStream = getFirstVideoStream(streams); VideoStream videoStream = getFirstVideoStream(streams);
//Add streams to output file //Add streams to output file
FFMpegHelper.addAudioStream(command, audioStream, toStereo); FFMpegHelper.addAudioStream(command, audioStream, this.toStereo);
FFMpegHelper.addSubtitleAndVideoStream(command, subtitleStream, videoStream, file); FFMpegHelper.addSubtitleAndVideoStream(command, subtitleStream, videoStream, file);
command.add(outFile); command.add(outFile);
@ -77,7 +82,7 @@ public class AnimeConverter extends AbstractConverter {
@Override @Override
public String[] getValidFormats() { public String[] getValidFormats() {
return videoFormats; return this.videoFormats;
} }
} }

View File

@ -11,7 +11,7 @@ public class AnimeConverterTest {
public void setUp() { public void setUp() {
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, -1, -1); false, -1, -1, "");
} }
@Test @Test