API: видео, тип релиза и субтитры в ответе релиза; Atmos и kHz у дорожек
docker / build (push) Successful in 1m18s

src/techinfo.py — правила по строкам «Видео:», «Тип релиза:»/«Качество»,
«Контейнер:», «Продолжительность:», «Субтитры:» и заголовку: поля video
(кодек, размер кадра, класс разрешения, fps, битрейт, битность, HDR,
профиль DV), release (тип, нормализованный источник, контейнер,
продолжительность), subtitles (языки с forced/full/SDH, формат, вшитые).
audio дорожек и original: khz и atmos (вход модели не меняется).
title_from_html больше не рвёт заголовок rutracker пробелами
(<span>/<wbr> на каждом слове). Покрытие на 600 страницах каждого
трекера: видео 90/93/100%, e2e озвучки без изменений. Тесты 275 ok.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
DenozordecandClaude Opus 5.5 committed 2026-11-02 22:26:57 +07:00
1 parent 89ffe4375b
commit dc19fe6255
9 files changed
+409 -16

No files matched your search

+52
View File
@@ -385,6 +385,58 @@ check("аудио: дорожка студии находит свою стро
_orig = original_info(_au)
check("оригинал: ENG, 768 kbps, 6 каналов", _orig and _orig["lang"] == "ENG" and _orig["bitrate_kbps"] == 768 and _orig["channels"] == 6, str(_orig))
check("оригинал: нет строки Original -> None", original_info(_au[:2]) is None)
check("оригинал: E-AC3+Atmos -> atmos, 48 kHz", _orig and _orig["atmos"] and _orig["khz"] == 48 and _orig["codec"] == "E-AC3", str(_orig))
from src.trackinfo import audio_summary, parse_audio_line
check("аудио: без Atmos -> atmos false", audio_summary(_au[0])["atmos"] is False)
check("аудио: 44.1 KHz и 48000 Гц", parse_audio_line("AC3, 2 ch, 44.1 KHz, 192 kbps")["khz"] == 44.1
and parse_audio_line("AAC 48000 Гц 2 ch 128 kbps")["khz"] == 48)
check("аудио: «48 kHz» не меняет вход модели (кодек без +Atmos)", parse_audio_line("English E-AC3+Atmos / 5.1 / 48 kHz / 768 kbps")["codec"] == "E-AC3")
print("== техданные: видео, тип релиза, субтитры ==")
from src.release import title_from_html
from src.techinfo import release_info, subtitles_info, video_info, _rate_kbps
_fx_html = open("data/samples/rt-topic-6870900.html", encoding="utf-8").read()
_fx_title = title_from_html(_fx_html)
check("заголовок rutracker без разрывов слов (<span>/<wbr>)",
_fx_title.startswith("Супер Марио: Галактическое кино / The Super Mario Galaxy Movie (Аарон Хорват"), _fx_title[:80])
_fx_text = html_to_text(_fx_html)
_v = video_info(_fx_text, _fx_title)
check("видео: HEVC 3840x2160 2160p 23.976 fps 24800 kbps 10 бит",
_v and (_v["codec"], _v["width"], _v["height"], _v["resolution"], _v["fps"], _v["bitrate_kbps"], _v["bit_depth"])
== ("HEVC", 3840, 2160, "2160p", 23.976, 24800, 10), str(_v))
check("видео: HDR — Dolby Vision, HDR10+, HDR10; профиль DV 8",
_v and _v["hdr"] == ["Dolby Vision", "HDR10+", "HDR10"] and _v["dv_profile"] == "8", str(_v and _v["hdr"]))
_r = release_info(_fx_text, _fx_title)
check("релиз: WEB-DL, MKV, 01:38:12 = 5892 с",
_r and (_r["source"], _r["container"], _r["duration"], _r["duration_sec"]) == ("WEB-DL", "MKV", "01:38:12", 5892), str(_r))
_s = subtitles_info(_fx_text, _fx_title)
check("субтитры: RUS forced, UKR forced+full+SDH, ENG full+SDH, softsub (SRT)",
_s and [(t["lang"], t["forced"], t["full"], t["sdh"]) for t in _s["tracks"]]
== [("RUS", True, False, False), ("UKR", True, True, True), ("ENG", False, True, True)]
and _s["format"] == "softsub (SRT)", str(_s))
check("видео: битрейт не склеивается с высотой кадра", _rate_kbps("Xvid 640x272 699 kb/s") == 699
and _rate_kbps("DivX 704 x 400 699 KB/s") == 699 and _rate_kbps("8 200 Кбит/сек") == 8200)
check("видео: «5763 Mбит/с» — на деле килобиты", _rate_kbps("MPEG-4 AVC, 5763 Mбит/с, 1280x720") == 5763)
check("видео: кадр 1920x800 — всё равно 1080p; fps 23.809523 целиком",
(lambda v: v["resolution"] == "1080p" and v["fps"] == 23.809523)(video_info("Видео: AVC, 1920x800, 23.809523 fps, 1776 Kbps")))
check("видео: строки «Видео» нет -> None", video_info("Аудио: AC3, 2 ch") is None)
check("релиз: «18 x ~ 00:20:00» и список файлов — без duration_sec",
release_info("Продолжительность: 18 x ~ 00:20:00")["duration_sec"] is None
and release_info("Продолжительность: 01:31:25, 01:25:23")["duration_sec"] is None)
check("релиз: «Формат : AVC» MediaInfo — не контейнер, «Формат: Matroska» — MKV",
release_info("Формат : AVC\nФормат : Matroska")["container"] == "MKV")
check("релиз: тип из заголовка, если «Качество» его не называет",
release_info("Качество: Hybrid (2160p)", "Фильм / Film [2024, BDRemux 2160p]")["source"] == "BDRemux")
_sn = subtitles_info("Субтитры: отсутствуют")
check("субтитры: «отсутствуют» — пустой список языков, а не None", _sn is not None and _sn["languages"] == [], str(_sn))
check("субтитры: nnm — поле до табуляции («Отсутствуют\\tДата…»)",
subtitles_info("Субтитры: Отсутствуют\tДата мировой премьеры: 2 апреля 2011")["languages"] == [])
check("субтитры: kinozal «Субтитры1: Full | iTunes • RUS»",
subtitles_info("Субтитры1: Full | iTunes • RUS\nСубтитры2: Forced | Official • UKR")["languages"] == ["RUS", "UKR"])
check("субтитры: вшитые -> hardsub", subtitles_info("Субтитры: русские, вшитые")["hardsub"] is True)
check("субтитры: строк нет — языки из «Sub (Rus, Eng)» заголовка",
subtitles_info("", "Фильм [2024] Dub + Sub (Rus, Eng)")["languages"] == ["RUS", "ENG"])
check("субтитры: нигде нет -> None", subtitles_info("Видео: AVC") is None)
_T = ["проф. дубляж", "проф. многоголосый", "люб. многоголосый", "многоголосый"]
check("тип: «Любительский (многоголосый …) Дубляжная» не дубляж",
guard_type("проф. дубляж", "Любительский (многоголосый закадровый) Дубляжная", "Дубляжная", _T) == "люб. многоголосый")