Earwitness
Does my recording contain location clues?
Earwitness is an open-source proof of concept that estimates where a recording was made from background sounds that public databases also log with precise time and position: thunder, matched against lightning records, and the Doppler whine of propeller aircraft, matched against ADS-B flight records. It is a clean-room reconstruction of the method colsto demonstrated on YouTube in 2026 (about 5 km for thunder with free data, about 100 m for aircraft).
Site: earwitness.dev. Source: github.com/cajdata/earwitness. Full specification: docs/HANDOFF.md.
Status
Pre-alpha. The thunder method runs end to end on real GOES GLM data and passes its synthetic acceptance check; no real recording has been validated yet (that is M6).
| Milestone | Scope | State |
|---|---|---|
| M0 | Scaffold, CI, packaging | done |
| M1 | Physics core, forward models, synthetic recordings (earwitness simulate) |
done |
| M2 | Thunder pipeline on GOES GLM: loader, search, refinement, outputs | done, see docs/VALIDATION.md |
| M3 | ADS-B data (adsb.lol) | next |
| M4 | Aircraft Doppler pipeline | planned |
| M5 | Desktop UI | planned |
| M6 | Real-world validation | planned |
| M7 | v0.1.0 release and site | planned |
Responsible use
This project exists to show that ordinary recordings leak location, to let people check their own recordings, and to document what does and does not prevent it. The rules it follows:
- The audit mode ("does my recording contain location clues?") leads the UI and the docs.
- Every example and default workflow uses your own recordings or synthetic cases. The project publishes no results that locate other people's recordings.
- No hosted service, no downloading media from URLs, no bundled third-party datasets.
- Blitzortung and LightningMaps data are never used; their terms do not allow it.
- Countermeasures that work and do not work will be documented in
docs/COUNTERMEASURES.md.
Quick start
Requires uv. ffmpeg on PATH is optional; it enables --codec
in the simulator and decoding of non-WAV input.
uv sync
uv run earwitness --help
Generate synthetic test recordings with a known answer:
uv run earwitness simulate aircraft --lat 35.2 --lon -97.4 --start 2026-09-08T18:00:00Z --minutes 20 --out case-aircraft
uv run earwitness simulate thunder --lat 35.2 --lon -97.4 --start 2026-07-02T21:00:00Z --minutes 30 --out case-thunder
Each case folder holds recording.wav, truth.json (location, start time, events, physics and
mixing parameters) and the synthetic source data the search will consume later (tracks.json
or strikes.json).
Locate a thunder recording against real GOES GLM lightning data. The first run downloads the
hours it needs into data/cache (about 110 MB per hour) and the Natural Earth land mask:
uv run earwitness analyze thunder recording.wav --date 2025-05-16 --time-window 2025-05-16T21:00:00Z 2025-05-17T00:00:00Z --bbox=-97,33,-82,42 --out runs/example
Or fetch and export the flashes first:
uv run earwitness data glm --date 2025-05-16 --hours 21-23 --bbox=-97,33,-82,42 --export flashes.parquet
Write --bbox=W,S,E,N with the equals sign, or give the four numbers as separate arguments,
so a negative western longitude is not mistaken for an option. Each analysis run writes a folder
with results.parquet, heatmap.geojson, histogram.json, per-candidate overlays,
config.toml, priors.json, summary.json and a run log.
How it works
The recording is the receiver, the lightning strikes or aircraft are the satellites, and the unknown recording start time is the receiver clock bias. For any candidate location, physics predicts what that spot would have heard and when. The search predicts the signal for every candidate and every start time, scores it against the recording, and the best score is the location. Audio is never inverted into a location directly.
Data sources and attribution
Nothing is bundled. Loaders download into a local cache (data/, gitignored).
| Source | Role | License |
|---|---|---|
| NOAA GOES GLM | Lightning (Americas) | NOAA open data |
| MET Norway Frost | Lightning (Nordic), adapter | CC BY 4.0 / NLOD |
| adsb.lol globe_history | Aircraft tracks | ODbL 1.0 |
| USGS 3DEP, Copernicus GLO-30 | Terrain | Public domain; free with attribution |
| Natural Earth | Land mask | Public domain |
| OpenStreetMap | Basemap tiles | ODbL; tile usage policy applies |
Development
uv run pytest
uv run ruff check . && uv run ruff format .
Conventions are in CONTRIBUTING.md. The build order and acceptance checks are in docs/HANDOFF.md.
License
Apache-2.0. See LICENSE.
Acknowledgements
The method is colsto's: thunder, Blitzortung, thunder, MET Norway, and propeller-aircraft Doppler. His code is not public; everything here is reconstructed from the videos.
Metadata
Release files for earwitness 0.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| earwitness-0.0.1.tar.gz | 144.7 kB | With provenance | Details for earwitness-0.0.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| earwitness-0.0.1-py3-none-any.whl | Python 3 | none | any | Details for earwitness-0.0.1-py3-none-any.whl |
Total release size: 212.0 kB
Release files / earwitness-0.0.1.tar.gz
| Download URL | earwitness-0.0.1.tar.gz |
|---|---|
| Size | 144.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ba868988034829181b922ede845bb4051581bbbef347d30cf65d32cf0c5633ba
|
|
BLAKE2b-256 checksum How to use checksums |
fdb00bb8716086b9c3e3b2931457dcd08cc6cfc3f827974ae1f3992c8bdf3927
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.
Transparency logRelease files / earwitness-0.0.1-py3-none-any.whl
| Download URL | earwitness-0.0.1-py3-none-any.whl |
|---|---|
| Size | 67.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4370d6ba53fa69476b660d84c804e4270843fe985d304c325ca1a00aad9805d9
|
|
BLAKE2b-256 checksum How to use checksums |
3e8d551d3bf5263c3c641d9a44610266908d416da9b815a6750089dea90913b0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.
Transparency logSecurity for earwitness 0.0.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for earwitness-0.0.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.