#!/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) "