A BirdNET recorder for a Raspberry Pi Zero 2 W and a USB microphone. It listens continuously, identifies what it hears on the device, and reports upstream whenever it has a link — which in the field it often does not.
It is built for the boring failure modes: the wifi drops for a day, the power cuts without warning, nobody visits for a month, and the SD card has to survive all of it.
- Records and identifies locally. BirdNET runs on the unit via
tflite-runtime, roughly 1 s of inference per 3 s chunk on a Zero 2 W. No network is needed to detect anything. - Keeps a 3-second pre-roll. A call that straddles a chunk boundary would otherwise be clipped at the start, so a saved clip is the 3 s before the detection plus the 3 s BirdNET fired on.
- Survives being offline. Detections go to local SQLite and clips to the card. Both reporting targets advance a high-water mark only on a successful send, so nothing is lost by being unreachable for days; the backlog drains when the link returns.
- Reports to BirdNET-Cloud, and optionally to your own birdbrain. Either,
both, or neither. The wire format to your own server is versioned
(
src/birdbrain/wire.py). - Serves its own pages on the LAN. Now / Today / Setup on port 8080, with playable audio, no internet needed and no CDN.
Everything here is shaped by three numbers: 415 MB of usable RAM, an SD card that dislikes small frequent writes, and a link that may be absent.
- Audio is never written to disk except for a detection. Capture is entirely in memory; the pre-roll buffer is one chunk.
- No spectrograms. They cost a per-request
ffmpegfork and a card write to produce an image the server can regenerate from the clip. - Measured, not assumed: dropping
librosafrom the quality metric saved 118 MB, and the write budget went from 66 MB/h to ~30 MB/h by slowing a heartbeat, moving diagnostics to tmpfs, and settingcommit=600on the root mount.
On a freshly-flashed Raspberry Pi OS Lite (64-bit, Bookworm):
scp scripts/tbb-bootstrap.sh pi@bnc1.local:~/
ssh pi@bnc1.local
bash ~/tbb-bootstrap.sh bnc1 --lat <lat> --lon <lon> --usbThat installs dependencies, builds a Python 3.11 venv, resolves the microphone,
writes the unit's .env and enables the services. Then:
systemctl --user status tbb-pipeline tbb-web
curl -s localhost:8080/healthzand open http://bnc1.local:8080 on a phone.
- docs/install.md — the full walkthrough, from flashing the card to what to check when nothing appears.
- docs/birdnetcloud.md — registering the unit with BirdNET-Cloud, and what it does and does not send.
- docs/tbb-provisioning.md — hardware options and the reasoning, including the Codec Zero HAT.
Reporting is off until you turn it on. A unit records, identifies and serves its own pages with no internet at all.
| Path | What |
|---|---|
src/birdbrain/tbb.py |
the tbb-pipeline entrypoint |
src/birdbrain/tbb_capture.py |
the capture loop: mic → BirdNET → SQLite + clips |
src/birdbrain/birdnetcloud_sync.py |
the BirdNET-Cloud bridge |
src/birdbrain/tbb_sync.py |
the optional sync to your own birdbrain |
src/birdbrain/wire.py |
the versioned wire format, and what happens when versions disagree |
src/birdbrain/web/tbb_app.py |
the LAN pages |
scripts/ |
provisioning, self-update, and the network watchdog |
deploy/tbb/field-profile.env |
the low-bandwidth overlay for a metered site |
This project is a thin wrapper around other people's hard work. None of the identification is ours.
BirdNET — the model that does the actual work. Research by Stefan Kahl, Connor M. Wood, Maximilian Eibl and Holger Klinck, at the K. Lisa Yang Center for Conservation Bioacoustics, Cornell Lab of Ornithology and Chemnitz University of Technology. If you use this for anything you publish, cite their paper rather than this repository:
Kahl, S., Wood, C. M., Eibl, M., & Klinck, H. (2021). BirdNET: A deep learning solution for avian diversity monitoring. Ecological Informatics, 61, 101236.
BirdNET-Pi — Patrick McGuire built the thing that showed a Raspberry Pi listening to a garden around the clock, with a local web interface, was not only possible but genuinely delightful. This repository is a different implementation aimed at a smaller board and a worse network connection, but the idea is his, and anyone deciding what a unit like this should feel like should look at BirdNET-Pi first.
birdnetlib (Apache-2.0) by Joe Weiss — the Python interface to BirdNET this unit calls, and the source of the bundled model files.
The code in this repository is MIT (see LICENSE). The BirdNET model is
not: the BirdNET_GLOBAL_6K_V2.4 files shipped with birdnetlib are
CC BY-NC-SA 4.0 — non-commercial, share-alike. The MIT licence on this
code does not extend to them and cannot.
In practice: run it in your garden, at your school, for a conservation project, for a paper. If you want to sell something built on it, or run it as part of a commercial service, you need to talk to the Cornell Lab about model licensing — the permissive licence on this wrapper does not help you there.
Extracted from birdbrain, which does the
same job for many YouTube wildlife streams at once. The history of every file
here came with it. The Python package is still importable as birdbrain; that
rename is a separate change so this one stayed a faithful extraction.