◂ База знанийRYA.AEAudio Fine Sync — точный синхрон по звуку поверх речевогообновлено 16 авг 2026
Речевой синхрон (3.2 Word-Sync) ставит съёмочный день на общую ось, но его точность — 0.6–0.9 секунды (15–20 кадров при 25p): опора — момент произнесения слова. Для раскладки дня хватает; чтобы резать по петличке как по основной дороге диалога — нет: губы разъезжаются. Fine Sync — третий, последний слой: взаимная корреляция самих звуковых волн доводит рассинхрон до единиц миллисекунд, полностью автоматически, за ~1.5 минуты на съёмочный день.
📌 Когда применять. После make_ingest.py и валидатора, до «Build Ingest» — на каждом проекте, где диалог будут резать по петличке. Поправки живут в ingest.json (wall_offset): на уже собранный таймлайн они не действуют — секвенции надо пересобрать. Не нужно: если петлички нет вовсе или точность в полкадра не требуется.
часы устройств ±5–22 мин word-sync 0.6–0.9 с fine sync 1–3 мс Build Ingest резать можно
1Идея2Измерение3Решение системы4Оплаченные грабли5Floor-грабля Premiere6Как пользоваться7Spread / Collect8Вердикт и флаги9Цифры YTCH1010Где лежит

3.3 · 1Идея: ошибка живёт в источнике, а не в паре

Источник — всё, что звучит и стоит на таймлайне: видеоклип (накамерный микрофон) и полоса петлички (WAV рекордера). Ключевой факт, доказанный на реальном материале: один клип смещён одинаково относительно всех петличек, одна полоса — относительно всех клипов. Ошибка положения принадлежит источнику.

Значит каждое измерение пары даёт уравнение Δ(A,B) = e_B − e_A, и N источников сцены дают до N(N−1)/2 уравнений на N неизвестных — переопределённую систему, которая решается целиком методом наименьших квадратов. Это принципиальное отличие от попарного синхрона (Premiere Synchronize, PluralEyes, Syncaila): они решают по одному уравнению за раз и выбрасывают избыточность — ту самую, что защищает от ошибок.

клип без речи чинится через общие петличкиложный захват = выброс невязкикачество = число, не «на глаз»

3.3 · 2Измерение: корреляция огибающих речи

Для каждой пары источников, пересекающихся во времени сцены, берётся несколько окон (по умолчанию 4 × 20 с) внутри пересечения:

# полоса речи → огибающая → нормированная взаимная корреляция
ffmpeg −ss (точный seek) → mono 16 кГц → highpass 200 / lowpass 3800
лог-RMS-огибающая, шаг 4 мс, минус медленный тренд (уровни/АРУ разные)
NCC(окно A, окно B ± диапазон поиска) → пик + параболическая интерполяция
→ Δ с точностью единицы мс при кадре 40 мс

Меряются все типы пар: камера↔петличка, петличка↔петличка и камера↔камера. Пары «петличка↔петличка» — не украшение: полосы двух рекордеров перекрываются по 30 минут и сшивают сцену в один жёсткий граф (см. грабли ниже). Ни один попарный синхронизатор таких рёбер не строит в принципе.

Защита на уровне окна: истинный сдвиг один на всю пару, поэтому разлёт окон > 50 мс = ложный захват на похожей фразе — измерение отбрасывается целиком (unstable), а не усредняется. Пик на краю диапазона поиска (5% зоны) = настоящий пик снаружи — окно выбрасывается. Пары с перекрытием < 25 с не меряются вовсе: короткое перекрытие — зона ложных захватов.

3.3 · 3Решение: МНК с весами Хьюбера

Система Δ = e_B − e_A решается итеративно (IRLS): вес измерения падает как 1/|невязка| за порогом 20 мс — ложный захват не портит решение тихо, а всплывает как выброс и фактически исключается. Калибровка (gauge): общий сдвиг сцены не наблюдаем, поэтому в каждой связной компоненте среднее поправок видео-клипов приравнивается нулю — видео остаётся, где его поставил речевой синхрон, двигается звук.

Что это даёт сверх попарного синхрона:

  • 1
    Клип без речи получает поправку — через пересечение с общими полосами. На YTCH10 клип с sync_source: clock уехал на 1.34 с = 33 кадра и вылечился без единого клика.
  • 2
    Ложный захват отбрасывается автоматически — у попарного синхрона ошибка молча становится результатом.
  • 3
    Невязка после решения — честная цифра качества. Единицы мс = синхрон доказан числом. Десятки мс = разбираться, не строить.

3.3 · 4Оплаченные грабли

Острова по 30-минутным файлам и мосты

Рекордер режет петличку по 30 минут. Если мерить только «камера↔петличка», сцена распадается на острова по границам файлов, связанные единственным клипом на стыке. Один ложный захват на нём сдвигает половину сцены — при идеальной невязке, потому что противоречить нечему. Поймано живьём на YTCH10: 1.4 с при невязке 1.5 мс.

Лечение: пары петличка↔петличка (сшивают острова) + поиск мостов (Тарьян) — связей, обрыв которых разваливает граф. Мост в отчёте = «домерить --repeat 3 или добавить перекрывающийся источник».

Нулевая невязка ничего не значит при dof = 0

Степени свободы = сколько измерений проверяют решение, а не задают его. Когда граф — дерево (измерений ровно столько, сколько неизвестных), невязка обязана быть нулевой — это свойство арифметики, не доказательство синхрона. Инструмент говорит это вслух и возвращает код 2; лечится --repeat 2 (повторные независимые замеры тех же пар другими окнами — они же страхуют мосты).

Сцены без общего звука распадаются на куски

Немой B-roll, снятый в стороне, корреляцией не привязать — он остаётся на речевой точности, и это видно в отчёте («сцена распадается на N кусков»). Внутри куска — миллисекунды, между кусками — прежние 0.6–0.9 с. Знать, где стык, и глянуть глазами.

3.3 · 5Квантование Premiere и политика «видео — хозяин»

Находка 16.08.2026 №1 (YTCH10): Premiere (UXP setSourceInOut) квантует source-in/out аудио-клипа к видеокадровой сетке — floor, даже для аудио-only WAV. Билдер задавал in = 324.512, Premiere молча делал 324.480 — дробь 14–32 мс срезалась, и петличка везде опаздывала на 0–40 мс.

Находка 16.08.2026 №2 (YTCH13, тик-дамп, 28/28 замеров): позицию аудио-клипа Premiere субкадрово НЕ держит — insert округляет позицию к ближайшему кадру (дробь <20 мс — вниз, >20 мс — вверх). Первая версия фикса («in-точка на сетку, дробь — в позицию слайса», ceil-политика quantizeTxPlacements) строилась на обратном предположении и потому не работала: компенсацию съедало округление позиции, остаток −31.6…+19.9 мс. Отдельно поймано: overwrite видео может лечь на +1 кадр от запрошенного (float-шум в секундах), а compound-транзакция исполняет свои overwrite в ОБРАТНОМ порядке — хвост раннего клипа съедает голову позднего.

Действующая архитектура (17.08.2026): у clip-API нет субкадрового рычага — значит, всё на сетку тиками, а миллисекунды живут в медиа. Полное описание этапа доставки чисел в Premiere — 3.4 Frame-Align & Build Verify.

1. Билдер кладёт всё сам на точные тики кадра (sceneLayout.gridAlignPlan + TickTime.createWithTicks): позиции видео и слайсов, in/out — целые кадры, Premiere нечего округлять и floor'ить. Блок целиком (видео + петля) якорится к ближайшему кадру — ступенек на границах V/A нет по построению. Видео кладётся последовательными транзакциями по возрастанию времени (защита от реверса compound).

2. Субкадровая точность переезжает в WAV (0113_frame_align.py, шаг 4.6 ранбука): на каждую (сцену × петличку) рендерится один WAV в координатах таймлайна — контент каждого слайса лежит в файле ровно на своём сэмпле (пер-слайсная компенсация: поправки fine-sync у каждого видеоклипа свои, одним сдвигом файла не лечится). Билдер кладёт identity-слайсы (offset == source-in) — синхрон ≤ 1 сэмпла.

3. Гейт числом (verify_build_sync.py, ГЕЙТ 6.5): после сборки дамп секвенций сверяется с планом по тикам — счётчики, позиции, in, длительности; допуск 2 мс. Ловит и то, что уши не слышат: клип на +1 кадр, съеденную голову, «вставленные», но пропавшие слайсы.

Политика «видео — хозяин» сохранена: видео стоит на кадрах, петличке при рендере режут/тянут головы блоков на сэмплы. Правило на будущее: любой механизм точного синхрона (finesync, Synchronize, Syncaila) заканчивается пересборкой через grid-раскладку + 0113 + verify — иначе пересборка вернёт до ±20 мс рассинхрона на слайс.

3.3 · 6Как пользоваться

1
Из UXP-панели основной путь

Вкладка Ingest: в сводке ingest видна строка Fine sync: applied <дата> либо Fine sync: NOT APPLIED. Кнопка Fine Sync рядом с Build Ingest: панель передаёт путь к ingest и запускает расчёт (Терминал открывается сам — внутри UXP нельзя, нужен ffmpeg и сотни гигабайт медиа). Когда поправки легли, панель сама перечитывает ingest и пишет «Fine sync applied — REBUILD the sequences».

потом Build / Rebuild Ingestпанель всегда перечитывает ingest с диска перед сборкой
2
Из терминала
cd ~/YTAI/scripts/999_extra/audio_finesync
python3 finesync_run.py "<папка проекта>"            # посмотреть, ничего не меняет (~1.5 мин/день)
python3 finesync_run.py "<папка проекта>" --apply    # применить + валидатор + ПЕРЕМЕР + вердикт

Отчёты → 00_Setup/01_Ingest/finesync/. Откат: рядом с ingest остаётся *_backup_finesync_*.json. Двойной клик — finesync.command (спросит папку в Finder). Ручной режим по шагам: finesync.py → finesolve.py.

Три инварианта, на которых всё держится:

  • I
    Синхрон — это измерение. Сборка — это пересчёт из чисел. Поправка ложится в wall_offset ingest; билдер пересобирает таймлайн (нарезку петличек, компрессию пауз) из чисел сам. «Возвращать клипы на место» руками не нужно ни в одном сценарии.
  • II
    Проверка — только независимым перемером другими окнами. Совпадение на тех же окнах, по которым считались поправки, не доказывает ничего.
  • III
    После поправок — Rebuild. В уже собранный таймлайн изменения ingest сами не приедут.

3.3 · 7Spread / Collect: путь через Premiere Synchronize

Для выборочной сверки штатным механизмом Premiere (или когда хочется контролировать глазами). Работает посценно — Synchronize живёт внутри одной секвенции. Ряд Premiere sync на вкладке Ingest:

1
Spread

Открыть секвенцию сцены → кнопка строит одноразовую {code}_{scene}_SYNC: каждый клип на своей V/A-паре (Synchronize серый, пока выделенные клипы лежат на одной дорожке), каждая петличка целой полосой на своей A-дорожке (резать нечего → floor'ить нечего), всё на сырых wall-позициях + преролл 30 с, чтобы было куда двигать влево. Манифест раскладки → 01_Ingest/finesync/sync_session_{scene}.json.

2
Человек

Выделить всё → Clip → Synchronize → Audio (Track Channel петлички).

3
Collect

Панель читает, куда Premiere подвинул каждый элемент; дельта = поправка. Перечитывает ingest с диска, сверяет сцену с манифестом (если ingest менялся после Spread — стоп, «re-Spread»: складывать поправки поверх поправок = удвоить их), вливает дельты в wall_offset (бэкап *_backup_syncspread_*) и просит Rebuild сцены. _SYNC-секвенция одноразовая — удалить.

Ограничение: >40 клипов в сцене — Spread отказывается (нужно 40+ дорожек), совет использовать Fine Sync. Оба пути кладут результат в одно место — ingest — и дают одинаковые миллиметры.

3.3 · 8Вердикт и флаги

что видночто значитчто делать
✅ все пары в допускепопадание точное (допуск — полкадра)строить таймлайн
⚠️ МОСТЫсвязь без страховки: ошибка в ней сдвинет кусок сцены--repeat 3 по этой сцене
⚠️ распадается на N кусковнет общего звука между кускамивнутри — мс, между — речевая точность; глянуть стык
⚠️ проверить нечем (dof=0)граф — дерево, нулевая невязка = арифметика--repeat 2 (в раннере включён по умолчанию)
пара вне допускаобычно короткое перекрытие или шум (машина, ходьба)перемерить точечно или принять

3.3 · 9Цифры: YTCH10, первый боевой прогон

значение
материал12 сцен · 151 клип · 40 полос петличек · 314 измерений
время счёта1 мин 33 с на весь съёмочный день
до поправокразброс до 1.7 с (42 кадра) внутри сцены
невязка решения0.1–2.5 мс по сценам, худший максимум 9.9 мс
контрольный перемер другими окнами159 / 159 пар в пределах полкадра, худшая 9.3 мс
после фикса floor-грабли, симуляция сборки212 слайсов: 0 раньше видео · 0 наложений · floor-потеря 0.000 мс (симуляция не знала об округлении позиции — на живом YTCH13 остаток был −31.6…+19.9 мс, см. секцию «Квантование Premiere»; закрыто grid-раскладкой + 0113)

Код панели прошёл адверсарное ревью (18 агентов, 15 находок, 9 подтверждено и закрыто: мосты в графе, отрицательные позиции головных слайсов, стейл-память при Collect, лимит прогрева дорожек и др.). Тесты: wallclock-сьют 107/107 (после перехода на grid-раскладку 17.08.2026; мок Premiere моделирует реальное квантование floor/nearest).

3.3 · 10Где лежит

чтогде
измеритель + решатель + раннер~/YTAI/scripts/999_extra/audio_finesync/ (README там же)
grid-раскладка (всё на тики кадра)0500_uxp/src/ingest/layout/sceneLayout.js · gridAlignPlan
рендер петли в координатах таймлайна999_extra/wordsync_multicam/0113_frame_align.py (+ 0500_uxp/tools/plan_cli.js)
гейт после сборки (дамп vs план, тики)999_extra/wordsync_multicam/verify_build_sync.py
Spread / Collect (чистая логика + тесты)0500_uxp/src/ingest/syncSpread.js · tests/ingest/wallclock/
постановка, история, сравнение путей0500_uxp/HANDOFF_audio_sync.md
шаг в конвейереdocs/wordsync/WORDSYNC_RUNBOOK.md — Шаг 4.5 с гейтом
речевой слой (предыдущий)/kb/multicam-wordsync/ · 999_extra/wordsync_multicam/
Fine Sync = третий слой синхрона: часы → речь → звук. Синхрон — измерение, сборка — пересчёт из чисел. Ошибка живёт в источнике; невязка — доказательство; видео — хозяин, петличке режем голову.