Files
lgtv_audio_cap/unraid/lgtv-audiocap-loopback.plg
Rene KievitsandClaude Opus 5 0759cc00aa 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>
2026-08-26 13:51:02 +02:00

88 lines
2.7 KiB
XML

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!DOCTYPE PLUGIN [
<!ENTITY name "lgtv-audiocap-loopback">
<!ENTITY author "Crylia">
<!ENTITY version "2026.08.26">
<!ENTITY pluginURL "https://git.crylia.de/Crylia/lgtv_audio_cap/raw/branch/main/unraid/&name;.plg">
]>
<!--
This plugin does exactly one thing: load the ALSA loopback (snd-aloop) that
the LG TV Audio Cap RTP receiver plays into, and make that persist across an
Unraid reboot. Everything else - actually receiving the TV's audio and
writing it into the loopback - runs as a normal Docker container (see
docker/Dockerfile in the project repo), because that part doesn't need
bare-metal access. Only the kernel module load does: Unraid boots from a
read-only USB image each time, so anything not re-applied via /boot/config/go
or a plugin is gone on the next boot, and a container can't load a host
kernel module for itself.
hw:Loopback,0,0 - playback end, feed this to the receiver container
hw:Loopback,1,0 - capture end, point HyperHDR's sound capture at this
-->
<PLUGIN name="&name;" author="&author;" version="&version;" pluginURL="&pluginURL;" min="6.9.0">
<CHANGES>
###2026.08.26
- Initial release.
</CHANGES>
<FILE Run="/bin/bash">
<INLINE>
set -e
NAME="&name;"
MARK="# ${NAME}: load ALSA loopback for LG TV Audio Cap (do not remove this line by hand)"
LOAD_CMD="/sbin/modprobe snd-aloop index=10 pcm_substreams=1 id=Loopback"
GO=/boot/config/go
echo "Installing ${NAME} &version;"
if ! $LOAD_CMD 2>/tmp/${NAME}.err; then
echo "warning: snd-aloop failed to load, see /tmp/${NAME}.err"
echo " this Unraid build's kernel may not include it"
fi
if ! grep -qF "$MARK" "$GO" 2>/dev/null; then
{
echo "$MARK"
echo "$LOAD_CMD"
} >> "$GO"
echo "Added the loopback load to $GO -- it will now load on every boot."
else
echo "$GO already loads the loopback; left it alone."
fi
echo ""
echo "Done. Check: cat /proc/asound/cards | grep -i loopback"
echo "In your receiver container's device settings, use hw:Loopback,0,0."
echo "In HyperHDR's sound capture settings, use hw:Loopback,1,0."
</INLINE>
</FILE>
<FILE Run="/bin/bash" Method="remove">
<INLINE>
set -e
NAME="&name;"
MARK="# ${NAME}: load ALSA loopback for LG TV Audio Cap (do not remove this line by hand)"
GO=/boot/config/go
if [ -f "$GO" ]; then
if grep -qF "$MARK" "$GO"; then
awk -v mark="$MARK" '
$0 == mark { skip = 1; next }
skip > 0 { skip--; next }
{ print }
' "$GO" > "${GO}.tmp"
mv "${GO}.tmp" "$GO"
echo "Removed the loopback load from $GO."
fi
fi
/sbin/rmmod snd_aloop 2>/dev/null || true
echo "${NAME} removed. The loopback will not load on the next boot."
</INLINE>
</FILE>
</PLUGIN>