Refactor MediaInfo.open(File) to throw IOException on error

This commit is contained in:
Reinhard Pointner 2016-03-11 08:16:59 +00:00
parent 8773e3b183
commit aca56eac9a
6 changed files with 48 additions and 67 deletions

View File

@ -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;
}
});
}
}

View File

@ -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;

View File

@ -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<StreamKind, List<Map<String, String>>> 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();
}
}
}

View File

@ -193,20 +193,19 @@ public enum SubtitleMetrics implements SimilarityMetric {
return mediaInfoCache.computeIfAbsent(file, (f) -> {
try {
Map<String, Object> props = new HashMap<String, Object>();
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();
});

View File

@ -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<StreamKind, List<Map<String, String>>> 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

View File

@ -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");