From 73e744359397ef85359e49166f758ca0876252db Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Mon, 8 Aug 2016 04:45:38 +0800 Subject: [PATCH] Implement advanced multi-part movie detection (via group by mediainfo) --- source/net/filebot/cli/CmdlineOperations.java | 1 + .../net/filebot/format/MediaBindingBean.java | 14 +++++++-- source/net/filebot/media/MediaDetection.java | 31 +++++++++++++++++++ source/net/filebot/media/VideoQuality.java | 14 ++++++++- .../net/filebot/ui/rename/MovieMatcher.java | 1 + 5 files changed, 58 insertions(+), 3 deletions(-) diff --git a/source/net/filebot/cli/CmdlineOperations.java b/source/net/filebot/cli/CmdlineOperations.java index 2b71b599..0740feb6 100644 --- a/source/net/filebot/cli/CmdlineOperations.java +++ b/source/net/filebot/cli/CmdlineOperations.java @@ -463,6 +463,7 @@ public class CmdlineOperations implements CmdlineInterface { // collect all File/MoviePart matches List> matches = new ArrayList>(); + // TODO: MediaDetection.groupByMediaCharacteristics() for (Entry> byMovie : filesByMovie.entrySet()) { for (List movieFileListByMediaFolder : mapByMediaFolder(byMovie.getValue()).values()) { for (List fileSet : mapByExtension(movieFileListByMediaFolder).values()) { diff --git a/source/net/filebot/format/MediaBindingBean.java b/source/net/filebot/format/MediaBindingBean.java index 9ea4a252..b361cef1 100644 --- a/source/net/filebot/format/MediaBindingBean.java +++ b/source/net/filebot/format/MediaBindingBean.java @@ -751,13 +751,23 @@ public class MediaBindingBean { } @Define("bitrate") - public Long getBitRate() { + public Long getOverallBitRate() { return new Double(getMediaInfo(StreamKind.General, 0, "OverallBitRate")).longValue(); } + @Define("vbr") + public Long getVideoBitRate() { + return new Double(getMediaInfo(StreamKind.Video, 0, "BitRate")).longValue(); + } + + @Define("abr") + public Long getAudioBitRate() { + return new Double(getMediaInfo(StreamKind.Audio, 0, "BitRate")).longValue(); + } + @Define("duration") public Long getDuration() { - return (long) Double.parseDouble(getMediaInfo(StreamKind.General, 0, "Duration")); + return new Double(getMediaInfo(StreamKind.General, 0, "Duration")).longValue(); } @Define("seconds") diff --git a/source/net/filebot/media/MediaDetection.java b/source/net/filebot/media/MediaDetection.java index 76ac642d..e1d49d93 100644 --- a/source/net/filebot/media/MediaDetection.java +++ b/source/net/filebot/media/MediaDetection.java @@ -1067,6 +1067,37 @@ public class MediaDetection { return map; } + public static List> groupByMediaCharacteristics(Collection files) { + List> groups = new ArrayList>(); + + mapByExtension(files).forEach((extension, filesByExtension) -> { + if (filesByExtension.size() < 2) { + groups.add(filesByExtension); + return; + } + + mapByMediaFolder(filesByExtension).forEach((mediaFolder, filesByMediaFolder) -> { + if (filesByMediaFolder.size() < 2) { + groups.add(filesByMediaFolder); + return; + } + + try { + filesByMediaFolder.stream().collect(groupingBy(new VideoQuality()::getVideoBitrate)).forEach((vbr, videos) -> { + groups.add(videos); + }); + } catch (Exception e) { + debug.warning(format("Failed to group by media characteristics: %s", e.getMessage())); + + // if mediainfo fails and we can't further group by video bitrate then just keep the grouping we have + groups.add(filesByMediaFolder); + } + }); + }); + + return groups; + } + public static Map> mapBySeriesName(Collection files, boolean anime, Locale locale) throws Exception { Map> result = new TreeMap>(String.CASE_INSENSITIVE_ORDER); diff --git a/source/net/filebot/media/VideoQuality.java b/source/net/filebot/media/VideoQuality.java index 53a7b4ec..2475739a 100644 --- a/source/net/filebot/media/VideoQuality.java +++ b/source/net/filebot/media/VideoQuality.java @@ -1,9 +1,9 @@ package net.filebot.media; -import static net.filebot.util.StringUtilities.*; import static java.util.Comparator.*; import static net.filebot.Logging.*; import static net.filebot.MediaTypes.*; +import static net.filebot.util.StringUtilities.*; import java.io.File; import java.util.Comparator; @@ -64,4 +64,16 @@ public class VideoQuality implements Comparator { }).orElseGet(f::length); } + public long getVideoBitrate(File f) { + return media(f).map(it -> { + return it.getVideoBitRate(); + }).orElse(0L); + } + + public long getAudioBitrate(File f) { + return media(f).map(it -> { + return it.getAudioBitRate(); + }).orElse(0L); + } + } diff --git a/source/net/filebot/ui/rename/MovieMatcher.java b/source/net/filebot/ui/rename/MovieMatcher.java index a2e472af..31b26fcd 100644 --- a/source/net/filebot/ui/rename/MovieMatcher.java +++ b/source/net/filebot/ui/rename/MovieMatcher.java @@ -195,6 +195,7 @@ class MovieMatcher implements AutoCompleteMatcher { // collect all File/MoviePart matches List> matches = new ArrayList>(); + // TODO: MediaDetection.groupByMediaCharacteristics() filesByMovie.forEach((movie, byMovie) -> { mapByMediaFolder(byMovie).forEach((mediaFolder, byFolder) -> { mapByExtension(byFolder).forEach((ext, moviePartFiles) -> {