{"id":13583257,"url":"https://github.com/rhodey/radiowitness","last_synced_at":"2026-01-27T22:01:50.485Z","repository":{"id":76900982,"uuid":"268882727","full_name":"rhodey/radiowitness","owner":"rhodey","description":"P25 public safety radio archive with Dat Protocol authenticated mirrors.","archived":false,"fork":false,"pushed_at":"2022-10-29T16:20:20.000Z","size":73,"stargazers_count":9,"open_issues_count":2,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-06T15:06:02.630Z","etag":null,"topics":["dat","hypercore","hyperdb","p25","p2p","radio","rtlsdr","sdr"],"latest_commit_sha":null,"homepage":"http://radiowitness.org","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rhodey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-06-02T18:50:08.000Z","updated_at":"2025-01-01T17:38:27.000Z","dependencies_parsed_at":"2024-01-21T22:08:43.133Z","dependency_job_id":"9bde9dd8-abc4-42c4-9be2-7fdfe09be603","html_url":"https://github.com/rhodey/radiowitness","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhodey%2Fradiowitness","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhodey%2Fradiowitness/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhodey%2Fradiowitness/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhodey%2Fradiowitness/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rhodey","download_url":"https://codeload.github.com/rhodey/radiowitness/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247531113,"owners_count":20953895,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dat","hypercore","hyperdb","p25","p2p","radio","rtlsdr","sdr"],"created_at":"2024-08-01T15:03:21.748Z","updated_at":"2026-01-27T22:01:45.459Z","avatar_url":"https://github.com/rhodey.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# RadioWitness\nRadioWitness is a [P25](https://en.wikipedia.org/wiki/Project_25) public safety radio archive with a web application and support for cryptographically authenticated mirrors through [Dat Protocol](https://dat.foundation/). Running this software requires two or more [RTLSDR radios](https://osmocom.org/projects/rtl-sdr/wiki/Rtl-sdr) and one or more local **P25 \"Phase 1\"** public safety radio networks.\n\n## Download \u0026 Build\n```\n$ git clone https://github.com/rhodey/radiowitness \u0026\u0026 cd radiowitness/\n$ git submodule update --init --recursive\n$ docker build -t radiowitness .\n$ docker build -t usbreset lib/c/usbreset\n```\n\n## Search for Radio Networks\nUsing the [Radio Reference Database](https://www.radioreference.com/apps/db/) find your local county and search the county page for **\"Project 25 Phase I\"**, for example Austin, Texas has the [Greater Austin/Travis Regional Radio System](https://www.radioreference.com/apps/db/?sid=2). If your county has a P25 Phase 1 network there will be a table labeled **\"System Frequencies\"** and running behind one or more of these frequencies should be a P25 [Control Channel](https://wiki.radioreference.com/index.php/Control_channel). The following example uses `-g` for radio gain and it is shown that frequency `851137500Hz` has the best reception of three control channel candidates:\n```\n$ chmod +x ./bin/rtl_devices.sh\n$ docker run $(./bin/rtl_devices.sh) --rm \\\n    radiowitness search p25 -g 26 -f \"851162500,851287500,851137500\" 2\u003e /dev/null\n\u003e 851162500 counted 0 frames.\n\u003e 851287500 counted 36 frames.\n\u003e 851137500 counted 43 frames.\n```\n\n## Decode and Play\nThe following example shows options for `3` RTLSDR radios multiplexed by `2` to support five concurrent radio calls, this is six minus one for the `-f 851137500` control channel. Sample rate `-s 1200000` is chosen because it divides evenly by the P25 channel rate `48000` making for efficient [resampling](https://dspguru.com/dsp/faqs/multirate/resampling/). Gain `-g 0` is automatic gain control but it is recommended that a static value be found using the search command:\n```\n$ docker run $(./bin/rtl_devices.sh) --rm -i \\\n    radiowitness decode p25 --radios 3 --mux 2 -s 1200000 -g 0 -f 851137500 \\\n      | docker run --rm -i radiowitness play p25 \\\n        | play -t raw -b 16 -e signed -r 8k -c 1 -\n```\n\n## Create Archive\nAfter having successfully tested decoding create a new P25 archive, this example uses directory `/tmp/archive-p25`. Values of **\"System ID\"**, **\"WACN\"**, **\"RFSS\"**, and **\"Site\"** can all be found on Radio Reference:\n```\n$ docker run --rm -v /tmp/archive-p25:/archive \\\n    radiowitness create p25 --name \"GATRRS Austin/Travis County\" \\\n      --lat \"30.245016\" --lon=\"-97.788914\" --sys 318 --wacn 781833 --rfss 1 --site 1\n```\n\n## Decode and Archive\nThe following example will decode, archive and replicate from directory tree `/tmp/archive-p25` and serve the web app and mirrors using WebSockets on TCP port `8081`:\n```\n$ docker run $(./bin/rtl_devices.sh) --rm -i \\\n    radiowitness decode p25 --radios 3 --mux 2 -s 1200000 -g 26 -f 851137500 \\\n      | docker run -i -v /tmp/archive-p25:/archive -p 8081:8081 \\\n          radiowitness archive p25\n```\n\n### Multi-Host\nArchive P25 decode stream from TCP port `1234` and replicate archive over WebSockets TCP port `8081`. `--limit 1000000` will limit the archive to the most recent one million calls and use storage approximate to **16KB/sec** for recorded audio. One million ten second radio calls is **160GB** of audio:\n```\n$ ncat -l -k -p 1234 -c \\\n    \"docker run --rm -i --name vpn.archive-p25 -v /tmp/archive-p25:/archive -p 8081:8081 \\\n      radiowitness archive p25 --limit 1000000\"\n```\n\nDecode with connectivity to `vpn.archive-p25` TCP port `1234`:\n```\n$ ncat vpn.archive-p25 1234 -c \\\n    \"docker run $(./bin/rtl_devices.sh) --rm -i \\\n      radiowitness decode p25 --radios 3 --mux 2 -s 1200000 -g 26 -f 851137500\"\n```\n\n## Mirrors\nRun a mirror if you want to add storage to your archive or mirror someone else. Mirror `vpn.archive-p25` using TCP port `8081`:\n```\n$ docker run -d --name vpn.mirror-p25 \\\n    -v /tmp/mirror-p25:/archive -p 8081:8081 \\\n      radiowitness mirror ws://vpn.archive-p25:8081 --limit 2000000\n```\n\n## Web App\nThe web app must be configured to reference an archive or mirror, then serve the `web/dist` directory using whatever HTTP server you like. The following example would serve from [localhost:8080](http://localhost:8080):\n```\n$ curl http://vpn.mirror-p25:8081/dat.json \\\n    | docker run --rm -i radiowitness config \\\n        --title \"Radio Venceremos\" \\\n        --description \"Austin Texas police and fire radio.\" \\\n        --host ws://vpn.mirror-p25:8081 \u003e web/config.json\n$ cd web/ \u0026\u0026 npm install \u0026\u0026 npm run build\n$ cd dist/ \u0026\u0026 python -m SimpleHTTPServer 8080\n```\n\n## License\nCopyright Rhodey \u003cmike@rhodey.org\u003e\nCreative Commons Attribution-NonCommercial\nhttps://creativecommons.org/licenses/by-nc/4.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhodey%2Fradiowitness","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frhodey%2Fradiowitness","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhodey%2Fradiowitness/lists"}