diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/AttributeUpdaterKernel.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/AttributeUpdaterKernel.java index 26cfcc9..03db8cb 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/AttributeUpdaterKernel.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/AttributeUpdaterKernel.java @@ -4,24 +4,38 @@ import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.AttributeConfig; import at.pcgamingfreaks.mkvaudiosubtitlechanger.intimpl.MkvFileCollector; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute; import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.ConfigUtil; +import lombok.extern.log4j.Log4j2; import java.io.File; +import java.util.ArrayList; import java.util.List; import java.util.Scanner; +@Log4j2 public class AttributeUpdaterKernel { MkvFileCollector collector = new MkvFileCollector(); + public void execute() { List configPattern = ConfigUtil.loadConfig(); Scanner scanner = new Scanner(System.in); System.out.println("Please enter the path to the files which should be updated: "); - List allValidPaths = collector.loadFiles(scanner.nextLine()); + List allValidPaths = null; + do{ + allValidPaths = collector.loadFiles(scanner.nextLine()); + if(allValidPaths == null){ + System.out.println("Please enter a valid path: "); + } + }while(allValidPaths == null); + log.info(allValidPaths.size() + " files where found and will now be processed!"); - for(File file: allValidPaths) { + for(File file : allValidPaths){ List attributes = collector.loadAttributes(file); - for(AttributeConfig config: configPattern) { - boolean fileIsChanged = config.processConfig(file, attributes); - if(fileIsChanged) { + for(AttributeConfig config : configPattern){ + /* + * Creating new ArrayList, because the method removes elements from the list by reference + */ + boolean fileIsChanged = config.processConfig(file, new ArrayList<>(attributes)); + if(fileIsChanged){ break; } } diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java new file mode 100644 index 0000000..5c21376 --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java @@ -0,0 +1,11 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger; + +import config.MKVToolProperties; + +public class Main { + public static void main(String[] args) { + MKVToolProperties.getInstance().defineMKVToolNixPath(); + AttributeUpdaterKernel kernel = new AttributeUpdaterKernel(); + kernel.execute(); + } +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/AttributeConfig.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/AttributeConfig.java index ad999c7..86cce89 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/AttributeConfig.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/AttributeConfig.java @@ -1,13 +1,21 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.config; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute; +import config.MKVToolProperties; import lombok.Getter; +import lombok.Setter; +import lombok.extern.log4j.Log4j2; import java.io.File; +import java.io.IOException; +import java.util.Iterator; import java.util.List; +@Log4j2 @Getter public class AttributeConfig { + int audioDefault; + int subtitleDefault; private List audio; private List subtitle; @@ -18,14 +26,135 @@ public class AttributeConfig { /** * Processes the config lists and apply the changes if the combination matches + * + * @param file is the file, which will be updated + * @param attributes has the metadata for the transferred file * @return If the current configuration matched and changes applied or not */ public boolean processConfig(File file, List attributes) { // check if size is bigger or equal 2 to make sure that there is at least one audio and subtitle line // TODO: implement empty audio or subtitle line - if(attributes.size() >= 2) { - // TODO: Update queryBuilder:updateAttributes here + if(attributes.size() >= 2){ + filterAttributes(attributes); + if(! attributes.isEmpty()){ + return updateFile(file, attributes); + } + } + return false; + } + + /* + * Filters the attributes that only those are remaining which are needed in the current configuration. + * Also analyzes which tracks were default before. + */ + private void filterAttributes(List attributes) { + Iterator iterator = attributes.iterator(); + while(iterator.hasNext()){ + FileAttribute elem = iterator.next(); + if("audio".equals(elem.getType())){ + if(elem.isDefaultTrack()){ + audioDefault = elem.getId(); + } + if(! audio.contains(elem.getLanguage())){ + iterator.remove(); + } + }else if("subtitles".equals(elem.getType())){ + if(elem.isDefaultTrack()){ + subtitleDefault = elem.getId(); + } + if(! subtitle.contains(elem.getLanguage())){ + iterator.remove(); + } + } + } + } + + /** + * Creates the command which will be executed if the attributes of the current file fit the current {@link AttributeConfig} + * + * @param file is the file, which will be updated + * @param attributes has the metadata for the transferred file + * @return if the the current file was updated or not. Returns true if the file already has the correct metadata set + */ + private boolean updateFile(File file, List attributes) { + StringBuilder stringBuffer = new StringBuilder("\""); + stringBuffer.append(MKVToolProperties.getInstance().getMkvpropeditPath()); + stringBuffer.append("\" \"").append(file.getAbsolutePath()).append("\" "); + stringBuffer.append("--edit track:").append(subtitleDefault).append(" --set flag-default=0 "); + stringBuffer.append("--edit track:").append(audioDefault).append(" --set flag-default=0 "); + TransferObject transfer = collectLines(attributes); + if(transfer.isValid){ + stringBuffer.append("--edit track:").append(transfer.getSubtitleIndex()).append(" --set flag-default=1 "); + stringBuffer.append("--edit track:").append(transfer.getAudioIndex()).append(" --set flag-default=1 "); + if(subtitleDefault == transfer.getSubtitleIndex() && audioDefault == transfer.getAudioIndex()){ + /* + * In this case the file would be change to the exact same audio and subtitle lines and we want to + * avoid unnecessary changes to the file + */ + return true; + } + try{ + Runtime.getRuntime().exec(stringBuffer.toString()); + }catch(IOException e){ + log.error("Couldn't make changes to file"); + + } + /* + * We return true even if there was an error. If there was an error, the chances that this file is still + * busy later. + */ + return true; + }else{ + return false; + } + } + + /** + * Analyzes the left over attributes and decides which is the most wanted for audio and subtitle + * + * @param attributes contains all the leftover attributes + * @return is an object, which contains information about which audio and subtitle line is the best suitable for + * the entered config. Also transfers a boolean which contains information about if the other two values + * were set + */ + private TransferObject collectLines(List attributes) { + TransferObject transfer = new TransferObject(); + int subtitleListIndex = - 1; + int audioListIndex = - 1; + for(FileAttribute elem : attributes){ + if("audio".equals(elem.getType())){ + for(int i = 0; i < audio.size(); i++){ + if(audio.get(i).equals(elem.getLanguage()) && (audioListIndex == - 1 || i < audioListIndex)){ + audioListIndex = i; + transfer.setAudioIndex(elem.getId()); + } + } + }else if("subtitles".equals(elem.getType())){ + for(int i = 0; i < subtitle.size(); i++){ + if(subtitle.get(i).equals(elem.getLanguage()) && (subtitleListIndex == - 1 || i < subtitleListIndex)){ + subtitleListIndex = i; + transfer.setSubtitleIndex(elem.getId()); + } + } + } + } + + transfer.analyzeIfValid(); + return transfer; + } + + @Getter + @Setter + private static class TransferObject { + private boolean isValid; + private int audioIndex = - 1; + private int subtitleIndex = - 1; + + TransferObject() { + } + + private void analyzeIfValid() { + isValid = audioIndex != - 1 && subtitleIndex != - 1; } - return true; } } diff --git a/src/main/resources/config.yaml b/src/main/resources/config.yaml index 44b2717..8d72007 100644 --- a/src/main/resources/config.yaml +++ b/src/main/resources/config.yaml @@ -3,8 +3,8 @@ config: audio: - jpn subtitle: - - ger - eng + - ger 2: audio: - eng