Busabase
Busabase는 AI 에이전트를 위한 오픈소스(MIT) 데이터베이스 및 작업 공간입니다
A Rewrite of BirdNetPi in Rust with DuckDB-Behavioral Powered Analytics
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗[!IMPORTANT] BirdNet-Behavior is licensed CC BY-NC-SA 4.0 — the same terms as the upstream BirdNET model and BirdNET-Pi. You may not use this project to build a commercial product. See LICENSE for details.
[!NOTE] This README describes the development tree (
main), not a release. The install commands below fetch the latest release —v0.17.1on 2026-10-20 — and the container image taggedlatestis that release's. Anything this README describes that is newer thanv0.17.1is marked (unreleased); the main one is the default classifier:v0.17.1installs the BirdNET+ V3.0 preview for everyone and has no--classifierflag. Links to the manual are to the files in this tree, so they match the commit you are reading. The manual for the release you installed is at the site root; the one for this tree is under/dev/; releases fromv0.17.1on also have a/vX.Y.Z/manual (how the manual is versioned).
A rewrite of BirdNET-Pi in Rust, derived from it and licensed accordingly. It listens to a USB microphone or RTSP stream, identifies birds in real time with a BirdNET neural network — BirdNET V2.4, the network BirdNET-Pi runs, by default (unreleased: v0.17.1 installs the BirdNET+ V3.0 preview, which remains an option) — and serves a fast, responsive web dashboard you open in any browser.
It ships as one self-contained binary — about 100 MB (the stripped binaries in the v0.17.1 release archives are 107 488 608 bytes on x86_64 and 99 158 736 on aarch64; the archives you download are 45.2 and 43.0 MB). The ONNX Runtime inference engine and the DuckDB analytics engine are compiled in — there is no Python, no pip, no virtualenv, and nothing else to install. The binary links against the host's system C library, so it targets modern 64-bit Linux (glibc ≥ 2.39 — Raspberry Pi OS Trixie, Debian 13, Ubuntu 24.04); a Docker image carries its own runtime for everything older. Upgrading is replacing one file.
It is a rewrite, and it is derived from BirdNET-Pi (the repository's LICENSE says so), which is why it carries the same licence. See Credits & Attribution.
| BirdNET-Pi (Python) | BirdNet-Behavior (Rust) | |
|---|---|---|
| Runtime | CPython interpreter + virtualenv | One native binary — no interpreter |
| Install | pip into a venv + system packages | one file, or one curl installer |
| Upgrade | re-resolve pip dependencies | replace one file |
| Inference | TensorFlow Lite (Python) | ONNX Runtime, linked in-process |
| Detection model | BirdNET V2.4 | BirdNET V2.4 by default for a new install, with BirdNET-Pi's defaults, measured against BirdNET-Pi; BirdNET+ V3.0 preview with --classifier birdnet-v3 (unreleased; v0.17.1 installs V3.0 for everyone) |
| Analytics | — | DuckDB behavioral engine, built in |
| HTTPS | reverse proxy (Caddy/nginx) | built in — --tls-mode self-signed or your own certificate |
| Offsite backups | copy them yourself | built in — encrypted on the station, to S3-compatible or SFTP |
| Sound levels | — | ISO 266 third-octave spectrum, IEC 61672 A-weighted |
| Per-source audio filtering | two fixed toggles | a parametric chain, with the response curve drawn as you type |
Behind a path (/birdnet) | own subdomain or port | BIRDNET_BASE_PATH |
| Each release ships | — | signed SLSA provenance + CycloneDX SBOM |
Every BirdNET build is dominated by the model itself — its weights cost the same memory whichever runtime loads them. What Rust removes is the overhead around the model: no interpreter to warm up, no virtualenv, no GIL serializing the request path. Audio capture and the detection loop run on a dedicated thread; the web server answers requests concurrently on a single Tokio runtime. It runs comfortably on a 2 GB Raspberry Pi.
Every screen leads with a plain-English headline, then layers the dense numbers beneath — designed to serve a casual hobbyist and a PhD ornithologist at once. Light + dark themes, fully responsive.
The same design system, with all six homes on a bottom tab-bar — iPhone 13 captures.
➡️ See every screen in the Field Guide — every PNG above has a matching docs/book/images/mobile/ capture for the same data and chrome at iPhone 13 width.
Both ways below are one command; choose by host. On a Raspberry Pi (OS Trixie) or modern x86_64 Linux, install the native binary: nothing else needs setting up. It downloads and sha256-verifies the binary, installs the classifier (see below), auto-detects your USB mic, asks for your location, and starts a hardened systemd service:
curl --proto '=https' --tlsv1.2 -fsSL https://github.com/tomtom215/BirdNet-Behavior/releases/latest/download/install.sh | sudo bash
Run it exactly as shown — pipe into
sudo bash, notsudo bash <(curl …)(the process-substitution form breaks undersudo). On a fresh 64-bit Raspberry Pi OS Trixie image the prebuilt binary runs as-is (glibc 2.39); the installer refuses early, with guidance, on anything older.
Prefer Docker? Use it if you're on older Pi OS (Bookworm, glibc 2.36) — the native binary won't run there — or you just want a container; it bundles its own runtime, so the host OS version doesn't matter. Raspberry Pi OS doesn't ship Docker, so install Docker Engine first (curl -fsSL https://get.docker.com | sudo sh), then run the one-liner below. It auto-detects your USB mic, asks for your location, writes a minimal .env, and starts the container. (The script and the compose files are fetched from main, but the image they pull is the latest release's, so until the next release a new container runs what v0.17.1 runs.)
bash <(curl -fsSL https://raw.githubusercontent.com/tomtom215/BirdNet-Behavior/main/quickstart.sh)
macOS (Apple Silicon) — the same installer detects macOS and sets up a per-user launchd LaunchAgent instead of systemd (no sudo):
curl --proto '=https' --tlsv1.2 -fsSL https://github.com/tomtom215/BirdNet-Behavior/releases/latest/download/install.sh | bash
On macOS it installs the
aarch64-apple-darwinbuild that the release workflow publishes for each version (v0.17.1has one); if that asset is missing for the version it resolved, it offers tobrew installthe dependencies and prints the one-time source-build steps. A Homebrew formula is planned. macOS is a preview: the macOS paths are not yet confirmed on hardware. (See docs/book/field/macos.md.)
Which model. (Unreleased: v0.17.1 installs the V3.0 preview, 541 MB, from this project's GitHub release with a Zenodo fallback, and has no choice.) A new install runs BirdNET V2.4 and its v2 range filter (about 85 MB), installed by the binary itself (birdnet-behavior --install-model birdnet-v24, then birdnet-v24-range-v2) and checked against SHA-256 values compiled into it. Those files come from Hugging Face and raw.githubusercontent.com, not from this project's releases, so a default install needs those two hosts as well as GitHub; it is offline-capable afterwards. The BirdNET+ V3.0 preview is a choice, --classifier birdnet-v3 (or BIRDNET_CLASSIFIER=birdnet-v3, also read by the container and by quickstart.sh); an existing station keeps the model its configuration names, and a Docker volume that holds the V3.0 model keeps it. Installation has the rules and the origins. When it's ready, open http://localhost:8502 — or, from another device on your LAN, http://<hostname>.local:8502 (or http://<pi-ip>:8502 by IP; the installer prints both, and the dashboard binds to all interfaces by default). Viewing is open; anything that changes something — the /admin panel, and deleting, relabelling, reviewing or locking a detection — needs a login. The bare-metal installer auto-generates that admin password (sign in as admin) and prints it once in its summary — save it. To restrict the dashboard to the machine itself, set BIRDNET_LISTEN=127.0.0.1:8502.
Uninstall (uninstall.sh ships inside the release tarball and as a standalone release asset). It removes only the software by default — your database, recordings, and settings are kept unless you opt in:
sudo ./uninstall.sh # remove the service + binary, KEEP all data
sudo ./uninstall.sh --dry-run # preview exactly what would change
sudo ./uninstall.sh --purge # remove everything, including data + model
📖 Full instructions: Installation · Docker guide · Configuration
| Platform | Status | Notes |
|---|---|---|
| Raspberry Pi 5 / 4B / 400 (64-bit) | ✅ Recommended | 64-bit Raspberry Pi OS Trixie |
| x86_64 Linux | ✅ Supported | glibc ≥ 2.39 (Debian 13 / Ubuntu 24.04+) |
| Pi OS Bookworm (glibc 2.36) | ⚠️ Docker only | Native binary needs glibc ≥ 2.39 — use Docker (bundles its own runtime) or upgrade to Trixie |
| macOS, Apple silicon | ⚠️ Preview | A release binary is built (aarch64-apple-darwin); the macOS paths are not yet confirmed on hardware. macOS guide |
| Pi 3 / Zero 2 W on 32-bit OS (armv7) | ❌ | No prebuilt ONNX Runtime — reflash with 64-bit Pi OS |
| Pi 3B+ / Zero 2 W on 64-bit OS | ❌ Not a supported target | STABILITY.md lists the Pi 4, 5 and 400; no test on these boards is recorded, and they have 1 GB and 512 MB of RAM |
Runtime requirement: glibc ≥ 2.39 (Pi OS Trixie / Debian 13 / Ubuntu 24.04). The prebuilt binaries are built on Ubuntu 24.04 to match pyke's ONNX Runtime baseline; install.sh refuses to install on an older glibc and points you to Docker. Every prebuilt binary and the Docker image ship the DuckDB behavioral-analytics engine built in and on by default — the installer and Docker compose set the analytics database path automatically (a manual binary run defaults to <database>.duckdb beside the SQLite file, and --analytics-db overrides that path; build with --no-default-features to omit the engine).
BirdNET-Pi's core — real-time detection from a USB mic or RTSP stream, with BirdNET V2.4 (or the BirdNET+ V3.0 preview), a SQLite detection database, per-species pages, Apprise notifications (Telegram, Slack, Discord, and dozens more), BirdWeather uploads, email alerts, CSV/JSON/eBird export, web-based admin, database backup/restore, and a password-protected admin panel (a session-cookie login at /login; viewing stays open) — plus the multi-source capture (USB + PipeWire + many RTSP at once), per-stream supervision, and offline-resilient uploads covered in Built for the field below. It does not do everything BirdNET-Pi does or does the same in every respect: the interface text is English only (species names come in 35 languages), there is no Reboot or Shutdown button, no scheduled self-update and no switch to skip the sign-in on the LAN, and several defaults and rules differ. What is and is not the same is measured; the feature gap analysis (Part 10) lists what is open.
New in BirdNet-Behavior:
--no-default-features to omit) — activity sessions, resident vs. migrant classification, dawn-chorus validation, species co-occurrence, migration phenology./r/<token>, HMAC-SHA256, 30-day expiry), and RSS/iCal feeds for rare and daily detections. Print stylesheet for the reports.--tls-mode self-signed generates a local CA and a certificate it signs (import the CA once; it lasts ten years while the leaf rotates itself a month early), or --tls-mode manual serves your own and re-reads it when certbot renews, with no restart and no deploy hook.--decrypt-backup restore path. The passphrase never leaves; there is no setting to send a backup in the clear./search filters every detection you have ever recorded by species, date, hour, confidence, source and review verdict, with bulk confirm/reject/delete for signed-in admins. Every filter is in the URL, so a useful search is a bookmark.➡️ Tour them all in the Field Guide. New settings for these features — the environment variables BNB_SHARE_SECRET, BNB_BASE_URL, BNB_STATION_LAT/BNB_STATION_LON and BIRDNET_BASE_PATH, and the config-file keys IMAGE_PROVIDER/FLICKR_API_KEY (read from birdnet.conf, not from the environment; also settings in the browser) — are documented in .env.example and the configuration reference.
A station is only useful if it keeps running when nobody is watching, and the data is only useful if you can trust it. Both the casual hobbyist who checks the dashboard over coffee and the researcher whose dataset underpins a conservation case get the same guarantees:
birdnet_detection_silence_seconds Prometheus gauge, on /api/v2/health, and as a plain-English "Last Detection" row on the System page. The same --doctor report is served at /admin/doctor behind the admin login — with the JSON at /admin/doctor.json and the redacted --support-bundle archive as a download — so a station can be diagnosed from a browser without a shell.BIRDWEATHER_URL) instead of the public community map — for rare or endangered species where a public observation map is a poaching risk — and the offline queue and ordered replay come with it.OFFSITE_BACKUP puts an encrypted copy of each weekly snapshot somewhere that is not the card, which is the only one of those failures the others cannot survive. With no RTC, capture fails open until NTP syncs so a bogus boot-time clock never silences the station. systemd watchdog supervision (WatchdogSec=120) restarts a hung process, and with exponential backoff (10 s stretching to 5 minutes, ) keeps retrying a crashing one for ever rather than marking the unit failed after a burst — so a cause that clears by itself (a late-mounting data disk, a port still held by the previous process) recovers unattended, and a permanently broken install retries quietly every five minutes instead of staying down until someone walks to it.📖 The complete playbook — hardware, power, storage, monitoring, recovery — is the Field Deployment Runbook in the operator manual.
The project is built to be read as well as run:
unsafe code is forbidden across the entire workspace (unsafe_code = "forbid" — not merely denied, so a stray #[allow] can't reintroduce it). Public API is documented under missing_docs.pedantic + nursery + cargo, and CI fails on any warning (-D warnings). rustfmt is checked, not just suggested.anyhow/thiserror reaching for a Box<dyn Error>.birdnet-core, birdnet-db) are deliberately synchronous and own no async runtime. The application layer owns the single Tokio runtime and pushes blocking work — inference, SQLite, DuckDB, file I/O — onto spawn_blocking. The detection loop hands finished detections to the async layer over a bounded channel, and every network integration is dispatched off that path, so a slow consumer or a dead uplink applies backpressure or queues instead of stalling detection or leaking memory.grep -rhE '^\s*#\[(tokio::)?test\]\s*$' --include='*.rs' src crates tests | wc -l prints 5791 at the commit this was written; property-based and parameterised tests run more cases than that): unit, integration, property-based (proptest), a soak test asserting bounded memory / file-descriptor / database growth, end-to-end tests that boot the real compiled binary as a subprocess (clean startup and shutdown, store-and-forward replay against a stub upload server), and cargo-fuzz harnesses for the untrusted-input parsers (audio decode, label parsing). Test policy bans fixed-sleep synchronization — readiness is signalled or polled.CI config job reads every workflow to keep it so); dtolnay/rust-toolchain names its Rust in an explicit toolchain: input — stable, or the MSRV in the MSRV job, where a step fails the job if the input drifts from Cargo.toml's rust-version and another proves the compiler that ran is that version; gates advisories, licenses, and sources. Every release publishes cross-compiled binaries (aarch64 + x86_64) carrying a signed attestation and a ; the model is fetched from a single origin, sha256-verified, and the install runs fully offline afterward.A single binary built from eight Rust workspace crates:
| Crate | Responsibility |
|---|---|
birdnet-core | Audio capture, decode, resample, mel spectrogram, ONNX inference, the detection pipeline, live spectrogram |
birdnet-db | SQLite (OLTP) + DuckDB (OLAP), migrations, resilience |
birdnet-web | axum web server, REST API, WebSocket, HTMX templates, audio player, admin |
birdnet-integrations | BirdWeather, Apprise, MQTT (Home Assistant discovery), Wikipedia images, email, heartbeat, weekly reports, auto-update |
birdnet-behavioral | DuckDB behavioral analytics (sessionization, retention, funnel, sequence matching) |
birdnet-timeseries | Time-series analytics (activity, diversity, trend, peak, gap, sessions) |
birdnet-migrate | BirdNET-Pi migration: schema detection, validation, import |
birdnet-scheduler | Solar calculations, recording-window scheduling |
📖 Architecture overview · full design docs in docs/architecture/.
Safe, non-destructive import — BirdNET-Pi's files are never modified, and nothing is written until you have seen what it would do and confirmed. Stop BirdNET-Pi, open Settings → Data (/station/data#import; /admin/migrate redirects there) and move across: your detection history (BirdDB.txt; duplicate rows are skipped, so re-running is safe), and, (unreleased: v0.17.1 imports the history only), your settings (birdnet.conf) and the recordings that go with it, each a step of its own with a command-line twin.
Prerequisites: Rust 1.99+ and git. The first build also compiles the bundled DuckDB (a few minutes of C++), so cmake and a C++ compiler must be on PATH.
git clone https://github.com/tomtom215/BirdNet-Behavior.git
cd BirdNet-Behavior
cargo build --release # optimized build — analytics on by default
cargo build --release --no-default-features # slim build, without the DuckDB analytics engine
cross build --release --target aarch64-unknown-linux-gnu # cross-compile for a Pi
cargo test --workspace --all-features # run tests
cargo clippy --workspace --all-targets --all-features -- -D warnings # lint (pedantic + nursery)
crates.io. Nothing has been published there as of 2026-10-20 (RELEASING.md says what is ready and what the maintainer decides first), so cargo install birdnet-behavior finds nothing today. Once it is published, the form to use is cargo install birdnet-behavior --locked: the inference engine (ort) is required as a release candidate, and without --locked an install resolves to whichever candidate is newest that day, not the one this project has run. It needs the same toolchain as a source build (cmake, a C++ compiler, a few minutes for DuckDB) and network access for the ONNX Runtime download. What it does not give you is what the release archives add: the in-app /help manual (a build from a package does not render it; the manual is online and BNB_HELP_DIR can point at a rendered copy such as an archive's help/) and the two DuckDB extensions embedded in the binary, which a cargo install build instead fetches on first use (icu and behavioral, into ~/.duckdb, so it needs the network once and a writable home directory; set BIRDNET_BUNDLED_EXTENSION_FILE and BIRDNET_BUNDLED_ICU_FILE at build time to embed them). Prefer the installer or the container for a station.
First step for any problem — run the built-in diagnostic, which prints a one-screen report (CPU, config, audio reachability, model, database, disk, network) with a concrete fix for each issue:
# Bare metal: the service runs as the account that ran the installer (there is no
# "birdnet" user); this prints that account and runs the doctor as it
sudo -u "$(systemctl show -p User --value birdnet-behavior)" birdnet-behavior --doctor
# Docker
docker compose exec birdnet birdnet-behavior --doctor
📖 Troubleshooting guide (the one guide; TROUBLESHOOTING.md only points to it).
The complete, navigable documentation lives in the manual, built with mdBook from the Markdown in docs/book/: installation, a screen-by-screen field guide, configuration, administration, migration, an FAQ, and troubleshooting. It is published at tomtom215.github.io/BirdNet-Behavior — the site root is the manual of the latest release, /vX.Y.Z/ holds the manual of each release from v0.17.1 on, and /dev/ is the manual of main (it describes unreleased changes). A push to main that touches docs/book/** rebuilds /dev/; the root and the /vX.Y.Z/ copies change when a release tag is pushed (RELEASING.md has the detail). The same rendered manual ships inside each release archive and is served offline at /help by the binary that contains it. Nothing marks an individual page "since 0.x": docs/README.md says how to find the manual that matches your version, and what else is in docs/.
tools/plate-index/Licensed under CC BY-NC-SA 4.0, matching the upstream BirdNET and BirdNET-Pi projects. See LICENSE and LICENSE-UPSTREAM for full terms.
The binary also contains other people's work — Rust packages, DuckDB, ONNX Runtime, fonts, htmx — under their own licences. NOTICE says what and under which terms, THIRD_PARTY_LICENSES.txt reproduces the texts, and both ship in every release archive and container image.
| Repository | Description |
|---|---|
| duckdb-behavioral | ClickHouse-inspired behavioral analytics for DuckDB |
| quack-rs | SDK for building DuckDB extensions in Rust |
| mallardmetrics | Single-binary web analytics (axum + DuckDB) |
| LyreBirdAudio | RTSP audio streaming |
highpass:120; notch:50:20) rendered identically for a local microphone and an RTSP camera, with the response curve drawn live as you type it. Mains hum needs a notch, and no high-pass can give you one.--install-model fetches a classifier against a sha256 compiled into the binary. How it works.BIRDNET_BASE_PATH=/birdnet for the one-hostname-many-services setup, and for Home Assistant ingress.PRIVACY_RANK; 0 turns it off). A station upgraded from v0.17.1 that never set it gets the rule too, so some detections near speech will no longer be stored. Details.FULL_DISK=keep; independent notification triggers.--doctor diagnostic (also served at /admin/doctor), Prometheus metrics, kiosk mode, a live spectrogram, and a first-run onboarding wizard.Restart=alwaysStartLimitIntervalSec=0cargo-denyCITATION.cff for academic citation, GOVERNANCE.md for the decision model, and a CHANGELOG.md kept in Keep-a-Changelog form.