Implement OFF for audio tracks

This commit is contained in:
RatzzFatzz
2025-10-16 17:10:11 +02:00
parent 37c65df60c
commit b0f927dfa8
16 changed files with 257 additions and 168 deletions

View File

@@ -3,7 +3,7 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.exceptions.MkvToolNixException;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfoDto;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfo;
import java.io.File;
import java.io.IOException;
@@ -25,7 +25,7 @@ public interface FileProcessor {
* @param attributes Track information of FileInfoDto
* @param nonForcedTracks List of all not forced tracks
*/
void detectDefaultTracks(FileInfoDto info, List<FileAttribute> attributes, List<FileAttribute> nonForcedTracks);
void detectDefaultTracks(FileInfo info, List<FileAttribute> attributes, List<FileAttribute> nonForcedTracks);
/**
* Populate FileInfoDto with the desired tracks, based on AttributeConfig.
@@ -33,7 +33,7 @@ public interface FileProcessor {
* @param nonForcedTracks List of all non-forced tracks
* @param nonCommentaryTracks List of all non-commentary tracks
*/
void detectDesiredTracks(FileInfoDto info, List<FileAttribute> nonForcedTracks, List<FileAttribute> nonCommentaryTracks,
void detectDesiredTracks(FileInfo info, List<FileAttribute> nonForcedTracks, List<FileAttribute> nonCommentaryTracks,
AttributeConfig... configs);
List<FileAttribute> retrieveNonForcedTracks(List<FileAttribute> attributes);
@@ -43,9 +43,9 @@ public interface FileProcessor {
/**
* Update the file.
* @param file to be updated
* @param fileInfo information to update file
* @param fileInfo information used to update file
* @throws IOException when error occurs accessing file retrieving information
* @throws MkvToolNixException when error occurs while sending query to mkvpropedit
*/
void update(File file, FileInfoDto fileInfo) throws IOException, MkvToolNixException;
void update(File file, FileInfo fileInfo) throws IOException, MkvToolNixException;
}

View File

@@ -81,15 +81,15 @@ public class MkvFileProcessor implements FileProcessor {
* {@inheritDoc}
*/
@Override
public void detectDefaultTracks(FileInfoDto info, List<FileAttribute> attributes, List<FileAttribute> nonForcedTracks) {
public void detectDefaultTracks(FileInfo info, List<FileAttribute> attributes, List<FileAttribute> nonForcedTracks) {
for (FileAttribute attribute : attributes) {
if (AUDIO.equals(attribute.getType())) {
if (attribute.isDefaultTrack()) info.getExistingDefaultAudioLanes().add(attribute);
if (attribute.isForcedTrack()) info.getExistingForcedAudioLanes().add(attribute);
} else if (SUBTITLES.equals(attribute.getType())) {
if (attribute.isDefaultTrack()) info.getExistingDefaultSubtitleLanes().add(attribute);
if (AUDIO.equals(attribute.type())) {
if (attribute.defaultTrack()) info.getExistingDefaultAudioLanes().add(attribute);
if (attribute.forcedTrack()) info.getExistingForcedAudioLanes().add(attribute);
} else if (SUBTITLES.equals(attribute.type())) {
if (attribute.defaultTrack()) info.getExistingDefaultSubtitleLanes().add(attribute);
if (attribute.isForcedTrack()) info.getExistingForcedSubtitleLanes().add(attribute);
if (attribute.forcedTrack()) info.getExistingForcedSubtitleLanes().add(attribute);
else if (!nonForcedTracks.contains(attribute)) info.getDesiredForcedSubtitleLanes().add(attribute);
}
}
@@ -99,19 +99,20 @@ public class MkvFileProcessor implements FileProcessor {
* {@inheritDoc}
*/
@Override
public void detectDesiredTracks(FileInfoDto info, List<FileAttribute> nonForcedTracks, List<FileAttribute> nonCommentaryTracks,
public void detectDesiredTracks(FileInfo info, List<FileAttribute> nonForcedTracks, List<FileAttribute> nonCommentaryTracks,
AttributeConfig... configs) {
Set<FileAttribute> tracks = SetUtils.retainOf(nonForcedTracks, nonCommentaryTracks);
Set<FileAttribute> audioTracks = tracks.stream().filter(a -> AUDIO.equals(a.getType())).collect(Collectors.toSet());
Set<FileAttribute> subtitleTracks = tracks.stream().filter(a -> SUBTITLES.equals(a.getType())).collect(Collectors.toSet());
Set<FileAttribute> audioTracks = tracks.stream().filter(a -> AUDIO.equals(a.type())).collect(Collectors.toSet());
Set<FileAttribute> subtitleTracks = tracks.stream().filter(a -> SUBTITLES.equals(a.type())).collect(Collectors.toSet());
for (AttributeConfig config : configs) {
Optional<FileAttribute> desiredAudio = detectDesiredTrack(config.getAudioLanguage(), audioTracks).findFirst();
Optional<FileAttribute> desiredSubtitle = detectDesiredSubtitleTrack(config.getSubtitleLanguage(), subtitleTracks).findFirst();
if (desiredAudio.isPresent() && ("OFF".equals(config.getSubtitleLanguage()) || desiredSubtitle.isPresent())) {
if (("OFF".equals(config.getAudioLanguage()) || desiredAudio.isPresent())
&& ("OFF".equals(config.getSubtitleLanguage()) || desiredSubtitle.isPresent())) {
info.setMatchedConfig(config);
info.setDesiredDefaultAudioLane(desiredAudio.get());
info.setDesiredDefaultAudioLane(desiredAudio.orElse(null));
info.setDesiredDefaultSubtitleLane(desiredSubtitle.orElse(null));
break;
}
@@ -119,7 +120,7 @@ public class MkvFileProcessor implements FileProcessor {
}
private Stream<FileAttribute> detectDesiredTrack(String language, Set<FileAttribute> tracks) {
return tracks.stream().filter(track -> language.equals(track.getLanguage()));
return tracks.stream().filter(track -> language.equals(track.language()));
}
private Stream<FileAttribute> detectDesiredSubtitleTrack(String language, Set<FileAttribute> tracks) {
@@ -130,16 +131,16 @@ public class MkvFileProcessor implements FileProcessor {
@Override
public List<FileAttribute> retrieveNonForcedTracks(List<FileAttribute> attributes) {
return attributes.stream()
.filter(elem -> !StringUtils.containsAnyIgnoreCase(elem.getTrackName(),
.filter(elem -> !StringUtils.containsAnyIgnoreCase(elem.trackName(),
Config.getInstance().getForcedKeywords().toArray(new CharSequence[0])))
.filter(elem -> !elem.isForcedTrack())
.filter(elem -> !elem.forcedTrack())
.collect(Collectors.toList());
}
@Override
public List<FileAttribute> retrieveNonCommentaryTracks(List<FileAttribute> attributes) {
return attributes.stream()
.filter(elem -> !StringUtils.containsAnyIgnoreCase(elem.getTrackName(),
.filter(elem -> !StringUtils.containsAnyIgnoreCase(elem.trackName(),
Config.getInstance().getCommentaryKeywords().toArray(new CharSequence[0])))
.collect(Collectors.toList());
}
@@ -148,40 +149,28 @@ public class MkvFileProcessor implements FileProcessor {
* {@inheritDoc}
*/
@Override
public void update(File file, FileInfoDto fileInfo) throws IOException, MkvToolNixException {
public void update(File file, FileInfo fileInfo) throws IOException, MkvToolNixException {
List<String> command = new ArrayList<>();
command.add(Config.getInstance().getPathFor(MkvToolNix.MKV_PROP_EDIT));
command.add(String.format(file.getAbsolutePath()));
if (fileInfo.isAudioDifferent()) {
if (fileInfo.getExistingDefaultAudioLanes() != null && !fileInfo.getExistingDefaultAudioLanes().isEmpty()) {
for (FileAttribute track : fileInfo.getExistingDefaultAudioLanes()) {
command.addAll(format(DISABLE_DEFAULT_TRACK, track.getId()));
}
}
command.addAll(format(ENABLE_DEFAULT_TRACK, fileInfo.getDesiredDefaultAudioLane().getId()));
removeExistingAndAddDesiredLanes(fileInfo.getExistingDefaultAudioLanes(), fileInfo.getDesiredDefaultAudioLane(), command);
}
if (!fileInfo.getExistingForcedAudioLanes().isEmpty()) {
for (FileAttribute track : fileInfo.getExistingForcedAudioLanes()) {
command.addAll(format(DISABLE_FORCED_TRACK, track.getId()));
command.addAll(format(DISABLE_FORCED_TRACK, track.id()));
}
}
if (fileInfo.isSubtitleDifferent()) {
if (fileInfo.getExistingDefaultSubtitleLanes() != null && !fileInfo.getExistingDefaultSubtitleLanes().isEmpty()) {
for (FileAttribute track : fileInfo.getExistingDefaultSubtitleLanes()) {
command.addAll(format(DISABLE_DEFAULT_TRACK, track.getId()));
}
}
if (fileInfo.getDesiredDefaultSubtitleLane() != null) {
command.addAll(format(ENABLE_DEFAULT_TRACK, fileInfo.getDesiredDefaultSubtitleLane().getId()));
}
removeExistingAndAddDesiredLanes(fileInfo.getExistingDefaultSubtitleLanes(), fileInfo.getDesiredDefaultSubtitleLane(), command);
}
if (fileInfo.areForcedTracksDifferent()) {
for (FileAttribute track : fileInfo.getDesiredForcedSubtitleLanes()) {
command.addAll(format(ENABLE_FORCED_TRACK, track.getId()));
command.addAll(format(ENABLE_FORCED_TRACK, track.id()));
}
}
@@ -192,6 +181,17 @@ public class MkvFileProcessor implements FileProcessor {
if (output.contains("Error")) throw new MkvToolNixException(output);
}
private void removeExistingAndAddDesiredLanes(Set<FileAttribute> existingDefaultLanes, FileAttribute desiredDefaultLanes, List<String> command) {
if (existingDefaultLanes != null && !existingDefaultLanes.isEmpty()) {
for (FileAttribute track : existingDefaultLanes) {
command.addAll(format(DISABLE_DEFAULT_TRACK, track.id()));
}
}
if (desiredDefaultLanes != null) {
command.addAll(format(ENABLE_DEFAULT_TRACK, desiredDefaultLanes.id()));
}
}
private List<String> format(String format, Object... args) {
return Arrays.asList(String.format(format, args).split(" "));
}

View File

@@ -17,16 +17,16 @@ public class SubtitleTrackComparator implements Comparator<FileAttribute> {
public int compare(FileAttribute track1, FileAttribute track2) {
int result = 0;
if (StringUtils.containsAnyIgnoreCase(track1.getTrackName(), preferredSubtitles)) {
if (StringUtils.containsAnyIgnoreCase(track1.trackName(), preferredSubtitles)) {
result++;
}
if (StringUtils.containsAnyIgnoreCase(track2.getTrackName(), preferredSubtitles)) {
if (StringUtils.containsAnyIgnoreCase(track2.trackName(), preferredSubtitles)) {
result--;
}
if (result == 0) {
if (track1.isDefaultTrack()) result++;
if (track2.isDefaultTrack()) result--;
if (track1.defaultTrack()) result++;
if (track2.defaultTrack()) result--;
}
return result;

View File

@@ -6,7 +6,7 @@ import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileCollector;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileProcessor;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfoDto;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfo;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ResultStatistic;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.DateUtils;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.ProjectUtil;
@@ -96,7 +96,7 @@ public abstract class AttributeUpdaterKernel {
* @param file file or directory to update
*/
void process(File file) {
FileInfoDto fileInfo = new FileInfoDto(file);
FileInfo fileInfo = new FileInfo(file);
List<FileAttribute> attributes = processor.loadAttributes(file);
if (attributes == null || attributes.isEmpty()) {
@@ -119,14 +119,14 @@ public abstract class AttributeUpdaterKernel {
/**
* Persist file changes.
*
* @param fileInfoDto contains information about file and desired configuration.
* @param fileInfo contains information about file and desired configuration.
*/
protected void updateFile(FileInfoDto fileInfoDto) {
protected void updateFile(FileInfo fileInfo) {
statistic.total();
switch (fileInfoDto.getStatus()) {
switch (fileInfo.getStatus()) {
case CHANGE_NECESSARY:
statistic.shouldChange();
commitChange(fileInfoDto);
commitChange(fileInfo);
break;
case NO_SUITABLE_CONFIG:
statistic.noSuitableConfigFound();
@@ -141,7 +141,7 @@ public abstract class AttributeUpdaterKernel {
}
}
private void commitChange(FileInfoDto fileInfo) {
private void commitChange(FileInfo fileInfo) {
if (Config.getInstance().isSafeMode()) {
return;
}

View File

@@ -5,7 +5,7 @@ import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileCollector;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileProcessor;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfoDto;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfo;
import lombok.extern.slf4j.Slf4j;
import me.tongfei.progressbar.ProgressBarBuilder;
import org.apache.commons.lang3.StringUtils;
@@ -67,13 +67,13 @@ public class CoherentAttributeUpdaterKernel extends AttributeUpdaterKernel {
void process(File file, int depth) {
// TODO: Implement level crawl if coherence is not possible on user entered depth
// IMPL idea: recursive method call, cache needs to be implemented
List<FileInfoDto> fileInfos = collector.loadFiles(file.getAbsolutePath()).stream()
.map(FileInfoDto::new)
List<FileInfo> fileInfos = collector.loadFiles(file.getAbsolutePath()).stream()
.map(FileInfo::new)
.collect(Collectors.toList());
for (AttributeConfig config : Config.getInstance().getAttributeConfig()) {
for (FileInfoDto fileInfo : fileInfos) {
for (FileInfo fileInfo : fileInfos) {
List<FileAttribute> attributes = processor.loadAttributes(fileInfo.getFile());
List<FileAttribute> nonForcedTracks = processor.retrieveNonForcedTracks(attributes);
@@ -98,7 +98,7 @@ public class CoherentAttributeUpdaterKernel extends AttributeUpdaterKernel {
log.info("No coherent match found for {}", file.getAbsoluteFile());
for (FileInfoDto fileInfo : fileInfos) {
for (FileInfo fileInfo : fileInfos) {
if (!Config.getInstance().isForceCoherent()) {
super.process(fileInfo.getFile());
} else {