diff --git a/birdnet-pi-zach/CHANGELOG.md b/birdnet-pi-zach/CHANGELOG.md index 8cfe01fbdc..ec6ba31a4e 100644 --- a/birdnet-pi-zach/CHANGELOG.md +++ b/birdnet-pi-zach/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2026.08.15 (15-08-2026) + +- Fix: `ALSA_CARD` now really selects the microphone. Its value was copied as-is into `REC_CARD`, but BirdNET-Pi hands `REC_CARD` to `arecord -D` / `ffmpeg -f alsa -i`, which expect an ALSA PCM name: a card index such as `1` gave `Unknown PCM 1` and no recording at all. It is now converted to `plughw:CARD=,DEV=0`, while a value that already is a PCM name (`dsnoop:CARD=Audio,DEV=0`, `default`, `null`, `pulse`, `pipewire`, ...) is used as provided +- Fix: setting `ALSA_CARD` no longer replaces the `~/BirdNET-Pi/birdnet.conf` symlink with a detached copy of `/config/birdnet.conf` (now only `/config/birdnet.conf`, which the symlink points to, is updated) + ## 2026.07.10-2 (10-07-2026) - Minor bugs fixed ## 2026.07.10 (10-07-2026) diff --git a/birdnet-pi-zach/README_standalone.md b/birdnet-pi-zach/README_standalone.md index 78ab7aeb8d..e33387bc40 100644 --- a/birdnet-pi-zach/README_standalone.md +++ b/birdnet-pi-zach/README_standalone.md @@ -101,6 +101,17 @@ Ensure you have the following installed on your system: If rtsp feed doesn't work, perhaps you need to add "-rtsp-transport tcp" to your ffmpeg instruction, or allow udp on your network +### Selecting the microphone + +By default the container records through PulseAudio (`REC_CARD=default` in `birdnet.conf`). To record directly from a USB microphone instead, find it on the host with `arecord -l`, then pass its card number (or its card id) as `ALSA_CARD`: + +```yaml + environment: + - ALSA_CARD=1 # "card 1: Audio [KT USB Audio]" in the output of "arecord -l" +``` + +At startup this writes `REC_CARD=plughw:CARD=1,DEV=0` into your `birdnet.conf`. A value that already is a full ALSA PCM name, as listed by `arecord -L`, is used as provided - for example `ALSA_CARD=dsnoop:CARD=Audio,DEV=0`, which allows the recording and the livestream services to read the same microphone at the same time. + ## Updating to the Latest Version To check for new versions of the container and update: diff --git a/birdnet-pi-zach/config.yaml b/birdnet-pi-zach/config.yaml index 401f3cf952..e87b2add01 100644 --- a/birdnet-pi-zach/config.yaml +++ b/birdnet-pi-zach/config.yaml @@ -116,5 +116,5 @@ tmpfs: true udev: true url: https://github.com/alexbelgium/hassio-addons/tree/master/birdnet-pi-zach usb: true -version: 2026.07.10.2 +version: 2026.08.15 video: true diff --git a/birdnet-pi-zach/rootfs/etc/cont-init.d/99-run.sh b/birdnet-pi-zach/rootfs/etc/cont-init.d/99-run.sh index 85c69008c8..a65e279b97 100755 --- a/birdnet-pi-zach/rootfs/etc/cont-init.d/99-run.sh +++ b/birdnet-pi-zach/rootfs/etc/cont-init.d/99-run.sh @@ -66,12 +66,26 @@ fi || true # Use ALSA CARD defined in add-on options if available if [ -n "${ALSA_CARD:-}" ]; then - bashio::log.warning "ALSA_CARD is defined, the birdnet.conf is adapt to use device $ALSA_CARD" - for file in "$HOME"/BirdNET-Pi/birdnet.conf /config/birdnet.conf; do - if [ -f "$file" ]; then - sed -i "/^REC_CARD/c\REC_CARD=$ALSA_CARD" "$file" - fi - done + # REC_CARD is passed as-is to "arecord -D" (scripts/birdnet_recording.sh) and to + # "ffmpeg -f alsa -i" (scripts/livestream.sh), so it must be an ALSA PCM name. + # ALSA_CARD holds a card index (1) or a card id (Audio), which are not PCM names: + # writing them as-is gives "Unknown PCM 1" and no recording at all. Build a PCM + # name from them, unless the value already is one of ALSA's own PCM names + # (checked against "arecord -L", e.g. default, null, pulse, sysdefault, front...). + if [[ "$ALSA_CARD" == *:* ]] || arecord -L 2> /dev/null | grep -qx "$ALSA_CARD"; then + REC_CARD="$ALSA_CARD" + else + REC_CARD="plughw:CARD=${ALSA_CARD},DEV=0" + fi + bashio::log.warning "ALSA_CARD is defined, the birdnet.conf is adapted to use device $REC_CARD" + # --follow-symlinks : $HOME/BirdNET-Pi/birdnet.conf is a symlink to /config/birdnet.conf + # (01-structure.sh), and sed -i would replace it with a regular file, detaching it from + # the file the WebUI writes to. Only /config/birdnet.conf is updated directly, since the + # home-path symlink is writable by the pi/caddy user and could be repointed before this + # root-run script gets to it. + if [ -f /config/birdnet.conf ]; then + sed -i --follow-symlinks "/^REC_CARD/c\REC_CARD=$REC_CARD" /config/birdnet.conf + fi fi # Define permissions for audio diff --git a/birdnet-pi/CHANGELOG.md b/birdnet-pi/CHANGELOG.md index 0e7a0db2ff..81bfb9ca5c 100644 --- a/birdnet-pi/CHANGELOG.md +++ b/birdnet-pi/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2026.08.15 (15-08-2026) + +- Fix: `ALSA_CARD` now really selects the microphone. Its value was copied as-is into `REC_CARD`, but BirdNET-Pi hands `REC_CARD` to `arecord -D` / `ffmpeg -f alsa -i`, which expect an ALSA PCM name: a card index such as `1` gave `Unknown PCM 1` and no recording at all. It is now converted to `plughw:CARD=,DEV=0`, while a value that already is a PCM name (`dsnoop:CARD=Audio,DEV=0`, `default`, `null`, `pulse`, `pipewire`, ...) is used as provided +- Fix: setting `ALSA_CARD` no longer replaces the `~/BirdNET-Pi/birdnet.conf` symlink with a detached copy of `/config/birdnet.conf` (now only `/config/birdnet.conf`, which the symlink points to, is updated) ## 2026.08.02 (02-08-2026) - Fix: ingress returned "502 Bad Gateway" because Caddy never listened on :8082. `91-nginx_ingress.sh` hooked the ingress site into `update_caddyfile.sh` with a sed anchored on `sudo caddy fmt --overwrite`, but 2026.07.10-1 strips `sudo` from every BirdNET-Pi script at build time, so the anchor stopped matching. `update_caddyfile.sh` then rewrote the Caddyfile from scratch just before Caddy started, dropping the ingress site - Fix: `caddy_ingress.sh` no longer appends a second `:8082` block when it runs twice (a duplicate site address makes Caddy refuse to start) diff --git a/birdnet-pi/README_standalone.md b/birdnet-pi/README_standalone.md index 70df465de1..485129d0c7 100644 --- a/birdnet-pi/README_standalone.md +++ b/birdnet-pi/README_standalone.md @@ -101,6 +101,17 @@ Ensure you have the following installed on your system: If rtsp feed doesn't work, perhaps you need to add "-rtsp-transport tcp" to your ffmpeg instruction, or allow udp on your network +### Selecting the microphone + +By default the container records through PulseAudio (`REC_CARD=default` in `birdnet.conf`). To record directly from a USB microphone instead, find it on the host with `arecord -l`, then pass its card number (or its card id) as `ALSA_CARD`: + +```yaml + environment: + - ALSA_CARD=1 # "card 1: Audio [KT USB Audio]" in the output of "arecord -l" +``` + +At startup this writes `REC_CARD=plughw:CARD=1,DEV=0` into your `birdnet.conf`. A value that already is a full ALSA PCM name, as listed by `arecord -L`, is used as provided - for example `ALSA_CARD=dsnoop:CARD=Audio,DEV=0`, which allows the recording and the livestream services to read the same microphone at the same time. + ## Updating to the Latest Version To check for new versions of the container and update: diff --git a/birdnet-pi/config.yaml b/birdnet-pi/config.yaml index c384100e7a..6c97aa543c 100644 --- a/birdnet-pi/config.yaml +++ b/birdnet-pi/config.yaml @@ -116,5 +116,5 @@ tmpfs: true udev: true url: https://github.com/alexbelgium/hassio-addons/tree/master/birdnet-pi usb: true -version: 2026.08.02 +version: 2026.08.15 video: true diff --git a/birdnet-pi/rootfs/etc/cont-init.d/99-run.sh b/birdnet-pi/rootfs/etc/cont-init.d/99-run.sh index 85c69008c8..a65e279b97 100755 --- a/birdnet-pi/rootfs/etc/cont-init.d/99-run.sh +++ b/birdnet-pi/rootfs/etc/cont-init.d/99-run.sh @@ -66,12 +66,26 @@ fi || true # Use ALSA CARD defined in add-on options if available if [ -n "${ALSA_CARD:-}" ]; then - bashio::log.warning "ALSA_CARD is defined, the birdnet.conf is adapt to use device $ALSA_CARD" - for file in "$HOME"/BirdNET-Pi/birdnet.conf /config/birdnet.conf; do - if [ -f "$file" ]; then - sed -i "/^REC_CARD/c\REC_CARD=$ALSA_CARD" "$file" - fi - done + # REC_CARD is passed as-is to "arecord -D" (scripts/birdnet_recording.sh) and to + # "ffmpeg -f alsa -i" (scripts/livestream.sh), so it must be an ALSA PCM name. + # ALSA_CARD holds a card index (1) or a card id (Audio), which are not PCM names: + # writing them as-is gives "Unknown PCM 1" and no recording at all. Build a PCM + # name from them, unless the value already is one of ALSA's own PCM names + # (checked against "arecord -L", e.g. default, null, pulse, sysdefault, front...). + if [[ "$ALSA_CARD" == *:* ]] || arecord -L 2> /dev/null | grep -qx "$ALSA_CARD"; then + REC_CARD="$ALSA_CARD" + else + REC_CARD="plughw:CARD=${ALSA_CARD},DEV=0" + fi + bashio::log.warning "ALSA_CARD is defined, the birdnet.conf is adapted to use device $REC_CARD" + # --follow-symlinks : $HOME/BirdNET-Pi/birdnet.conf is a symlink to /config/birdnet.conf + # (01-structure.sh), and sed -i would replace it with a regular file, detaching it from + # the file the WebUI writes to. Only /config/birdnet.conf is updated directly, since the + # home-path symlink is writable by the pi/caddy user and could be repointed before this + # root-run script gets to it. + if [ -f /config/birdnet.conf ]; then + sed -i --follow-symlinks "/^REC_CARD/c\REC_CARD=$REC_CARD" /config/birdnet.conf + fi fi # Define permissions for audio