Add hearing impaired tracks as low prio default match

This commit is contained in:
RatzzFatzz
2025-12-21 00:44:49 +01:00
parent 1e31326ea2
commit c7670e36c1
5 changed files with 86 additions and 62 deletions

View File

@@ -1,14 +1,20 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl; package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackAttributes; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackAttributes;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
@RequiredArgsConstructor
public class SubtitleTrackComparator implements Comparator<TrackAttributes> { public class SubtitleTrackComparator implements Comparator<TrackAttributes> {
private final String[] preferredSubtitles; private final Set<String> preferredSubtitles;
private final Set<String> hearingImpairedKeywords;
public SubtitleTrackComparator(Collection<String> preferredSubtitles, Collection<String> hearingImpairedKeywords) {
this.preferredSubtitles = new HashSet<>(preferredSubtitles.stream().map(String::toLowerCase).toList());
this.hearingImpairedKeywords = new HashSet<>(hearingImpairedKeywords.stream().map(String::toLowerCase).toList());
}
/** /**
* {@inheritDoc} * {@inheritDoc}
@@ -17,12 +23,22 @@ public class SubtitleTrackComparator implements Comparator<TrackAttributes> {
public int compare(TrackAttributes track1, TrackAttributes track2) { public int compare(TrackAttributes track1, TrackAttributes track2) {
int result = 0; int result = 0;
if (StringUtils.containsAnyIgnoreCase(track1.trackName(), preferredSubtitles)) { String track1Name = track1.trackName().toLowerCase();
result++; String track2Name = track2.trackName().toLowerCase();
}
if (StringUtils.containsAnyIgnoreCase(track2.trackName(), preferredSubtitles)) { if (preferredSubtitles.contains(track1Name)) result++;
result--; else for (String keyword: preferredSubtitles) if (track1Name.contains(keyword)) result++;
}
if (preferredSubtitles.contains(track2Name)) result--;
else for (String keyword: preferredSubtitles) if (track2Name.contains(keyword)) result--;
if (track1.hearingImpaired()) result--;
else if (hearingImpairedKeywords.contains(track1Name)) result--;
else for (String keyword: hearingImpairedKeywords) if (track1Name.contains(keyword)) result--;
if (track2.hearingImpaired()) result++;
else if (hearingImpairedKeywords.contains(track2Name)) result++;
else for (String keyword: hearingImpairedKeywords) if (track2Name.contains(keyword)) result++;
if (result == 0) { if (result == 0) {
if (track1.defaultt()) result++; if (track1.defaultt()) result++;

View File

@@ -15,7 +15,7 @@ public class AttributeChangeProcessor {
private final Set<String> forcedKeywords; private final Set<String> forcedKeywords;
public AttributeChangeProcessor(String[] preferredSubtitles, Set<String> forcedKeywords, Set<String> commentaryKeywords, Set<String> hearingImpairedKeywords) { public AttributeChangeProcessor(String[] preferredSubtitles, Set<String> forcedKeywords, Set<String> commentaryKeywords, Set<String> hearingImpairedKeywords) {
this.subtitleTrackComparator = new SubtitleTrackComparator(preferredSubtitles); this.subtitleTrackComparator = new SubtitleTrackComparator(Arrays.stream(preferredSubtitles).toList(), hearingImpairedKeywords);
this.commentaryKeywords = commentaryKeywords; this.commentaryKeywords = commentaryKeywords;
this.hearingImpairedKeywords = hearingImpairedKeywords; this.hearingImpairedKeywords = hearingImpairedKeywords;
this.forcedKeywords = forcedKeywords; this.forcedKeywords = forcedKeywords;
@@ -24,26 +24,12 @@ public class AttributeChangeProcessor {
private List<TrackAttributes> filterForPossibleDefaults(List<TrackAttributes> tracks) { private List<TrackAttributes> filterForPossibleDefaults(List<TrackAttributes> tracks) {
Stream<TrackAttributes> attributes = tracks.stream(); Stream<TrackAttributes> attributes = tracks.stream();
if (true) { // TODO: config for including commentary return attributes
attributes = attributes
.filter(attr -> !attr.commentary()) .filter(attr -> !attr.commentary())
.filter(attr -> { .filter(attr -> {
if (attr.trackName() == null) return true; if (attr.trackName() == null) return true;
return commentaryKeywords.stream().noneMatch(keyword -> keyword.compareToIgnoreCase(attr.trackName()) == 0); return commentaryKeywords.stream().noneMatch(keyword -> keyword.compareToIgnoreCase(attr.trackName()) == 0);
}); })
}
if (true) { // TODO: config for including hearing impaired
attributes = attributes
.filter(attr -> !attr.hearingImpaired())
.filter(attr -> {
if (attr.trackName() == null) return true;
return hearingImpairedKeywords.stream().noneMatch(keyword -> keyword.compareToIgnoreCase(attr.trackName()) == 0);
});;
}
return attributes
.filter(attr -> !attr.forced()) .filter(attr -> !attr.forced())
.filter(attr -> { .filter(attr -> {
if (attr.trackName() == null) return true; if (attr.trackName() == null) return true;

View File

@@ -12,32 +12,42 @@ import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
class SubtitleTrackComparatorTest { class SubtitleTrackComparatorTest {
private static final SubtitleTrackComparator comparator = new SubtitleTrackComparator(new String[]{"unstyled"});
private static Stream<Arguments> compareArguments() { private static Stream<Arguments> compareArguments() {
return Stream.of( return Stream.of(
Arguments.of(List.of(attr("unstyled sub", false), attr("styled sub", false)), Arguments.of(attr(""), attr(""), 0),
List.of(attr("unstyled sub", false), attr("styled sub", false))), Arguments.of(attr("pref"), attr(""), 1),
Arguments.of(List.of(attr("styled sub", false), attr("unstyled sub", false)), Arguments.of(attr(""), attr("pref"), -1),
List.of(attr("unstyled sub", false), attr("styled sub", false))), Arguments.of(attr("pref"), attr("pref"), 0),
Arguments.of(List.of(attr("unstyled sub", true), attr("styled sub", false)), Arguments.of(attr("", true), attr("", true), 0),
List.of(attr("unstyled sub", true), attr("styled sub", false))), Arguments.of(attr("", true), attr(""), -1),
Arguments.of(List.of(attr("styled sub", true), attr("unstyled sub", false)), Arguments.of(attr("CC", true), attr(""), -1),
List.of(attr("unstyled sub", false), attr("styled sub", true))), Arguments.of(attr("CC"), attr(""), -1),
Arguments.of(attr(""), attr("", true), 1),
Arguments.of(attr(""), attr("CC", true), 1),
Arguments.of(attr(""), attr("CC"), 1),
Arguments.of(List.of(attr("unstyled sub", true), attr("unstyled sub", false)), Arguments.of(attr("pref", true), attr("pref"), -1),
List.of(attr("unstyled sub", true), attr("unstyled sub", false))) Arguments.of(attr("pref", true), attr("pref", true), 0),
Arguments.of(attr("pref"), attr("pref", true), 1),
Arguments.of(attr("", true), attr("pref"), -2),
Arguments.of(attr("pref"), attr("", true), 2)
); );
} }
@ParameterizedTest @ParameterizedTest
@MethodSource("compareArguments") @MethodSource("compareArguments")
void compare(List<TrackAttributes> input, List<TrackAttributes> expected) { void compare(TrackAttributes track1, TrackAttributes track2, int expected) {
assertIterableEquals(expected, input.stream().sorted(comparator.reversed()).toList()); SubtitleTrackComparator comparator = new SubtitleTrackComparator(List.of("pref"), List.of("CC", "SDH"));
int actual = comparator.compare(track1, track2);
assertEquals(expected, actual);
} }
private static TrackAttributes attr(String trackName, boolean defaultTrack) { private static TrackAttributes attr(String trackname) {
return new TrackAttributes(0, "", trackName, defaultTrack, false, false, false, TrackType.SUBTITLES); return attr(trackname, false);
}
private static TrackAttributes attr(String trackName, boolean hearingImpaired) {
return new TrackAttributes(0, "", trackName, false, false, false, hearingImpaired, TrackType.SUBTITLES);
} }
} }

View File

@@ -71,19 +71,29 @@ class AttributeChangeProcessorTest {
Map.ofEntries() Map.ofEntries()
), ),
Arguments.of( Arguments.of(
List.of(AUDIO_ENG_DEFAULT, AUDIO_GER_HEARING, SUB_GER), List.of(AUDIO_GER, withName(SUB_GER, "SDH")),
arr(a("ger:ger")), null,
Map.ofEntries()
),
Arguments.of(
List.of(AUDIO_ENG_DEFAULT, withName(AUDIO_GER, "SDH"), SUB_GER),
arr(a("ger:ger")), null,
Map.ofEntries()
),
Arguments.of(
List.of(AUDIO_ENG_DEFAULT, AUDIO_GER_COMMENTARY, AUDIO_GER_HEARING, AUDIO_GER, SUB_GER_FORCED, SUB_GER),
arr(a("ger:ger")), "ger:ger", arr(a("ger:ger")), "ger:ger",
Map.ofEntries(off(AUDIO_ENG_DEFAULT), on(AUDIO_GER), on(SUB_GER)) Map.ofEntries(on(AUDIO_GER), on(withName(SUB_GER, "SDH")))
),
Arguments.of(
List.of(AUDIO_GER, withName(SUB_GER, "SDH"), SUB_GER),
arr(a("ger:ger")), "ger:ger",
Map.ofEntries(on(AUDIO_GER), on(SUB_GER))
),
Arguments.of(
List.of(AUDIO_GER, SUB_GER_HEARING),
arr(a("ger:ger")), "ger:ger",
Map.ofEntries(on(AUDIO_GER), on(SUB_GER_HEARING))
),
Arguments.of(
List.of(AUDIO_GER, SUB_GER_HEARING, SUB_GER),
arr(a("ger:ger")), "ger:ger",
Map.ofEntries(on(AUDIO_GER), on(SUB_GER))
),
Arguments.of(
List.of(AUDIO_GER, SUB_ENG_HEARING, SUB_GER),
arr(a("ger:eng")), "ger:eng",
Map.ofEntries(on(AUDIO_GER), on(SUB_ENG_HEARING))
) )
); );
} }
@@ -128,9 +138,9 @@ class AttributeChangeProcessorTest {
Arguments.of(List.of(AUDIO_GER, AUDIO_ENG, withName(AUDIO_GER, "Forced"), SUB_GER), Set.of(AUDIO_GER, AUDIO_ENG, SUB_GER)), Arguments.of(List.of(AUDIO_GER, AUDIO_ENG, withName(AUDIO_GER, "Forced"), SUB_GER), Set.of(AUDIO_GER, AUDIO_ENG, SUB_GER)),
Arguments.of(List.of(AUDIO_GER, AUDIO_ENG, withName(AUDIO_GER, "commentary"), SUB_GER), Set.of(AUDIO_GER, AUDIO_ENG, SUB_GER)), Arguments.of(List.of(AUDIO_GER, AUDIO_ENG, withName(AUDIO_GER, "commentary"), SUB_GER), Set.of(AUDIO_GER, AUDIO_ENG, SUB_GER)),
Arguments.of(List.of(AUDIO_GER, AUDIO_ENG, withName(AUDIO_GER, "Commentary"), SUB_GER), Set.of(AUDIO_GER, AUDIO_ENG, SUB_GER)), Arguments.of(List.of(AUDIO_GER, AUDIO_ENG, withName(AUDIO_GER, "Commentary"), SUB_GER), Set.of(AUDIO_GER, AUDIO_ENG, SUB_GER)),
Arguments.of(List.of(AUDIO_GER, AUDIO_ENG, withName(AUDIO_GER, "SDH"), SUB_GER), Set.of(AUDIO_GER, AUDIO_ENG, SUB_GER)), Arguments.of(List.of(AUDIO_GER, AUDIO_ENG, withName(AUDIO_GER, "SDH"), SUB_GER), Set.of(AUDIO_GER, AUDIO_ENG, SUB_GER, withName(AUDIO_GER, "SDH"))),
Arguments.of(List.of(AUDIO_GER, AUDIO_ENG, withName(AUDIO_GER, "sdh"), SUB_GER), Set.of(AUDIO_GER, AUDIO_ENG, SUB_GER)), Arguments.of(List.of(AUDIO_GER, AUDIO_ENG, withName(AUDIO_GER, "sdh"), SUB_GER), Set.of(AUDIO_GER, AUDIO_ENG, SUB_GER, withName(AUDIO_GER, "sdh"))),
Arguments.of(List.of(AUDIO_GER, AUDIO_ENG, SUB_GER, SUB_GER_FORCED, AUDIO_GER_COMMENTARY, AUDIO_GER_HEARING), Set.of(AUDIO_GER, AUDIO_ENG, SUB_GER)) Arguments.of(List.of(AUDIO_GER, AUDIO_ENG, SUB_GER, SUB_GER_FORCED, AUDIO_GER_COMMENTARY, AUDIO_GER_HEARING), Set.of(AUDIO_GER, AUDIO_ENG, SUB_GER, AUDIO_GER_HEARING))
); );
} }

View File

@@ -13,7 +13,7 @@ public class FileInfoTestUtil {
public static final TrackAttributes AUDIO_GER_COMMENTARY = new TrackAttributes(0, "ger", "", false, false, true, false, TrackType.AUDIO); public static final TrackAttributes AUDIO_GER_COMMENTARY = new TrackAttributes(0, "ger", "", false, false, true, false, TrackType.AUDIO);
public static final TrackAttributes AUDIO_ENG_COMMENTARY = new TrackAttributes(1, "eng", "", false, false, true, false, TrackType.AUDIO); public static final TrackAttributes AUDIO_ENG_COMMENTARY = new TrackAttributes(1, "eng", "", false, false, true, false, TrackType.AUDIO);
public static final TrackAttributes AUDIO_GER_HEARING = new TrackAttributes(0, "ger", "", false, false, false, true, TrackType.AUDIO); public static final TrackAttributes AUDIO_GER_HEARING = new TrackAttributes(0, "ger", "", false, false, false, true, TrackType.AUDIO);
public static final TrackAttributes AUDIO_ENG_HEARING = new TrackAttributes(1, "ger", "", false, false, false, true, TrackType.AUDIO); public static final TrackAttributes AUDIO_ENG_HEARING = new TrackAttributes(1, "eng", "", false, false, false, true, TrackType.AUDIO);
public static final TrackAttributes SUB_GER = new TrackAttributes(0, "ger", "", false, false, false, false, TrackType.SUBTITLES); public static final TrackAttributes SUB_GER = new TrackAttributes(0, "ger", "", false, false, false, false, TrackType.SUBTITLES);
public static final TrackAttributes SUB_ENG = new TrackAttributes(1, "eng", "", false, false, false, false, TrackType.SUBTITLES); public static final TrackAttributes SUB_ENG = new TrackAttributes(1, "eng", "", false, false, false, false, TrackType.SUBTITLES);
@@ -21,6 +21,8 @@ public class FileInfoTestUtil {
public static final TrackAttributes SUB_ENG_DEFAULT = new TrackAttributes(1, "eng", "", true, false, false, false, TrackType.SUBTITLES); public static final TrackAttributes SUB_ENG_DEFAULT = new TrackAttributes(1, "eng", "", true, false, false, false, TrackType.SUBTITLES);
public static final TrackAttributes SUB_GER_FORCED = new TrackAttributes(0, "ger", "", false, true, false, false, TrackType.SUBTITLES); public static final TrackAttributes SUB_GER_FORCED = new TrackAttributes(0, "ger", "", false, true, false, false, TrackType.SUBTITLES);
public static final TrackAttributes SUB_ENG_FORCED = new TrackAttributes(1, "eng", "", false, true, false, false, TrackType.SUBTITLES); public static final TrackAttributes SUB_ENG_FORCED = new TrackAttributes(1, "eng", "", false, true, false, false, TrackType.SUBTITLES);
public static final TrackAttributes SUB_GER_HEARING = new TrackAttributes(0, "ger", "", false, false, false, true, TrackType.SUBTITLES);
public static final TrackAttributes SUB_ENG_HEARING = new TrackAttributes(1, "eng", "", false, false, false, true, TrackType.SUBTITLES);
public static TrackAttributes withName(TrackAttributes track, String trackName) { public static TrackAttributes withName(TrackAttributes track, String trackName) {
return new TrackAttributes(track.id(), track.language(), trackName, track.defaultt(), track.forced(), track.commentary(), track.hearingImpaired(), track.type()); return new TrackAttributes(track.id(), track.language(), trackName, track.defaultt(), track.forced(), track.commentary(), track.hearingImpaired(), track.type());