Refactor VideoQuality comparator

@see https://www.filebot.net/forums/viewtopic.php?f=6&t=3647&p=20384#p20384
This commit is contained in:
Reinhard Pointner 2016-04-17 08:44:03 +00:00
parent 28dcd8279f
commit 0c94aed7e7
5 changed files with 70 additions and 53 deletions

View File

@ -7,7 +7,6 @@ import java.io.IOException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Collections;
import java.util.List;

View File

@ -10,7 +10,6 @@ import static net.filebot.Settings.*;
import static net.filebot.WebServices.*;
import static net.filebot.hash.VerificationUtilities.*;
import static net.filebot.media.MediaDetection.*;
import static net.filebot.media.MediaSize.*;
import static net.filebot.media.XattrMetaInfo.*;
import static net.filebot.subtitle.SubtitleUtilities.*;
import static net.filebot.util.FileUtilities.*;
@ -61,6 +60,7 @@ import net.filebot.media.AutoDetection;
import net.filebot.media.AutoDetection.Group;
import net.filebot.media.AutoDetection.Type;
import net.filebot.media.MediaDetection;
import net.filebot.media.VideoQuality;
import net.filebot.media.XattrMetaInfoProvider;
import net.filebot.similarity.CommonSequenceMatcher;
import net.filebot.similarity.EpisodeMatcher;
@ -609,7 +609,7 @@ public class CmdlineOperations implements CmdlineInterface {
throw new CmdlineException("File already exists: " + destination);
}
if (conflictAction == ConflictAction.OVERRIDE || (conflictAction == ConflictAction.AUTO && VIDEO_SIZE_ORDER.compare(source, destination) > 0)) {
if (conflictAction == ConflictAction.OVERRIDE || (conflictAction == ConflictAction.AUTO && VideoQuality.isBetter(source, destination))) {
if (!destination.delete()) {
log.log(Level.SEVERE, "Failed to override file: " + destination);
}

View File

@ -412,7 +412,7 @@ public class MediaBindingBean {
}
@Define("original")
public String getOriginalFileName() throws Exception {
public String getOriginalFileName() {
return getOriginalFileName(getMediaFile());
}

View File

@ -1,49 +0,0 @@
package net.filebot.media;
import static net.filebot.Logging.*;
import static net.filebot.MediaTypes.*;
import java.io.File;
import java.util.Comparator;
import net.filebot.format.MediaBindingBean;
public class MediaSize implements Comparator<File> {
public static final Comparator<File> VIDEO_SIZE_ORDER = new MediaSize();
@Override
public int compare(File f1, File f2) {
long[] v1 = getSizeValues(f1);
long[] v2 = getSizeValues(f2);
// best to worst
for (int i = 0; i < v1.length; i++) {
int d = Long.compare(v1[i], v2[i]);
if (d != 0) {
return d;
}
}
return 0;
}
public long[] getSizeValues(File f) {
long[] v = { -1, -1 };
if (VIDEO_FILES.accept(f) || SUBTITLE_FILES.accept(f)) {
try {
MediaBindingBean media = new MediaBindingBean(null, f, null);
v[1] = media.getInferredMediaFile().length(); // File Size
v[0] = media.getDimension().stream().mapToLong(Number::longValue).reduce((a, b) -> a * b).orElse(-1); // Video Resolution
} catch (Throwable e) {
debug.warning(format("Failed to read media info: %s [%s]", e.getMessage(), f.getName()));
}
} else {
v[1] = f.length(); // File Size
}
return v;
}
}

View File

@ -0,0 +1,67 @@
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 java.io.File;
import java.util.Comparator;
import java.util.Optional;
import java.util.function.ToDoubleFunction;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import net.filebot.format.MediaBindingBean;
public class VideoQuality implements Comparator<File> {
public static boolean isBetter(File f1, File f2) {
return new VideoQuality().compare(f1, f2) > 0;
}
@Override
public int compare(File f1, File f2) {
ToDoubleFunction<File> repack = this::isRepack;
ToDoubleFunction<File> resolution = this::getResolution;
ToDoubleFunction<File> size = this::getSize;
return Stream.of(repack, resolution, size).mapToInt(c -> {
try {
return comparingDouble(c).compare(f1, f2);
} catch (Throwable e) {
debug.warning(format("Failed to read media info: %s", e.getMessage()));
return 0;
}
}).filter(i -> i != 0).findFirst().orElse(0);
}
private Optional<MediaBindingBean> media(File f) {
if (VIDEO_FILES.accept(f) || SUBTITLE_FILES.accept(f)) {
return Optional.of(new MediaBindingBean(null, f, null));
}
return Optional.empty();
}
private static final Pattern REPACK = Pattern.compile("(?<!\\p{Alnum})(PROPER|REPACK)(?!\\p{Alnum})", Pattern.CASE_INSENSITIVE);
private static final double ZERO = 0;
public double isRepack(File f) {
return media(f).map(it -> {
return find(it.getFileName(), REPACK) || find(it.getOriginalFileName(), REPACK) ? 1 : ZERO;
}).orElse(ZERO);
}
public double getResolution(File f) {
return media(f).map(it -> {
return it.getDimension().stream().mapToDouble(Number::doubleValue).reduce((a, b) -> a * b).orElse(ZERO);
}).orElse(ZERO);
}
public double getSize(File f) {
return media(f).map(it -> {
return it.getInferredMediaFile().length();
}).orElseGet(f::length);
}
}