Let the Device field be picked, not typed blind

Diagnosing capture on a real TV meant reading pactlSources off the
screen and typing an exact PulseAudio source name back in through the
same remote-driven text field — no way to copy-paste, easy to
mistype, and the one piece of information (which source, if any, is
actually RUNNING) was buried in a JSON dump.

Added two choice() pickers bound to the same capture.device setting:
one built from pactlSources (pulse/auto backends), one built from
alsaCapturePcms (alsa backend), both parsed from diagnostics the
service already collects — no new Luna method needed. Diagnostics
already run once at boot, so the picker is populated immediately,
before the user ever presses "Run diagnostics" by hand.

Picking a value writes straight into capture.device, and the plain
text field stays as the fallback for anything the parser misses.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Rene Kievits
2026-08-26 13:51:02 +02:00
co-authored by Claude Opus 5
parent f3a4cddfd6
commit 0759cc00aa
10 changed files with 380 additions and 2 deletions
+34
View File
@@ -40,6 +40,40 @@ sudo modprobe snd-aloop index=10 pcm_substreams=1 id=Loopback
./host/lgtv-audiocap-receiver.py --output aplay --device hw:Loopback,0,0
```
### On Unraid
Unraid boots from a read-only USB image, so nothing here can be "just a
systemd service" — the loopback and the receiver need to be split into the
one part that genuinely needs the bare-metal kernel and the part that doesn't.
**The loopback (bare metal):** install
[`unraid/lgtv-audiocap-loopback.plg`](../unraid/lgtv-audiocap-loopback.plg) —
*Plugins → Install Plugin*, paste the raw URL to that file. It loads
`snd-aloop` immediately and adds one line to `/boot/config/go` so it survives
a reboot; *Plugins → Uninstall* removes exactly that line and nothing else.
**The receiver (a normal container):** build
[`docker/Dockerfile`](../docker/Dockerfile) and add it like any other Unraid
container — *Docker → Add Container*:
| Setting | Value |
| --- | --- |
| Repository | your image, e.g. `192.168.0.4:5000/lgtv-audiocap-receiver` |
| Network Type | Bridge (or Host, either works — it only ever listens on one UDP port) |
| Port | `5004` UDP → `5004` |
| Extra Parameters | `--device /dev/snd:/dev/snd` |
It's entirely configured through environment variables — see
[`docker/entrypoint.sh`](../docker/entrypoint.sh) for the full list
(`PORT`, `DEVICE`, `RATE`, `CHANNELS`, `LATENCY_MS`, …). The default `DEVICE`
is already `hw:Loopback,0,0`, so nothing needs setting for the common case.
Point the **HyperHDR container** at the loopback the same way: add
`--device /dev/snd:/dev/snd` to its extra parameters too, then use
`hw:Loopback,1,0` in its Sound Capture settings. Both containers reach the
same host kernel device, so no networking between them is needed for this
part — only the TV needs to know the host's IP, for the RTP stream itself.
### On the TV
*Outputs → HyperHDR audio (RTP/L16)*