Enhance Avisynth video workflow and metadata tools

This commit is contained in:
ajp_anton
2026-07-30 03:20:19 +00:00
parent d60ce51b14
commit 100cad1cb5
26 changed files with 2350 additions and 1161 deletions
+75
View File
@@ -0,0 +1,75 @@
from __future__ import annotations
from dataclasses import dataclass
_MATRIX = {1: "bt709", 5: "smpte170m", 6: "smpte170m", 9: "bt2020nc", 10: "bt2020nc"}
_PRIMARIES = {1: "bt709", 9: "bt2020", 12: "smpte432"}
_TRANSFER = {1: "bt709", 16: "smpte2084", 18: "arib-std-b67"}
_RANGE = {0: "tv", 1: "pc"}
@dataclass(frozen=True)
class ColorMetadata:
matrix: int | None
primaries: int | None
transfer: int | None
color_range: int | None
@property
def colorspace(self) -> str | None:
return _MATRIX.get(self.matrix)
def ffmpeg_args(self) -> list[str]:
values = [
("-colorspace", self.colorspace),
("-color_primaries", _PRIMARIES.get(self.primaries)),
("-color_trc", _TRANSFER.get(self.transfer)),
("-color_range", _RANGE.get(self.color_range)),
]
return [part for option, value in values if value is not None for part in (option, value)]
def x264_args(self) -> list[str]:
values = [
("--colormatrix", self.colorspace),
("--colorprim", _PRIMARIES.get(self.primaries)),
("--transfer", _TRANSFER.get(self.transfer)),
("--range", _RANGE.get(self.color_range)),
]
return [part for option, value in values if value is not None for part in (option, value)]
def x265_params(self) -> str:
values = [
("colorprim", _PRIMARIES.get(self.primaries)),
("transfer", _TRANSFER.get(self.transfer)),
("colormatrix", self.colorspace),
("range", "full" if self.color_range == 1 else "limited" if self.color_range == 0 else None),
]
return ":".join(f"{name}={value}" for name, value in values if value is not None)
def mkvmerge_args(self) -> list[str]:
values = [
("--color-matrix-coefficients", self.matrix),
("--color-primaries", self.primaries),
("--color-transfer-characteristics", self.transfer),
("--color-range", {0: 1, 1: 2}.get(self.color_range)),
]
return [part for option, value in values if value is not None for part in (option, f"0:{value}")]
def hevc_bitstream_filter(self) -> str | None:
values = [
("colour_primaries", self.primaries),
("transfer_characteristics", self.transfer),
("matrix_coefficients", self.matrix),
("video_full_range_flag", self.color_range),
]
params = ":".join(f"{name}={value}" for name, value in values if value is not None)
return f"hevc_metadata={params}" if params else None
def expected_probe_values(self) -> dict[str, str | None]:
return {
"matrix": {1: "Rec709", 5: "Rec601", 6: "Rec601", 9: "Rec2020", 10: "Rec2020"}.get(self.matrix),
"primaries": _PRIMARIES.get(self.primaries),
"transfer": _TRANSFER.get(self.transfer),
"range": _RANGE.get(self.color_range),
}