filebot icon

VideoQuality.java

filebot | PRO | 06/30/23 06:21:50 AM UTC | 0 ⭐ | 1921 👁️ | Never ⏰ | []
Java |

2.95 KB

|

Source Code

|

0 👍

/

0 👎

package net.filebot.media;
 
import static java.util.Comparator.*;
import static net.filebot.MediaTypes.*;
import static net.filebot.media.CachedMediaCharacteristics.*;
import static net.filebot.media.MediaDetection.*;
import static net.filebot.media.MediaFileUtilities.*;
import static net.filebot.util.StringUtilities.*;
 
import java.io.File;
import java.util.Comparator;
import java.util.regex.Pattern;
 
public class VideoQuality implements Comparator<File> {
 
    public static final Comparator<File> DESCENDING_ORDER = new VideoQuality(VideoFormat.DEFAULT_GROUPS, releaseInfo.getRepackPattern()).reversed();
 
    public static boolean isBetter(File f1, File f2) {
        return DESCENDING_ORDER.compare(f1, f2) < 0;
    }
 
    private final VideoFormat quality;
    private final Pattern repack;
 
    public VideoQuality(VideoFormat quality, Pattern repack) {
        this.quality = quality;
        this.repack = repack;
    }
 
    private final Comparator<File> chain = comparingInt(this::getQuality)
            .thenComparing(VideoCodec::compare)
            .thenComparingInt(this::getRepack)
            .thenComparingDouble(this::getScore)
            .thenComparingLong(File::length);
 
    @Override
    public int compare(File f1, File f2) {
        return chain.compare(getPrimaryFile(f1), getPrimaryFile(f2));
    }
 
    private File getPrimaryFile(File f) {
        return findPrimaryFile(f, VIDEO_FILES).orElse(f);
    }
 
    private int getRepack(File f) {
        return find(f.getName(), repack) ? 1 : 0;
    }
 
    private int getQuality(File f) {
        // use primary video file when checking video resolution of subtitle files or disk folders
        return getMediaCharacteristics(f, mi -> {
            Integer w = mi.getWidth();
            Integer h = mi.getHeight();
 
            // invalid media file
            if (w == null || h == null) {
                return null;
            }
 
            return quality.guessFormat(w, h);
        }).orElse(Integer.MIN_VALUE);
    }
 
    private double getScore(File f) {
        // use primary video file when checking video resolution of subtitle files or disk folders
        return getMediaCharacteristics(f, mi -> {
            Integer w = mi.getWidth();
            Integer h = mi.getHeight();
            Double br = mi.getBitRate();
 
            // invalid media file
            if (w == null || h == null || br == null) {
                return null;
            }
 
            return w * h * br;
        }).orElse(Double.MIN_VALUE);
    }
 
    public enum VideoCodec {
 
        MPEG, AVC, HEVC;
 
        public static VideoCodec get(MediaCharacteristics mi) {
            switch (mi.getVideoCodec()) {
                case "HEVC":
                    return HEVC;
                case "AVC":
                    return AVC;
                case "MPEG-4 Visual":
                    return MPEG;
            }
 
            // print missing codec name
            throw new UnsupportedOperationException("Unknown Video Codec: " + mi.getVideoCodec());
        }
 
        public static int compare(File f1, File f2) {
            VideoCodec vc1 = getMediaCharacteristics(f1, VideoCodec::get).orElse(null);
            VideoCodec vc2 = getMediaCharacteristics(f2, VideoCodec::get).orElse(null);
 
            if (vc1 == null || vc2 == null) {
                return 0;
            }
 
            return vc1.compareTo(vc2);
        }
 
    }
 
}
 

Comments