Listen to audio: from microphone to the web (in real time) [WORKING]

With this “less than 2€” usb microphone
https://www.amazon.es/Hosaire-Micrófono-Makio-Portátil-Sobremesa/dp/B071G7ZLRT/ref=pd_sim_147_1/260-5421862-6642729

you can listen in your HA webserver in almost real-time (2 seconds delay).

Instructions (for a raspberry-pi with virtual-env over raspbian and homeassistan user, based in post Camera in HD@30fps without reencoding (0%CPU) WORKING! )

  1. Let ‘homeassistant’ user open audio devices and install ffmpeg:
sudo usermod -a -G audio homeassistant
sudo apt-get install ffmpeg
  1. Create a directory to static access for HA (www)
cd /home/homeassistant/.homeassistant
mkdir www
  1. Restart HA (needed to read new ‘www’ directory)

  2. Install a HLS player plugin on your favorite browser I.e for firefox: https://addons.mozilla.org/es/firefox/addon/native_hls_playback/ or for chrome: https://chrome.google.com/webstore/detail/native-hls-playback/emnphkkblegpebimobpbekeedfgemhof

  3. run the capture at /home/homeassistant/.homeassistant/www

cd /home/homeassistant/.homeassistant/www
ffmpeg -f alsa -ac 1 -i hw:1,0 -f hls -hls_flags delete_segments stream.m3u8

This will create (and update) a m3u8 file and some .ts parts of h264 captured video. (Control-c or ‘q’ to stop it)

  1. With ffmpeg runnig, open your browser and navigate to
    http://your.homeasistant.baseurl/local/stream.m3u8
    (changing ‘your.homeasistant.baseurl’ for your home assistant base url)

  2. You could see a javascript player that play the audio with 5-10 seconds delay. Seek to the end of stream to get 2 seconds delay.

You can make the same with video, or video + audio (see post Camera in HD@30fps without reencoding (0%CPU) WORKING! )

I you like this, please help me to get a built-in component to do this without need of any plugging, and to start-stop realtime capture from HA frontend, posting here or in post before.

Thanks.

1 Like

anyway to install on Hassio?

let me see…because I dont know how is Hassio inside…

ffmpeg is included in hassio, so only change ‘homeassistant’ user for ‘ha’ and config dir:

maybe:

sudo usermod -a -G audio ha
mkdir /home/ha/config/www

restart HA and execute ffmepg inside ‘www’ dir

cd /home/ha/config/www
ffmpeg -f alsa -ac 1 -i hw:1,0 -f hls -hls_flags delete_segments stream.m3u8

there is a component called ffmpeg wil it work?

here is the link

We don’t have access to the command line easily on hassio, it’s possible but not easy for most.

Would have g another package that uses ffmpeg installed help?

Also, could I use this with an external audio device (such as a record player) and use it to stream to a Chromecast ?

Ok… I would try with a command-line switch…
Please, wait some minutes… to try…

2 Likes

Ok, I m trying to ge a working switch to start and stop audio capture. It takes me a few because of stdin/stdout broken pipes in background execution, path, and other things…
but seems that I dont undestand the logic of the command-line switch.

  • Switch on: means launch ffmpeg capture in bg
  • switch off: pkill the
  • switch state: pgrep for ffmpeg process.
    All work fine at command line, but in command-line switch, states are not synced. command-line is very powerfull but horrible documented, and I cant figure how HA determine the state of the switch, how make the scape, how is the enviroment where command are executed, path, shell, pipes, etc.etc.

This is my actual code for the switch:

switch:
  - platform: command_line
    switches:
      ffmpeg_mic:
        command_on: '/usr/bin/ffmpeg -f alsa -ac 1 -i hw:1,0 -nostdin -loglevel quiet -f hls -hls_flags delete_segments
/home/homeassistant/.homeassistant/www/stream.m3u8 &'
        command_off: 'pkill -9 -f "/usr/bin/ffmpeg -f alsa -ac 1 -i hw:1,0 " || echo'
        command_state: 'pgrep -f "/usr/bin/ffmpeg -f alsa -ac 1 -i hw:1,0 "'
        friendly_name: microphone

I have append a ‘|| echo’ to make the command_off allways result ‘0’ (echo $? = 0) to make HA see that execution of command_off has positive result even if process is not runnig.
But It doesnt sync state as expected. I am supposing commands are executed without shell so pipes and redirections dont work. But nothing is documented…

Probably could be easy write it in python… but I have to read a lot to make HA components…

So, sorry, you have to wait for someone write a good component for HA.

I surrender with command-line switch. One command-line works fine on console, but fails in HA.
This is my working mic2web script:

#!/bin/bash
# This is a prototipe command-line tool to output a microphone to www web directory of homeassitant
AUDIO_CARD="hw:CARD=Device,DEV=0"
FFMPEG="/usr/bin/ffmpeg"
CONFIG_DIR=".homeassistant"
cd ~/$CONFIG_DIR
case $1 in
#  on) $FFMPEG -f alsa -ac 1 -i $AUDIO_CARD -nostdin -loglevel quiet -f hls -hls_flags delete_segments
 www/stream.m3u8 &>/dev/null &;;
  on) nohup $FFMPEG -f alsa -ac 1 -i $AUDIO_CARD -f hls -hls_flags delete_segments www/stream.m3u8 > ${0##*/}.log 2>&1 <
 /dev/null & ;;
  off) pkill -9 -f "$FFMPEG -f alsa -ac 1 -i $AUDIO_CARD "; rm -f ${0##*/}.log exit 0;;
  *) pgrep -f "$FFMPEG -f alsa -ac 1 -i $AUDIO_CARD ";;
esac

and this is the switch:

switch:
  - platform: command_line
    switches:
      ffmpeg_mic:
        command_on: '/home/homeassistant/.homeassistant/mic2web on'
        command_off: '/home/homeassistant/.homeassistant/mic2web off'
        command_state: '/home/homeassistant/.homeassistant/mic2web'
        friendly_name: microphone

The same mic2web running from threaded HA fails to open the audio card.

Nobody know how is the enviroment where command_on is executed… maybe user permissons… (developers help could be appreciated here).

Note that the other 2 commands work fine.

Sorry about that. I cant waste more time here.
Thanks.

Casually, I have found the error:
Problem is about microphone card, not about HA enviroment.
The firs time I open the card it output an error about it is busy ot opened , and 5 second after, I can open it without error.
So then I could change the code by:


  on)
arecord -D $AUDIO_CARD --dump-hw-params
sleep 5
arecord -D $AUDIO_CARD --dump-hw-params
nohup $FFMPEG -f alsa -ac 1 -i $AUDIO_CARD -f hls -hls_flags delete_segments www/stream.m3u8 > ${0##*/}.log 2>&1 < /dev/null &
;;

But It make 5 seconds delay, so I suspect about who is opened the card? Ok. I discover that pulseaudio is the responsible, so. i.e you configure
AUDIO_CARD=“default”
the alsa open the card througth pulseaudio, so no error is reported, and all works lik a charm.

Note that if you dont has pulseaudio, and/or default input card is the mic where you want to record, first script work fine putting AUDIO_CARD=“default”

I put it here to simply copy-paste…

#!/bin/bash
# This is a prototipe command-line tool to output a microphone to www web directory of homeassitant
AUDIO_CARD="default"
FFMPEG="/usr/bin/ffmpeg"
CONFIG_DIR=".homeassistant"
cd ~/$CONFIG_DIR
case $1 in
#  on) $FFMPEG -f alsa -ac 1 -i $AUDIO_CARD -nostdin -loglevel quiet -f hls -hls_flags delete_segments
 www/stream.m3u8 &>/dev/null &;;
  on) nohup $FFMPEG -f alsa -ac 1 -i $AUDIO_CARD -f hls -hls_flags delete_segments www/stream.m3u8 > ${0##*/}.log 2>&1 <
 /dev/null & ;;
  off) pkill -9 -f "$FFMPEG -f alsa -ac 1 -i $AUDIO_CARD "; rm -f ${0##*/}.log exit 0;;
  *) pgrep -f "$FFMPEG -f alsa -ac 1 -i $AUDIO_CARD ";;
esac

Now, the next could be build a lovelace card that “command_on” the audio capture, and open a new browser with the realtime sound captured.

Next, could be a button to capture i.e 30 seconds mp3 file and sent it by pushbullet or something similar…

Another tips, change ‘-f alsa’ in linux for ‘-f dshow’ for windows or ‘-f avfoundation’ for mac make it work on other platforms.

Thanks for your work on this.

I have installed on Home Assistant in Docker as described, but could not find the hidden /.homeassistant directory so I created one. However, when I run the script although I can see the packets of audio data being created and indeed if I stop the script, when I browse to the directory I can see the last 5 or so packets contained, I fail to hear any audio when I browse to http://your.homeassistant.baseurl/local/stream.m3u8. Can you please advise as to where the packets are being served or what I might be doing wrong?

Thank you

Sorry. I dont know very much about “in Docker” installation, and may be has problems with access to hardware things like microphones or audio cards…
Are you using raspberry pi? If yes, why you dont try hassbian (raspbian + python venv).
Its important to get where config HA folder is. I think that on every installation has to have config yaml files inside…
can you reach HA webserver to http://xxx.xxx.xxx.xxx:8123 ?

Thanks for coming back to me.

I have now tried on Hassio and the switches will not stay on?

I note that "command_on: ‘/usr/bin/ffmpeg -f alsa -ac 1 -i hw:1,0 -nostdin -loglevel quiet -f hls -hls_flags delete_segments/home/homeassistant/.homeassistant/www/stream.m3u8 &’ "- ther*e’s a path that I don’t recognise in Hassio. The path to www on Hassio is /var/www or I can create a directory as /config/www

Can you please advise whether this is why the switch doesn’t remain on and which directory is the best path?