This is the my solution I'm trying, but I'm not sure if it's stable.
1. Device Detection
> script:
sudo nano /usr/local/bin/detect_alsa_device.sh
Code:
#!/bin/bash
LAST_DEVICE_FILE="/var/local/last-alsa-device"
echo "Starting ALSA device detector..."
# Check if the stored device file exists
if [ ! -f "$LAST_DEVICE_FILE" ]; then
echo "No last ALSA device record found. Skipping..."
exit 0
fi
# Read the last stored ALSA device information from the file
LAST_FILE_ROW1=$(head -n 1 "$LAST_DEVICE_FILE")
LAST_FILE_ROW2=$(head -n 2 "$LAST_DEVICE_FILE" | tail -n 1)
LAST_FILE_ROW3=$(head -n 3 "$LAST_DEVICE_FILE" | tail -n 1)
LAST_FILE_ROW4=$(head -n 4 "$LAST_DEVICE_FILE" | tail -n 1)
# Extract stored values
LAST_CARD=$(echo "$LAST_FILE_ROW1" | awk '{gsub(":", "", $2); print $2}')
LAST_DEVICE=$(echo "$LAST_FILE_ROW1" | cut -d' ' -f3-)
LAST_OUTPUT_MODE="$LAST_FILE_ROW2"
LAST_VOLUME_MAX="$LAST_FILE_ROW3"
LAST_MIXER_TYPE="$LAST_FILE_ROW4"
# Pooling
while true; do
# Detect the current ALSA device
CURRENT_CARD=$(aplay -l | grep "$LAST_DEVICE" | awk -F'[: ]+' '{print $2}')
# If the device is not found, continue the loop
if [[ -z "$CURRENT_CARD" ]]; then
echo "Last ALSA device ($LAST_DEVICE) not found in aplay -l. Skipping..."
sleep 3
continue
fi
CURRENT_DEVICE="$LAST_DEVICE"
echo "Last ALSA: card $LAST_CARD ($LAST_DEVICE)"
echo "Current ALSA: card $CURRENT_CARD ($CURRENT_DEVICE)"
# Get the currently stored ALSA device in Moode
CFG_MPD_CARD=$(moodeutl -q "SELECT value FROM cfg_mpd WHERE param='device';" | awk -F'|' '{print $1}')
if [ "$CFG_MPD_CARD" != "$LAST_CARD" ]; then
echo "Updating Moode to use last known ALSA device ($LAST_CARD : $LAST_DEVICE) | $LAST_OUTPUT_MODE | $LAST_VOLUME_MAX | $LAST_MIXER_TYPE ..."
sleep 1
moodeutl -q "UPDATE cfg_mpd SET value='$LAST_CARD' WHERE param='device'; \
UPDATE cfg_system SET value='$LAST_DEVICE' WHERE param='adevname'; \
UPDATE cfg_system SET value='$LAST_CARD' WHERE param='cardnum'; \
UPDATE cfg_system SET value='$LAST_OUTPUT_MODE' WHERE param='alsa_output_mode'; \
UPDATE cfg_system SET value='$LAST_VOLUME_MAX' WHERE param='alsavolume_max'; \
UPDATE cfg_mpd SET value='$LAST_MIXER_TYPE' WHERE param='mixer_type';"
echo "Cleaning \$_SESSION variables..."
moodeutl -D cardnum
moodeutl -D adevname
moodeutl -D alsa_output_mode
moodeutl -D alsavolume_max
moodeutl -D amixname
break
fi
sleep 5
done
sleep 1
# Restart Moode services as the www-data user
if ! pgrep -f "moodeutl -r" > /dev/null; then
echo "Restarting Moode servers..."
/bin/su -s /bin/bash -c "moodeutl -r" www-data
else
echo "Moode server is already being restarted. Skipping..."
fi
> systemd Service:
sudo nano /etc/systemd/system/detect_alsa_device.service
Code:
[Unit]
Description=Detect ALSA device and restore last known output
After=sound.target network.target
Requires=sound.target
[Service]
ExecStart=/usr/local/bin/detect_alsa_device.sh
Restart=on-failure
RestartSec=5
User=root
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
[Install]
WantedBy=multi-user.target
2. Device Monitoring
> script:
sudo nano /usr/local/bin/monitor_alsa_device.sh
Code:
#!/bin/bash
WATCH_DIR="/etc/alsa/conf.d/"
LAST_DEVICE_FILE="/var/local/last-alsa-device"
echo "Starting ALSA device monitor..." | systemd-cat -t monitor_alsa_device
inotifywait -m -e moved_to,delete_self,modify "$WATCH_DIR" | while read path action file; do
if [ "$file" == "_audioout.conf" ]; then
echo "Detected change in _audioout.conf ($action)"
CURRENT_CARD=$(moodeutl --hwparams | grep "card" | awk -F'[: ]+' '{print $2}')
CURRENT_DEVICE=$(moodeutl --hwparams | grep "card" | cut -d' ' -f3-)
if [[ "$CURRENT_CARD" == "empty" ]]; then
echo "ALSA device not initialized yet. Skipping update."
continue
fi
echo "Temporarily stopping detect_alsa_device.service"
systemctl stop detect_alsa_device.service
sleep 1
FORMATTED_ENTRY="card $CURRENT_CARD: $CURRENT_DEVICE"
echo "Recording last ALSA device: $FORMATTED_ENTRY"
echo "$FORMATTED_ENTRY" > "$LAST_DEVICE_FILE"
moodeutl -q "SELECT value FROM cfg_system WHERE param='alsa_output_mode'" >> "$LAST_DEVICE_FILE"
moodeutl -q "SELECT value FROM cfg_system WHERE param='alsavolume_max'" >> "$LAST_DEVICE_FILE"
moodeutl -q "SELECT value FROM cfg_mpd WHERE param='mixer_type'" >> "$LAST_DEVICE_FILE"
fi
done
> systemd Service:
sudo nano /etc/systemd/system/monitor_alsa_device.service
Code:
[Unit]
Description=Monitor ALSA device changes for Moode
After=sound.target network.target
Requires=sound.target
[Service]
ExecStart=/usr/local/bin/monitor_alsa_device.sh
Restart=on-failure
RestartSec=5s
User=root
[Install]
WantedBy=multi-user.target
Any insights or suggestions would be greatly appreciated.
Thanks!