Files
Omarchy-Stream/lib/config.sh
Levi Woodard ab23107300 Add runtime status checker + headless/X11 docs; distro-support refinements
- status.sh: runtime health check (service state, boot wiring, display backend auto-detect, encoder, ports, web UI, /dev/uinput, pairing) ending in a g2g verdict or concrete TODO list

- docs: TROUBLESHOOTING §12 (headless graphical-session.target boot trap) + §13 (X11/NVENC path & stale wlr drop-in env conflict); ARCHITECTURE capture-backend comparison; FOLLOWUPS P3 (installer X11/Ubuntu support); README diagnostics pointer

- lib/{config,packages,permissions,service}.sh, files/sway-headless.service: in-progress Debian/Ubuntu + headless support refinements

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 22:57:03 +00:00

90 lines
3.2 KiB
Bash

#!/usr/bin/env bash
# Write a tuned ~/.config/sunshine/sunshine.conf for low-latency LAN streaming.
# Only overwrites if (a) no config exists, or (b) our managed marker is present.
SUNSHINE_CONF_DIR="$HOME/.config/sunshine"
SUNSHINE_CONF="$SUNSHINE_CONF_DIR/sunshine.conf"
MANAGED_MARKER="# managed-by: omarchy-moonlight"
write_sunshine_config() {
local mode="${1:-mirror}"
mkdir -p "$SUNSHINE_CONF_DIR"
if [[ -f "$SUNSHINE_CONF" ]] && ! grep -qF "$MANAGED_MARKER" "$SUNSHINE_CONF"; then
ok "Existing sunshine.conf is user-managed — leaving it alone"
info " To re-apply tuned defaults, delete $SUNSHINE_CONF and re-run install.sh"
return 0
fi
local encoder_block
case "$GPU_VENDOR" in
nvidia)
encoder_block=$'encoder = nvenc\nnvenc_preset = p1\nnvenc_tune = ll\nnvenc_rc = cbr\nnvenc_coder = auto'
;;
amd)
encoder_block=$'encoder = vaapi\namd_quality = speed\namd_rc = cbr\namd_usage = ultralowlatency'
;;
intel)
encoder_block=$'encoder = quicksync\nqsv_preset = veryfast\nqsv_coder = auto'
;;
*)
encoder_block=$'# encoder auto-detected by Sunshine'
;;
esac
local capture_block
case "$mode" in
headless)
# wlr capture of the Hyprland headless output that prep-cmd hooks create.
# global_prep_cmd is parsed as a JSON array by Sunshine, so keep it on one line.
capture_block="# Capture: wlr — captures a Hyprland headless output created on stream start.
capture = wlr
output_name = HEADLESS-1
# Hooks that create/resize HEADLESS-1 on stream start and remove it on stop.
global_prep_cmd = [{\"do\":\"${DO_SCRIPT}\",\"undo\":\"${UNDO_SCRIPT}\"}]"
;;
mirror|*)
capture_block="# Capture: KMS (DRM) — the right choice on Wayland.
capture = kms"
;;
esac
info "Writing tuned $SUNSHINE_CONF (GPU: $GPU_VENDOR, mode: $mode)"
cat >"$SUNSHINE_CONF" <<EOF
$MANAGED_MARKER
# Generated by omarchy-moonlight install.sh on $(date -Iseconds)
# Delete this marker line to take ownership; the installer will then leave the file alone.
#
# Tuned for low-latency LAN streaming on Hyprland/Wayland.
# Tune further via the web UI at https://localhost:47990
sunshine_name = ${HOSTNAME_SHORT}
$capture_block
# Encoder tuned for $GPU_VENDOR
$encoder_block
# Threading — more threads helps high-bitrate H.265/AV1.
min_threads = 4
# Audio sink is intentionally left unset so Sunshine auto-detects the default
# PulseAudio/PipeWire sink and creates its virtual 'sink-sunshine-stereo'.
# Hard-coding audio_sink = pulse here breaks capture: Sunshine treats it as a
# literal sink name, can't resolve its monitor source, and pa_simple_new()
# fails with "Invalid argument" -> no audio in the stream.
# Keyboard / mouse / gamepad pass-through via /dev/uinput.
# (Requires user to be in the 'input' group; install.sh handles this.)
# Lock the web UI to localhost-only regardless of what the socket binds to.
# Reach the admin panel from another machine via an SSH tunnel:
# ssh -L 47990:127.0.0.1:47990 <user>@<host>
# then open https://localhost:47990 in a browser. The streaming/pairing port
# (47989) stays LAN-accessible — only the admin UI is locked down.
origin_web_ui_allowed = pc
EOF
ok "Wrote sunshine.conf"
}