build: assemble pinned OBS 32.0.4 runtimes for Linux and Windows

Linux builds libobs and an allowlist of official plugins from source in OBS's
relocatable layout. Windows copies the official release byte-for-byte so the
Game Capture hook keeps its signature. Adds a headless Wayland rig for
PipeWire/portal capture tests on machines without a display.
This commit is contained in:
2026-10-08 13:51:22 +02:00
parent eb364d25e2
commit 80b6abdb32
4 changed files with 264 additions and 0 deletions
+94
View File
@@ -0,0 +1,94 @@
#!/usr/bin/env bash
# Run a command inside a disposable headless Wayland desktop for capture tests.
#
# scripts/rig/headless-wayland.sh <command> [args...]
#
# Starts a private D-Bus session with PipeWire, WirePlumber, headless Sway and
# xdg-desktop-portal-wlr (auto-selecting the only output), plus a 60 FPS test
# pattern standing in for a game. Everything is torn down when the command exits.
#
# This rig exercises the PipeWire/portal path on a machine without a display.
# It does not replace validation on real hardware (Hyprland, X11, Windows).
set -euo pipefail
if [[ $# -eq 0 ]]; then
echo "usage: $0 <command> [args...]" >&2
exit 2
fi
if [[ -z "${CLIPBIN_RIG_INNER:-}" ]]; then
exec env CLIPBIN_RIG_INNER=1 dbus-run-session -- "$0" "$@"
fi
rig_dir="$(mktemp -d "${TMPDIR:-/tmp}/clipbin-rig.XXXXXX")"
pids=()
cleanup() {
for pid in "${pids[@]}"; do kill "${pid}" 2>/dev/null || true; done
wait 2>/dev/null || true
# The D-Bus-activated document portal mounts a FUSE filesystem here.
fusermount3 -u "${XDG_RUNTIME_DIR}/doc" 2>/dev/null || true
rm -rf "${rig_dir}"
}
trap cleanup EXIT
export XDG_RUNTIME_DIR="${rig_dir}/runtime"
export XDG_CONFIG_HOME="${rig_dir}/config"
export XDG_CURRENT_DESKTOP=sway
export XDG_SESSION_TYPE=wayland
mkdir -p "${XDG_RUNTIME_DIR}" "${XDG_CONFIG_HOME}/xdg-desktop-portal-wlr" "${XDG_CONFIG_HOME}/sway"
chmod 700 "${XDG_RUNTIME_DIR}"
width="${CLIPBIN_RIG_WIDTH:-1920}"
height="${CLIPBIN_RIG_HEIGHT:-1080}"
cat > "${XDG_CONFIG_HOME}/sway/config" <<EOF
output HEADLESS-1 resolution ${width}x${height}@60Hz
default_border none
EOF
cat > "${XDG_CONFIG_HOME}/xdg-desktop-portal-wlr/config" <<EOF
[screencast]
chooser_type=none
output_name=HEADLESS-1
max_fps=60
EOF
wait_for() {
local what="$1" check="$2"
for _ in $(seq 100); do
if eval "${check}"; then return 0; fi
sleep 0.1
done
echo "rig: ${what} did not start; logs in ${rig_dir}" >&2
exit 1
}
pipewire > "${rig_dir}/pipewire.log" 2>&1 & pids+=($!)
wait_for pipewire '[[ -S "${XDG_RUNTIME_DIR}/pipewire-0" ]]'
wireplumber > "${rig_dir}/wireplumber.log" 2>&1 & pids+=($!)
pipewire-pulse > "${rig_dir}/pipewire-pulse.log" 2>&1 & pids+=($!)
WLR_BACKENDS=headless WLR_LIBINPUT_NO_DEVICES=1 WLR_HEADLESS_OUTPUTS=1 \
sway --config "${XDG_CONFIG_HOME}/sway/config" > "${rig_dir}/sway.log" 2>&1 & pids+=($!)
wait_for sway 'compgen -G "${XDG_RUNTIME_DIR}/wayland-*" > /dev/null'
WAYLAND_DISPLAY="$(basename "$(compgen -G "${XDG_RUNTIME_DIR}/wayland-*" | grep -v lock | head -1)")"
export WAYLAND_DISPLAY
SWAYSOCK="$(compgen -G "${XDG_RUNTIME_DIR}/sway-ipc.*" | head -1)"
export SWAYSOCK
dbus-update-activation-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP XDG_RUNTIME_DIR XDG_CONFIG_HOME SWAYSOCK
/usr/lib/xdg-desktop-portal-wlr > "${rig_dir}/xdpw.log" 2>&1 & pids+=($!)
/usr/lib/xdg-desktop-portal -r > "${rig_dir}/xdp.log" 2>&1 & pids+=($!)
# A moving 60 FPS picture with a tone, standing in for a game.
SDL_VIDEODRIVER=wayland ffplay -loglevel error -fs -window_title clipbin-test-game \
-f lavfi "testsrc2=size=${width}x${height}:rate=60,format=yuv420p" \
> "${rig_dir}/game.log" 2>&1 & pids+=($!)
sleep 1
echo "rig: ready (WAYLAND_DISPLAY=${WAYLAND_DISPLAY}, logs in ${rig_dir})" >&2
status=0
"$@" || status=$?
if [[ -n "${CLIPBIN_RIG_KEEP_LOGS:-}" ]]; then
cp -r "${rig_dir}" "${CLIPBIN_RIG_KEEP_LOGS}"
fi
exit "${status}"