python3 $C/1502_lut_pick/lut_board.py --project $P · $V $HC/solo.py sound_ab --job $J. Машина ничего не выбирает: доска и варианты ждут Романа на Color и Sound; что не определилось — гамма, лицо, сдвиг изолятора — отказ с именем клипа, а не умолчание.Единого вызова «автоматика ингеста» нет: две команды в двух средах (доске нужны numpy, PIL и Vision — .venv_vlm; solo — .venv_transcribe). Доска lut_board — инструмент слоя 15_color; движки фильма кодом снимают свою пробу лица. Обе дороги ведут на страницу версии, где Роман и выбирает.
Шаг этапа — одна команда lut_board: машина готовит доску, выбирает Роман на Color.
Ничего по имени камеры и ничего по прокси: гамма и битность — с оригинала, лицо и яркость — с проявленного кадра. Каждое число печатается на доске вместе с источником.
| Показатель | Откуда | Норма или ворота | Файл |
|---|---|---|---|
| Гамма клипа | сайдкар Sony {stem}M01.XML, CaptureGammaEquation → тег DJI com.dji.camera.ColorGammaSxS (только оригинал) → кэш замера | известна библиотеке; незнакомая — отказ с именем клипа; Rec.709 — пропуск | _build/<CODE>_gamma_cache.json; источник виден на доске |
| Кандидаты проявки | библиотека по гамме, до 6 на камеру | меньше зажатых теней (black_share): S-Log3 neutral 14,9 %, neutral legacy 0,01 %; D-Log2 plus 55,7 %, minus 0,11 % | 1501_lut_library/manifest.json |
| Проб-кадр клипа | середина клипа через ведущую проявку, 320 px, около 10 КБ | кадр читается (frame_ok); имя несёт проявку | _build/<CODE>_lut_board_files/ |
| Лицо и кожа | Apple Vision на проявленном кадре; яркость по центральным 70 % рамки | лицо есть → экспозиция по лицу; нет — 0 стопов, «экспозиция не трогается» | покрытие (coverage) на доске |
| Целость кадра | доля пикселей ≥ 250 (пережог) и ≤ 6 (чёрное) | эталон для look: пережог ≤ 5 %, чёрное ≤ 2 % | доска, KPI |
| Промах по лицу | log2(цель / яркость лица); цель из профиля канала (YTEVO 134), умолчание 150, учится по выбору | ступени −1 … +1 по 0,5, при нужде до ±3; дальше — «лестницы не хватает» | _build/<CODE>_color_choice.json |
| Куб тот самый | sha256 копии против манифеста | совпал; иначе отказ, план не пишется | color_apply.py --verify |
лестница ±1 по 0,5 — всем клипам; больше промах — достраивается до ±3. Цель — профиль канала (YTEVO 134), иначе 150.
+3 витрины = +7,2 в Lumetri — уже за ползунком: color_plan.py не зажимает, а просит другую проявку.
Кадры снимаются с зеркала прокси (--frames-from), гамма и битность — с оригинала. Раскладка color_apply — чистая stdlib, работает при размонтированной карте: гамма из кэша.
Одна пара проявок DJI D-Log2: на клине разница 3 пункта, на кадрах дня — 23, на выборке, смещённой в тёмное, — 55,6. Поэтому доска берёт тёмные клипы, а клин только отбирает кандидатов. Замер 22.09 — 15_color, stage_detect_calibration.md.
_lut_board_files/; номер прогона в _lut_board_version.json01_Source/00_LUT/_build/--feedback выбор.json: проявка по камерам, look, экспозиция по клипам, machine, corrected, блок stageYTs/{CH}/color_profile.json по гамме, не по камере; decided_by: roman; цель лица учится по отмеченным кадрамprobe → color_probe_v1.json (кожа середина и света, YuNet) → board → 08_Cut/color/board_v1.jpgprobe → qc/color_probe.json, board → ~/Downloads/<CODE>_v4_choices/color_board.jpg; headless: measureC=~/YTAI/scripts/15_color; P=<папка проекта>; VLM=~/YTAI/environment/.venv_vlm/bin/python3 python3 $C/1502_lut_pick/lut_board.py --project $P # шаг этапа дословно; доске нужны numpy, PIL, Vision — README слоя зовёт её из $VLM, с --frames-from <зеркало прокси> --jobs 6 $VLM $C/1502_lut_pick/lut_board.py --project $P --feedback выбор.json # записать выбор: color_choice + профиль канала python3 $C/1503_color_apply/color_apply.py --project $P --verify # гамма каждого клипа, отказы, кубы по sha256; сухо
V=~/YTAI/environment/.venv_transcribe/bin/python; HC=~/YTAI/scripts/05_editing/0510_headless_cut; J=<задание 08_Cut>
$V $HC/solo.py probe --job $J && $V $HC/solo.py board --job $J # лицо и кожа → доска проявка × look; autocut и headless — на странице ColorШаг этапа — solo.py sound_ab (autocut — audio.py stems · clean · ladder): машина готовит варианты, выбирает Роман на Sound.
Петлички DJI пишут 32-bit float: пик штатно выше 0 dBFS, речь тихая. Поэтому мерится речь, а не пик, и до лимитера всё держится в float. Полная цепочка — на странице Sound; здесь — что автоматика снимает с каждого файла до выбора.
| Источник | Что меряем | Норма или ворота | Файл |
|---|---|---|---|
| Петличка TX## — уровень | речь, не пик: окна речи → усиление к −30 LUFS на входе изолятора; пик источника; доля над потолком −1 дБ | пик до +31,9 dBFS — норма float; лимитер только в float | autocut clean/<стем>.json: speech_level_in_lufs, peak_in_dbfs |
| Петличка — комната | хвост через 100 / 200 / 300 мс после фразы (tail_db) | сухая речь −35…−50 дБ; YTCG37 как записано −24 / −28 / −31, после изоляции −32 / −35 / −42 | solo sound_dialog_<tag>.json |
| Петличка — сдвиг изолятора | кросс-корреляция источник ↔ голос на самом громком окне 60 с | ≤ 48 сэмплов (1 мс), иначе стадия остановлена; длина выхода = входу | lag_check там же |
| Основная полоса сцены (трек Premiere) | ebur128 по файлу-полосе: I, LRA, TP → gain = −23 − I | тише −45 LUFS — не речь (TX02 пилота −49…−51); поправка −10…+15 дБ; пример тише −50 — звука нет | 00_Setup/01_Ingest/<CODE>_audio_level.json |
| Копия для распознавания | RMS → gain = −20 − RMS в пределах −6…+20; alimiter limit=0.85 level=disabled | копия не тише источника на 6 дБ | day_ingest s2_audio.py |
| Камеры FX3, ZV-E1, Pocket | потоки и каналы: у Pocket два потока, второй — внутренний микрофон; L и R часто разные микрофоны | по замеру каждого файла: канал на −91 дБ — цифровой ноль; -ac 1 смешивает двух людей | автоматического шага нет — открыто |
Четыре варианта на одной сетке сэмплов и в одном уровне — сравнивается характер, а не громкость. Выбирает человек на слух; без выбора машина берёт вариант по замерам и объявляет это.
| Вариант | Что делает | Для чего | Команда |
|---|---|---|---|
| raw · v1_Orig | петличка как есть: срез низа 80–100 Гц, уровень по речи | эталон «как записано» | audio.py clean · solo.py sound_ab |
| soft · v2_Soft | 60 % выделенного голоса + 40 % источника; в solo — плюс тембр петлички | комната слышна, но не мешает; паузы живые | те же |
| clean · v3_Clean | autocut 100 %, solo 90 % изолятора, без тембра | сухой голос; при 100 % в паузах цифровая тишина | те же |
| warm · v4_Warm | autocut: clean + рецепт C (+4 дБ на 120 Гц, +1,5 на 240, +1,5 на 3,5 кГц, −1,5 на 9,5 кГц); solo: 90 % + тембр петлички lav_warm (200 · 560 · 3800 Гц, полка от 8 кГц) | «тёплый с телом» — выбор Романа 12.07.2026 для накамерного звука | те же |
| v5_RecipeC (только solo) | 90 % изолятора + рецепт C | сравнить рецепт камеры с тембром петлички | solo.py sound_ab |
Изолятор — системный AUSoundIsolation (999_extra/bin/voice_isolate --wet 100 --quality high: локально, ×80 реального времени). autocut держит варианты на −30 LUFS; sound_ab доводит кусок до −16 LUFS: компрессор soft (−24 дБ, 2:1), двойное моно, AAC 256 кбит/с. Adobe Podcast Enhance — только для звука камеры.
Уровень у вариантов один: autocut держит −30 LUFS, лестница solo — −16 LUFS. Живая петличка в миксе — против цифровой тишины в паузах; doc_cut держит 0,72 изолятора.
sound_ab --job $J --take E --sec 24 → ~/Downloads/<CODE>_sound_choice/<CODE>_E_v1_Orig.m4a … _v5_RecipeC.m4asound.speech: {"clean": "isolate", "wet": 0.9, "eq": "lav_warm", "comp": "soft"} → solo.py dialogaudio.py ladder --what sound,music,edges → ~/Downloads/<…>_choices/{sound,music,edges}/audio_page.py): строки × варианты, плеер у каждого, отметка в браузере, «Скопировать выбор»--variant день=вариант; без выбора — по замерам: шум в паузах, спектр, сдвигsound_ab в Telegram ничего не шлёт: файлы и ссылку отправляет сессия рукамиtg_status.py и вехи Job.tg у headless есть — лист к ним не подключёнV=~/YTAI/environment/.venv_transcribe/bin/python; HC=~/YTAI/scripts/05_editing/0510_headless_cut; J=<задание 08_Cut> $V $HC/solo.py sound_ab --job $J # шаг этапа дословно: пять вариантов → ~/Downloads/<CODE>_sound_choice/ $V $HC/solo.py sound_ab --job $J --take E --sec 24 # другой дубль, другая длина куска $V $HC/solo.py dialog --job $J # речь фильма выбранным вариантом (sound.speech)
AC=~/YTAI/scripts/05_editing/0510_autocut $V $AC/audio.py stems --cut … --cache … && $V $AC/audio.py clean # стемы → raw · soft · clean · warm; уровень, пик, сдвиг → clean/<стем>.json $V $AC/audio.py ladder --what sound,music,edges # лестницы + страница выбора python3 ~/YTAI/scripts/17_audio/1701_level/audio_level_plan.py --project $P --main TX01 --dry-run # полосы основной по сценам (трек Premiere), сухо
lut_board, color_apply, solo develop_forcolor_choice.json и профиль каналаprobe · board, headless measureclean), пять вариантов на куске (solo sound_ab)exposure_verified_against_premiere: false; гамма в doc_cut и story_cut — развилки на Color| Проверка | Когда | Норма | Откуда взялась |
|---|---|---|---|
| Гамма у каждого клипа | до доски и до плана | известна или отказ с именем клипа; Rec.709 — пропуск | 61 клип DJI из 163 под S-Log3: luma 58 → 23 |
| Лицо найдено | ступень экспозиции, покрытие | KPI «лиц найдено X из Y»; без лица — 0 стопов | счёт шёл по небу за лобовым стеклом |
| Лестницы хватает | промах по лицу | |промах| ≤ 3 стопов витрины, ≤ 7 Lumetri | крайняя ступень молча шла за ответ |
| Куб тот самый | --verify, develop_for | sha256 = манифест | «DJI Action basic» внутри — Mavic 3 Pro, D-Log M |
| Каждый исходник замерен | stems · clean | уровень речи, пик, сдвиг ≤ 48 сэмплов, длина = входу | изолятор роняет громкую речь и несёт постоянную −82 dBFS |
| Варианты собраны до Story · Color · Sound | конец ингеста | файлы лежат, страница собрана, ссылка у Романа | «эхо» на готовом фильме стоило пересборки |
| Ничего не выбрано молча | везде | умолчание объявлено на странице версии; доска предлагает выбор Романа, не свой | кривая без «ок» дважды вернулась «пересветом» |
| Выбор покрывает клипы дня | --feedback | слаги выбора = клипы на диске; гамма хотя бы у одной камеры | профиль рождался без проявок при «ВЫБОР СОХРАНЁН» |
| Файл | Что хранит | Кто пишет |
|---|---|---|
YTs/{CH}/color_profile.json | проявка по гамме и камерам, look, цель лица; decided_by, learned_from | lut_board --feedback; есть у YTEVO и YTUVIE; бэкап перед записью |
01_Source/00_LUT/_build/<CODE>_color_choice.json | выбор дня: develop, look, exposure по клипам, machine, corrected, stage | lut_board --feedback; старые проекты читаются из 00_Setup/01_Ingest |
_build/<CODE>_gamma_cache.json · _color_plan.json | замер гамм с источником; раскладка в stops_lumetri (×2,4), refused, skipped | color_apply --apply; руками не править |
1501_lut_library/manifest.json | 169 кубов: 137 проявка · 27 look · 2 pre · 3 legacy; sha256, black_share, гамма входа | lut_lib.py --import · --validate --deep; в git, store на Drive |
00_Setup/01_Ingest/<CODE>_audio_level.json | полосы основной по сценам: I, LRA, TP, gain_db, примеры, поправка мастера | audio_level_plan.py — единственный писатель; прошлый план в _backup |
autocut clean/<стем>.json · variant_choice.json | уровень речи, усиление, пик, сдвиг изолятора; выбранный вариант по дням | audio.py clean; руками — --variant |
17_audio/standard.py · color_plan.py | числа звука: −23, −45, −50, −10…+15, мастер −14 / −16; цвета: ступени ±1…±3, цель 150, ×2,4, ±7 | сессия после решения Романа; копий не заводить |