Simplify conversion to one fail-safe H.264 profile

This commit is contained in:
SpiderFish
2026-08-26 11:33:22 +10:00
parent b9b31abf2e
commit 3a2d79609b
2 changed files with 15 additions and 20 deletions
+5 -5
View File
@@ -54,11 +54,11 @@ the `.env.example` values through Coolify's environment-variable UI.
## Codec policy ## Codec policy
Cached video is H.264 High Profile, Level 4.1, 8-bit `yuv420p`, CRF 18, capped Cached video is H.264 High Profile, 8-bit `yuv420p`, CRF 18, capped at 15 Mbps.
at 15 Mbps. Existing audio, subtitles, chapters, and Matroska attachments are Resolution and frame rate are preserved. Existing audio, subtitles, chapters,
preserved when the container supports them. Ten-bit SDR is converted with and Matroska attachments are copied. Ten-bit SDR is converted with
error-diffusion dithering; HDR10, HLG, and Dolby Vision-labelled sources are error-diffusion dithering; sources carrying explicit HDR10 or HLG transfer
tone-mapped to BT.709 SDR before encoding. metadata are tone-mapped to BT.709 SDR.
The fixed source blacklist is: The fixed source blacklist is:
+10 -15
View File
@@ -39,7 +39,7 @@ H264_CRF = os.environ.get("H264_CRF", "18")
H264_PRESET = os.environ.get("H264_PRESET", "medium") H264_PRESET = os.environ.get("H264_PRESET", "medium")
H264_MAXRATE = os.environ.get("H264_MAXRATE", "15M") H264_MAXRATE = os.environ.get("H264_MAXRATE", "15M")
H264_BUFSIZE = os.environ.get("H264_BUFSIZE", "30M") H264_BUFSIZE = os.environ.get("H264_BUFSIZE", "30M")
ENCODE_PROFILE = f"h264-high41-8bit-crf{H264_CRF}-{H264_PRESET}-{H264_MAXRATE}-quality-v2" ENCODE_PROFILE = f"h264-high-8bit-crf{H264_CRF}-{H264_PRESET}-{H264_MAXRATE}-quality-v3"
FFMPEG = os.environ.get("FFMPEG", "/usr/bin/ffmpeg") FFMPEG = os.environ.get("FFMPEG", "/usr/bin/ffmpeg")
FFPROBE = os.environ.get("FFPROBE", "/usr/bin/ffprobe") FFPROBE = os.environ.get("FFPROBE", "/usr/bin/ffprobe")
@@ -389,8 +389,10 @@ class Manager:
continue continue
old = inventory.get(relative) or {} old = inventory.get(relative) or {}
if old.get("fingerprint") == current_fingerprint: if old.get("fingerprint") == current_fingerprint:
if relative in catalog and catalog[relative].get("item_id"): if relative in catalog:
old["item_id"] = catalog[relative]["item_id"] for key in ("item_id", "color_transfer", "color_primaries", "color_space"):
if catalog[relative].get(key):
old[key] = catalog[relative][key]
continue continue
details = catalog.get(relative) details = catalog.get(relative)
view = VIEW_ROOT / relative view = VIEW_ROOT / relative
@@ -469,13 +471,8 @@ class Manager:
profile = (info.get("profile") or "").lower() profile = (info.get("profile") or "").lower()
return codec in BLACKLISTED_CODECS or (codec == "h264" and (depth > 8 or "10" in profile)) return codec in BLACKLISTED_CODECS or (codec == "h264" and (depth > 8 or "10" in profile))
def is_hdr(self, info, source): def is_hdr(self, info):
transfer = (info.get("color_transfer") or "").lower() return (info.get("color_transfer") or "").lower() in {"smpte2084", "arib-std-b67"}
name = source.name.lower()
return (
transfer in {"smpte2084", "arib-std-b67"}
or any(token in name for token in ("hdr10", "hdr.", ".hdr", "dovi", "dolby.vision"))
)
def candidate_list(self): def candidate_list(self):
now = time.time() now = time.time()
@@ -581,15 +578,13 @@ class Manager:
self.process = None self.process = None
def ffmpeg_command(self, source, partial, info): def ffmpeg_command(self, source, partial, info):
hdr = self.is_hdr(info, source) hdr = self.is_hdr(info)
if hdr: if hdr:
transfer = (info.get("color_transfer") or "").lower() transfer = (info.get("color_transfer") or "").lower()
if transfer == "arib-std-b67": if transfer == "arib-std-b67":
input_colors = "tin=arib-std-b67:pin=bt2020:min=bt2020nc:" input_colors = "tin=arib-std-b67:pin=bt2020:min=bt2020nc:"
elif transfer == "smpte2084":
input_colors = ""
else: else:
input_colors = "tin=smpte2084:pin=bt2020:min=bt2020nc:" input_colors = ""
video_filter = ( video_filter = (
f"zscale={input_colors}t=linear:npl=100,format=gbrpf32le," f"zscale={input_colors}t=linear:npl=100,format=gbrpf32le,"
"zscale=p=bt709,tonemap=tonemap=hable:desat=0," "zscale=p=bt709,tonemap=tonemap=hable:desat=0,"
@@ -604,7 +599,7 @@ class Manager:
"-vf", video_filter, "-vf", video_filter,
"-c:v", "libx264", "-preset", H264_PRESET, "-crf", H264_CRF, "-c:v", "libx264", "-preset", H264_PRESET, "-crf", H264_CRF,
"-maxrate", H264_MAXRATE, "-bufsize", H264_BUFSIZE, "-maxrate", H264_MAXRATE, "-bufsize", H264_BUFSIZE,
"-pix_fmt", "yuv420p", "-profile:v", "high", "-level:v", "4.1", "-pix_fmt", "yuv420p", "-profile:v", "high",
"-c:a", "copy", "-c:s", "copy", "-c:a", "copy", "-c:s", "copy",
] ]
if hdr: if hdr: