nlve/tests/dragscroll.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

143 lines
6.3 KiB
Bash
Executable file
Raw 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
# Монтаж едет следом, пока тащишь клип у кромки окна.
#
# При большом увеличении видно секунды, а двигать кусок надо на минуты.
# Если монтаж не прокручивается, клип упирается в край окна и дальше не
# идёт: приходится отпускать, прокручивать, брать снова — и так десятки
# раз.
#
# Проверяется так: монтаж из одного клипа, сильное увеличение, клип
# тащится к правому краю и там удерживается на месте. Рука стоит, значит
# двигать может только прокрутка. Результат читается из сохранённого
# проекта, а не с картинки.
#
# Запуск (экран :99 поднят):
# tests/dragscroll.sh [<путь к nlve>]
set -e
cd "$(dirname "$0")/.."
BIN=${1:-$PWD/nlve}
DISP=${NLVE_DISPLAY:-:99}
SRC=$PWD/test/поток/пара.nlve
PROJ=$PWD/test/поток/прокрутка.nlve
[ -f "$SRC" ] || { echo "нет монтажа $SRC"; exit 2; }
# Невидимый экран поднят через xvfb-run, у него свой файл доступа, а в
# окружении обычно лежит файл рабочего экрана. С чужим файлом xdotool не
# видит ни одного окна, и проверка «проходит» вслепую, ничего не проверив.
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; }
# Монтаж из одного клипа: второй убран, чтобы перетаскивание ни на кого
# не наезжало и не заказывало переход.
python3 - "$SRC" "$PROJ" <<'PY'
import json, sys
d = json.load(open(sys.argv[1]))
keep = None
for t in d['tracks']:
for c in t['clips']:
if c['kind'] == 'video' and c['tl_start'] < 0.001:
keep = c.get('group')
for t in d['tracks']:
t['clips'] = [c for c in t['clips'] if c.get('group') == keep]
json.dump(d, open(sys.argv[2], 'w'), ensure_ascii=False)
PY
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
rm -rf test/поток/профиль-прокрутка
mkdir -p test/поток/профиль-прокрутка
rm -f "$PROJ.autosave"
SP=$PWD/test/поток/профиль-прокрутка
XDG_CONFIG_HOME=$SP XDG_CACHE_HOME=$SP XDG_DATA_HOME=$SP DISPLAY=$DISP \
setsid "$BIN" "$PROJ" >/dev/null 2>&1 < /dev/null &
sleep 14
X="timeout 8 xdotool"
# Окно ищем по имени монтажа и проверяем, что оно на экране. По одному
# «nlve» находятся и обломки прошлых запусков: они невидимы, нажатия в
# них уходят в никуда, и проверка молча показывает «ничего не двинулось».
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 2
start() {
$X key ctrl+s
sleep 2
python3 -c "
import json
d = json.load(open('$PROJ'))
for t in d['tracks']:
for c in t['clips']:
if c['kind'] == 'video':
print('%.3f' % c['tl_start']); raise SystemExit
print('0')
"
}
echo " начало клипа до правок: $(start) с"
ROW=${NLVE_ROW:-505} # высота видеодорожки в окне
GRAB=${NLVE_GRAB:-650} # точка захвата внутри клипа (клип начинается с 588)
EDGE=1255 # кромка у правого края окна
# Увеличение: шесть щелчков колесом с Ctrl, опора в точке захвата, чтобы
# клип из-под указателя не уехал.
I=0
while [ $I -lt 6 ]; do
$X mousemove $GRAB $ROW
$X keydown ctrl click 4 keyup ctrl
sleep 0.3
I=$((I + 1))
done
sleep 1
# Берём клип и тащим к правому краю, где и держим: рука стоит, едет
# только прокрутка.
$X mousemove $GRAB $ROW mousedown 1
sleep 0.3
$X mousemove 800 $ROW
sleep 0.3
$X mousemove $EDGE $ROW
sleep 6
$X mouseup 1
sleep 2
MOVED=$(start)
echo " начало клипа после перетаскивания с удержанием: $MOVED с"
for p in $(pgrep -x nlve); do
tr '\0' '\n' < /proc/$p/environ 2>/dev/null | grep -qx "DISPLAY=$DISP" && kill $p
done
rm -f "$PROJ.autosave"
python3 -c "
moved = $MOVED
# После шести щелчков колесом в окне видно около полутора секунд монтажа.
# Указатель доезжает до кромки и встаёт, поэтому без прокрутки клип
# уезжает на эти полторы секунды и больше никуда. С прокруткой за шесть
# секунд удержания набегает втрое больше. Порог стоит между измеренными
# величинами: 1.1 с на сборке без прокрутки, 3+ с с прокруткой.
if moved < 2.5:
print(' ПЛОХО: клип уехал всего на %.3f с — монтаж не прокручивался' % moved)
raise SystemExit(1)
print(' ok: клип уехал на %.3f с, дальше видимой части' % moved)
"