mjshiggins/dopplertrack
DataLocate a recording's position by matching aircraft propeller Doppler curves against historical ADS-B flight tracks.
What it does
dopplertrack estimates where an outdoor (or often indoor) recording was made by exploiting a faint side effect of aircraft flyovers: propeller blade-pass tones between roughly 60 and 400 Hz sweep downward as a plane passes, and the sweep shape depends on the listener's position relative to the aircraft's real trajectory. For each candidate ground point, the tool models the curve that a given flight would produce, compares it with a high-resolution spectrogram, and ranks the matches. It is a reimplementation of the method in colsto's video "I discovered a sound that leaks your exact location", which shipped no code.
The pipeline is split into commands: spectrogram (ffmpeg decode plus a whitened STFT of the 40–450 Hz band), detect/fit (locate and parameterize flyover curves), fetch-day/extract-region (pull one day of ADS-B and keep flights touching a bounding box), search (grid search over points and flight pairs), and refine (finer grid, optional extra events). The README explains each stage in the pipeline section.
It is aimed at researchers, hobbyists, and privacy-minded readers interested in acoustic inference and geolocation; it assumes some comfort with command-line tools and geospatial data.
Quick start
You need uv, ffmpeg, and a recording whose date you know. From the repository root:
uv sync
uv run dopplertrack spectrogram recording.mp4 rec.npz
uv run dopplertrack detect rec.npz --band 60 300 --top 10 --out detected.json
uv run dopplertrack fit rec.npz --window 2090 2200 --band 95 200 --harmonics 2 --out ev1.json
uv run dopplertrack fit rec.npz --window 3020 3130 --band 95 195 --out ev2.json
uv run dopplertrack fetch-day 2026-09-08 traces_ny.npz --bbox 40.4 41.3 -74.4 -72.6
uv run dopplertrack search rec.npz --events ev1.json ev2.json --traces traces_ny.npz \
--bbox 40.4 41.3 -74.4 -72.6 --spacing 200 --out results.csv
uv run dopplertrack refine rec.npz results.csv --events ev1.json ev2.json --traces traces_ny.npz \
--bbox 40.4 41.3 -74.4 -72.6 --extra ev3.json ev4.json --out fine.csv
The window numbers and bounding box are placeholders; replace them with your recording's flyover windows and search area. detect prints a ranked list of candidate flyovers, and its JSON output can be passed directly to search --events. For a recording with a known location, search --point LAT LON scores that single point instead of a grid, which is the quickest sanity check of the data and physics usage notes.
Results and accuracy
The project is a proof of concept validated on two recordings status. On the reference Oyster Bay recording, a blind search over a 100 × 150 km region ranks the true flight pair first of 328 and refines to 43 m from the true location on a 50 m grid, though the margin over the runner-up pair is only 4.9%. On a 12-hour eagle-cam stream in North Fort Myers, automatic detection finds the right pair of a 607-pair set, but two events place the camera only within about 2 km; adding three more detected flyovers brings it to 592 m. The README attributes the sharper Oyster Bay result to a low, lateral pass, while near-overhead passes constrain position poorly second recording.
Constraints
- The method needs a known recording date to fetch the corresponding ADS-B day, and a search region; the reference clip's start time and the two aircraft were recovered by the search, not supplied.
fetch-daystreams a ~4 GB daily archive from adsb.lol, so a fast, reliable connection matters;extract-regionworks on an archive already on disk data sources.- The scorer measures brightness under the modelled curve, which can reward a wrong flight pair where the spectrogram is busy; the author reports thin margins on the eagle-cam case.
- Long recordings and large regions are computationally heavy: the Oyster Bay search took 19 minutes on a laptop, the eagle-cam search 8 minutes.
- Compatibility beyond the documented Linux-style uv/ffmpeg workflow is not spelled out; Windows and macOS instructions are absent.
- The project is MIT-licensed.
HotRepo's take
The repository's new-project record on 2026-11-04 (Python list) shows 102 stars and 14 forks gained in roughly 20 hours since creation. That is a single-snapshot observation, so it says little about sustained interest: the more useful signal is the README's own careful accounting of thin margins and geometry-dependent error, which makes the 43 m Oyster Bay result and the 592 m eagle-cam result read as measured bounds rather than headline claims. Readers evaluating the tool should weigh the two validations' limits (near-overhead passes, busy spectrograms) more than the star count.
Written by AI from the project's README, updated . The project's own docs are the source of truth.