From aca56eac9a2febfe493fadfba92e9407422fe40d Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Fri, 11 Mar 2016 08:16:59 +0000 Subject: [PATCH] Refactor MediaInfo.open(File) to throw IOException on error --- .../net/filebot/format/MediaBindingBean.java | 19 +++++----- .../mediainfo/MediaDurationFilter.java | 13 +++---- source/net/filebot/mediainfo/MediaInfo.java | 36 +++++++++---------- .../net/filebot/subtitle/SubtitleMetrics.java | 23 ++++++------ .../net/filebot/ui/rename/BindingDialog.java | 18 ++-------- source/net/filebot/web/ID3Lookup.java | 6 ++-- 6 files changed, 48 insertions(+), 67 deletions(-) diff --git a/source/net/filebot/format/MediaBindingBean.java b/source/net/filebot/format/MediaBindingBean.java index 2b7490d6..9c4386d1 100644 --- a/source/net/filebot/format/MediaBindingBean.java +++ b/source/net/filebot/format/MediaBindingBean.java @@ -34,6 +34,8 @@ import java.util.TreeSet; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; +import com.cedarsoftware.util.io.JsonWriter; + import net.filebot.Cache; import net.filebot.CacheType; import net.filebot.Language; @@ -45,6 +47,7 @@ import net.filebot.hash.HashType; import net.filebot.media.MetaAttributes; import net.filebot.mediainfo.MediaInfo; import net.filebot.mediainfo.MediaInfo.StreamKind; +import net.filebot.mediainfo.MediaInfoException; import net.filebot.similarity.SimilarityComparator; import net.filebot.util.FileUtilities; import net.filebot.util.WeakValueHashMap; @@ -60,8 +63,6 @@ import net.filebot.web.SortOrder; import net.filebot.web.TMDbClient.MovieInfo; import net.filebot.web.TheTVDBSeriesInfo; -import com.cedarsoftware.util.io.JsonWriter; - public class MediaBindingBean { private final Object infoObject; @@ -960,15 +961,13 @@ public class MediaBindingBean { File inferredMediaFile = getInferredMediaFile(); synchronized (sharedMediaInfoObjects) { - mediaInfo = sharedMediaInfoObjects.get(inferredMediaFile); - if (mediaInfo == null) { - MediaInfo mi = new MediaInfo(); - if (!mi.open(inferredMediaFile)) { - throw new RuntimeException("Cannot open media file: " + inferredMediaFile); + mediaInfo = sharedMediaInfoObjects.computeIfAbsent(inferredMediaFile, f -> { + try { + return new MediaInfo().open(f); + } catch (Exception e) { + throw new MediaInfoException(e.getMessage()); } - sharedMediaInfoObjects.put(inferredMediaFile, mi); - mediaInfo = mi; - } + }); } } diff --git a/source/net/filebot/mediainfo/MediaDurationFilter.java b/source/net/filebot/mediainfo/MediaDurationFilter.java index 6e99fadd..61517ae5 100644 --- a/source/net/filebot/mediainfo/MediaDurationFilter.java +++ b/source/net/filebot/mediainfo/MediaDurationFilter.java @@ -1,5 +1,7 @@ package net.filebot.mediainfo; +import static net.filebot.Logging.*; + import java.io.File; import java.io.FileFilter; @@ -25,12 +27,11 @@ public class MediaDurationFilter implements FileFilter { public long getDuration(File file) { synchronized (mediaInfo) { - if (mediaInfo.open(file)) { - try { - return Long.parseLong(mediaInfo.get(StreamKind.General, 0, "Duration")); - } catch (NumberFormatException e) { - // ignore, assume duration couldn't be read - } + try { + String duration = mediaInfo.open(file).get(StreamKind.General, 0, "Duration"); + return Long.parseLong(duration); + } catch (Exception e) { + debug.warning("Failed to read video duration: " + e.getMessage()); } } return -1; diff --git a/source/net/filebot/mediainfo/MediaInfo.java b/source/net/filebot/mediainfo/MediaInfo.java index 052b251a..6db9c0bb 100644 --- a/source/net/filebot/mediainfo/MediaInfo.java +++ b/source/net/filebot/mediainfo/MediaInfo.java @@ -1,7 +1,5 @@ package net.filebot.mediainfo; -import static net.filebot.Logging.*; - import java.io.Closeable; import java.io.File; import java.io.IOException; @@ -29,31 +27,35 @@ public class MediaInfo implements Closeable { } } - public synchronized boolean open(File file) { + public synchronized MediaInfo open(File file) throws IOException { if (!file.isFile() || file.length() < 64 * 1024) { - return false; + throw new IllegalArgumentException("Invalid media file: " + file); } - String path = file.getAbsolutePath(); + String path = file.getCanonicalPath(); // on Mac files that contain accents cannot be opened via JNA WString file paths due to encoding differences so we use the buffer interface instead for these files if (Platform.isMac() && !StandardCharsets.US_ASCII.newEncoder().canEncode(path)) { try (RandomAccessFile raf = new RandomAccessFile(file, "r")) { - return openViaBuffer(raf); - } catch (IOException e) { - debug.warning("Failed to open random access file: " + e.getMessage()); - return false; + if (openViaBuffer(raf)) { + throw new IOException("Failed to initialize media info buffer: " + path); + } } } - return MediaInfoLibrary.INSTANCE.Open(handle, new WString(path)) > 0; + if (0 == MediaInfoLibrary.INSTANCE.Open(handle, new WString(path))) { + // failed to open file + throw new IOException("Failed to open media file: " + path); + } + + return this; } private boolean openViaBuffer(RandomAccessFile f) throws IOException { byte[] buffer = new byte[4 * 1024 * 1024]; // use large buffer to reduce JNA calls int read = -1; - if (MediaInfoLibrary.INSTANCE.Open_Buffer_Init(handle, f.length(), 0) <= 0) { + if (0 == MediaInfoLibrary.INSTANCE.Open_Buffer_Init(handle, f.length(), 0)) { return false; } @@ -249,15 +251,9 @@ public class MediaInfo implements Closeable { * Helper for easy usage */ public static Map>> snapshot(File file) throws IOException { - MediaInfo mi = new MediaInfo(); - try { - if (mi.open(file)) { - return mi.snapshot(); - } else { - throw new IOException("Failed to open file: " + file); - } - } finally { - mi.close(); + try (MediaInfo mi = new MediaInfo()) { + return mi.open(file).snapshot(); } } + } diff --git a/source/net/filebot/subtitle/SubtitleMetrics.java b/source/net/filebot/subtitle/SubtitleMetrics.java index edd70c85..00457962 100644 --- a/source/net/filebot/subtitle/SubtitleMetrics.java +++ b/source/net/filebot/subtitle/SubtitleMetrics.java @@ -193,20 +193,19 @@ public enum SubtitleMetrics implements SimilarityMetric { return mediaInfoCache.computeIfAbsent(file, (f) -> { try { Map props = new HashMap(); - MediaInfo mediaInfo = new MediaInfo(); - if (mediaInfo.open(file)) { - float fps = round(Float.parseFloat(mediaInfo.get(StreamKind.Video, 0, "FrameRate"))); - if (fps > 0) { - props.put(FPS, fps); - } - long seconds = (long) floor(Long.parseLong(mediaInfo.get(StreamKind.Video, 0, "Duration")) / (double) 1000); - if (seconds > 0) { - props.put(SECONDS, seconds); - } - return props; + MediaInfo mediaInfo = new MediaInfo().open(file); + + float fps = round(Float.parseFloat(mediaInfo.get(StreamKind.Video, 0, "FrameRate"))); + if (fps > 0) { + props.put(FPS, fps); } + long seconds = (long) floor(Long.parseLong(mediaInfo.get(StreamKind.Video, 0, "Duration")) / (double) 1000); + if (seconds > 0) { + props.put(SECONDS, seconds); + } + return props; } catch (Exception e) { - debug.warning("Failed to read video properties: " + e); + debug.warning("Failed to read video properties: " + e.getMessage()); } return emptyMap(); }); diff --git a/source/net/filebot/ui/rename/BindingDialog.java b/source/net/filebot/ui/rename/BindingDialog.java index e3c4d737..40095ca7 100644 --- a/source/net/filebot/ui/rename/BindingDialog.java +++ b/source/net/filebot/ui/rename/BindingDialog.java @@ -54,7 +54,6 @@ import net.filebot.format.MediaBindingBean; import net.filebot.media.MediaDetection; import net.filebot.mediainfo.MediaInfo; import net.filebot.mediainfo.MediaInfo.StreamKind; -import net.filebot.mediainfo.MediaInfoException; import net.filebot.util.DefaultThreadFactory; import net.filebot.util.FileUtilities.ExtensionFileFilter; import net.filebot.util.ui.LazyDocumentListener; @@ -293,22 +292,11 @@ class BindingDialog extends JDialog { private Map>> getMediaInfo(File file) { try { - MediaInfo mediaInfo = new MediaInfo(); - - // read all media info - if (mediaInfo.open(file)) { - try { - return mediaInfo.snapshot(); - } finally { - mediaInfo.close(); - } - } - } catch (MediaInfoException e) { + return MediaInfo.snapshot(file); + } catch (Exception e) { log.log(Level.SEVERE, e.getMessage(), e); + return null; } - - // could not retrieve media info - return null; } @Override diff --git a/source/net/filebot/web/ID3Lookup.java b/source/net/filebot/web/ID3Lookup.java index 79de99f3..953ea48a 100644 --- a/source/net/filebot/web/ID3Lookup.java +++ b/source/net/filebot/web/ID3Lookup.java @@ -15,7 +15,6 @@ import javax.swing.Icon; import net.filebot.ResourceManager; import net.filebot.mediainfo.MediaInfo; import net.filebot.mediainfo.MediaInfo.StreamKind; -import net.filebot.mediainfo.MediaInfoException; public class ID3Lookup implements MusicIdentificationService { @@ -36,9 +35,8 @@ public class ID3Lookup implements MusicIdentificationService { try (MediaInfo mediaInfo = new MediaInfo()) { for (File f : filter(files, AUDIO_FILES, VIDEO_FILES)) { try { - if (!mediaInfo.open(f)) { - throw new MediaInfoException("Failed to read media info: " + f); - } + // open or throw exception + mediaInfo.open(f); // artist and song title information is required String artist = getString(mediaInfo, "Performer", "Composer");