Add Avisynth video encoding workflow

This commit is contained in:
ajp_anton
2026-07-21 00:41:00 +00:00
parent f50f465465
commit 49296d6f45
37 changed files with 9487 additions and 76 deletions
+139
View File
@@ -0,0 +1,139 @@
from __future__ import annotations
import shutil
import subprocess
from pathlib import Path
from tools.exiftool import run_exiftool_command
EXCLUDED_COPY_TAGS = [
"--File:all",
"--ExifTool:all",
"--Composite:all",
"--SourceFile",
"--Directory",
"--FileName",
"--FileSize",
"--FileModifyDate",
"--FileAccessDate",
"--FileInodeChangeDate",
"--FilePermissions",
"--FileType",
"--FileTypeExtension",
"--MIMEType",
"--ImageWidth",
"--ImageHeight",
"--ExifImageWidth",
"--ExifImageHeight",
"--PixelXDimension",
"--PixelYDimension",
"--RelatedImageWidth",
"--RelatedImageHeight",
"--ImageSize",
"--Megapixels",
"--XResolution",
"--YResolution",
"--ResolutionUnit",
"--Duration",
"--DurationScale",
"--DurationValue",
"--MediaDuration",
"--MediaTimeScale",
"--TrackDuration",
"--TrackCreateDate",
"--TrackModifyDate",
"--MediaCreateDate",
"--MediaModifyDate",
"--AvgBitrate",
"--Bitrate",
"--MaxBitrate",
"--VideoFrameRate",
"--CaptureFrameRate",
"--AudioBitrate",
"--AudioSampleRate",
"--AudioSamplingRate",
"--AudioBitsPerSample",
"--AudioChannels",
"--CompressorID",
"--CompressorName",
"--MediaDataOffset",
"--MediaDataSize",
]
def copy_meaningful_metadata(
exiftool: str,
source: Path,
destination: Path,
) -> None:
if destination.suffix.lower() in {".mp4", ".mov"}:
copy_meaningful_metadata_with_exiftool(exiftool, source, destination)
return
copy_container_metadata_with_ffmpeg(source, destination)
def copy_meaningful_metadata_with_exiftool(
exiftool: str,
source: Path,
destination: Path,
) -> None:
args = [
"-overwrite_original",
"-TagsFromFile",
str(source),
"-all:all",
*EXCLUDED_COPY_TAGS,
str(destination),
]
run_exiftool_command(
exiftool,
args,
check=True,
capture_output=True,
text=True,
)
def copy_container_metadata_with_ffmpeg(source: Path, destination: Path) -> None:
ffmpeg = shutil.which("ffmpeg")
if not ffmpeg:
print(" metadata: ffmpeg not found; skipped best-effort metadata remux")
return
temp_output = destination.with_name(f"{destination.stem}.metadata-copy{destination.suffix}")
temp_output = _unique_path(temp_output)
command = [
ffmpeg,
"-y",
"-hide_banner",
"-loglevel",
"error",
"-i",
str(destination),
"-i",
str(source),
"-map",
"0",
"-map_metadata",
"1",
"-c",
"copy",
str(temp_output),
]
try:
subprocess.run(command, check=True, capture_output=True, text=True)
temp_output.replace(destination)
finally:
if temp_output.exists():
temp_output.unlink()
def _unique_path(path: Path) -> Path:
if not path.exists():
return path
for index in range(1, 10000):
candidate = path.with_name(f"{path.stem}-{index}{path.suffix}")
if not candidate.exists():
return candidate
raise RuntimeError(f"Could not find a unique temporary path for {path}")