From c8e6389b779e1fa6005ec2f52905c5d083c96024 Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Tue, 5 Jun 2018 13:35:39 +0700 Subject: [PATCH] Refactor common media characteristics (e.g. to use ffprobe instead of libmediainfo internally for various use cases, via -Dnet.filebot.media.parser=ffprobe) --- source/net/filebot/media/AutoDetection.java | 8 +++--- .../media/MediaCharacteristicsParser.java | 27 +++++++++++++++++++ source/net/filebot/media/MediaDetection.java | 3 +-- .../filebot/media/MediaDurationFilter.java | 4 +-- .../net/filebot/subtitle/SubtitleMetrics.java | 6 ++--- .../net/filebot/web/OpenSubtitlesClient.java | 4 +-- 6 files changed, 39 insertions(+), 13 deletions(-) create mode 100644 source/net/filebot/media/MediaCharacteristicsParser.java diff --git a/source/net/filebot/media/AutoDetection.java b/source/net/filebot/media/AutoDetection.java index cede9e0e..45d2e245 100644 --- a/source/net/filebot/media/AutoDetection.java +++ b/source/net/filebot/media/AutoDetection.java @@ -34,7 +34,6 @@ import java.util.logging.Level; import java.util.regex.Pattern; import java.util.stream.Stream; -import net.filebot.mediainfo.MediaInfo; import net.filebot.similarity.NameSimilarityMetric; import net.filebot.util.FastFile; import net.filebot.web.Episode; @@ -84,6 +83,9 @@ public class AutoDetection { private static final Pattern SERIES_EPISODE_PATTERN = Pattern.compile("^tv[sp][ _.-]", CASE_INSENSITIVE); private static final Pattern ANIME_EPISODE_PATTERN = Pattern.compile("^\\[[^\\]]+Subs\\]", CASE_INSENSITIVE); + private static final Pattern JAPANESE_AUDIO_LANGUAGE_PATTERN = Pattern.compile("jpn|Japanese", CASE_INSENSITIVE); + private static final Pattern JAPANESE_SUBTITLE_CODEC_PATTERN = Pattern.compile("ASS|SSA", CASE_INSENSITIVE); + public boolean isMusic(File f) { return AUDIO_FILES.accept(f) && !VIDEO_FILES.accept(f); } @@ -116,8 +118,8 @@ public class AutoDetection { if (VIDEO_FILES.accept(f) && f.length() > ONE_MEGABYTE) { // check for Japanese audio or characteristic subtitles - try (MediaCharacteristics mi = new MediaInfo().open(f)) { - return mi.getDuration().toMinutes() < 60 || mi.getAudioLanguage().contains("Japanese") && mi.getSubtitleCodec().contains("ASS"); + try (MediaCharacteristics mi = MediaCharacteristicsParser.open(f)) { + return mi.getDuration().toMinutes() < 60 || find(mi.getAudioLanguage(), JAPANESE_AUDIO_LANGUAGE_PATTERN) && find(mi.getSubtitleCodec(), JAPANESE_SUBTITLE_CODEC_PATTERN); } catch (Exception e) { debug.warning("Failed to read audio language: " + e.getMessage()); } diff --git a/source/net/filebot/media/MediaCharacteristicsParser.java b/source/net/filebot/media/MediaCharacteristicsParser.java new file mode 100644 index 00000000..9d928f95 --- /dev/null +++ b/source/net/filebot/media/MediaCharacteristicsParser.java @@ -0,0 +1,27 @@ +package net.filebot.media; + +import java.io.File; + +import net.filebot.mediainfo.MediaInfo; +import net.filebot.util.SystemProperty; + +public enum MediaCharacteristicsParser { + + libmediainfo, ffprobe; + + public static MediaCharacteristicsParser getDefault() { + return SystemProperty.of("net.filebot.media.parser", MediaCharacteristicsParser::valueOf, libmediainfo).get(); + } + + public static MediaCharacteristics open(File f) throws Exception { + switch (getDefault()) { + case libmediainfo: + return new MediaInfo().open(f); + case ffprobe: + return new FFProbe().open(f); + } + + throw new IllegalStateException(); + } + +} \ No newline at end of file diff --git a/source/net/filebot/media/MediaDetection.java b/source/net/filebot/media/MediaDetection.java index 30939725..3f859b44 100644 --- a/source/net/filebot/media/MediaDetection.java +++ b/source/net/filebot/media/MediaDetection.java @@ -48,7 +48,6 @@ import net.filebot.Language; import net.filebot.Resource; import net.filebot.WebServices; import net.filebot.archive.Archive; -import net.filebot.mediainfo.MediaInfo; import net.filebot.similarity.DateMatcher; import net.filebot.similarity.EpisodeMetrics; import net.filebot.similarity.MetricAvg; @@ -1115,7 +1114,7 @@ public class MediaDetection { filesByExtension.stream().collect(groupingBy(f -> { if (VIDEO_FILES.accept(f) && f.length() > ONE_MEGABYTE) { - try (MediaCharacteristics mi = new MediaInfo().open(f)) { + try (MediaCharacteristics mi = MediaCharacteristicsParser.open(f)) { ChronoUnit d = mi.getDuration().toMinutes() < 10 ? ChronoUnit.MINUTES : ChronoUnit.HOURS; String v = mi.getVideoCodec(); String a = mi.getAudioCodec(); diff --git a/source/net/filebot/media/MediaDurationFilter.java b/source/net/filebot/media/MediaDurationFilter.java index ea600984..90114ba0 100644 --- a/source/net/filebot/media/MediaDurationFilter.java +++ b/source/net/filebot/media/MediaDurationFilter.java @@ -5,8 +5,6 @@ import static net.filebot.Logging.*; import java.io.File; import java.io.FileFilter; -import net.filebot.mediainfo.MediaInfo; - public class MediaDurationFilter implements FileFilter { private final long min; @@ -24,7 +22,7 @@ public class MediaDurationFilter implements FileFilter { } public long getDuration(File f) { - try (MediaCharacteristics mi = new MediaInfo().open(f)) { + try (MediaCharacteristics mi = MediaCharacteristicsParser.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/subtitle/SubtitleMetrics.java b/source/net/filebot/subtitle/SubtitleMetrics.java index 5e01bbdc..dc8f7b53 100644 --- a/source/net/filebot/subtitle/SubtitleMetrics.java +++ b/source/net/filebot/subtitle/SubtitleMetrics.java @@ -16,7 +16,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import net.filebot.media.MediaCharacteristics; -import net.filebot.mediainfo.MediaInfo; +import net.filebot.media.MediaCharacteristicsParser; import net.filebot.similarity.CrossPropertyMetric; import net.filebot.similarity.EpisodeMetrics; import net.filebot.similarity.MetricAvg; @@ -184,8 +184,8 @@ public enum SubtitleMetrics implements SimilarityMetric { private final Map> mediaInfoCache = synchronizedMap(new WeakHashMap>(64)); private Map getVideoProperties(File file) { - return mediaInfoCache.computeIfAbsent(file, key -> { - try (MediaCharacteristics mi = new MediaInfo().open(file)) { + return mediaInfoCache.computeIfAbsent(file, f -> { + try (MediaCharacteristics mi = MediaCharacteristicsParser.open(f)) { 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 5364435c..dedccedd 100644 --- a/source/net/filebot/web/OpenSubtitlesClient.java +++ b/source/net/filebot/web/OpenSubtitlesClient.java @@ -29,8 +29,8 @@ import net.filebot.Cache.TypedCache; import net.filebot.CacheType; import net.filebot.ResourceManager; import net.filebot.media.MediaCharacteristics; +import net.filebot.media.MediaCharacteristicsParser; import net.filebot.media.MediaDetection; -import net.filebot.mediainfo.MediaInfo; import net.filebot.util.ExceptionUtilities; import net.filebot.util.Timer; import net.filebot.web.OpenSubtitlesXmlRpc.BaseInfo; @@ -312,7 +312,7 @@ public class OpenSubtitlesClient implements SubtitleProvider, VideoHashSubtitleS sub.setSubContent(readFile(subtitleFile)); } - try (MediaCharacteristics mi = new MediaInfo().open(videoFile)) { + try (MediaCharacteristics mi = MediaCharacteristicsParser.open(videoFile)) { sub.setMovieFPS(String.valueOf(mi.getFrameRate())); sub.setMovieTimeMS(String.valueOf(mi.getDuration().toMillis())); } catch (Throwable e) {