Релиз: аудио дорожек из строк «Аудио», дорожка без студии на другом языке (укр. дубляж), профиль DV из «Dolby Vision P8»
docker / build (push) Successful in 1m36s

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
DenozordecandClaude Sonnet 5.5 committed 2026-11-08 13:39:57 +07:00
1 parent 76e887b4ba
commit 690275dcb0
3 files changed
+29 -3

No files matched your search

+26 -2
View File
@@ -142,8 +142,8 @@ def aggregate(tracks: list[dict]) -> dict:
uniq = rest
# дорожка без студии, при наличии дорожки того же типа со студией, — как
# правило, та же дорожка в виде кодек-строки («AC3 … | MVO, AlexFilm»)
typed = {t["translation_type"] for t in uniq if t.get("studio")}
uniq = [t for t in uniq if t.get("studio") or t["translation_type"] not in typed]
typed = {(t["translation_type"], t.get("lang")) for t in uniq if t.get("studio")}
uniq = [t for t in uniq if t.get("studio") or (t["translation_type"], t.get("lang")) not in typed]
studios = [{"studio": t["studio"], "translation_type": t["translation_type"],
"lang": t.get("lang"), "is_18plus": t["is_18plus"], "episodes": t.get("episodes")}
for t in uniq if t.get("studio")]
@@ -365,6 +365,29 @@ def segmenter_warning(model_on: bool, used: str, segs_page: list[str],
return None
def fill_audio(predictor, tracks: list[dict], lines: list[dict]) -> None:
"""Строки «Аудио N: … |студия|» -> к дорожкам (на месте).
* у дорожки нет `audio` (студию дали кодек-строка или заголовок) -> берём строку по студии;
* строка с типом озвучки, но без студии («Ukrainian AC3 … |Dub|»), и такого языка среди
дорожек ещё нет -> новая дорожка (source=codec): тип без студии страница не даёт.
"""
for t in tracks:
if not t.get("audio") and t.get("studio"):
info = next(iter(match_audio(t["studio"], lines)), None)
if info:
t["audio"] = audio_summary(info)
have = {t.get("lang") for t in tracks}
for info in lines:
if (info["names"] or info["original"] or info["commentary"] or not info["lang"] or info["lang"] in have
or not RE_CODEC_TRACK.match("Аудио: " + info["raw"]) or not codec_ok(info["raw"])):
continue
t = predictor._predict_batch([info["raw"]], [info])[0]
t.update(source="codec", episode_ranges=[], episodes=None)
tracks.append(t)
have.add(info["lang"])
def predict_release(predictor, *, html: str | None = None, text: str | None = None,
title: str | None = None, segmenter: str = "model") -> dict:
"""Предсказание для релиза целиком (html или текст страницы).
@@ -419,6 +442,7 @@ def predict_release(predictor, *, html: str | None = None, text: str | None = No
segs = title_segments(title or "")
if segs:
merge_title_tracks(tracks, predictor._predict_batch(segs))
fill_audio(predictor, tracks, lines)
result = aggregate(tracks)
warn = segmenter_warning(seg_model is not None and segmenter == "model", used,
segs_page + segs_codec, rule_segments(page_text))
+1 -1
View File
@@ -52,7 +52,7 @@ RE_RATE = re.compile(r"(?i)(?<![\d.,xх×*])(?<![xх×*] )(\d{1,3}(?: \d{3})+|\d
RE_DEPTH = re.compile(r"(?i)(?<![\d.,])(8|10|12)\s*-?\s*(?:bits?|бит)(?!\s*/)")
RE_DV_PROFILE = re.compile(r"(?i)dolby\s*vision[^/\n]{0,15}?profile\s*(\d+(?:\.\d+)?)|dvhe\.0?(\d+)")
# сокращение в заголовке: «DV 8.1», «DV P7», «DoVi P5»; только реальные профили, «DV 10-bit» — не профиль
RE_DV_SHORT = re.compile(r"(?i)\b(?:DV|DoVi)\s*(?:P|profile\s*)?([45789](?:\.[1-4])?)\b(?!\s*-?\s*bit)")
RE_DV_SHORT = re.compile(r"(?i)\b(?:DV|DoVi|Dolby\s*Vision)\s*(?:P|profile\s*)?([45789](?:\.[1-4])?)\b(?!\s*-?\s*bit)")
HDR_FLAGS = [ # (шаблон, флаг) — что нашли, в этом порядке и отдаём
(r"dolby\s*vision|\bDoVi\b|\bDV\b", "Dolby Vision"), # «DV» из заголовка; \b не цепляет DVD/DVDRip
(r"HDR10\+|HDR10\s*plus", "HDR10+"),
+2
View File
@@ -472,6 +472,8 @@ _vn = video_info("Видео: HEVC/H.265, 3840x2160, ~21.4 Mbps",
"В поисках Дори / Finding Dory (2016) UHD BDRip [H.265/2160p] [4K, HDR10, DV 8.1, 10-bit]")
check("видео nnm: 10-bit и «DV 8.1» только в заголовке -> bit_depth 10, Dolby Vision, профиль 8.1",
(_vn["bit_depth"], _vn["hdr"], _vn["dv_profile"]) == (10, ["Dolby Vision", "HDR10"], "8.1"), str(_vn))
check("видео kinozal: «Dolby Vision P8» в заголовке -> профиль 8",
video_info("Видео: MPEG-H HEVC, 24 Мбит/с, 3840x2074, 10 бит", "Настройщик / 4K, HEVC, HDR10+, Dolby Vision P8, Hybrid / WEB-DL")["dv_profile"] == "8")
check("видео: «DVDRip», «DV 10-bit» — не Dolby Vision-профиль",
(lambda a, b: a["hdr"] == [] and a["dv_profile"] is None and b["dv_profile"] is None and b["bit_depth"] == 10)(
video_info("Видео: XviD, 720x400", "Фильм [2001, DVDRip]"), video_info("Видео: HEVC, 3840x2160", "Фильм [DV 10-bit]")))