◂ База знанийRYA.AESync Verification — проверка синхрона независимым приборомобновлено 26 сен 2026
Ингест собирает, проверка судит — это разные этапы. У них разные входы (ингест читает день, проверка читает уже собранный .prproj), разные инструменты и разный смысл кода возврата. Смешивать их нельзя по одной причине: прибор, которым проверяешь, обязан быть точнее того, что проверяешь. Родной Clip → Synchronize в Premiere кладёт клипы только на целые кадры — 40 мс при 25p, — а численный синхрон держит 1–14 мс. Поэтому Premiere здесь не корректор, а независимый свидетель: он может подтвердить, но не уточнить.
📌 Когда применять. После 4.2 Fine Sync и 4.3 Frame-Align: первый вердикт — кнопкой Verify Sync сразу после Build, на каждой сцене; остальные приборы — когда вердикт красный или перед тем, как отдавать проект монтажёру. Ответ этапа: «числам можно верить» или «вот источник, который врёт». Проверка ничего не чинит: она измеряет и ставит вердикт.
ингест собран 4.1–4.3→ кнопка Verify Sync→ точный прибор pair_check→ предполётная sync_ready→ стенд + Synchronize→ вердикт в кадрах→ ингест обычно не трогаем
1Почему отдельный этап2Пять приборов3Правило разрешения4Стенд под Synchronize5Оплаченные грабли6Как пользоваться7Что считать успехом8Цифры YTUVIE019Запись экрана10Билдер сжимает видео11Где лежит

4.4 · 1Почему это отдельный этап, а не хвост ингеста

Ингест отвечает на вопрос «где стоит каждый клип» и заканчивается числом в ingest.json. Проверка отвечает на другой вопрос — «этому числу можно верить?» — и заканчивается вердиктом. Разделить их пришлось после дня, когда обе роли были в одной кнопке: Collect и мерил, и тут же переписывал ингест. Пока он был один, любое измерение немедленно становилось правкой, и грубый прибор молча портил точный.

Ингест — строит
  • вход: съёмочный день, транскрипты, рекордер
  • выход: ingest.json + секвенции в Premiere
  • код возврата: «собралось / не собралось»
  • ошибка дорогая: пересборка
Проверка — судит
  • вход: готовый ingest.json + сохранённый .prproj
  • выход: вердикт в миллисекундах и кадрах
  • код возврата: «в допуске / врёт / не измерить»
  • ошибка дешёвая: перемерить

⚠️ Практическое следствие: у проверки нет права записи по умолчанию. Она сначала печатает таблицу, а пишет только по явному подтверждению человека.

4.4 · 2Пять приборов и их разрешение

приборчто меряетметодразрешениенезависим от
Verify Sync
verify_sync.py
каждую пару звуковых дорожек собранной сцены — по факту .prproj, не по планукорреляция огибающих речи 200–3800 Гц, шаг 4 мс (функции timeline_sync_audit.py)единицы мс, вердикт в кадрахпланировщика и ингеста
finesyncпоправки ко всем источникам сразукорреляция огибающих речи + МНК1–3 мс—
pair_checkкаждую пару источников отдельноGCC-PHAT на 48 кГц0,008 мсfinesync (другой метод)
Clip → Synchronizeкуда Premiere сама подвинет клипвнутренний, закрытыйкадр = 40 мсвсего нашего кода
prproj_verifyсовпал ли собранный таймлайн с планомчтение .prproj0,5 кадрапанели UXP

Ценность родного Synchronize — не в точности, а в независимости: это чужой алгоритм, написанный другими людьми и не знающий о наших числах. Если он согласен — совпадение неслучайно. Если нет — есть повод перемерить точным прибором, а не переписать точное грубым.

⚠️ pair_check намеренно сделан другим методом, чем finesync: фаза (GCC-PHAT) против огибающей громкости. Два прибора с одним методом согласятся и на общей ошибке.

4.4 · 3Правило разрешения: грубым не правят точное

Главное правило этапа, и оно нарушается легче всего. Шкала, в масштабе:

0,008 мс   pair_check (GCC-PHAT)          ▏
1–3 мс     finesync                       ▍
13–14 мс   худшая пара на реальном дне    ██
20 мс      половина кадра                 ███
40 мс      КАДР — пол Premiere            ██████

Всё, что Synchronize способен сказать, — это «ноль, один кадр или два». Дробей у него нет: и наша раскладка, и его ответ лежат на одной кадровой сетке. Поэтому «дельта 40 мс» после него значит не «рассинхрон 40 мс», а «округление в одну сторону против нашего округления в другую».

⚠️ Записать его ответ в ингест — значит заменить измерение в 13 мс округлением в 40. Петля Spread → Synchronize → Collect квантована с обеих сторон, и на хорошем ингесте она может только ухудшить.

⚠️ И обратное: «все пары в допуске» от грубого прибора — не аттестат. Он не умеет померить то, что проверяет, и его «PASS» — это отсутствие мнения, а не одобрение.

4.4 · 4Стенд: как разложить, чтобы Synchronize не был серым

Premiere включает пункт меню не всегда, и причины нигде не документированы. Проверено на живом проекте — условий два:

G1 · один клип на дорожку

В выделении не больше одного клипа на каждой дорожке. Два — и пункт гаснет.

G2 · дорожки таргетированы

Предположительно нужны включённые цели дорожек. На практике не подтвердилось: пара сработала при MZ.TrackTargeted=0 у второй дорожки.

⚠️ Источник правила G1 — 18-секундный ролик, у Adobe документации на него нет. Раскладка сделана так, чтобы условие выполнялось по построению, но выдавать его за документированное нельзя.

Геометрия стенда
рабочий таймлайн урока            стенд _SYNC (одноразовый)
V1  FX3   ████ ███ ██████         V1   FX3-1263  ████
V2  ZVE1  ████ ███ ██████         V2   ZVE1-1946 ████
V3  экран ██████████████          V3   ZVE1-1947      ███
V4  ролики        ██ █            V4   FX3-1264       ███
A5  петличка ██████████████       ...   по клипу на дорожку
A6  петличка ██████████████       A11  петличка ██████████████
                                  A12  петличка ██████████████
Synchronize СЕРЫЙ по праву:       Synchronize активен:
на V1 пять клипов подряд          на каждой дорожке ровно один
  • Секвенция рождается из пресета .sqpreset, а не засевается клипом. В UXP нет API создания дорожек, и панель рождала их вставкой одноразовой заглушки — а удаление в живой Premiere отрабатывает вхолостую. Пресет создаёт нужное число дорожек сам: ни сида, ни заглушек, ни мусора.
  • Цели дорожек — в пресете. Поле mTargeted пишется на каждую аудиодорожку, и это единственный способ отдать секвенцию человеку с уже включёнными целями: API таргетинга в UXP нет. ⚠️ Блок <VideoTracks> в пресете пуст — видеодорожки подорожечно не настраиваются.
  • Каждому клипу своя видеодорожка. Положить камеру audio-only (videoTrackIndex = -1) нельзя: у A/V-клипа Premiere всё равно кладёт видео, и кладёт всё на V1. Параметр работает только на настоящих аудиофайлах — петличка ложится так честно.
  • Преролл 30 с. Иначе клипу, которому надо уехать влево, некуда: из нуля Premiere его не сдвинет.
  • Позиции квантованы к сетке сразу, и в манифест пишется уже квантованное. Иначе дельта вберёт в себя наше же округление — до ±20 мс поверх измеренного.
  • Выделение ставит панель через Sequence.setSelection, а не человек через ⌘A: ⌘A ловит однокадровый мусор, и на дорожке оказывается два выделенных айтема.
Что в стенд НЕ идёт

Только опоры синхрона — съёмочные камеры и петлички. Запись экрана и ролики-примеры исключаются, и не ради экономии дорожек:

  • запись экрана снята отдельной сессией; корреляция её звука со студийным — разброс по окнам в секунды, то есть общего сигнала нет вовсе;
  • ролики-примеры поставлены измерением по комнатному воспроизведению с разбросом 0,0–0,8 мс — грубый прибор может только испортить такое число.

⚠️ Раз часть источников исключена, Collect обязан вычитать общий сдвиг группы: Synchronize равняет всё по одному опорному клипу, и без вычитания исключённые источники уезжают относительно включённых на всю его величину при каждом прогоне.

4.4 · 5Оплаченные грабли

  • Секвенция без единого настоящего клипа. Раскладка складывала все перезаписи в одну пакетную транзакцию — единственное такое место в коде. Пакетный компаунд выполняет действия в обратном порядке, и в секвенции оказалось 30 айтемов, все до одного — однокадровый мусор. Synchronize был серым потому, что синхронизировать было нечего. Лечение: по одной транзакции на источник, по возрастанию времени.
  • Однокадровый мусор на каждой дорожке. Удаление айтемов в живой Premiere 25.6/26 отрабатывает вхолостую — не падает, но клип остаётся. Пока дорожки рождались вставкой заглушки, по огрызку оставалось на каждой. В рабочих секвенциях их по четыре: V1/A1 в нуле и обе петличные дорожки с хвоста.
  • Медиана между кадрами. Общий сдвиг считался медианой дельт, а дельты кратны кадру. При чётном числе источников медиана встаёт между двумя значениями: на реальной сцене вышло 20 мс — полкадра, величина, которой нет ни у одного клипа. Вычитание такой базы двигало каждый клип на полкадра. Лечение: база снапится к кадровой сетке. Та же ошибка когда-то показала шов в 233 мс как «сдвиг 116 мс».
  • Сравнение ровно на шаге квантования. Порог «остаток ≤ кадра» при остатке ровно в кадр решается мусором в последнем бите числа с плавающей точкой. Сравнивать надо целыми кадрами.
  • Стык файлов по длительности контейнера. У записи экрана с переменным кадром контейнер длиннее потока на 68–88 мс, и встык по нему оставлял на шве дыру почти в два кадра. Считать надо по звуковому потоку: он пишется постоянной частотой дискретизации и равен реально прошедшему времени.
  • Карта звука только по V1. Экспорт ходил по первой видеодорожке и трём первым звуковым. На четырёхдорожечной раскладке это давало карту на 6 клипов вместо 15, первой строкой — огрызок, а звук второй камеры и звук экрана объявлялись «внешними», то есть петличкой. Настоящую петличку на A5/A6 экспорт не видел вовсе.
  • Молчащий канал камеры. В диалоге выбирается один Audio track channel на все клипы разом. Замер: у одной камеры правый канал −91 dB, цифровая тишина. Взять его — и эта камера останется без опоры, Premiere оставит её на месте, а это читается как «дельта 0», неотличимо от идеального совпадения. Петличка вдобавок моно. Канал 1.

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

Сразу после Build — кнопка Verify Sync
  1. Открыть секвенцию сцены → вкладка Ingest → Verify Sync. Панель сама сохраняет проект (прибор читает сохранённый .prproj), кладёт заказ в /tmp/ytai_verify_sync.json и открывает Терминал: звук внутри UXP мерить нечем, нет ffmpeg.
  2. verify_sync.py снимает дамп секвенции (00_Setup/logs/verify_sync_dump.json) и меряет каждую пару звуковых дорожек функциями арбитра timeline_sync_audit.py — на частоте самой секвенции, поиск ±6 с.
  3. Вердикт — в строке статуса панели, таблица пар — в логе Ingest, файл — 00_Setup/01_Ingest/{CODE}_sync_verdict.json.
вердиктчто значитчто делать
SYNC ✓худшая пара камера ↔ петличка ≤ ½ кадрасцена годна, дальше цвет
DESYNC ✗есть пары камера ↔ петличка больше ½ кадра; статус называет худшую и дорожкиточный прибор по этой сцене (pair_check), затем чинить числом — не двигать клипы
INSTRUMENT ✗контроль петличка ↔ петличка не ≈ 0 — сломан замер, а не проектостальным числам не верить; разбирать прибор
NO DATAни одной пары камера ↔ петличка с достаточным перекрытием и ясным пиком (пик < 0,25 не судится)проверить, есть ли петличка на сцене; судить приборами ниже

Пары камера ↔ камера — справочно, в гейт не входят. Тот же замер из терминала: python3 verify_sync.py --dump dump.json --fps 25 --seq {CODE}_{сцена} --json-out verdict.json (0500_uxp/tools/verify_sync/). Промах в минуты кнопка не ищет — для него timeline_sync_audit.py --dump … --max-shift 40.

Численная проверка — без Premiere, точным прибором
V=~/YTAI/environment/.venv_transcribe/bin/python
W=~/YTAI/scripts/999_extra/wordsync_multicam

$V $W/pair_check.py --project "$P"                  # по каждой паре, GCC-PHAT
$V $W/pair_check.py --project "$P" --scene 02_...   # одна сцена, 8 окон
python3 $W/prproj_verify.py --project "$P"          # собранное против плана

⚠️ pair_check требует пересечения по времени не меньше 2 × win-sec (по умолчанию 30 с). Пара короче молча не судится — её просто нет в отчёте.

Предполётная: будет ли команда доступна
python3 $W/sync_ready.py --project "$P"                      # все секвенции, ⌘A
python3 $W/sync_ready.py --project "$P" --selection pairs    # модель «выделил пару»
python3 $W/sync_ready.py --project "$P" --strays             # что снести руками
python3 $W/sync_ready.py --project "$P" --also-autosave      # сохранённое vs автосейв

Печатает по каждой дорожке: клипов, огрызков, цель, кадр источника; матрицу перекрытий; и вердикт тремя блоками, которые нельзя смешивать — жёстко (проверено) · по опыту (у Adobe не документировано) · не читается из .prproj. Замок дорожки в проекте не хранится вообще, и прибор честно говорит это, а не выдумывает колонку.

⚠️ --also-autosave сверяет сохранённый проект со свежайшим автосейвом. Классическая потеря вечера: секвенция живёт в автосейве, а в сохранённом файле её нет, потому что ⌘S нажали до того, как раскладка дошла до конца.

Стенд в Premiere
  1. Открыть секвенцию урока → Spread. Панель сама сделает пресет, создаст секвенцию, уложит источники и поставит выделение.
  2. Щёлкнуть по таймлайну (фокус обязан быть в нём, иначе меню Clip серое целиком) → Clip → Synchronize → Audio track channel 1 → OK.
  3. ⌘S. Без сохранения приборы прочитают пустоту.
  4. Collect — печатает таблицу остатков. Пишет в ингест только по второму щелчку.
  5. Удалить _SYNC, сгенерированный .sqpreset и импортированные стендом петлички. Манифест sync_session_*.json оставить — это архив того, что проверяли.

⚠️ Кнопка Clean выделяет весь однокадровый мусор; если снос не сработает (а он часто не срабатывает) — нажать ⌫. Это же способ вычистить огрызки из уже собранных секвенций уроков.

4.4 · 7Что считать успехом

✅ «Premiere согласен»

Худший остаток по камерам меньше кадра. Значит чужой алгоритм не нашёл расхождения в пределах своего разрешения. Писать нечего — и это правильный исход этапа, а не отказ.

❌ «Расхождение больше кадра»

Повод перемерить точным прибором — pair_check по этой сцене, — а не переписать ингест. Грубый прибор показал, где смотреть; что именно там, скажет точный.

⚠️ Отдельный ложный исход: «ни один источник не сдвинулся». Клип, который Premiere не сумела сопоставить, она оставляет на месте, и это читается как «дельта 0» — неотличимо от идеального совпадения. Поэтому сторожить надо сырые дельты, а не остатки: при идеальном синхроне остатки и так в нуле, и проверка «ничего не двинулось» на них ложно срабатывала бы именно на лучшем случае.

⚠️ Петличкам поправки не пишутся никогда. После frame-align это не записи рекордера, а timeline-domain рендеры: поправка уже запечена в сам звук, wall_offset у них ноль. Сдвинуть им число — значит обесценить рендер, звук в файле останется на месте. Остаток по петличке больше кадра означает «перегони 4.4», а не «подвинь».

4.4 · 8Цифры реального дня

Три урока, две камеры, две петлички, 25p.

чточислочем измерено
пар в допуске37 из 37pair_check, GCC-PHAT
худшая пара14,2 мс = 0,36 кадрато же
дельты Premiere0, 40 или 80 мс — все кратны кадруClip → Synchronize
собранное против плана17/17, 13/13, 5/5prproj_verify
артефактов вставкипо 4 на сценуто же

Систематика, которую видно только точным прибором: одна камера держится одной петлички, другая — другой, между группами ~11 мс при разбросе в отдельных парах до 0,5 мс. Семь независимых замеров в коридоре +9,9…+11,7. Это не рассинхрон, а разница акустического пути или задержка звука в кодеке камеры — и «исправление» увело бы камеру от её же звука.

⚠️ 11 мс — 0,27 кадра. Значит это решает исход только там, где клип и так стоит у границы кадра. На одной из сцен шесть клипов из восьми стояли в 1,3–6 мс от половины кадра — именно там Premiere и разошлась с нами на два кадра, а на остальных, где запас 13–18 мс, на один.

4.4 · 9Запись экрана: источник, которому не мерил никто

Приборы выше проверяют камеры и петличку. Запись экрана они не трогают, и до 25.09.2026 её позицию не мерил никто ни разу. Ингест кладёт её так: sync_source: "lesson_start", wall_offset: 0, fine_sync: {} — встык от начала урока. Второй части достаётся wall_offset, равный длительности первой, то есть снова встык. Проверено на всех одиннадцати версиях ингеста YTUVIE01, лежащих на диске.

⚠️ creation_time записи экрана в ингесте — подделка. У YTUVIE01 он стоял в 100 мс от creation_time первой камеры урока: поле дописано под lesson_start, а не прочитано из файла. Настоящее время лежит рядом в device_creation_time и с ним не совпадает. По creation_time синхрон записи экрана проверить нельзя — он выглядит связно и врёт.

4.2 Fine Sync эту дыру не закрывает: он берёт окна внутри предполагаемого пересечения и доводит уже примерно верную раскладку. Промах в минуты для него вне поля зрения.

Опора

WAV петлички в координатах таймлайна — рендер 0113 TX01_{сцена}_timeline.wav в Sound/ урока (полевой день — 01_Source/{сцена}/Sound/). Не путать с лежащим рядом срезом урока {CODE}_{урок}_TX01_timeline.wav: он в стенном времени урока, паузы в нём не вырезаны. Полная длина секвенции, старт = таймлайн 0. Значит позиция записи экрана вычитывается из него напрямую, без промежуточной математики.

Прибор

Полная взаимная корреляция огибающих речи, FFT. Полоса 200–3800 Гц, шаг 4 мс — те же, что у finesync, чтобы число было сопоставимо с тем, чем меряли камеры.

Запись экрана YTUVIE01стоялазамерпромахпик
1.1.1. Первая часть.mov0:002:06.660+2:06.660.98
1.1.1.1. Вторая часть.mov18:26.6424:23.710+5:57.070.97
1.1.2..mov0:000:33.780+0:33.780.99
1.1.3.mov0:000:06.276+0:06.280.99

Вторая петличка подтвердила три замера из четырёх в пределах 6 мс. У первой части TX02 дал ложный пик 0.35 против 0.98 у TX01 — там вторая петличка молчала; судить по слабому пику нельзя.

⚠️ Две грабли самого замера, обе поймались на живых данных.
Свес за конец опоры. Искать только позиции, где цель влезает в опору целиком, нельзя: запись экрана обычно идёт до конца урока и торчит за конец петлички на секунды. Тогда верный ответ оказывается за пределом поиска, а функция упирается в край и возвращает мусор — на уроке 1.1.3 ответ 6.28 с при пределе поиска 4.3 с и пик 0.161. Опору дополнять нулями, нормировать по реально перекрывшемуся куску.
Дрейф проверять четвертями. Гонять файл по четвертям отдельно: если все дают одно и то же начало файла ±1 мс — дрейфа нет и число верное. Низкий общий пик при согласных четвертях означает лишь размытый хвост, а не плохой замер (вторая часть: целиком 0.67, по четвертям 0.93–0.99).

Замеренное пишется в wall_offset ингеста, sync_source становится speech_xcorr, рядом кладётся бэкап — как это делает finesync. Дальше Build Ingest: поправки в готовый таймлайн сами не приедут.

4.4 · 10Билдер сжимает видео и не сжимает петличку

⚠️ Исправлено 25.09.2026 вечером. В первой редакции этой карточки причиной был назван ручной сдвиг клипов на таймлайне. Это неверно: клипы никто не двигал. Паузы убирает сам билдер, и дефект в нём. Физика ниже описана верно, виновник был назван неправильно — исправление оставлено на виду, потому что ошибка ровно того сорта, о котором эта глава.

После 4.3 Frame-Align петличка на A5/A6 — это один отрендеренный WAV во всю длину секвенции, а не нарезка. Его ось времени — настенная: содержимое в точке t соответствует настенному t.

Билдер при укладке выбрасывает паузы между дублями: клип встаёт не на свой wall_offset, а вплотную к предыдущему. Куски петлички он при этом режет по тем же границам — то есть режет верно, — но внутри куска ставит source_in == timeline_start. Смещение, накопленное выброшенными паузами, в source_in не попадает. Видео уехало, звук остался.

YTUVIE01, урок 1.1.1расхождениечто это значит
камеры ↔ камеры−8…+62 мсмежду собой целы
клипы ДО первой выброшенной паузы−375, −437 мснакопленного сдвига ещё нет
клипы ПОСЛЕ неё ↔ петличка−28,7 сровно выброшенная пауза
TX01 ↔ TX02−6 мсконтрольная пара: прибор исправен

В уроках с паузами поменьше промах вышел −177…−322 мс — так же незаметно на слух и так же неверно.

⚠️ Почему это не ловилось годами. prproj_verify.py сверяет собранный таймлайн с планом, который считает тот же самый планировщик, — и честно пишет «сошлось 21 из 21, расхождений нет». Проверялось «легло ли по плану», а не «верен ли план». Сверка с собственным планом — не проверка. Единственный внешний арбитр здесь — сам звук.

⚠️ Ингест тоже не истина. В том же проекте у двух клипов последнего дубля (RYA-ZVE1-1954, RYA-FX3-1271) сам wall_offset промахивался на −1,88 с, и это выглядело как «пауза 1,96 с». Остальные 18 клипов сошлись с ингестом в пределах ±41 мс. Поправку поэтому берут из замера звука, а не из ингеста: починка «по ингесту» уводит ровно на его собственную ошибку.

Чинится без Premiere. Петличка — рендер, обычный файл. Новый WAV строится так, что identity-укладка становится верной: new[t] = old[t + сдвиг(дубль)]. Сдвиг берётся замером — где содержимое клипа реально лежит в петличке минус где клип стоит на таймлайне; сегментом служит дубль, а не урок (на уроке 2 усреднение по уроку оставляло 80 мс, по дублям — 26 мс). Результат на YTUVIE01: 28 730 → 31 мс, 322 → 26 мс, 248 → 22 мс, все три урока внутри кадра.

⚠️ Формат петлички — pcm_f32le. Пересобрать её в pcm_s24le значит срезать всё, что выше 0 dBFS: во float это законный сигнал, и у двух файлов пик упирается ровно в ноль. Кодек и раскладку каналов брать с источника, оригиналы складывать рядом.

4.4 · 11Где лежит

файлчто делает
0500_uxp/tools/verify_sync/verify_sync.py · .commandкнопка Verify Sync: дамп сохранённого .prproj → вердикт по сцене в кадрах
999_extra/wordsync_multicam/timeline_sync_audit.pyарбитр: попарная сверка звука по факту таймлайна (его функции зовёт кнопка)
999_extra/wordsync_multicam/screencast_offset.py · relav2.pyпозиция файла в петличке полной корреляцией · пересборка петлички по замеру
999_extra/wordsync_multicam/pair_check.pyGCC-PHAT по каждой паре, без Premiere
999_extra/wordsync_multicam/sync_ready.pyпредполётная: будет ли команда доступна
999_extra/wordsync_multicam/sync_verdict.pyвердикт после синхрона, из .prproj
999_extra/wordsync_multicam/prproj_verify.pyсобранный таймлайн против плана
999_extra/wordsync_multicam/spread_fcpxml.pyраскладка файлом, в обход панели
999_extra/prproj_timeline_extract.pyобщий читатель .prproj для приборов из проекта
0500_uxp/src/ingest/syncSpread.jsраскладка, контракт L1–L9, отбор выделения, вычитание базы
0500_uxp/src/ingest/placement/sequencePreset.jsгенератор .sqpreset с mTargeted
0500_uxp/src/ingest/placement/syncSelection.jsчтение таймлайна и setSelection

Соседи по флоу: 4.1 Word-Sync ставит день на общую ось, 4.2 Fine Sync доводит до миллисекунд, 4.3 Frame-Align кладёт на кадровую сетку. Эта страница — про то, как убедиться, что всё три сработали.

Ингест собирает, проверка судит. Прибор, которым проверяешь, обязан быть точнее того, что проверяешь — иначе «PASS» означает не одобрение, а отсутствие мнения. Родной Synchronize ценен независимостью, а не точностью: его пол — кадр, наш синхрон — миллисекунды. Поэтому он подтверждает, но не уточняет, а Collect сначала отчитывается и только потом, по явному подтверждению, пишет.
пример: YTUVIE01 (25.09.2026, три урока, 37 пар, худшая 14,2 мс) · предыдущий: YTCH13 (кадровое квантование вставки, 28 замеров из 28)