nlve/tests/genquiet.sh
4aiman 0fa9bb6130 Клип встаёт на курсор, монтаж едет следом, сборка ждёт конца правки
Три жалобы из настоящей работы над фильмом, и все про одно: положить
кусок туда, куда нужно, было нельзя.

Файл из списка падал в конец дорожки, стоило месту под ним оказаться
занятым, — а занято оно почти всегда: клип длиной в целый файл упирается
хвостом в то, что правее, даже когда начало легло в пустоту. Теперь
монтаж раздвигается: MakeRoomAt режет все дорожки в точке вставки и
сдвигает всё, что начинается с неё и правее, на длину нового клипа. Звук
и надписи едут вместе с картинкой, иначе синхрон рассыплется.

Точка вставки при этом округляется к кадровой сетке. Без этого вставка
давала наезд в пять миллисекунд: рез внутри раздвижки округляет время
сам, а клип клался на неокруглённый курсор. Отсюда и был «кроссфейд без
видимого перекрытия».

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

Тяжёлая сборка больше не начинается с первым движением: список кусков
пересобирается сразу, а ffmpeg запускается, когда монтаж постоял тихо
полторы секунды и клип никто не держит мышью. Сам наезд перестал быть
сюрпризом — строка состояния называет дорожку, величину и клипы.

Проверки числами: раздвижка монтажа и прилипание хвостом. С окном:
insertat.sh, dragscroll.sh, genquiet.sh. Все три прогнаны и на прежней
сборке, где падают: клип в конце дорожки вместо курсора, 0.667 с вместо
4.238 с, сборка через 0.20 с вместо 1.62 с.
2026-10-15 23:33:58 +03:00

117 lines
5 KiB
Bash
Executable file
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh
# Тяжёлая сборка начинается не сразу, а когда правка закончилась.
#
# Наезд двух клипов на одной дорожке — это заказ на переход, и считается
# он минутами. Пока человек подбирает место, заказ меняется каждым
# движением руки, и начатая работа уходит в корзину. Поэтому список
# кусков пересобирается сразу (монтаж обязан показывать правду), а вот
# ffmpeg запускается, когда монтаж постоял тихо.
#
# Проверяется так: клип тащится на соседа, создавая наезд. С момента,
# когда кнопку отпустили, считается время до первой команды ffmpeg в
# журнале. Оно обязано быть близко к заданной тишине, но работа всё-таки
# обязана начаться — отложить не значит забыть.
#
# Журнал только читается: усечь его значит снести запись чужой работы.
#
# Запуск (экран :99 поднят):
# tests/genquiet.sh [<путь к nlve>]
set -e
cd "$(dirname "$0")/.."
BIN=${1:-$PWD/nlve}
DISP=${NLVE_DISPLAY:-:99}
SRC=$PWD/test/поток/пара.nlve
PROJ=$PWD/test/поток/тишина.nlve
LOG=$(dirname "$BIN")/nlve.log
[ -f "$SRC" ] || { echo "нет монтажа $SRC"; exit 2; }
export DISPLAY=$DISP
reachable() { timeout 5 xdotool getdisplaygeometry >/dev/null 2>&1; }
if ! reachable; then
for p in $(pgrep -x Xvfb); do
A=$(tr '\0' '\n' < /proc/$p/cmdline | grep -A1 -x -- -auth | tail -1)
[ -f "$A" ] || continue
XAUTHORITY=$A; export XAUTHORITY
reachable && break
done
fi
reachable ||
{ echo "нет доступа к экрану $DISP: подними его (xvfb-run) и повтори"; exit 2; }
cp "$SRC" "$PROJ"
for p in $(pgrep -x nlve); do
tr '\0' '\n' < /proc/$p/environ 2>/dev/null | grep -qx "DISPLAY=$DISP" && kill $p
done
sleep 1
SP=$PWD/test/поток/профиль-тишина
rm -rf "$SP"; mkdir -p "$SP"
rm -rf "$PROJ-cache"
rm -f "$PROJ.autosave"
XDG_CONFIG_HOME=$SP XDG_CACHE_HOME=$SP XDG_DATA_HOME=$SP \
setsid "$BIN" "$PROJ" >/dev/null 2>&1 < /dev/null &
sleep 14
X="timeout 8 xdotool"
WID=
for w in $($X search --name "тишина.nlve" 2>/dev/null); do
xwininfo -id "$w" 2>/dev/null | grep -q IsViewable && { WID=$w; break; }
done
[ -n "$WID" ] || { echo "живое окно редактора не найдено"; exit 2; }
$X windowmove "$WID" 0 0 windowsize "$WID" 1270 990
sleep 3
ROW=${NLVE_ROW:-505}
# Сколько команд ffmpeg в журнале сейчас. Считаем строки, а не чистим
# файл: журнал общий, и усечение уносит чужую работу.
runs() { grep -c '^> .*ffmpeg' "$LOG" 2>/dev/null || echo 0; }
BEFORE=$(runs)
echo " команд в журнале до правки: $BEFORE"
# Тащим первый клип вправо на соседа: наезд примерно в секунду.
$X mousemove 650 $ROW mousedown 1
sleep 0.3
$X mousemove 670 $ROW
sleep 0.3
$X mousemove 683 $ROW
sleep 0.3
$X mouseup 1
# С этой точки отсчёт. Опрашиваем журнал почаще, чтобы поймать момент
# запуска, а не ждать наугад.
T0=$(date +%s.%N)
WAITED=0
while [ "$WAITED" -lt 60 ]; do
N=$(runs)
[ "$N" -gt "$BEFORE" ] && break
sleep 0.2
WAITED=$((WAITED + 1))
done
T1=$(date +%s.%N)
AFTER=$(runs)
for p in $(pgrep -x nlve); do
tr '\0' '\n' < /proc/$p/environ 2>/dev/null | grep -qx "DISPLAY=$DISP" && kill $p
done
pkill -f "тишина.nlve-cache" 2>/dev/null || true
rm -f "$PROJ.autosave"
python3 -c "
задержка = $T1 - $T0
было, стало = $BEFORE, $AFTER
print(' команд после правки: %d, пауза до запуска: %.2f с' % (стало, задержка))
if стало <= было:
print(' ПЛОХО: сборка не началась вовсе — отложить не значит забыть')
raise SystemExit(1)
# Задано полторы секунды тишины. Нижняя граница с запасом на разброс
# опроса, верхняя — чтобы отложенное не превратилось в забытое.
if задержка < 1.2:
print(' ПЛОХО: сборка началась через %.2f с — правку не дождались'
% задержка)
raise SystemExit(1)
if задержка > 6:
print(' ПЛОХО: сборка началась только через %.2f с' % задержка)
raise SystemExit(1)
print(' ok: сборка дождалась конца правки и всё-таки началась')
"