From f7f41509e198ad269c4a8da5fab0f9483d69f3c4 Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Sat, 12 Jan 2013 15:21:33 +0000 Subject: [PATCH] * extracted common MusicIdentificationService interface and added a dummy one that is only reading MediaInfo/ID3 --- .../net/sourceforge/filebot/WebServices.java | 17 +++++++ .../filebot/cli/CmdlineOperations.java | 8 +-- .../filebot/format/MediaBindingBean.java | 12 ++++- .../ui/rename/AudioFingerprintMatcher.java | 6 +-- .../net/sourceforge/filebot/web/AcoustID.java | 5 +- .../sourceforge/filebot/web/ID3Lookup.java | 51 +++++++++++++++++++ .../web/MusicIdentificationService.java | 21 ++++++++ 7 files changed, 111 insertions(+), 9 deletions(-) create mode 100644 source/net/sourceforge/filebot/web/ID3Lookup.java create mode 100644 source/net/sourceforge/filebot/web/MusicIdentificationService.java diff --git a/source/net/sourceforge/filebot/WebServices.java b/source/net/sourceforge/filebot/WebServices.java index a71e7329..d2590152 100644 --- a/source/net/sourceforge/filebot/WebServices.java +++ b/source/net/sourceforge/filebot/WebServices.java @@ -25,9 +25,11 @@ import net.sourceforge.filebot.web.AcoustID; import net.sourceforge.filebot.web.AnidbClient; import net.sourceforge.filebot.web.EpisodeListProvider; import net.sourceforge.filebot.web.FanartTV; +import net.sourceforge.filebot.web.ID3Lookup; import net.sourceforge.filebot.web.IMDbClient; import net.sourceforge.filebot.web.LocalSearch; import net.sourceforge.filebot.web.MovieIdentificationService; +import net.sourceforge.filebot.web.MusicIdentificationService; import net.sourceforge.filebot.web.OpenSubtitlesClient; import net.sourceforge.filebot.web.SearchResult; import net.sourceforge.filebot.web.SerienjunkiesClient; @@ -87,6 +89,11 @@ public final class WebServices { } + public static MusicIdentificationService[] getMusicIdentificationServices() { + return new MusicIdentificationService[] { AcoustID, new ID3Lookup() }; + } + + public static EpisodeListProvider getEpisodeListProvider(String name) { for (EpisodeListProvider it : WebServices.getEpisodeListProviders()) { if (it.getName().equalsIgnoreCase(name)) @@ -107,6 +114,16 @@ public final class WebServices { } + public static MusicIdentificationService getMusicIdentificationService(String name) { + for (MusicIdentificationService it : getMusicIdentificationServices()) { + if (it.getName().equalsIgnoreCase(name)) + return it; + } + + return null; // default + } + + private static class TheTVDBClientWithLocalSearch extends TheTVDBClient { public TheTVDBClientWithLocalSearch(String apikey) { diff --git a/source/net/sourceforge/filebot/cli/CmdlineOperations.java b/source/net/sourceforge/filebot/cli/CmdlineOperations.java index 130d5507..18a01964 100644 --- a/source/net/sourceforge/filebot/cli/CmdlineOperations.java +++ b/source/net/sourceforge/filebot/cli/CmdlineOperations.java @@ -66,7 +66,6 @@ import net.sourceforge.filebot.similarity.SimilarityMetric; import net.sourceforge.filebot.subtitle.SubtitleFormat; import net.sourceforge.filebot.ui.Language; import net.sourceforge.filebot.vfs.MemoryFile; -import net.sourceforge.filebot.web.AcoustID; import net.sourceforge.filebot.web.AudioTrack; import net.sourceforge.filebot.web.Episode; import net.sourceforge.filebot.web.EpisodeFormat; @@ -75,6 +74,7 @@ import net.sourceforge.filebot.web.Movie; import net.sourceforge.filebot.web.MovieFormat; import net.sourceforge.filebot.web.MovieIdentificationService; import net.sourceforge.filebot.web.MoviePart; +import net.sourceforge.filebot.web.MusicIdentificationService; import net.sourceforge.filebot.web.SearchResult; import net.sourceforge.filebot.web.SortOrder; import net.sourceforge.filebot.web.SubtitleDescriptor; @@ -103,9 +103,9 @@ public class CmdlineOperations implements CmdlineInterface { return renameMovie(files, action, conflictAction, outputDir, format, getMovieIdentificationService(db), query, locale, strict); } - if (WebServices.AcoustID.getName().equalsIgnoreCase(db) || containsOnly(files, AUDIO_FILES)) { + if (getMusicIdentificationService(db) != null || containsOnly(files, AUDIO_FILES)) { // music mode - return renameMusic(files, action, conflictAction, outputDir, format, WebServices.AcoustID); + return renameMusic(files, action, conflictAction, outputDir, format, getMusicIdentificationService(db) == null ? AcoustID : getMusicIdentificationService(db)); } // auto-determine mode @@ -505,7 +505,7 @@ public class CmdlineOperations implements CmdlineInterface { } - public List renameMusic(Collection files, RenameAction renameAction, ConflictAction conflictAction, File outputDir, ExpressionFormat format, AcoustID service) throws Exception { + public List renameMusic(Collection files, RenameAction renameAction, ConflictAction conflictAction, File outputDir, ExpressionFormat format, MusicIdentificationService service) throws Exception { // map old files to new paths by applying formatting and validating filenames Map renameMap = new LinkedHashMap(); diff --git a/source/net/sourceforge/filebot/format/MediaBindingBean.java b/source/net/sourceforge/filebot/format/MediaBindingBean.java index c9ca27f8..2b77814b 100644 --- a/source/net/sourceforge/filebot/format/MediaBindingBean.java +++ b/source/net/sourceforge/filebot/format/MediaBindingBean.java @@ -82,6 +82,8 @@ public class MediaBindingBean { return getEpisode().getSeriesStartDate().getYear(); if (infoObject instanceof Movie) return getMovie().getYear(); + if (infoObject instanceof AudioTrack) + return new Scanner(getMediaInfo(StreamKind.General, 0, "Recorded_Date")).useDelimiter("\\D+").nextInt(); return null; } @@ -422,6 +424,9 @@ public class MediaBindingBean { @Define("genres") public Object getGenres() { + if (infoObject instanceof AudioTrack) + return asList(getMediaInfo(StreamKind.General, 0, "Genre").split(";")); + return getMetaInfo().getProperty("genres"); } @@ -561,7 +566,12 @@ public class MediaBindingBean { @Define("pi") public Integer getPart() { - return ((MoviePart) infoObject).getPartIndex(); + if (infoObject instanceof AudioTrack) + return Integer.parseInt(getMediaInfo(StreamKind.General, 0, "Track/Position")); + if (infoObject instanceof MoviePart) + return ((MoviePart) infoObject).getPartIndex(); + + return null; } diff --git a/source/net/sourceforge/filebot/ui/rename/AudioFingerprintMatcher.java b/source/net/sourceforge/filebot/ui/rename/AudioFingerprintMatcher.java index 4f119739..e711ebd1 100644 --- a/source/net/sourceforge/filebot/ui/rename/AudioFingerprintMatcher.java +++ b/source/net/sourceforge/filebot/ui/rename/AudioFingerprintMatcher.java @@ -13,17 +13,17 @@ import java.util.Locale; import java.util.Map.Entry; import net.sourceforge.filebot.similarity.Match; -import net.sourceforge.filebot.web.AcoustID; import net.sourceforge.filebot.web.AudioTrack; +import net.sourceforge.filebot.web.MusicIdentificationService; import net.sourceforge.filebot.web.SortOrder; class AudioFingerprintMatcher implements AutoCompleteMatcher { - private AcoustID service; + private MusicIdentificationService service; - public AudioFingerprintMatcher(AcoustID service) { + public AudioFingerprintMatcher(MusicIdentificationService service) { this.service = service; } diff --git a/source/net/sourceforge/filebot/web/AcoustID.java b/source/net/sourceforge/filebot/web/AcoustID.java index 7dd14ae7..1056163f 100644 --- a/source/net/sourceforge/filebot/web/AcoustID.java +++ b/source/net/sourceforge/filebot/web/AcoustID.java @@ -25,7 +25,7 @@ import net.sourceforge.filebot.ResourceManager; import com.cedarsoftware.util.io.JsonReader; -public class AcoustID { +public class AcoustID implements MusicIdentificationService { private static final FloodLimit REQUEST_LIMIT = new FloodLimit(3, 1, TimeUnit.SECONDS); @@ -37,16 +37,19 @@ public class AcoustID { } + @Override public String getName() { return "AcoustID"; } + @Override public Icon getIcon() { return ResourceManager.getIcon("search.acoustid"); } + @Override public Map lookup(Iterable files) throws Exception { Map results = new LinkedHashMap(); diff --git a/source/net/sourceforge/filebot/web/ID3Lookup.java b/source/net/sourceforge/filebot/web/ID3Lookup.java new file mode 100644 index 00000000..8e44d23a --- /dev/null +++ b/source/net/sourceforge/filebot/web/ID3Lookup.java @@ -0,0 +1,51 @@ + +package net.sourceforge.filebot.web; + + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.Icon; + +import net.sourceforge.filebot.mediainfo.MediaInfo; +import net.sourceforge.filebot.mediainfo.MediaInfo.StreamKind; + + +public class ID3Lookup implements MusicIdentificationService { + + @Override + public String getName() { + return "ID3"; + } + + + @Override + public Icon getIcon() { + return null; + } + + + @Override + public Map lookup(Iterable files) throws Exception { + Map info = new HashMap(); + + MediaInfo mediaInfo = new MediaInfo(); + for (File f : files) { + if (!mediaInfo.open(f)) { + throw new IOException("MediaInfo failed to open file: " + f); + } + + String artist = mediaInfo.get(StreamKind.General, 0, "Performer"); + String title = mediaInfo.get(StreamKind.General, 0, "Title"); + String album = mediaInfo.get(StreamKind.General, 0, "Album"); + mediaInfo.close(); + + info.put(f, new AudioTrack(artist, title, album)); + } + + return info; + } + +} diff --git a/source/net/sourceforge/filebot/web/MusicIdentificationService.java b/source/net/sourceforge/filebot/web/MusicIdentificationService.java new file mode 100644 index 00000000..a3fc6f8e --- /dev/null +++ b/source/net/sourceforge/filebot/web/MusicIdentificationService.java @@ -0,0 +1,21 @@ + +package net.sourceforge.filebot.web; + + +import java.io.File; +import java.util.Map; + +import javax.swing.Icon; + + +public interface MusicIdentificationService { + + String getName(); + + + Icon getIcon(); + + + Map lookup(Iterable files) throws Exception; + +}