Refactor common media characteristics (e.g. to use ffprobe instead of libmediainfo internally for various use cases)

This commit is contained in:
Reinhard Pointner 2018-06-03 19:45:17 +07:00
parent 82557248d4
commit e8ca45789c
7 changed files with 68 additions and 32 deletions

View File

@ -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());
}

View File

@ -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();
}

View File

@ -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()));

View File

@ -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()));
}

View File

@ -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<StreamKind, List<Map<String, String>>> snapshot() {
Map<StreamKind, List<Map<String, String>>> mediaInfo = new EnumMap<StreamKind, List<Map<String, String>>>(StreamKind.class);

View File

@ -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<String, Object> 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());
}

View File

@ -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);
}