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.concurrent.TimeUnit;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import com.cedarsoftware.util.io.JsonWriter;
|
||||||
|
|
||||||
import net.filebot.Cache;
|
import net.filebot.Cache;
|
||||||
import net.filebot.CacheType;
|
import net.filebot.CacheType;
|
||||||
import net.filebot.Language;
|
import net.filebot.Language;
|
||||||
|
@ -45,6 +47,7 @@ import net.filebot.hash.HashType;
|
||||||
import net.filebot.media.MetaAttributes;
|
import net.filebot.media.MetaAttributes;
|
||||||
import net.filebot.mediainfo.MediaInfo;
|
import net.filebot.mediainfo.MediaInfo;
|
||||||
import net.filebot.mediainfo.MediaInfo.StreamKind;
|
import net.filebot.mediainfo.MediaInfo.StreamKind;
|
||||||
|
import net.filebot.mediainfo.MediaInfoException;
|
||||||
import net.filebot.similarity.SimilarityComparator;
|
import net.filebot.similarity.SimilarityComparator;
|
||||||
import net.filebot.util.FileUtilities;
|
import net.filebot.util.FileUtilities;
|
||||||
import net.filebot.util.WeakValueHashMap;
|
import net.filebot.util.WeakValueHashMap;
|
||||||
|
@ -60,8 +63,6 @@ import net.filebot.web.SortOrder;
|
||||||
import net.filebot.web.TMDbClient.MovieInfo;
|
import net.filebot.web.TMDbClient.MovieInfo;
|
||||||
import net.filebot.web.TheTVDBSeriesInfo;
|
import net.filebot.web.TheTVDBSeriesInfo;
|
||||||
|
|
||||||
import com.cedarsoftware.util.io.JsonWriter;
|
|
||||||
|
|
||||||
public class MediaBindingBean {
|
public class MediaBindingBean {
|
||||||
|
|
||||||
private final Object infoObject;
|
private final Object infoObject;
|
||||||
|
@ -960,15 +961,13 @@ public class MediaBindingBean {
|
||||||
File inferredMediaFile = getInferredMediaFile();
|
File inferredMediaFile = getInferredMediaFile();
|
||||||
|
|
||||||
synchronized (sharedMediaInfoObjects) {
|
synchronized (sharedMediaInfoObjects) {
|
||||||
mediaInfo = sharedMediaInfoObjects.get(inferredMediaFile);
|
mediaInfo = sharedMediaInfoObjects.computeIfAbsent(inferredMediaFile, f -> {
|
||||||
if (mediaInfo == null) {
|
try {
|
||||||
MediaInfo mi = new MediaInfo();
|
return new MediaInfo().open(f);
|
||||||
if (!mi.open(inferredMediaFile)) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Cannot open media file: " + inferredMediaFile);
|
throw new MediaInfoException(e.getMessage());
|
||||||
}
|
|
||||||
sharedMediaInfoObjects.put(inferredMediaFile, mi);
|
|
||||||
mediaInfo = mi;
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package net.filebot.mediainfo;
|
package net.filebot.mediainfo;
|
||||||
|
|
||||||
|
import static net.filebot.Logging.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileFilter;
|
import java.io.FileFilter;
|
||||||
|
|
||||||
|
@ -25,12 +27,11 @@ public class MediaDurationFilter implements FileFilter {
|
||||||
|
|
||||||
public long getDuration(File file) {
|
public long getDuration(File file) {
|
||||||
synchronized (mediaInfo) {
|
synchronized (mediaInfo) {
|
||||||
if (mediaInfo.open(file)) {
|
|
||||||
try {
|
try {
|
||||||
return Long.parseLong(mediaInfo.get(StreamKind.General, 0, "Duration"));
|
String duration = mediaInfo.open(file).get(StreamKind.General, 0, "Duration");
|
||||||
} catch (NumberFormatException e) {
|
return Long.parseLong(duration);
|
||||||
// ignore, assume duration couldn't be read
|
} catch (Exception e) {
|
||||||
}
|
debug.warning("Failed to read video duration: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package net.filebot.mediainfo;
|
package net.filebot.mediainfo;
|
||||||
|
|
||||||
import static net.filebot.Logging.*;
|
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
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) {
|
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
|
// 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)) {
|
if (Platform.isMac() && !StandardCharsets.US_ASCII.newEncoder().canEncode(path)) {
|
||||||
try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
|
try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
|
||||||
return openViaBuffer(raf);
|
if (openViaBuffer(raf)) {
|
||||||
} catch (IOException e) {
|
throw new IOException("Failed to initialize media info buffer: " + path);
|
||||||
debug.warning("Failed to open random access file: " + e.getMessage());
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
private boolean openViaBuffer(RandomAccessFile f) throws IOException {
|
||||||
byte[] buffer = new byte[4 * 1024 * 1024]; // use large buffer to reduce JNA calls
|
byte[] buffer = new byte[4 * 1024 * 1024]; // use large buffer to reduce JNA calls
|
||||||
int read = -1;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,15 +251,9 @@ public class MediaInfo implements Closeable {
|
||||||
* Helper for easy usage
|
* Helper for easy usage
|
||||||
*/
|
*/
|
||||||
public static Map<StreamKind, List<Map<String, String>>> snapshot(File file) throws IOException {
|
public static Map<StreamKind, List<Map<String, String>>> snapshot(File file) throws IOException {
|
||||||
MediaInfo mi = new MediaInfo();
|
try (MediaInfo mi = new MediaInfo()) {
|
||||||
try {
|
return mi.open(file).snapshot();
|
||||||
if (mi.open(file)) {
|
|
||||||
return mi.snapshot();
|
|
||||||
} else {
|
|
||||||
throw new IOException("Failed to open file: " + file);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
mi.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,8 +193,8 @@ public enum SubtitleMetrics implements SimilarityMetric {
|
||||||
return mediaInfoCache.computeIfAbsent(file, (f) -> {
|
return mediaInfoCache.computeIfAbsent(file, (f) -> {
|
||||||
try {
|
try {
|
||||||
Map<String, Object> props = new HashMap<String, Object>();
|
Map<String, Object> props = new HashMap<String, Object>();
|
||||||
MediaInfo mediaInfo = new MediaInfo();
|
MediaInfo mediaInfo = new MediaInfo().open(file);
|
||||||
if (mediaInfo.open(file)) {
|
|
||||||
float fps = round(Float.parseFloat(mediaInfo.get(StreamKind.Video, 0, "FrameRate")));
|
float fps = round(Float.parseFloat(mediaInfo.get(StreamKind.Video, 0, "FrameRate")));
|
||||||
if (fps > 0) {
|
if (fps > 0) {
|
||||||
props.put(FPS, fps);
|
props.put(FPS, fps);
|
||||||
|
@ -204,9 +204,8 @@ public enum SubtitleMetrics implements SimilarityMetric {
|
||||||
props.put(SECONDS, seconds);
|
props.put(SECONDS, seconds);
|
||||||
}
|
}
|
||||||
return props;
|
return props;
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
debug.warning("Failed to read video properties: " + e);
|
debug.warning("Failed to read video properties: " + e.getMessage());
|
||||||
}
|
}
|
||||||
return emptyMap();
|
return emptyMap();
|
||||||
});
|
});
|
||||||
|
|
|
@ -54,7 +54,6 @@ import net.filebot.format.MediaBindingBean;
|
||||||
import net.filebot.media.MediaDetection;
|
import net.filebot.media.MediaDetection;
|
||||||
import net.filebot.mediainfo.MediaInfo;
|
import net.filebot.mediainfo.MediaInfo;
|
||||||
import net.filebot.mediainfo.MediaInfo.StreamKind;
|
import net.filebot.mediainfo.MediaInfo.StreamKind;
|
||||||
import net.filebot.mediainfo.MediaInfoException;
|
|
||||||
import net.filebot.util.DefaultThreadFactory;
|
import net.filebot.util.DefaultThreadFactory;
|
||||||
import net.filebot.util.FileUtilities.ExtensionFileFilter;
|
import net.filebot.util.FileUtilities.ExtensionFileFilter;
|
||||||
import net.filebot.util.ui.LazyDocumentListener;
|
import net.filebot.util.ui.LazyDocumentListener;
|
||||||
|
@ -293,23 +292,12 @@ class BindingDialog extends JDialog {
|
||||||
|
|
||||||
private Map<StreamKind, List<Map<String, String>>> getMediaInfo(File file) {
|
private Map<StreamKind, List<Map<String, String>>> getMediaInfo(File file) {
|
||||||
try {
|
try {
|
||||||
MediaInfo mediaInfo = new MediaInfo();
|
return MediaInfo.snapshot(file);
|
||||||
|
} catch (Exception e) {
|
||||||
// read all media info
|
|
||||||
if (mediaInfo.open(file)) {
|
|
||||||
try {
|
|
||||||
return mediaInfo.snapshot();
|
|
||||||
} finally {
|
|
||||||
mediaInfo.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (MediaInfoException e) {
|
|
||||||
log.log(Level.SEVERE, e.getMessage(), e);
|
log.log(Level.SEVERE, e.getMessage(), e);
|
||||||
}
|
|
||||||
|
|
||||||
// could not retrieve media info
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent evt) {
|
public void actionPerformed(ActionEvent evt) {
|
||||||
|
|
|
@ -15,7 +15,6 @@ import javax.swing.Icon;
|
||||||
import net.filebot.ResourceManager;
|
import net.filebot.ResourceManager;
|
||||||
import net.filebot.mediainfo.MediaInfo;
|
import net.filebot.mediainfo.MediaInfo;
|
||||||
import net.filebot.mediainfo.MediaInfo.StreamKind;
|
import net.filebot.mediainfo.MediaInfo.StreamKind;
|
||||||
import net.filebot.mediainfo.MediaInfoException;
|
|
||||||
|
|
||||||
public class ID3Lookup implements MusicIdentificationService {
|
public class ID3Lookup implements MusicIdentificationService {
|
||||||
|
|
||||||
|
@ -36,9 +35,8 @@ public class ID3Lookup implements MusicIdentificationService {
|
||||||
try (MediaInfo mediaInfo = new MediaInfo()) {
|
try (MediaInfo mediaInfo = new MediaInfo()) {
|
||||||
for (File f : filter(files, AUDIO_FILES, VIDEO_FILES)) {
|
for (File f : filter(files, AUDIO_FILES, VIDEO_FILES)) {
|
||||||
try {
|
try {
|
||||||
if (!mediaInfo.open(f)) {
|
// open or throw exception
|
||||||
throw new MediaInfoException("Failed to read media info: " + f);
|
mediaInfo.open(f);
|
||||||
}
|
|
||||||
|
|
||||||
// artist and song title information is required
|
// artist and song title information is required
|
||||||
String artist = getString(mediaInfo, "Performer", "Composer");
|
String artist = getString(mediaInfo, "Performer", "Composer");
|
||||||
|
|
Loading…
Reference in New Issue