Refactor MediaInfo.open(File) to throw IOException on error
This commit is contained in:
parent
8773e3b183
commit
aca56eac9a
|
@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue