casparcg user, /opt/casparcg, X11, DeckLink, NDIPlayout host (recommended): use the ordered setup scripts and
scripts/setup/MANUAL_INSTALL.md— kernel 117, NVIDIA open 595,~/highascg, nodm/Openbox.
This guide mirrors the intent of scripts/install-phase2.sh, install-phase3.sh, and install-helpers.sh, but every step is manual (no install.sh). Adjust paths and versions to your machine.
Privileges: Steps below assume a normal user with sudo. Commands that need root are prefixed with sudo. Alternatively, open a root shell once: sudo -i, then run the same commands without the sudo prefix.
casparcg and own /opt/casparcgNo interactive shell; home directory exists for nodm/X11:
USER_CASPAR=casparcg
USER_SHELL=$(command -v nologin || command -v false || echo "/usr/sbin/nologin")
sudo useradd -r -m -s "$USER_SHELL" "$USER_CASPAR"
If the user already exists, skip useradd.
sudo mkdir -p /opt/casparcg/{media,log,template,data,cef-cache,config}
sudo chown -R casparcg:casparcg /opt/casparcg
sudo chmod -R 775 /opt/casparcg
Deploy binaries, config/casparcg.config, run.sh, and lib/ (CEF, etc.) into /opt/casparcg, then re-run sudo chown if root created files.
video, audio, render, …)Only add groups that exist on your system (same list as install-phase3.sh):
for GRP in video audio render plugdev dialout input; do
if getent group "$GRP" &>/dev/null; then
sudo usermod -aG "$GRP" casparcg
fi
done
| Group | Typical use |
|---|---|
video |
/dev/dri, GPU |
render |
DRM/KMS (e.g. kmsgrab / GPU) |
audio |
ALSA / Pulse / PipeWire |
plugdev |
Some USB devices |
dialout |
Serial ports |
input |
Input devices |
Reboot or log out so membership applies to new sessions.
Packages (see install-phase3.sh):
sudo apt update
sudo apt install -y nodm openbox unclutter xterm util-linux
sudo tee /etc/default/nodm >/dev/null <<'EOF'
NODM_ENABLED=true
NODM_USER=casparcg
NODM_X_OPTIONS='-s 0 -dpms -nolisten tcp'
EOF
sudo mkdir -p /home/casparcg
echo 'exec openbox-session' | sudo tee /home/casparcg/.xsession >/dev/null
sudo chmod +x /home/casparcg/.xsession
sudo chown casparcg:casparcg /home/casparcg/.xsession
```AS ROOT
mkdir -p /home/casparcg/.config/openbox
# Create and edit autostart — see openbox_autostart.md / install-phase3.sh for a full example
chmod +x /home/casparcg/.config/openbox/autostart
chown -R casparcg:casparcg /home/casparcg/.config
Restart:
sudo systemctl restart nodm
Aligned with install-phase2.sh (§2.2) and fetch_decklink_tarball in install-helpers.sh.
Download Desktop Video for Linux from Blackmagic Capture & Playback (license acceptance required). You can also set a tarball path via HIGHASCG_DECKLINK_TAR or place a copy at /tmp/decklink.tar.gz when using the automated helper.
Install:
cd /tmp
https://swr.cloud.blackmagicdesign.com/DesktopVideo/v16.0/Blackmagic_Desktop_Video_Linux_16.0.tar.gz?verify=1776791815-QyDaLVBq%2FvE14glhLV6tJb33C2Aw%2Fs4NEIRpOu%2BIPsE%3D
tar -xzf decklink.tar.gz # use your actual filename
sudo dpkg -i /tmp/Blackmagic_Desktop_Video_Linux_16.0/deb/x86_64/desktopvideo_16.0a14_amd64.deb
sudo dpkg -i /tmp/Blackmagic_Desktop_Video_Linux_16.0/deb/x86_64/desktopvideo-gui_16.0a14_amd64.deb
sudo apt install -f -y
sudo modprobe blackmagic_io 2>/dev/null || true
dpkg -l desktopvideo
command -v desktopvideo_setup # optional GUI
Aligned with install-phase2.sh (§2.3) and fetch_ndi_sdk_tarball in install-helpers.sh.
Download NDI SDK for Linux from NDI (account / license). The automated installer script is typically named Install_NDI_SDK_v6_Linux.sh.
Run the installer (needs root to install system-wide):
cd /tmp
wget https://downloads.ndi.tv/SDK/NDI_SDK_Linux/Install_NDI_SDK_v6_Linux.tar.gz
tar -xzf Install_NDI_SDK_v6_Linux.tar.gz
chmod +x Install_NDI_SDK_v6_Linux.sh
sudo ./Install_NDI_SDK_v6_Linux.sh --accept-license
install-phase2.sh):NDI_LIB_SRC=$(find "NDI SDK for Linux/lib/x86_64-linux-gnu" -maxdepth 1 -type f -name 'libndi.so.6.*' 2>/dev/null | head -1)
if [ -n "$NDI_LIB_SRC" ] && [ -f "$NDI_LIB_SRC" ]; then
sudo install -m 0644 "$NDI_LIB_SRC" /usr/lib/x86_64-linux-gnu/
NDI_BASE=$(basename "$NDI_LIB_SRC")
sudo ln -sf "$NDI_BASE" /usr/lib/x86_64-linux-gnu/libndi.so.6
sudo ln -sf libndi.so.6 /usr/lib/x86_64-linux-gnu/libndi.so
sudo ldconfig
fi
If paths differ, locate libndi.so.6.* inside the extracted SDK and adjust.
install-phase3.sh): copy next to Caspar for loaders that search the app directory:sudo cp /usr/lib/x86_64-linux-gnu/libndi.so.6 /opt/casparcg/ 2>/dev/null || true
sudo chown casparcg:casparcg /opt/casparcg/libndi.so.6 2>/dev/null || true
If Caspar loads bundled CEF from /opt/casparcg/lib:
echo /opt/casparcg/lib | sudo tee /etc/ld.so.conf.d/casparcg.conf >/dev/null
sudo ldconfig
Alternatively set LD_LIBRARY_PATH=/opt/casparcg/lib in the environment that starts Caspar (value must be the directory, not the .so path). That does not require sudo if you only change a user’s systemd unit or shell script.
udisks2 and policykit-1; copy scripts/polkit/50-highascg-udisks.rules to /etc/polkit-1/rules.d/ so the casparcg user (group plugdev) can run udisksctl unmount / power-off without a password. The full installer does this in install-phase4.sh (section 4.3b). If a stick does not auto-mount under /media/…, check udev/udisks2 logs and that the volume is not already mounted elsewhere./etc/asound.conf: optional — only for Web UI system-wide ALSA default. Default installer skips this; set HIGHASCG_INSTALL_ASOUND_SUDOERS=1 during install (see install-phase3.sh). Per-user ~/.asoundrc needs no sudo.install-phase2.sh (Sync to VBlank off). Pair with Caspar screen consumer vsync on — reference/screen-consumer-vsync-nvidia.md.HIGHASCGEXF at /home/casparcg/exfat, sync via highascg-exfat-sync.service and config/exfat-sync.json (see docs/WO47_ISO_VS_EXFAT.md, docs/EXFAT_SERVER_UPDATE.md). WO-38 media/drive partition mount was removed (no startup wait, no Settings mount UI).| Step | Done |
|---|---|
User casparcg exists with home |
☐ |
sudo chown -R casparcg:casparcg /opt/casparcg |
☐ |
Groups: video, audio, render, plugdev, dialout, input |
☐ |
nodm configured; .xsession → openbox-session |
☐ |
Openbox autostart + Caspar run.sh or equivalent |
☐ |
DeckLink desktopvideo packages installed |
☐ |
NDI SDK + libndi.so.6 + ldconfig |
☐ |
ldconfig or LD_LIBRARY_PATH for /opt/casparcg/lib |
☐ |
HighAsCG cloned to /opt/highascg, npm install, service (optional) |
☐ |
| Reboot and verify X + Caspar | ☐ |
Replace YOUR_REPO with your GitHub URL (HTTPS or SSH), for example https://github.com/mko1989/highascg.git (same default as HIGHASCG_GIT_URL in scripts/install-config.sh).
Requirements: Node.js ≥ 20 (see NodeSource or install-phase4.sh). Ubuntu’s default nodejs package is often too old.
/opt/highascg and install dependenciessudo rm -rf /opt/highascg
sudo mkdir -p /opt/highascg
sudo chown casparcg:casparcg /opt/highascg
sudo -u casparcg git clone --depth 1 https://github.com/mko1989/highascg.git /opt/highascg
cd /opt/highascg
sudo -u casparcg npm install --omit=dev
cd /opt/highascg
if [ ! -f highascg.config.json ] && [ -f highascg.config.example.json ]; then
sudo -u casparcg cp highascg.config.example.json highascg.config.json
fi
sudo chown -R casparcg:casparcg /opt/highascg
sudo chmod -R 775 /opt/highascg
Edit highascg.config.json (or use env vars — see root README.md) as needed.
three)The browser-side 3D Previs feature (PGM cell 2D/3D toggle, imported stage models, LED-style video mapping) is gated behind HIGHASCG_PREVIS=1 or config.features.previs3d === true (see root index.js and docs/MODULES.md).
The three package is listed under optionalDependencies in package.json. A minimal install such as npm install --omit=dev without optional packages does not install it.
To pull optional dependencies (including three):
cd /opt/highascg
sudo -u casparcg npm run install:previs
# equivalent: npm install --include=optional
Enable the server-side feature flag (pick one):
systemd Environment=
Environment=HIGHASCG_PREVIS=1
Or in highascg.config.json:
"features": {
"previs3d": true
}
In the web UI (with Previs enabled), operators can: toggle the PGM preview cell to 3D, import a .glb stage, tag meshes as screens, and use Scene settings (virtual canvas size, video texture cap, lights). The inspector Screen mapping section includes a virtual-canvas region control (drag / corner resize) to crop how PGM video maps onto a screen; that layout is stored in the browser (with the rest of previs state in localStorage, key highascg.previs.state.v1). It is optional workflow polish, not required for a minimal playout install.
install-phase4.sh)sudo tee /etc/systemd/system/highascg.service >/dev/null <<'EOF'
[Unit]
Description=HighAsCG Playout Control Server
After=network.target
[Service]
Type=simple
User=casparcg
Group=casparcg
UMask=002
WorkingDirectory=/opt/highascg
ExecStart=/usr/bin/node /opt/highascg/index.js
Restart=always
RestartSec=5
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable highascg.service
sudo systemctl start highascg.service
Check: systemctl status highascg, then open http://SERVER_IP:4200/ (or the port in your config).
go2rtc-static download timeoutThe go2rtc-static package runs node dist/install.js after install and downloads a go2rtc binary from GitHub (got request timeout 30s). Slow links, firewalls, or GitHub blocks produce:
TimeoutError: Timeout awaiting 'request' for 30000ms
Workaround A — system binary + skip scripts (typical on restricted servers)
go2rtc binary on the server (e.g. AlexxIT/go2rtc releases for Linux amd64), place it at e.g. /usr/local/bin/go2rtc, chmod +x.Deploy Node modules without running the post-install download:
cd /opt/highascg
npm ci --ignore-scripts
Point HighAsCG at that binary (either is fine):
HIGHASCG_GO2RTC_BINARY=/usr/local/bin/go2rtcGO2RTC_BIN=/usr/local/bin/go2rtc (also respected by the go2rtc-static package if present)In systemd, add e.g. Environment=HIGHASCG_GO2RTC_BINARY=/usr/local/bin/go2rtc under [Service].
Workaround B — proxy: if GitHub is only reachable via proxy, set HTTPS_PROXY / https_proxy during npm install (the download script uses https-proxy-agent).
Workaround C: run npm ci on a machine with reliable GitHub access, then rsync node_modules to the server (or use npm pack / offline mirror).
If you want the entire stack (Caspar debs, nodm, Tailscale, Syncthing, etc.), clone the repo to a path with the full scripts/ tree and run:
git clone https://github.com/YOUR_ORG/highascg.git
cd highascg
sudo ./scripts/install.sh
That uses scripts/install-config.sh (including HIGHASCG_GIT_URL) and install-phase4.sh to deploy to /opt/highascg; for a machine that already has the repo cloned, phase 4 can sync from SCRIPT_DIR instead of cloning again.
client/scripts/dev-push.sh / npm run deploy:dev — rsync or scp to a remote host (see scripts/README.md and .env.deploy).
| Topic | File |
|---|---|
User, groups, nodm, openbox, /opt/casparcg |
scripts/install-phase3.sh |
| FFmpeg base, NVIDIA, DeckLink, NDI | scripts/install-phase2.sh |
| Tarball fetch helpers | scripts/install-helpers.sh |
| Openbox autostart notes | openbox_autostart.md (repo root) |