The BirdNET team’s setup for the MacOS command-line Python version is on GitHub here.
Here is a short step-by-step that I wrote for myself (a MacOS user – YMMV)
These steps are now very close to those found on the BirdNET-Analyzer GitHub page, but they have a few more details and reminders-to-myself.
Use Python 3.11 (click here for Python-install reminders)
CD into a directory you’ve created to house BirdNET-Analyzer. Pay attention to what you name it because that will become part of the path that’s used to call the script. For example; avoid spaces in the directory name. Here’s an example you can use:
cd BirdNET-Analyzer_GitHub_clone
git clone https://github.com/BirdNET-team/BirdNET-Analyzer.git (or the latest "clone" URL from GitHub)
CD down into the newly-cloned BirdNET directory. It should be the only thing the directory you just created.
cd BirdNET-Analyzer
From inside the BirdNET-Analyzer directory, create and activate a new virtual environment (it’s named “venv” in this example).
python3 -m venv venv source venv/bin/activate
Install BirdNET’s requirements manually (yes, really use a period at the end…) :
pip install .
Test by running the help command:
python3 -m birdnet_analyzer.analyze --h
Verify the installation
python -m birdnet_analyzer.analyze <path_to_an_audio_file_on_YOUR_drive.wav>
Here’s an example of a command-line that worked on my Mac the day I wrote this. Note that there’s no longer a parameter for the input-directory path (ala “-i”). It’s positional; it’s always the last entry in the command.
python3 -m birdnet_analyzer.analyze --threads 8 --lat 44.415947 --lon -91.700659 --skip_existing_results -o /Users/mikeoconnor/Documents/birdnet_analyzer/run_files/2025 /Volumes/Bio_2025
Translated, that command is saying:
python3
— run this Python script
-m
run a module of a file rather than a file
birdnet-analyzer.analize
the name of the script and the module to run
--threads 8
let the script use up to 8 parallel processes on my machine (YMMV)
--lat and --lon
geo coordinates of the recordings (narrows down the analysis)
--skip_existing_results
only process new files in the directory
-o
path to the destination directory
/Volumes/Bio_2025
the last chunk is the path to the input directory, it doesn’t have a parameter it’s positional
