Wednesday, 20 August 2025

BirdNet-Pi: streaming the microphone

This is about audio streaming from my system's mic.

I wanted to use AI to do all the thinking & lead me through the config.

But it didn't turn out to be so simple.

The plan is to eventually run 2 bird identification systems side-by-side. This will allow me to compare systems with different settings and maybe compare (say) BirdNet-Pi with BirdNet-Go.

But I need to use one microphone, so that the mic & its location doesn't complicate things.

 I thought I could use ChatGPT to find all the necessary software and modifications required for this to work, and all I'd have to do was a bit of typing.

you stupid boy!

So I started out just following AI's instructions. It was a bit like working alongside an over-confident, over-enthusiastic apprentice; if its instructions didn't work, it would say "Ah! that's because you need to do this, and then it will definitely work!".

And if that didn't work, it would reply "Yes I see, that's because you need to type in such-and-such, and then it will definitely work!".

At one stage, after going unsuccessfully around the same loop 3 times, I eventually said to 'my assistant' "If you don't know how to do this, just say so!"

It responded after a short pause "Got it—I understand your frustration...." and changed track slightly.

Later on, I challenged my AI buddy, suggesting it was giving me config settings for the wrong version of mediamTX.

There was a long pause, it printed a message: "Thought for 3m 30s"

Then replied "You're right to question it - some of my earlier suggestions mixed versions. Here's the straight answer...." 

Eventually I started to think about each step and managed to overcome some of AI's error (e.g. by using the correct 'key' names in the config file for the version of mediamTX in use).

However, despite these problems, I would say that using AI was definitely a big plus, I just needed to properly follow & understand what was happening, question the advice given, and sometimes use my judgement to make changes or steer AI with appropriate questions.

I now call my AI apprentice, Pike

implementation

This post describes creating an RTSP audio stream using the following:-

  • ALSA dsnoop virtual device
  • media server (mediamTX)
  • stream command (using ffmpeg)
  • play command (remote client)

In order to stream the audio from the microphone I need to ensure it can be used by more than one application. So the /home/<user>/.asoundrc file on the BirdNet-Pi should be modified like this:-

pcm.!default {
    type pulse
}

ctl.!default {
    type pulse
}

pcm.!default {
    type plug
    slave.pcm "sharedmic"
}

pcm.sharedmic {
    type dsnoop
    ipc_key 123456
    slave {
        pcm "hw:1,0"
        channels 1
        rate 44100
    }
}

ctl.!default {
    type hw
    card 1
}

Then I install mediamTX on BirdNet-Pi via terminal:-

  wget https://github.com/bluenviron/mediamtx/releases/latest/download/mediamtx_v1.14.0_linux_arm64.tar.gz
  tar -xvzf mediamtx_v1.14.0_linux_arm64.tar.gz
  sudo install -m 0755 mediamtx /usr/local/bin/mediamtx
  sudo mkdir -p /etc/mediamtx
  sudo cp mediamtx.yml /etc/mediamtx/mediamtx.yml

Then run mediamTX:-

  /usr/local/bin/mediamtx /etc/mediamtx/mediamtx.yml

However, this didn't work for a few reasons, including port conflicts.

To check which ports are in use, type in a BirdNet-Pi terminal:-

 sudo netstat -tulpn

Also, key names were wrong, so I completely replaced the contents of the mediamtx.yml config file with this:-

# /etc/mediamtx/mediamtx.yml - minimal for v1.14
#rtspPort: 8554
#rtmpPort: 1935

# Use secure protocol variants (RTSPS, TLS, SRTP).
# Available values are "no", "strict", "optional".
rtspEncryption: "no"
# Address of the TCP/RTSP listener. This is needed only when encryption is "no" or "optional".
#rtspAddress: :8554
rtspAddress: 0.0.0.0:8554

# Enable publishing and reading streams with the RTMP protocol.
rtmp: yes
# Address of the RTMP listener. This is needed only when encryption is "no" or "optional".
rtmpAddress: :1935

# Enable reading streams with the HLS protocol.
hls: yes
# Address of the HLS listener.
hlsAddress: :8989

# Address of the UDP/RTP listener. This is needed only when "udp" is in rtspTransports.
rtpAddress: :9000
# Address of the UDP/RTCP listener. This is needed only when "udp" is in rtspTransports.
rtcpAddress: :9001

paths:
  mic:
    publishUser: "" #no user name required
    publishPass: "" #no password required



Now use ffmpeg to create the audio stream on BirdNet-Pi terminal:-

ffmpeg -f pulse -i alsa_input.usb-0d8c_USB_PnP_Sound_Device-00.mono-fallback -ac 1 -ar 44100 -c:a aac -b:a 64k -f rtsp rtsp://127.0.0.1:8554/mic

Then in another terminal on my Linux laptop, play the audio:-

ffplay -rtsp_transport tcp -buffer_size 131072 rtsp://192.168.1.149:8554/mic

 This seems to work well, without any noticeable buffering problems.

 

as a service

MediamTX, create a file:-

sudo nano /etc/systemd/system/mediamtx.service

Add contents:-

[Unit]
Description=MediaMTX RTSP Server
After=network.target

[Service]
ExecStart=/usr/local/bin/mediamtx /etc/mediamtx/mediamtx.yml
Restart=always
User=steve
WorkingDirectory=/home/steve

[Install]
WantedBy=multi-user.target

Run service commands:-

sudo systemctl daemon-reload

sudo systemctl enable mediamtx.service

sudo systemctl start mediamtx.service

sudo systemctl status mediamtx.service

Check if service will auto start on boot:-

sudo systemctl is-enabled mediamtx.service

 

Birdnet Stream, create a file:-

sudo nano /etc/systemd/system/birdnet-stream.service

Add contents:-

 [Unit]
Description=BirdNET Audio Stream
After=sound.target pulseaudio.service
Wants=pulseaudio.service

[Service]
ExecStartPre=/bin/sleep 5
Environment="PULSE_SERVER=unix:/run/user/1000/pulse/native"
User=steve
ExecStart=/usr/bin/ffmpeg \
  -f pulse -i alsa_input.usb-0d8c_USB_PnP_Sound_Device-00.mono-fallback \
  -ac 1 -ar 44100 -c:a aac \
  -bufsize 2M -max_delay 500000 \
  -f rtsp rtsp://127.0.0.1:8554/mic
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target


Run service commands:-

sudo systemctl daemon-reload

sudo systemctl enable birdnet-stream.service

sudo systemctl start birdnet-stream.service

sudo systemctl status birdnet-stream.service

Check if service will auto start on boot:-

sudo systemctl is-enabled birdnet-stream.service

 

That's it. Its a goer!


to do!

Now that I have a working audio stream, the next step (when time permits) is to setup a second RaspberryPi for my comparison BirdNet system.


BirdNet-Pi

 

BirdNet-Go



No comments:

Post a Comment