That is fantastic news, thank you! I’m really looking forward to it.
To give you some context on why a native Audio Sink would be such a game-changer for me: I am using Dahua cameras, and unfortunately, I never managed to get WebRTC working properly within openHAB. Because of that, I had to build a rather complex, custom workaround just to get TTS (Text-to-Speech) working on the camera speakers.
I thought I’d share my current setup with you, just in case you are interested in how I currently “brute-force” the audio return channel.
Here is my current architecture:
1. Virtual Soundcards (ALSA) I use the ALSA loopback kernel module (snd-aloop) to create a virtual audio device for each camera on my openHAB system (e.g., hw:eingang, hw:garage, hw:briefkasten).
2. Exposing to openHAB (Squeezelite) To make these virtual soundcards available as Audio Sinks in openHAB, I run a dedicated Squeezelite instance for each camera as a systemd service. Example for the Front Door (Eingang):
Ini, TOML
[Unit]
Description=Squeezelite Player Eingang
After=network.target
[Service]
ExecStart=/usr/bin/squeezelite -n "Audio_Kamera_Eingang" -o plughw:CARD=eingang,DEV=0 -m 00:00:00:00:00:14
Restart=always
User=openhabian
[Install]
WantedBy=multi-user.target
3. The “VOX-Watcher” (Bash Script & Curl) Finally, I have a bash script running as a background service. It uses sox to constantly listen to the virtual ALSA device. As soon as openHAB sends a TTS message to the Squeezelite player, sox detects the audio, writes it to the RAM disk (/dev/shm), encodes it to G.711A (.alaw), and immediately pushes it to the Dahua camera’s API via curl.
Bash
#!/bin/bash
# Trap to handle safe exit
trap "echo -e '\n[!] Script terminating...'; exit" SIGINT SIGTERM
echo "========================================================="
echo " VOX-Watcher started."
echo " Waiting for audio on (plughw:eingang,1,0)..."
echo "========================================================="
RAM_FILE="/dev/shm/tts_eingang.alaw"
COUNTER=0
while true; do
# 1. Listen via sox (VOX detection)
sox -S -t alsa plughw:eingang,1,0 -t raw -r 8000 -c 1 -e a-law $RAM_FILE silence 1 0.1 0.1% 1 1.5 0.1% vol 10.0
# 2. Check if file is created and not empty
if [ -s "$RAM_FILE" ]; then
((COUNTER++))
FILESIZE=$(stat -c%s "$RAM_FILE")
echo "[$(date +'%H:%M:%S')] Audio #$COUNTER detected! ($FILESIZE Bytes)"
echo "-> Pushing to Dahua Camera API..."
# 3. Push file to Camera via curl
curl -s --max-time 20 --digest -u 'admin:PASSWORD' -X POST -H "Content-Type: Audio/G.711A" --data-binary @$RAM_FILE "http://192.168.178.61/cgi-bin/audio.cgi?action=postAudio&httptype=singlepart&channel=1" > /dev/null
if [ $? -eq 0 ]; then
echo "-> Successfully pushed!"
else
echo "-> [!] ERROR sending to camera!"
fi
# 4. Clean up RAM
rm -f $RAM_FILE
else
sleep 1
fi
done
As you can see, it completely works, but it’s a massive and clunky workaround relying on virtual loopbacks, external players, and bash scripts polling for audio.
Having this handled natively within your Frigate binding would clean up the system architecture tremendously! Thanks again for considering it for the to-do list.