视频压缩(需要40系以上N卡)

import java.io.File
import kotlin.time.measureTime

fun main() {
    val srcDir = "X:\\Movies"
    val dstDir = "Z:\\Movies2"

    val total = File(srcDir).walk().filter { it.isFile }.count()

    var count = 0
    File(srcDir).walk()
        .filter { it.isFile }
        .forEach {
            "start process $it".logi()
            try {
                val time = measureTime {
                    val src = it
                    val dst = File(it.absolutePath.replace(srcDir, dstDir)).alsoParentMkdirs()
                    if (it.extension.lowercase() in listOf("mp4", "mkv", "wmv", "m4v", "avi", "mov", "mts")) {
                        val output = dst.absolutePath.replace(dst.extension, "mp4")
                        if (File(output).exists()) {
                            "file exists $output".logi()
                            return@measureTime
                        }
                        ffmpegCov(src.absolutePath, output)
                    } else {
                        if (dst.exists()) {
                            "file exists $dst".logi()
                            return@measureTime
                        }
                        src.copyTo(dst, bufferSize = 1 * 1024 * 1024)
                    }
                }
                "${++count}/$total use time $time end process $it".logi()
            } catch (e: Exception) {
                "failed process $it".loge()
                e.printStackTrace()
            }
        }
}

fun ffmpegCov(input: String, output: String) {
    val cmd = listOf(
        "cmd", "/c",
        "ffmpeg", "-hide_banner", "-loglevel", "warning", "-stats",
        "-hwaccel", "cuda", "-hwaccel_output_format", "cuda",
        "-i", input.wrap(),
        "-c:v", "av1_nvenc", "-cq", "36", "-preset", "p4",
//        "-c:a", "copy",
        output.wrap()
    )
    exec(cmd).waitFor()
}

fun exec(cmd: List<String>) = ProcessBuilder().apply {
    command(*cmd.toTypedArray())
    inheritIO()
}.start()

fun String.wrap() = "\"$this\""

fun File.alsoParentMkdirs() = also {
    if (it.parentFile?.exists() != true) it.parentFile?.mkdirs()
}

fun <T> T.logi() = also(::println)

fun <T> T.loge() = also(System.err::println)

质量对比
SSIM:
ffmpeg -i video1.mp4 -i video2.mp4 -lavfi ssim="stats_file=ssim.log" -f null -

VMAF:
ffmpeg -i "对比视频" -i "源视频" -filter_complex "[0:v][1:v]libvmaf=model=version=vmaf_v0.6.1:log_path='C\:\\Users\\litte\\Desktop\\vmaf_log.txt':n_threads=99" -f null -