Кадр для окна пишется в кэш проекта, а кэш заводится при первой сборке вставок. Кадрирование открывают и раньше — тогда ffmpeg падал с «No such file or directory», а окно показывало «Не удалось получить кадр» вместе с цепочкой фильтров. Выглядело так, будто дело в цепочке; дело было в отсутствующей папке. Замерено на том же файле и той же цепочке: в существующей папке команда отдаёт кадр в 320 КБ, в несуществующей — код выхода 254. Папка теперь создаётся перед записью. Не создалась — кадр пишется во временный файл, чтобы окно всё равно показало картинку. Проверка tests/cropdialog.sh: проект без папки кэша, щелчок по кнопке кадрирования, смотрим, появился ли файл кадра. Папка убирается прямо перед щелчком: иначе её успевает создать заготовка чёрной вставки, и проверка меряет не то. На прежней сборке падает.
123 lines
5.5 KiB
Bash
Executable file
123 lines
5.5 KiB
Bash
Executable file
#!/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
|