Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install dependencies
run: npm ci
- name: Build & validate dataset
run: node scripts/build.js
- name: Generate docs
Expand Down Expand Up @@ -41,6 +43,8 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install dependencies
run: npm ci
- name: Build dataset
run: node scripts/build.js
- name: Copy data into docs for Pages
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ jobs:
with:
node-version: "20"

- name: Install dependencies
run: npm ci

- name: Determine version
id: version
run: |
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ node_modules/
*.log
.DS_Store
.idea/
.env
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,27 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

---

## [1.6.0] — 2026-06-17

### Added

- **Schema validation now enforced in the build** — every entry is validated against `schema/camera.schema.json` via Ajv. Previously the build only hand-checked five required fields, so the schema had silently drifted from the data; it is now the single source of truth and CI fails on any violation.
- **11 fields added to the schema** that the data already used but never declared: localized prices `msrp_eur`, `msrp_gbp`, `msrp_inr`, `msrp_aed`, `msrp_aud`, `msrp_cad`, `msrp_vnd`, `msrp_chf`; plus `markets`, `generation`, and `release_notes`.
- **`storage.notes`** field — free-text storage notes (e.g. external-hub requirements).
- **`hdcvi` and `mxpeg`** added to the `protocols` enum (HD-CVI coax for HiLook/Dahua analog; MxPEG for Mobotix).
- **Reolink Video Doorbell PoE** enriched — verified Frigate config (tested by blakeblacksear on v0.14, go2rtc), Home Assistant details (`local_push`, doorbell button, two-way audio, ONVIF events), plus `soc` (Novatek NT98566), `poe_class`, and outdoor `environment`.

### Fixed

- Removed invalid `ip_rating: null` from 3 indoor cameras (Amcrest ASH42-W, Tapo C121, Tapo C135) — the field is optional and `null` is not a valid rating.

### Changed

- Dataset mirroring to a downstream consumer is now opt-in via the `DATA_MIRROR_DIR` env var (configurable through a local, gitignored `.env`), replacing a hardcoded copy path in the build script.
- **Project now points to the website at [cctv-database.com](https://cctv-database.com)** — README links and `package.json` `homepage` updated. The GitHub Pages demo redirects there, with a standalone offline copy kept at `docs/demo.html`. The README now states explicitly that the dataset is CC0 and always will be.

---

## [1.5.0] — 2026-06-12

### Added
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ An open, structured database of 1,314 CCTV / IP camera models and their technica

Camera spec sheets are scattered across vendor PDFs, retailer pages, and paywalled databases (IPVM, etc.) in inconsistent formats. This repo normalises them into one machine-readable structure so they can be compared, filtered, and reused.

**The dataset is CC0 and always will be** — free to use, copy, and redistribute with no restrictions. The website is just a convenient viewer; the data here is the source of truth.

---

## Browse online

**[Live Demo ](https://ch-bas.github.io/cctv-camera-databse)**
**[Browse the database → cctv-database.com](https://cctv-database.com)**

Prefer to self-host or browse offline? A [standalone demo](docs/demo.html) (just `demo.html` + `cameras.json`, no build step) is included — serve the `docs/` folder locally with any static server, e.g. `python3 -m http.server` inside `docs/`, then open it.

<p align="center">
<img src="docs/demo.gif" alt="CCTV Camera Database — browse, search, filter, and inspect 1,296 cameras across 64 brands" width="800" />
Expand Down
1 change: 0 additions & 1 deletion cameras/amcrest/ash42-w.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
"protocols": [
"rtsp"
],
"ip_rating": null,
"audio": {
"microphone": true,
"speaker": true,
Expand Down
19 changes: 16 additions & 3 deletions cameras/reolink/video-doorbell-poe.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
"range_m": 5
},
"power": {
"method": "PoE (IEEE 802.3af) / 12-24VAC doorbell wiring / 24VDC"
"method": "PoE (IEEE 802.3af) / 12-24VAC doorbell wiring / 24VDC",
"poe_class": 2
},
"storage": {
"onboard": true,
Expand Down Expand Up @@ -52,6 +53,10 @@
"works with Reolink NVR"
],
"release_year": 2022,
"environment": [
"outdoor"
],
"soc": "Novatek NT98566",
"sources": [
"https://reolink.com/product/reolink-video-doorbell-poe/"
],
Expand Down Expand Up @@ -88,11 +93,19 @@
},
"rtsp_url_template": "rtsp://{user}:{pass}@{ip}:554/h264Preview_01_main",
"best_substream": "rtsp://{user}:{pass}@{ip}:554/h264Preview_01_sub",
"notes": "Portrait 3:4 aspect ratio (white model 1920x2560, black model is 4:3 at 2560x1920). Set detect to 720x960 for white or 960x720 for black to maintain correct ratio. For two-way audio: use go2rtc as the RTSP proxy — Frigate does not natively handle talk-back. In go2rtc config add the camera as an RTSP source, then enable WebRTC with opus re-encoding for the back-channel: 'streams: doorbell: - rtsp://{user}:{pass}@{ip}:554/h264Preview_01_main - ffmpeg:doorbell#audio=opus'. Button press events are not exposed via RTSP; use HA Reolink integration's Visitor binary_sensor or subscribe to ONVIF events via MQTT."
"notes": "Portrait 3:4 aspect ratio (white model 1920x2560, black model is 4:3 at 2560x1920). Set detect to 720x960 for white or 960x720 for black to maintain correct ratio. For two-way audio: use go2rtc as the RTSP proxy — Frigate does not natively handle talk-back. In go2rtc config add the camera as an RTSP source, then enable WebRTC with opus re-encoding for the back-channel: 'streams: doorbell: - rtsp://{user}:{pass}@{ip}:554/h264Preview_01_main - ffmpeg:doorbell#audio=opus'. Button press events are not exposed via RTSP; use HA Reolink integration's Visitor binary_sensor or subscribe to ONVIF events via MQTT.",
"verified": true,
"tested_by": "blakeblacksear",
"tested_version": "0.14",
"recommended_stream_type": "go2rtc"
},
"home_assistant": {
"integration": "reolink",
"notes": "Native Reolink integration auto-discovers via ONVIF (port 8000). Doorbell button press is exposed as a 'Visitor' binary_sensor entity. Two-way audio works in the Reolink app; for HA dashboard intercom, use go2rtc WebRTC card with opus back-channel."
"notes": "Native Reolink integration auto-discovers via ONVIF (port 8000). Doorbell button press is exposed as a 'Visitor' binary_sensor entity. Two-way audio works in the Reolink app; for HA dashboard intercom, use go2rtc WebRTC card with opus back-channel.",
"connection_type": "local_push",
"doorbell_button": true,
"two_way_audio": true,
"onvif_events": true
},
"blue_iris": {
"profile": "Reolink",
Expand Down
1 change: 0 additions & 1 deletion cameras/tapo/c121.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
"rtsp",
"onvif"
],
"ip_rating": null,
"audio": {
"microphone": true,
"speaker": true,
Expand Down
1 change: 0 additions & 1 deletion cameras/tapo/c135.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
"rtsp",
"onvif"
],
"ip_rating": null,
"audio": {
"microphone": true,
"speaker": true,
Expand Down
22 changes: 16 additions & 6 deletions data/cameras.json
Original file line number Diff line number Diff line change
Expand Up @@ -2679,7 +2679,6 @@
"protocols": [
"rtsp"
],
"ip_rating": null,
"audio": {
"microphone": true,
"speaker": true,
Expand Down Expand Up @@ -80367,7 +80366,8 @@
"range_m": 5
},
"power": {
"method": "PoE (IEEE 802.3af) / 12-24VAC doorbell wiring / 24VDC"
"method": "PoE (IEEE 802.3af) / 12-24VAC doorbell wiring / 24VDC",
"poe_class": 2
},
"storage": {
"onboard": true,
Expand Down Expand Up @@ -80395,6 +80395,10 @@
"works with Reolink NVR"
],
"release_year": 2022,
"environment": [
"outdoor"
],
"soc": "Novatek NT98566",
"sources": [
"https://reolink.com/product/reolink-video-doorbell-poe/"
],
Expand Down Expand Up @@ -80431,11 +80435,19 @@
},
"rtsp_url_template": "rtsp://{user}:{pass}@{ip}:554/h264Preview_01_main",
"best_substream": "rtsp://{user}:{pass}@{ip}:554/h264Preview_01_sub",
"notes": "Portrait 3:4 aspect ratio (white model 1920x2560, black model is 4:3 at 2560x1920). Set detect to 720x960 for white or 960x720 for black to maintain correct ratio. For two-way audio: use go2rtc as the RTSP proxy — Frigate does not natively handle talk-back. In go2rtc config add the camera as an RTSP source, then enable WebRTC with opus re-encoding for the back-channel: 'streams: doorbell: - rtsp://{user}:{pass}@{ip}:554/h264Preview_01_main - ffmpeg:doorbell#audio=opus'. Button press events are not exposed via RTSP; use HA Reolink integration's Visitor binary_sensor or subscribe to ONVIF events via MQTT."
"notes": "Portrait 3:4 aspect ratio (white model 1920x2560, black model is 4:3 at 2560x1920). Set detect to 720x960 for white or 960x720 for black to maintain correct ratio. For two-way audio: use go2rtc as the RTSP proxy — Frigate does not natively handle talk-back. In go2rtc config add the camera as an RTSP source, then enable WebRTC with opus re-encoding for the back-channel: 'streams: doorbell: - rtsp://{user}:{pass}@{ip}:554/h264Preview_01_main - ffmpeg:doorbell#audio=opus'. Button press events are not exposed via RTSP; use HA Reolink integration's Visitor binary_sensor or subscribe to ONVIF events via MQTT.",
"verified": true,
"tested_by": "blakeblacksear",
"tested_version": "0.14",
"recommended_stream_type": "go2rtc"
},
"home_assistant": {
"integration": "reolink",
"notes": "Native Reolink integration auto-discovers via ONVIF (port 8000). Doorbell button press is exposed as a 'Visitor' binary_sensor entity. Two-way audio works in the Reolink app; for HA dashboard intercom, use go2rtc WebRTC card with opus back-channel."
"notes": "Native Reolink integration auto-discovers via ONVIF (port 8000). Doorbell button press is exposed as a 'Visitor' binary_sensor entity. Two-way audio works in the Reolink app; for HA dashboard intercom, use go2rtc WebRTC card with opus back-channel.",
"connection_type": "local_push",
"doorbell_button": true,
"two_way_audio": true,
"onvif_events": true
},
"blue_iris": {
"profile": "Reolink",
Expand Down Expand Up @@ -87615,7 +87627,6 @@
"rtsp",
"onvif"
],
"ip_rating": null,
"audio": {
"microphone": true,
"speaker": true,
Expand Down Expand Up @@ -87775,7 +87786,6 @@
"rtsp",
"onvif"
],
"ip_rating": null,
"audio": {
"microphone": true,
"speaker": true,
Expand Down
22 changes: 16 additions & 6 deletions docs/cameras.json
Original file line number Diff line number Diff line change
Expand Up @@ -2679,7 +2679,6 @@
"protocols": [
"rtsp"
],
"ip_rating": null,
"audio": {
"microphone": true,
"speaker": true,
Expand Down Expand Up @@ -80367,7 +80366,8 @@
"range_m": 5
},
"power": {
"method": "PoE (IEEE 802.3af) / 12-24VAC doorbell wiring / 24VDC"
"method": "PoE (IEEE 802.3af) / 12-24VAC doorbell wiring / 24VDC",
"poe_class": 2
},
"storage": {
"onboard": true,
Expand Down Expand Up @@ -80395,6 +80395,10 @@
"works with Reolink NVR"
],
"release_year": 2022,
"environment": [
"outdoor"
],
"soc": "Novatek NT98566",
"sources": [
"https://reolink.com/product/reolink-video-doorbell-poe/"
],
Expand Down Expand Up @@ -80431,11 +80435,19 @@
},
"rtsp_url_template": "rtsp://{user}:{pass}@{ip}:554/h264Preview_01_main",
"best_substream": "rtsp://{user}:{pass}@{ip}:554/h264Preview_01_sub",
"notes": "Portrait 3:4 aspect ratio (white model 1920x2560, black model is 4:3 at 2560x1920). Set detect to 720x960 for white or 960x720 for black to maintain correct ratio. For two-way audio: use go2rtc as the RTSP proxy — Frigate does not natively handle talk-back. In go2rtc config add the camera as an RTSP source, then enable WebRTC with opus re-encoding for the back-channel: 'streams: doorbell: - rtsp://{user}:{pass}@{ip}:554/h264Preview_01_main - ffmpeg:doorbell#audio=opus'. Button press events are not exposed via RTSP; use HA Reolink integration's Visitor binary_sensor or subscribe to ONVIF events via MQTT."
"notes": "Portrait 3:4 aspect ratio (white model 1920x2560, black model is 4:3 at 2560x1920). Set detect to 720x960 for white or 960x720 for black to maintain correct ratio. For two-way audio: use go2rtc as the RTSP proxy — Frigate does not natively handle talk-back. In go2rtc config add the camera as an RTSP source, then enable WebRTC with opus re-encoding for the back-channel: 'streams: doorbell: - rtsp://{user}:{pass}@{ip}:554/h264Preview_01_main - ffmpeg:doorbell#audio=opus'. Button press events are not exposed via RTSP; use HA Reolink integration's Visitor binary_sensor or subscribe to ONVIF events via MQTT.",
"verified": true,
"tested_by": "blakeblacksear",
"tested_version": "0.14",
"recommended_stream_type": "go2rtc"
},
"home_assistant": {
"integration": "reolink",
"notes": "Native Reolink integration auto-discovers via ONVIF (port 8000). Doorbell button press is exposed as a 'Visitor' binary_sensor entity. Two-way audio works in the Reolink app; for HA dashboard intercom, use go2rtc WebRTC card with opus back-channel."
"notes": "Native Reolink integration auto-discovers via ONVIF (port 8000). Doorbell button press is exposed as a 'Visitor' binary_sensor entity. Two-way audio works in the Reolink app; for HA dashboard intercom, use go2rtc WebRTC card with opus back-channel.",
"connection_type": "local_push",
"doorbell_button": true,
"two_way_audio": true,
"onvif_events": true
},
"blue_iris": {
"profile": "Reolink",
Expand Down Expand Up @@ -87615,7 +87627,6 @@
"rtsp",
"onvif"
],
"ip_rating": null,
"audio": {
"microphone": true,
"speaker": true,
Expand Down Expand Up @@ -87775,7 +87786,6 @@
"rtsp",
"onvif"
],
"ip_rating": null,
"audio": {
"microphone": true,
"speaker": true,
Expand Down
Loading
Loading