github tphakala/birdnet-go 20261031
BirdNET-Go 20261031

3 hours ago

This release makes BirdNET-Go's audio handling fully native: clips are encoded, decoded and processed without FFmpeg, and spectrograms are rendered inside BirdNET-Go, so SoX is no longer needed, and a long list of daylight saving time fixes so that hours and days line up correctly on every date of the year. Settings are much harder to overwrite by accident, alert rules stop repeating themselves, and Privacy Guard gets several accuracy fixes. MySQL and MariaDB installs get a thorough hardening pass, including MySQL 9.7 LTS support, clearer startup errors and a safer legacy to enhanced database migration. Installs that still run the legacy database schema are now reminded to migrate.

Before you upgrade

  • Privacy Guard: set the threshold to 0.6. The default Privacy Guard Threshold is now 0.6 instead of 0.35, because 0.35 treated short bursts of loud bird calls as speech and discarded valid bird detections. Your saved value is not changed by the upgrade, so if you use Privacy Guard and still have 0.35, set Privacy Guard Threshold to 0.6 under Settings > Filters > Privacy Filtering to avoid these false discards. This reduces false discards but does not remove them, since a few very loud bird calls can still score above 0.6. Speech detection stays best effort, so quiet or distant speech may not be caught.
  • Native audio: some old clips cannot be processed. Download, denoise, normalize and audible bat playback work on clips BirdNET-Go itself wrote. Clips in other formats, such as raw .aac files from 2024, HE-AAC, Ogg Vorbis or stereo files, answer with an error instead of being processed. Playback is unchanged.
  • Native spectrograms: SoX is gone, and some clip formats get none. Spectrograms are drawn by BirdNET-Go itself for WAV, FLAC, MP3, M4A and Opus (.opus) clips. Clips in other formats, for example imported .aac or .ogg files or files with upper-case extensions, show no spectrogram. Playback is unchanged, and spectrogram images already on disk are still served.
  • Equalizer filters set to 0dB are now really off. A filter set to 0dB in the equalizer settings, including the default High Pass and Low Pass filters, was still being applied at 12 dB per octave even though the settings page said it was not filtering. If you turned the equalizer on and kept the default filters, it now stops filtering until you raise a filter above 0dB.
  • Sound level monitoring (octave bands). If you use sound level monitoring, the high bands now read higher because the octave bands are measured with a more accurate meter. At 48 kHz the 20 kHz band reads about 6.4 dB higher on broadband sound, 16 kHz about 3.3 dB, 12.5 kHz about 1.9 dB and 10 kHz about 1.2 dB, with smaller changes below. Expect a step in your charts and in any Prometheus or MQTT dashboards.

New Features

Fully Native Audio Encoding and Processing

BirdNET-Go no longer uses FFmpeg to encode or process audio clips. AAC, MP3 and Opus clip export is done by native Go encoders only, with no fallback to FFmpeg and no downgrade to WAV, and FFmpeg is not needed for clip export in any format. The on-demand features in the audio player (clip download, denoise, normalize, gain preview and audible bat playback) now run in pure Go too, and the settings pages no longer ask for FFmpeg for these. FFmpeg is still used to capture RTSP streams. The equalizer now uses the shared go-audio-dsp library, and it skips and logs a filter it cannot run safely, for example one at or above half the sample rate, or a notch whose width is at least twice its center frequency.

This is the result of long-term work that started with porting the FLAC, Opus, AAC and MP3 encoders and decoders to native Go and making them fast with vectorization. It means fewer programs to install, no process to start for every clip, and lower system resource use (#4571, #4572, #4581, #4583, #4587, #4588, #4590, #4604, #4733).

Native Spectrograms

With audio decoding now done inside BirdNET-Go (see above), spectrograms are rendered by BirdNET-Go itself, without the overhead of starting SoX, and in some cases both FFmpeg and SoX, for every image. SoX is no longer needed at all, so there is one less program to install. The result is lower system resource use, and a more responsive web UI because spectrograms appear faster. Bat spectrograms are drawn at the clip's own sample rate, so a 192 kHz clip shows 0 to 96 kHz and a 384 kHz AudioMoth clip shows 0 to 192 kHz. Bird clips recorded at 48 kHz are analysed at their own rate without resampling, long clips are decoded as a stream so they no longer need hundreds of megabytes of memory, and a clip that is still being written is never published as a short image. A clip the renderer cannot handle answers with a client error instead of a server error, and a clip that no longer exists is reported at once instead of after a 5 second wait (#4635, #4640, #4642, #4659, #4663, #4681, #4700, #4701, #4702, #4715).

Equalizer Editor Improvements

The response graph in the audio settings is now computed by the backend from the same filter chain the audio path builds, so what you see is what you hear. LowPass and HighPass filters now have an editable Q. Per-source equalizers can use frequencies up to 192 kHz for ultrasonic sources, and the graph sweeps the whole band for those sources. Saving a filter that cannot run on a source, for example a 60 kHz notch on a 48 kHz source, now tells you instead of confirming the save. Numeric fields commit when you leave the field or press Enter, with a notice when a value is adjusted, the graph axis grows to hold the real peak, and values you saved are no longer rewritten when settings load (#4632, #4636, #4638, #4641, #4643, #4644, #4647, #4823, #4829, #4831).

Legacy Database Migration Reminders

Installs that still run the legacy database schema now get a startup warning, a persistent bell notice, a banner on the dashboard and a weekly push reminder (for users with push notifications set up) to run the migration in System > Database. The legacy schema will stop working in a future release; no date or version is set. The Database page now also shows migration status and action errors instead of an empty area (#4792, #4801, #4804, #4805, #4808, #4809, #4811).

Stronger MySQL and MariaDB Support

BirdNET-Go now reports the MySQL or MariaDB server version and character set in the health check, the startup log and the bell, and tells you when the server is not one of the tested releases (MySQL 8.4 and 9.7 LTS, MariaDB 10.11, 11.4, 11.8 and 12.3). MySQL 9.7 LTS is now supported. The migration to the enhanced database refuses to start on an unsupported server or a schema whose character set cannot hold your text. The database size check reports the real schema size, a database that cannot be used at startup now names the setting to check without printing the user name and client address, and the detection rate chart is no longer shifted by the server time zone (#4919, #4926, #4928, #4938, #4939, #4942).

More New Features

  • Privacy filter activity record (backend only for now). The privacy filter now keeps a local hourly rollup and a list of discarded detections with the speech hits behind each discard, readable through two read-only API endpoints. It will show whether the filter matches anything and whether discards jump after a threshold change. There is nothing to see in the web UI yet; upcoming releases will show this data there (#4817, #4842, #4854).
  • Per-model detection details in the API (backend only for now). Detections now include which models contributed, with first and last hit times, and a new insights endpoint compares models over a date range. This is groundwork, and upcoming releases will bring this data to the web UI (#4800, #4803, #4810).
  • Warning for data on temporary container storage. Running in Docker or Podman without a volume for config, database, models or clips now raises a health warning, because that data is lost when the container is recreated (#4655).
  • Richer support dumps. Dumps now record the inference runtime and host environment, and a USB device and sound card inventory (#4668, #4672).
  • Trusted proxies in the web UI. The Security settings page has a new Reverse Proxy card where you list the reverse proxies BirdNET-Go should trust, or tick Trust Cloudflare. A connection check shows how the server sees your own request (direct, through a trusted proxy, or through a proxy that is not trusted) and offers to trust your proxy with one click. This matters if you use the subnet login bypass behind a reverse proxy. Allowed Subnets uses the same list editor (#4580).
  • Login for plain HTTP clients behind an HTTPS base URL. If your base URL is HTTPS but another container or device connects directly over plain HTTP, it could log in but every later request failed, because its session cookie was marked Secure. An advanced security option now lets you list the exact addresses of such clients. It is off by default and changes nothing unless you use it; see the configuration reference (#4546 by @ozenyunus35).
  • Error reports stop from old builds. Builds more than six months old no longer send error reports, because they describe bugs that are long fixed (#4683).

Security

  • System page deep links require login. Opening a System page such as Database or Terminal from a saved link while logged out now redirects to the login page like the settings pages do. The API already refused unauthenticated requests (#4739).
  • Support dumps redact more. Trusted proxy and plain HTTP client address lists are redacted, and USB microphone serial numbers and trailing coordinates are masked (#4658, #4678).
  • Error Tracking opt-out applies at once. Turning Error Tracking off in settings now stops server and browser reporting immediately, with no restart or page reload, and turning it on takes effect at startup and for notifications. Reporting also backs off while the Sentry host is unreachable, which stops a flood of DNS lookups on networks that block it (#4832, #4841, #4852, #4853, #4855).

Bug Fixes

Privacy Guard

  • Privacy Guard speech timing fixes. Speech detection is best effort and cannot catch all speech. This release fixes two cases where detected speech was not taken into account for a clip: speech in the pre-capture part of a clip, and speech heard by five second models such as BirdNET v3.0 and Perch v2 with overlap (#4620, #4610).
  • Fewer false discards of bird calls. A single human-sound label hit no longer counts as speech when the audio is scored many times, and only voiced human sounds count, not hands, chewing or group actions. This should reduce bird detections wrongly discarded as speech (#4629, #4637).
  • Pending speech hits are resolved when label confirmation is turned off (#4824).

Audio & Streaming

  • Gain and sound level MQTT changes apply live. A gain change on a sound card or stream applies immediately without interrupting live audio or needing a restart, and sound level data reaches MQTT as soon as MQTT is enabled (#4609).
  • Aged-out clip libraries are cleaned up. References to clips that retention already deleted are now cleared on libraries that had aged out, every rendered spectrogram of a deleted clip is removed when spectrograms are not kept, and the hourly check backs off to once a day while it finds nothing (#4598, #4602, #4603).
  • The clip name matches the file after an export format change. Detections that were pending when you switched, for example from AAC to FLAC, no longer point at a file that does not exist (#4654).
  • Apple M4 and M5 Macs no longer leak memory while analysing audio (#4630).
  • Audio playback recovers after a failed load. A dashboard card that appeared while its clip was still being written, and the detail page player, no longer stay dead until a reload, and dead clips cost far fewer requests (#4646, #4703, #4705, #4706, #4708).
  • Live audio on the dashboard. Playback errors are now shown, the live spectrogram keeps its auto-start preference when you leave the page, and starting live audio no longer sends a stray disconnect (#4736, #4737, #4738).
  • The installer stops stacking unused mounts. The systemd unit no longer mounts a tmpfs for the old HLS directory on every start, and leftovers are unmounted (#4652).
  • Disk statistics for NVMe, SD card, loop and macOS devices. Read, write and busy figures were empty for most devices that are not sdX (#4750).
  • Model unloading is safe during analysis. Unloading a model while it was analysing audio could crash (#4789).
  • FFmpeg version is found behind wrapper scripts. (#4778)

Alerts & Notifications

  • Alert cooldowns are per species. A Robin alert no longer silences a Blackbird alert for the length of the cooldown (#4676).
  • Built-in rules notify once per incident. Low disk space, High CPU usage and High memory usage no longer repeat on every cooldown, keep their escalation steps when you edit and save them, and no default rule is duplicated at startup, reset or import. Rules the editor had turned into custom rules are repaired (#4714, #4716, #4717, #4719, #4720, #4723, #4724).
  • Notification settings say what applies. With the alert rules engine active, the Channels tab shows a notice instead of detection filters that have no effect (#4679).
  • Push-only notifications no longer show up as bell entries that the notification list does not contain (#4802).

Integrations

  • MQTT and BirdWeather retries work. With the database enabled, the MQTT retry settings had no effect. MQTT now publishes as its own queued job, the first retry waits the configured initial delay instead of double, a retry uses the settings and client current at that moment, and a slow upload can no longer be sent twice by an overlapping retry. Default retry values now match across the config template, code and guide (#4742, #4745, #4746, #4747, #4752).
  • BirdWeather uploads carry the right time for the repeated hour when clocks go back (#4875).
  • The eBird "Expected today" feature works again. The request URL contained /v2 twice (#4563 by @timeobonnin-prog).
  • Detections survive a short database outage. The database save is retried while the database is unreachable, and live events are published only for detections that were stored (#4918, #4929).

Settings

  • Settings are no longer overwritten. A save used to undo changes the server made outside the form, such as a model install or uninstall from the gallery, and two saves at the same moment could drop one of them. Saves now start from the current server state, are applied one at a time, and are checked with an ETag so a stale copy is refused. A reverse proxy that rewrites the ETag, such as Apache with mod_deflate or Caddy with encode, no longer makes every save fail (#4775, #4777, #4781, #4782, #4793, #4767).
  • Clearer save feedback. The error banner can be dismissed, a failed save is announced once, identical toasts replace each other instead of stacking, and unsaved-change dots agree with the save toolbar, including on the Analysis page tabs (#4780, #4790, #4794, #4795, #4796, #4797, #4798).
  • Settings pages open correctly when logged out. Opening a settings page from a saved link while logged out showed a 404. It now shows the login form and returns you to the page afterwards. Resetting unsaved address list changes also clears stale error messages, and the unsaved-change dots on tabs are visible again (#4586).
  • Species names with a dot keep their settings. Species such as St. Helena Plover or Larus sp. lost their threshold, actions and interval when settings loaded, and logging module settings with a dot in the name were lost the same way (#4562 by @choksi2212, #4728, #4731).

Time Zones & Daylight Saving

  • Hours and days line up on DST change days. Hour drill-downs, hour and time-of-day search filters, daily counts, species per day, trends, heatmaps, the dawn chorus insight, gone-quiet day counts, the hourly distribution, species diversity and system event buckets now use each detection's own local time instead of one offset for the whole range. Stations with half-hour offsets, and zones where a change skips local midnight, get correct days too (#4843, #4844, #4845, #4846, #4848, #4851, #4856, #4864, #4867, #4868, #4869, #4870, #4871, #4872, #4873, #4889, #4895, #4896, #4903).
  • The repeated hour keeps its own time. When clocks go back, the second occurrence of an hour is now stored, listed and matched to weather with its own instant instead of the first occurrence's (#4863, #4876, #4891, #4892, #4897).
  • Scheduled backups run when scheduled on days a DST change skips the time, and a backup run can no longer hang forever when it finishes or fails (#4874, #4900, #4902).
  • Species tracking periods follow your settings. Yearly resets use the tracking year when the reset date is not January 1, and reading the daily summary for a later date no longer moves the tracker's period (#4898, #4904, #4908, #4911).

Database & Migration

  • The migration copies everything. Reviews, comments, locks and secondary predictions written while the migration runs now reach the enhanced database, hourly weather rows that builds before January 2025 saved without a daily event are kept (92% of one real snapshot had been skipped), the progress watermark is no longer reset, MySQL 8.4 no longer loses predictions, and stopping or rolling back waits for the worker to finish (#4905, #4907, #4912, #4913, #4915, #4950, #4951, #4954).
  • Legacy cleanup is safer. It refuses unless the migration proves the data reached the enhanced database, never drops live enhanced tables, and now actually appears on MySQL and MariaDB installs, where it was never offered (#4840, #4849, #4850, #4933, #4935, #4952).
  • Startup no longer fails on leftover tables. An upgrade that stopped at a populated notification history table now starts, tables that hold only regenerable data are replaced, populated ones are kept, and a refusal explains the recovery step (#4814, #4816, #4825, #4827, #4914, #4917).
  • More MySQL and MariaDB fixes. New tables use utf8mb4 and empty latin1 tables are converted, a lost connection at startup is retried instead of guessing the database mode, host addresses in IPv6 form work, connection failures are reported once an hour, and a query on the prediction rank column works on MySQL (#4834, #4923, #4930, #4931, #4932, #4936, #4944, #4946, #4948).
  • Dynamic thresholds are reliable. Expired thresholds are no longer deleted every second, saves are retried through connection drops including at shutdown, a reset no longer leaves a species stuck or brings it back, and a slow database no longer stalls detection or shutdown during a reset (#4924, #4937, #4940, #4941, #4945, #4947, #4949).
  • Imports and search order. Re-importing the same BirdNET-Pi source no longer duplicates every row, and paged searches break ties by detection id so a page never repeats or skips a row (#4865, #4866, #4901).
  • Legacy time-of-day search counts and filters correctly again for notes with a zero start time (#4953).

Dashboard & Analytics

  • No false "new this season" icons. Species carried over from the previous season are no longer flagged during the first week of a new season (#4457 by @gilindoesgit).
  • Speed improvements. Species first and last detection lookups, species and hourly counts, species diversity and the last detection date are much cheaper on large databases (#4592 by @Kerakis, #4687, #4688, #4689 by @gilindoesgit). Event streams no longer wake up 100 times a second per client (#4685 by @gilindoesgit), the human and dog label check in the top results is cached, removing thousands of allocations per analysis window (#4684 by @gilindoesgit), and the live audio library loads on first playback instead of in every page (#4686 by @gilindoesgit).

Web UI & System

  • Reverse proxy sub-paths work everywhere. OAuth login, the About page logo and the licenses and database links keep the base path (#4556 by @choksi2212, #4713 by @ocundale).
  • Every page has one address. A trailing slash resolves to the same page, and /ui/settings shows General (#4657).
  • Logging cannot freeze detection. Console output no longer blocks when a Docker log driver stops reading, and a fatal startup error is printed before the process exits (#4712, #4725).
  • Support dump logs stay readable. Timestamps, device tokens and dates are no longer mangled by the privacy scrubber (#4627, #4628, #4671).

Internationalization

🛡️ VirusTotal Results:

Don't miss a new birdnet-go release

NewReleases is sending notifications on new releases.