Окно кадрирования работает и в проекте, где кэша ещё нет

Кадр для окна пишется в кэш проекта, а кэш заводится при первой сборке
вставок. Кадрирование открывают и раньше — тогда ffmpeg падал с «No such
file or directory», а окно показывало «Не удалось получить кадр» вместе с
цепочкой фильтров. Выглядело так, будто дело в цепочке; дело было в
отсутствующей папке.

Замерено на том же файле и той же цепочке: в существующей папке команда
отдаёт кадр в 320 КБ, в несуществующей — код выхода 254.

Папка теперь создаётся перед записью. Не создалась — кадр пишется во
временный файл, чтобы окно всё равно показало картинку.

Проверка tests/cropdialog.sh: проект без папки кэша, щелчок по кнопке
кадрирования, смотрим, появился ли файл кадра. Папка убирается прямо
перед щелчком: иначе её успевает создать заготовка чёрной вставки, и
проверка меряет не то. На прежней сборке падает.
This commit is contained in:
4aiman 2026-10-17 20:37:15 +03:00
commit af03ec1b93
3 changed files with 140 additions and 3 deletions

View file

@ -1062,7 +1062,7 @@ Wine с новой библиотекой не грузилось ничего.
уход выглядит как накапливающийся рассинхрон, которого нет. На это уже уход выглядит как накапливающийся рассинхрон, которого нет. На это уже
попались один раз. попались один раз.
Ещё десять проверок гоняют саму программу на невидимом экране Ещё одиннадцать проверок гоняют саму программу на невидимом экране
(`Xvfb :99`). Рабочий экран они не занимают: (`Xvfb :99`). Рабочий экран они не занимают:
``` ```
@ -1076,6 +1076,7 @@ Wine с новой библиотекой не грузилось ничего.
./tests/dropgap.sh [<путь к nlve>] клип садится в дыру без наезда ./tests/dropgap.sh [<путь к nlve>] клип садится в дыру без наезда
./tests/dragorder.sh [<путь к nlve>] связка переехала — порядок цел ./tests/dragorder.sh [<путь к nlve>] связка переехала — порядок цел
./tests/pickcycle.sh [<путь к nlve>] щелчок перебирает наехавшие клипы ./tests/pickcycle.sh [<путь к nlve>] щелчок перебирает наехавшие клипы
./tests/cropdialog.sh [<путь к nlve>] окно кадрирования показывает кадр
``` ```
Отдельно от них `tests/imagecrop.sh` — сквозная, без окна: делает Отдельно от них `tests/imagecrop.sh` — сквозная, без окна: делает
@ -1085,7 +1086,11 @@ Wine с новой библиотекой не грузилось ничего.
а не поля. Ей нужны `tests/nlvetool` (`./build.sh test`), ffmpeg и python а не поля. Ей нужны `tests/nlvetool` (`./build.sh test`), ffmpeg и python
с PIL. с PIL.
Последним восьми нужен монтаж в `test/поток/`: `длинный-фейд.nlve` — один `cropdialog.sh` строит свой монтаж сам, но ему нужна настоящая съёмка:
кадр для окна берётся из файла. Путь задаётся переменной
`NLVE_CROP_SOURCE`.
Остальным нужен монтаж в `test/поток/`: `длинный-фейд.nlve` — один
клип с затуханием секунд на семьдесят (такой кусок сводится около клип с затуханием секунд на семьдесят (такой кусок сводится около
полутора минут, и всё это время человек продолжает работать), полутора минут, и всё это время человек продолжает работать),
`пара.nlve` — два клипа без затуханий. Путь к первому задаётся `пара.nlve` — два клипа без затуханий. Путь к первому задаётся
@ -1102,7 +1107,7 @@ xdotool не видит ни одного окна и проверка «про
экран шире: `Xvfb :98 -screen 0 1600x1000x24` и `ЭКРАН=:98`. экран шире: `Xvfb :98 -screen 0 1600x1000x24` и `ЭКРАН=:98`.
Каждую из них стоит прогонять и на прежней сборке: проверка, которая Каждую из них стоит прогонять и на прежней сборке: проверка, которая
проходит везде, не проверяет ничего. Все десять на сборке до своей правки проходит везде, не проверяет ничего. Все одиннадцать на сборке до своей правки
падают. Замерено: клип у кромки уезжает на 0.7 с против 4.2 с, файл из падают. Замерено: клип у кромки уезжает на 0.7 с против 4.2 с, файл из
списка падает в конец дорожки вместо курсора, сборка начинается через списка падает в конец дорожки вместо курсора, сборка начинается через
0.2 с вместо 1.6 с, клип в дыру садится с наездом 0.007383 с, дорожка 0.2 с вместо 1.6 с, клип в дыру садится с наездом 0.007383 с, дорожка

View file

@ -247,6 +247,15 @@ begin
FTransform := ATransform; FTransform := ATransform;
FPreviewFile := APreviewFile; FPreviewFile := APreviewFile;
{ Кадр пишется в кэш проекта, а его может ещё не быть: кэш заводится
при первой сборке вставок, а кадрирование открывают и раньше. Тогда
ffmpeg падал с «No such file or directory», и окно показывало «Не
удалось получить кадр» с цепочкой фильтров — выглядело так, будто
дело в самой цепочке. }
if (FPreviewFile <> '') and
(not ForceDirectories(ExtractFilePath(FPreviewFile))) then
FPreviewFile := GetTempFileName;
lblSource.Caption := Format('%s: %dx%d → кадр проекта %dx%d', lblSource.Caption := Format('%s: %dx%d → кадр проекта %dx%d',
[ExtractFileName(APath), AInfo.Width, AInfo.Height, ADstWidth, ADstHeight]); [ExtractFileName(APath), AInfo.Width, AInfo.Height, ADstWidth, ADstHeight]);

123
tests/cropdialog.sh Executable file
View file

@ -0,0 +1,123 @@
#!/bin/sh
# Окно кадрирования показывает кадр и в проекте, где кэша ещё нет.
#
# Кадр для окна пишется в кэш проекта, а кэш заводится при первой сборке
# вставок. Кадрирование открывают и раньше — тогда ffmpeg падал с «No
# such file or directory», а окно писало «Не удалось получить кадр» и
# показывало цепочку фильтров. Выглядело так, будто дело в цепочке,
# хотя дело было в отсутствующей папке.
#
# Проверяется так: проект без папки кэша, щелчок по кнопке кадрирования
# на клипе, затем смотрим, появился ли файл кадра. Появился — окну было
# что показать.
#
# Нужен настоящий файл съёмки: кадр берётся из него. Путь задаётся
# переменной NLVE_CROP_SOURCE.
#
# Запуск (экран :99 поднят):
# tests/cropdialog.sh [<путь к nlve>]
set -e
cd "$(dirname "$0")/.."
BIN=${1:-$PWD/nlve}
DISP=${NLVE_DISPLAY:-:99}
SRC=${NLVE_CROP_SOURCE:-/mnt/02F6E7F6F6E7E7BD/writable2/kamenolomni2/DJI_20261010143437_0044_D.MP4}
WORK=$PWD/test/кадр
PROJ=$WORK/проверка.nlve
[ -f "$SRC" ] || { echo "нет съёмки $SRC — задай NLVE_CROP_SOURCE"; 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; }
rm -rf "$WORK"
mkdir -p "$WORK"
python3 - "$SRC" "$PROJ" <<'PY'
import json, sys
исходник, куда = sys.argv[1], sys.argv[2]
инфо = {'valid': True, 'kind': 'video', 'has_video': True,
'video_codec': 'hevc', 'width': 2688, 'height': 1512,
'fps_num': 60000, 'fps_den': 1001, 'pix_fmt': 'yuv420p',
'duration': 2466.0, 'has_audio': True, 'audio_codec': 'aac',
'sample_rate': 48000, 'channels': 2}
json.dump({
'version': 1, 'next_id': 20,
'master': dict(инфо, video_bitrate=55000000),
'pool': [{'id': 'm1', 'path': исходник, 'normalized_path': '',
'info': инфо}],
'tracks': [
{'id': 't1', 'name': 'V1', 'kind': 'video', 'clips': [
{'id': 'c1', 'media': 'm1', 'kind': 'video', 'src_in': 447.0,
'tl_start': 0.0, 'duration': 20.0, 'edge_in': 'snap',
'edge_out': 'snap', 'group': '', 'volume': 1.0,
'opacity': 1.0, 'fade_in': 0.0, 'fade_out': 0.0,
# Увеличение со смещением: цепочка выходит с crop, как в
# разобранном случае.
'transform': {'fit': 'fit', 'rotation': 0, 'flip_h': False,
'flip_v': False, 'zoom': 1.98,
'offset_x': 0.49, 'offset_y': -0.49},
'text': ''}]},
{'id': 't2', 'name': 'A1', 'kind': 'audio', 'clips': []}],
'settings': {}
}, open(куда, 'w'), ensure_ascii=False)
print(' проект на 20 секунд, увеличение 198%, папки кэша нет')
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
SP=$WORK/профиль
mkdir -p "$SP"
XDG_CONFIG_HOME=$SP XDG_CACHE_HOME=$SP XDG_DATA_HOME=$SP \
setsid "$BIN" "$PROJ" >/dev/null 2>&1 < /dev/null &
sleep 18
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
# Папку кэша убираем прямо перед открытием окна. Иначе её успевает
# создать заготовка чёрной вставки, которая делается при открытии
# проекта, и проверка меряет не то: нужен именно случай, когда к моменту
# открытия кадрирования папки нет.
rm -rf "$WORK/проверка.nlve-cache"
# Кнопка кадрирования — квадратик в правом нижнем углу клипа. Клип занят
# всю ширину окна, поэтому кнопка у правого края дорожки.
$X mousemove 1257 531 click 1
sleep 7
DLG=
for w in $($X search --name "Кадрирование" 2>/dev/null); do
xwininfo -id "$w" 2>/dev/null | grep -q IsViewable && { DLG=$w; break; }
done
SHOT=$WORK/проверка.nlve-cache/pancrop.png
if [ -f "$SHOT" ]; then
echo " ok: кадр получен ($(stat -c %s "$SHOT") байт), папка кэша создана"
RC=0
else
echo " ПЛОХО: кадра нет — окну нечего показать"
[ -n "$DLG" ] || echo " (окно кадрирования вообще не открылось)"
RC=1
fi
for p in $(pgrep -x nlve); do
{ tr "\0" "\n" < /proc/$p/environ; } 2>/dev/null | grep -qx "DISPLAY=$DISP" && kill $p
done
exit $RC