diff --git a/source/net/filebot/media/AutoDetection.java b/source/net/filebot/media/AutoDetection.java index cd929bd2..cede9e0e 100644 --- a/source/net/filebot/media/AutoDetection.java +++ b/source/net/filebot/media/AutoDetection.java @@ -17,7 +17,6 @@ import static net.filebot.util.StringUtilities.*; import java.io.File; import java.io.FileFilter; -import java.time.Duration; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; @@ -36,7 +35,6 @@ import java.util.regex.Pattern; import java.util.stream.Stream; import net.filebot.mediainfo.MediaInfo; -import net.filebot.mediainfo.MediaInfo.StreamKind; import net.filebot.similarity.NameSimilarityMetric; import net.filebot.util.FastFile; import net.filebot.web.Episode; @@ -118,9 +116,8 @@ public class AutoDetection { if (VIDEO_FILES.accept(f) && f.length() > ONE_MEGABYTE) { // check for Japanese audio or characteristic subtitles - try (MediaInfo mi = new MediaInfo().open(f)) { - long minutes = Duration.ofMillis(Long.parseLong(mi.get(StreamKind.General, 0, "Duration"))).toMinutes(); - return minutes < 60 || mi.get(StreamKind.General, 0, "AudioLanguageList").contains("Japanese") && mi.get(StreamKind.General, 0, "TextCodecList").contains("ASS"); + try (MediaCharacteristics mi = new MediaInfo().open(f)) { + return mi.getDuration().toMinutes() < 60 || mi.getAudioLanguage().contains("Japanese") && mi.getSubtitleCodec().contains("ASS"); } catch (Exception e) { debug.warning("Failed to read audio language: " + e.getMessage()); } diff --git a/source/net/filebot/media/MediaCharacteristics.java b/source/net/filebot/media/MediaCharacteristics.java index b46bd8a8..de48a5bf 100644 --- a/source/net/filebot/media/MediaCharacteristics.java +++ b/source/net/filebot/media/MediaCharacteristics.java @@ -2,16 +2,22 @@ package net.filebot.media; import java.time.Duration; -public interface MediaCharacteristics { +public interface MediaCharacteristics extends AutoCloseable { String getVideoCodec(); + String getAudioCodec(); + String getAudioLanguage(); String getSubtitleCodec(); Duration getDuration(); - float getFrameRate(); + Integer getWidth(); + + Integer getHeight(); + + Float getFrameRate(); } diff --git a/source/net/filebot/media/MediaDetection.java b/source/net/filebot/media/MediaDetection.java index 3adc35ad..30939725 100644 --- a/source/net/filebot/media/MediaDetection.java +++ b/source/net/filebot/media/MediaDetection.java @@ -17,7 +17,6 @@ import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.text.CollationKey; -import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Collection; @@ -50,7 +49,6 @@ import net.filebot.Resource; import net.filebot.WebServices; import net.filebot.archive.Archive; import net.filebot.mediainfo.MediaInfo; -import net.filebot.mediainfo.MediaInfo.StreamKind; import net.filebot.similarity.DateMatcher; import net.filebot.similarity.EpisodeMetrics; import net.filebot.similarity.MetricAvg; @@ -1117,12 +1115,12 @@ public class MediaDetection { filesByExtension.stream().collect(groupingBy(f -> { if (VIDEO_FILES.accept(f) && f.length() > ONE_MEGABYTE) { - try (MediaInfo mi = new MediaInfo().open(f)) { - Object d = Duration.ofMillis(Long.parseLong(mi.get(StreamKind.General, 0, "Duration"))).toMinutes() < 10 ? ChronoUnit.MINUTES : ChronoUnit.HOURS; - String v = mi.get(StreamKind.Video, 0, "CodecID"); - String a = mi.get(StreamKind.Audio, 0, "CodecID"); - String w = mi.get(StreamKind.Video, 0, "Width"); - String h = mi.get(StreamKind.Video, 0, "Height"); + try (MediaCharacteristics mi = new MediaInfo().open(f)) { + ChronoUnit d = mi.getDuration().toMinutes() < 10 ? ChronoUnit.MINUTES : ChronoUnit.HOURS; + String v = mi.getVideoCodec(); + String a = mi.getAudioCodec(); + Integer w = mi.getWidth(); + Integer h = mi.getHeight(); return asList(d, v, a, w, h); } catch (Exception e) { debug.warning(format("Failed to read media characteristics: %s", e.getMessage())); diff --git a/source/net/filebot/media/MediaDurationFilter.java b/source/net/filebot/media/MediaDurationFilter.java index e97ac723..ea600984 100644 --- a/source/net/filebot/media/MediaDurationFilter.java +++ b/source/net/filebot/media/MediaDurationFilter.java @@ -6,7 +6,6 @@ import java.io.File; import java.io.FileFilter; import net.filebot.mediainfo.MediaInfo; -import net.filebot.mediainfo.MediaInfo.StreamKind; public class MediaDurationFilter implements FileFilter { @@ -25,11 +24,8 @@ public class MediaDurationFilter implements FileFilter { } public long getDuration(File f) { - try (MediaInfo mi = new MediaInfo().open(f)) { - String duration = mi.get(StreamKind.General, 0, "Duration"); - if (duration.length() > 0) { - return Long.parseLong(duration); - } + try (MediaCharacteristics mi = new MediaInfo().open(f)) { + return mi.getDuration().toMillis(); } catch (Exception e) { debug.warning(format("Failed to read video duration: %s", e.getMessage())); } diff --git a/source/net/filebot/mediainfo/MediaInfo.java b/source/net/filebot/mediainfo/MediaInfo.java index a4c29a14..e4caaad7 100644 --- a/source/net/filebot/mediainfo/MediaInfo.java +++ b/source/net/filebot/mediainfo/MediaInfo.java @@ -5,11 +5,11 @@ import static java.util.stream.Collectors.*; import static net.filebot.Logging.*; import static net.filebot.util.RegularExpressions.*; -import java.io.Closeable; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.lang.ref.Cleaner; +import java.time.Duration; import java.util.ArrayList; import java.util.EnumMap; import java.util.LinkedHashMap; @@ -22,8 +22,9 @@ import com.sun.jna.Pointer; import com.sun.jna.WString; import net.filebot.media.ImageMetadata; +import net.filebot.media.MediaCharacteristics; -public class MediaInfo implements Closeable { +public class MediaInfo implements MediaCharacteristics { private Pointer handle; private Cleaner.Cleanable cleanable; @@ -138,6 +139,46 @@ public class MediaInfo implements Closeable { return MediaInfoLibrary.INSTANCE.Count_Get(handle, streamKind.ordinal(), streamNumber); } + @Override + public String getVideoCodec() { + return get(StreamKind.Video, 0, "CodecID"); + } + + @Override + public String getAudioCodec() { + return get(StreamKind.Audio, 0, "CodecID"); + } + + @Override + public String getAudioLanguage() { + return get(StreamKind.General, 0, "AudioLanguageList"); + } + + @Override + public String getSubtitleCodec() { + return get(StreamKind.General, 0, "TextCodecList"); + } + + @Override + public Duration getDuration() { + return Duration.ofMillis(Long.parseLong(get(StreamKind.General, 0, "Duration"))); + } + + @Override + public Integer getWidth() { + return Integer.parseInt(get(StreamKind.Video, 0, "Width")); + } + + @Override + public Integer getHeight() { + return Integer.parseInt(get(StreamKind.Video, 0, "Height")); + } + + @Override + public Float getFrameRate() { + return Float.parseFloat(get(StreamKind.Video, 0, "FrameRate")); + } + public Map>> snapshot() { Map>> mediaInfo = new EnumMap>>(StreamKind.class); diff --git a/source/net/filebot/subtitle/SubtitleMetrics.java b/source/net/filebot/subtitle/SubtitleMetrics.java index fb7e81ab..5e01bbdc 100644 --- a/source/net/filebot/subtitle/SubtitleMetrics.java +++ b/source/net/filebot/subtitle/SubtitleMetrics.java @@ -15,8 +15,8 @@ import java.util.WeakHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.filebot.media.MediaCharacteristics; import net.filebot.mediainfo.MediaInfo; -import net.filebot.mediainfo.MediaInfo.StreamKind; import net.filebot.similarity.CrossPropertyMetric; import net.filebot.similarity.EpisodeMetrics; import net.filebot.similarity.MetricAvg; @@ -185,10 +185,8 @@ public enum SubtitleMetrics implements SimilarityMetric { private Map getVideoProperties(File file) { return mediaInfoCache.computeIfAbsent(file, key -> { - try (MediaInfo mi = new MediaInfo().open(file)) { - float fps = Float.parseFloat(mi.get(StreamKind.Video, 0, "FrameRate")); - long millis = Long.parseLong(mi.get(StreamKind.Video, 0, "Duration")); - return getProperties(fps, millis); + try (MediaCharacteristics mi = new MediaInfo().open(file)) { + return getProperties(mi.getFrameRate(), mi.getDuration().toMillis()); } catch (Exception e) { debug.warning("Failed to read video properties: " + e.getMessage()); } diff --git a/source/net/filebot/web/OpenSubtitlesClient.java b/source/net/filebot/web/OpenSubtitlesClient.java index 9bbe0ec2..5364435c 100644 --- a/source/net/filebot/web/OpenSubtitlesClient.java +++ b/source/net/filebot/web/OpenSubtitlesClient.java @@ -28,9 +28,9 @@ import net.filebot.Cache; import net.filebot.Cache.TypedCache; import net.filebot.CacheType; import net.filebot.ResourceManager; +import net.filebot.media.MediaCharacteristics; import net.filebot.media.MediaDetection; import net.filebot.mediainfo.MediaInfo; -import net.filebot.mediainfo.MediaInfo.StreamKind; import net.filebot.util.ExceptionUtilities; import net.filebot.util.Timer; import net.filebot.web.OpenSubtitlesXmlRpc.BaseInfo; @@ -312,9 +312,9 @@ public class OpenSubtitlesClient implements SubtitleProvider, VideoHashSubtitleS sub.setSubContent(readFile(subtitleFile)); } - try (MediaInfo mi = new MediaInfo().open(videoFile)) { - sub.setMovieFPS(mi.get(StreamKind.Video, 0, "FrameRate")); - sub.setMovieTimeMS(mi.get(StreamKind.General, 0, "Duration")); + try (MediaCharacteristics mi = new MediaInfo().open(videoFile)) { + sub.setMovieFPS(String.valueOf(mi.getFrameRate())); + sub.setMovieTimeMS(String.valueOf(mi.getDuration().toMillis())); } catch (Throwable e) { debug.log(Level.SEVERE, "Failed to read media info", e); }