diff --git a/over-video.py b/over-video.py index f2887d1..5b46077 100755 --- a/over-video.py +++ b/over-video.py @@ -53,7 +53,7 @@ class CodecPar: else: return [] - if not self.is_valid(value): + if self.is_valid and not self.is_valid(value): raise ValueError("%s is not a valid %s" %(value, self.name)) return [self.prefix, value] @@ -257,6 +257,22 @@ x265_tunes = [ "ssim" ] +codec_h265 = Codec( + "h265", + "HEVC encoded using a hardware encoder via VAAPI. Very good quality and faster-than-realtime times.", + ["-vaapi_device", "/dev/dri/renderD128", "-filter:v", "format=nv12,hwupload", "-profile:v", "main", "-codec:v", "hevc_vaapi", "-rc_mode", "CQP"], + [ + CodecPar( + "QP", + "-qp", + True, + None, + StrIntInRange(0, 52), + "Quality factor: 0 is lossless, 22-27 generally very good, 52 worst." + ) + ] +) + codec_x265 = Codec( "x265", "HEVC encoded using x265. Very good quality and decent encode times.", @@ -443,6 +459,7 @@ codec_sdrop = Codec( ) video_codec_router = CodecRouter("M") +video_codec_router.add_codec(codec_h265) video_codec_router.add_codec(codec_x265) video_codec_router.add_codec(codec_x264) video_codec_router.add_codec(codec_rav1e) @@ -467,7 +484,7 @@ subtitle_codec_router.add_codec(codec_sdrop) # see doc/command_assembler.png command = over.types.ndict() command.identify = Command("ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", "INFILE") -command.normalize_prepass = Command("ffmpeg", "-i", "INFILE", "MAP", "-filter:a", "loudnorm=i=-23.0:tp=-2.0:lra=7.0:print_format=json", "-f", "null", "/dev/null") +command.normalize_prepass = Command("ffmpeg", "CUT_FROM", "-i", "INFILE", "-threads", str(multiprocessing.cpu_count()), "CUT_TO", "MAP", "-filter:a", "loudnorm=i=-23.0:tp=-2.0:lra=7.0:print_format=json", "-vn", "-sn", "-f", "null", "/dev/null") command.encode_generic = Command("ffmpeg", "FPS", "CUT_FROM", "-i", "INFILE", "-threads", str(multiprocessing.cpu_count()), "CUT_TO", "MAP", "VIDEO", "AUDIO", "SUBTITLE", "OUTFILE") command.sub_vfilter = Command("-filter:v", "ARGS") command.sub_afilter = Command("-filter:a", "ARGS", "-ar", "48k") @@ -530,9 +547,12 @@ def get_preset(presets, preset): factory_presets = " ".join([ "@share:video=x264:23,slow;audio=opus;container=mp4;ffmpeg-vfilter=scale=1280:trunc(ow/a/2)*2", "@share-portrait:video=x264:23,slow;audio=opus;container=mp4;ffmpeg-vfilter=scale=720:trunc(ow/a/2)*2", - "@archive-hq:video=x265:23,slow;audio=opus;container=mkv", - "@archive:video=x265:25,medium;audio=opus;container=mkv", - "@archive-animation:video=x265:27,slow;audio=opus;container=mkv" + "@archive-sw-22:video=x265:22,slow;audio=opus;container=mkv", + "@archive-sw-24:video=x265:24,slow;audio=opus;container=mkv", + "@archive-sw-27:video=x265:27,slow;audio=opus;container=mkv", + "@archive-animation:video=x265:27,slow,animation;audio=opus;container=mkv", + "@archive-26:video=h265:26;audio=opus;container=mkv", + "@archive-28:video=h265:28;audio=opus;container=mkv" ]) # -------------------------------------------------- @@ -598,6 +618,7 @@ if __name__ == "__main__": files = over.types.ndict() audio_words = [] video_words = [] + subtitle_words = [] files.container = "mkv" if not main.cfg.audio: @@ -625,6 +646,14 @@ if __name__ == "__main__": if main.cfg.ffmpeg_vfilter: video_words.append("vfilter<.>=%s<.>" %(main.cfg.ffmpeg_vfilter)) + if not main.cfg.subtitle: + main.log.fail("--subtitle<.> is not set") + main.exit(1) + elif main.cfg.subtitle in ("copy", "drop"): + subtitle_words.append("%s<.>" %(main.cfg.subtitle)) + else: + subtitle_words.append("codec<.>=%s<.>" %(main.cfg.subtitle)) + if main.cfg.video == "drop": if main.cfg.audio.startswith("pcm"): files.container = "wav" @@ -667,10 +696,14 @@ if __name__ == "__main__": else: main.log.info("settings", end=":\n") - main.log.info("audio: %s", ", ".join(audio_words)) main.log.info("video: %s", ", ".join(video_words)) + main.log.info("audio: %s", ", ".join(audio_words)) + main.log.info("subtitle: %s", ", ".join(subtitle_words)) main.log.info("container: %s<.>", files.container) + if main.cfg.cut: + main.log.warn("cut: start at %s<.>, take %s<.>", main.cfg.cut[0], main.cfg.cut[1]) + if main.cfg.move: main.log.info("move source files to %s<.>/", main.cfg.move) @@ -750,6 +783,8 @@ if __name__ == "__main__": info.video_bitrate = over.text.Unit(video["bit_rate"], "b/s") elif "tags" in video and "BPS" in video["tags"]: info.video_bitrate = over.text.Unit(int(video["tags"]["BPS"]), "b/s") + elif "tags" in video and "BPS-eng" in video["tags"]: + info.video_bitrate = over.text.Unit(int(video["tags"]["BPS-eng"]), "b/s") else: info.video_bitrate = "??<.>" info.pixel_fmt = video["pix_fmt"] @@ -808,6 +843,8 @@ if __name__ == "__main__": command.normalize_prepass.reset() command.normalize_prepass.INFILE = "file:" + str(files.infile) + command.normalize_prepass.CUT_FROM = ["-ss", main.cfg.cut[0]] if main.cfg.cut else None + command.normalize_prepass.CUT_TO = ["-to", main.cfg.cut[1]] if main.cfg.cut else None command.normalize_prepass.MAP = info.map_command command.normalize_prepass.run(stderr=True) diff --git a/version.py b/version.py index 0505248..0d71bff 100644 --- a/version.py +++ b/version.py @@ -2,7 +2,7 @@ # encoding: utf-8 major = 2 # VERSION_MAJOR_IDENTIFIER -minor = 0 # VERSION_MINOR_IDENTIFIER -# VERSION_LAST_MM 2.0 -patch = 0 # VERSION_PATCH_IDENTIFIER +minor = 2 # VERSION_MINOR_IDENTIFIER +# VERSION_LAST_MM 2.2 +patch = 2 # VERSION_PATCH_IDENTIFIER str = ".".join(str(v) for v in (major, minor, patch))