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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
30 changes: 30 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE/release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
## Summary

<!-- One-paragraph overview of what this release delivers -->

### Added

<!-- New brands, cameras, schema fields, frontend features.
Reference issues with "closes #N" to auto-close them on merge. -->

-

### Fixed

<!-- Data corrections, removed fabricated configs, deduplication, audits -->

-

### Changed

<!-- Schema migrations, workflow changes, breaking changes -->

- Database: **X,XXX cameras across XX brands**

## Checklist

- [ ] `npm run build` passes — all cameras validate
- [ ] `package.json` version bumped (release auto-creates tag + GitHub Release on merge)
- [ ] CHANGELOG.md has a section for this version (used as release notes)
- [ ] README.md stats synced (camera/brand counts, badges, brand table)
- [ ] No fabricated specs — every new camera has a verifiable source URL
44 changes: 34 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name: release

on:
push:
branches: [main]
tags:
- "v*"

Expand All @@ -18,25 +19,48 @@ jobs:
with:
node-version: "20"

- name: Determine version
id: version
run: |
if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then
echo "version=${GITHUB_REF#refs/tags/v}" >> "$GITHUB_OUTPUT"
else
echo "version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"
fi

- name: Skip if release already exists
id: check
env:
GH_TOKEN: ${{ github.token }}
run: |
if gh release view "v${{ steps.version.outputs.version }}" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
echo "exists=true" >> "$GITHUB_OUTPUT"
echo "Release v${{ steps.version.outputs.version }} already exists — skipping."
else
echo "exists=false" >> "$GITHUB_OUTPUT"
fi

- name: Build dataset
if: steps.check.outputs.exists == 'false'
run: node scripts/build.js

- name: Extract version from tag
id: version
run: echo "version=${GITHUB_REF#refs/tags/v}" >> "$GITHUB_OUTPUT"

- name: Extract changelog for this version
if: steps.check.outputs.exists == 'false'
id: changelog
run: |
# Extract the section for this version from CHANGELOG.md
awk '/^## \['"${{ steps.version.outputs.version }}"'\]/{found=1; next} /^## /{if(found) exit} found' CHANGELOG.md > /tmp/release-notes.md
echo "body<<RELEASE_EOF" >> "$GITHUB_OUTPUT"
cat /tmp/release-notes.md >> "$GITHUB_OUTPUT"
echo "RELEASE_EOF" >> "$GITHUB_OUTPUT"
# Extract the section for this version from CHANGELOG.md (header may be "## [X.Y.Z]" or "## X.Y.Z")
awk '/^## \[?'"${{ steps.version.outputs.version }}"'\]?/{found=1; next} /^## /{if(found) exit} found' CHANGELOG.md > /tmp/release-notes.md
{
echo "body<<RELEASE_EOF"
cat /tmp/release-notes.md
echo "RELEASE_EOF"
} >> "$GITHUB_OUTPUT"

- name: Create GitHub Release
- name: Create GitHub Release (creates tag if missing)
if: steps.check.outputs.exists == 'false'
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ steps.version.outputs.version }}
name: v${{ steps.version.outputs.version }}
body: ${{ steps.changelog.outputs.body }}
files: |
Expand Down
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,37 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

---

## [1.5.0] — 2026-06-12

### Added

- **SV3C brand** (13 cameras incl. C25 & C12 verified via Amazon): PoE bullets/domes, WiFi/PoE PTZs, solar dual-lens kit — all specs from official product pages; honest ONVIF notes (C25 and the original B05W have ONVIF, the rest are RTSP-only)
- **Dahua DH-SDT7425-4P-AD3E-PV-i** (issue #11) — CN-market dual-channel panoramic+PTZ with full datasheet specs: 180° stitched 3840x1080 panoramic + 4MP 25x PTZ, starlight 0.001 lux, DC 36V/35W, Smart H.265, 150m IR + white light deterrence. ONVIF autotracking behavior verified via frigate#22135 (Channel 2 has unified VideoEncoder+PTZ profile, unlike SDT4E series)
- **Real video/power specs** for 4 Reolink doorbells and 12 Reolink cameras from official datasheets

### Fixed

- **Full Dahua config audit** (109 cameras): 8 panoramic/multi-sensor cameras got stitched-stream aspect-ratio and channel-layout notes, 8 PTZs got ONVIF autotracking instructions, 4 HDCVI analog cameras corrected (were listed as ethernet with invalid protocol — now coax), 2 duplicates removed, 1 misnamed ZAS varifocal variant renamed
- **Full Hikvision config audit** (150 cameras): PanoVu 4-sensor channel layout (101/201/301/401), TandemVu PTZ+bullet dual-camera setup, fisheye dewarp channel notes, 12 PTZs got ONVIF autotracking setup (incl. the enable-Integration-Protocol gotcha), 5 analog cameras corrected from "hdcvi" (Dahua's tech) to Turbo HD (HD-TVI) over coax, 2 miscategorized types fixed (DS-2CD2385G1-I → turret, DS-2CD2443G2-I(W) → box), solar camera got battery-drain warning

- **Fabricated RTSP/configs removed** from 13 more cameras: Aqara G3/G5 Pro (HomeKit/Matter only), Zebronics, Wyze battery & floodlight cameras (docker-wyze-bridge notes), Yale (cloud-only), ABUS battery model
- **22 duplicate camera files removed**: Axis, Arlo, Dahua, Google Nest, Hikvision, Reolink, Uniview, Tapo, ADT, CP Plus, Somfy duplicates consolidated with markets merged
- **Night vision corrections**: Axis P5655-E (has OptimizedIR), Hikvision DS-2CD2025FWD-I ("-I" suffix = EXIR 30m)
- **9 cameras** missing `power_source` field populated (Arlo, Eufy, Ring)
- **IK vandal ratings** moved out of `ip_rating` field into features (9 cameras)
- **12 cameras** with empty connectivity fixed (4G/WiFi derived from model specs)
- **22 enterprise cameras** had redundant `http` protocol removed
- **15 cameras** with megapixel/resolution mismatches corrected
- **Doorbell detect configs** flipped to portrait for UniFi G4 Doorbell/Pro
- **Cathexis cameras**: RTSP added (ONVIF implies RTSP)
- Thermal Axis cameras: corrected megapixels (0.3MP/0.08MP LWIR sensors)

### Changed

- Database now covers **1,314 cameras** across **67 brands**

---

## [1.4.0] — 2026-06-11

### Added
Expand Down
65 changes: 33 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# CCTV Camera Database

An open, structured database of 1,324 CCTV / IP camera models and their technical specifications, covering 66 brands across every market segment — from budget consumer WiFi cameras to enterprise PTZ domes and thermal imaging systems. Each camera is a validated JSON file, aggregated into a single queryable dataset (JSON + CSV).
An open, structured database of 1,314 CCTV / IP camera models and their technical specifications, covering 67 brands across every market segment — from budget consumer WiFi cameras to enterprise PTZ domes and thermal imaging systems. Each camera is a validated JSON file, aggregated into a single queryable dataset (JSON + CSV).

[![cameras](https://img.shields.io/badge/cameras-1%2C324-blue)](data/cameras.json)
[![brands](https://img.shields.io/badge/brands-66-green)](cameras/)
[![cameras](https://img.shields.io/badge/cameras-1%2C314-blue)](data/cameras.json)
[![brands](https://img.shields.io/badge/brands-67-green)](cameras/)
[![license](https://img.shields.io/badge/license-CC0-lightgrey)](LICENSE)

---
Expand All @@ -27,7 +27,7 @@ Camera spec sheets are scattered across vendor PDFs, retailer pages, and paywall
- **Filter** — narrow by brand, camera type, night vision, resolution, or market
- **Sort** — click any column header to sort ascending/descending
- **Detail drawer** — click a row to slide open the full spec sheet (resolution, connectivity, protocols, storage, audio, pricing, source links)
- **Pagination** — page through all 1,324 cameras, 25 per page
- **Pagination** — page through all 1,314 cameras, 25 per page
- **Stats bar** — live counts for total cameras, brands, 4K+, WiFi, and no-subscription models

---
Expand All @@ -51,15 +51,15 @@ a Claude Code skill for AI-powered video production built on [Remotion](https://
```
cctv-camera-database/
├── cameras/ # source of truth — one JSON file per camera, grouped by brand
│ ├── hikvision/ # 139 cameras
│ ├── reolink/ # 133 cameras
│ ├── dahua/ # 101 cameras
│ ├── hanwha/ # 62 cameras
│ ├── axis/ # 58 cameras
│ ├── tapo/ # 56 cameras
│ ├── hikvision/ # 150 cameras
│ ├── reolink/ # 130 cameras
│ ├── dahua/ # 107 cameras
│ ├── hanwha/ # 71 cameras
│ ├── axis/ # 66 cameras
│ ├── tapo/ # 62 cameras
│ └── …60 more brands
├── data/ # GENERATED — do not edit by hand
│ ├── cameras.json # all 1,324 cameras as one array
│ ├── cameras.json # all 1,314 cameras as one array
│ └── cameras.csv # flattened, spreadsheet-friendly
├── schema/
│ └── camera.schema.json
Expand Down Expand Up @@ -117,45 +117,45 @@ Or open `data/cameras.csv` in any spreadsheet for a quick browse.

| Metric | Count |
|--------|-------|
| Total cameras | **1,324** |
| Brands | **66** |
| Total cameras | **1,314** |
| Brands | **67** |
| Form factors | 10 (bullet, dome, turret, PTZ, dual-lens, panoramic, covert, box, fisheye, doorbell) |
| PoE wired | 863 |
| WiFi | 427 |
| Battery / wire-free | 130 |
| 4K / 8MP+ | 411 |
| 4–5MP | 588 |
| 1080p–2MP | 296 |
| PoE wired | 856 |
| WiFi | 430 |
| Battery / wire-free | 155 |
| 4K / 8MP+ | 417 |
| 4–5MP | 594 |
| 1080p–2MP | 292 |

### All 66 brands
### All 67 brands

| Brand | Cameras | Segment |
|-------|---------|---------|
| Hikvision | 151 | Enterprise + consumer, global |
| Reolink | 133 | Prosumer, no-subscription, global |
| Dahua | 111 | Enterprise + consumer, global |
| Hikvision | 150 | Enterprise + consumer, global |
| Reolink | 130 | Prosumer, no-subscription, global |
| Dahua | 107 | Enterprise + consumer, global |
| Hanwha | 71 | Enterprise AI, Korea/global |
| Axis | 68 | Enterprise premium, global |
| Tapo (TP-Link) | 64 | Consumer budget, global |
| Axis | 66 | Enterprise premium, global |
| Tapo (TP-Link) | 62 | Consumer budget, global |
| Eufy (Anker) | 36 | Consumer no-subscription, global |
| Arlo | 31 | Consumer premium wire-free, global |
| Ring (Amazon) | 30 | Consumer ecosystem, US/EU/AU |
| Arlo | 29 | Consumer premium wire-free, global |
| Ring (Amazon) | 25 | Consumer ecosystem, US/EU/AU |
| Avigilon | 24 | Enterprise NDAA, US/CA |
| Amcrest | 24 | Prosumer, US |
| Ubiquiti UniFi | 26 | Prosumer/SMB, US/global |
| Annke | 23 | Prosumer, global |
| Google Nest | 23 | Consumer smart home, global |
| Google Nest | 19 | Consumer smart home, global |
| Bosch | 22 | Enterprise, EU/global |
| EZVIZ (Hikvision) | 21 | Consumer, global |
| Lorex | 21 | Consumer NVR systems, CA/US |
| HiLook (Hikvision) | 20 | Budget installer, EU/UK/AU |
| Lupus Electronics | 20 | Privacy-first, DE/AT/CH |
| Tiandy | 20 | Enterprise + prosumer, CN/ME/Africa |
| Uniview | 17 | Enterprise NDAA, global |
| Uniview | 15 | Enterprise NDAA, global |
| Blink (Amazon) | 16 | Budget battery, US/UK/EU |
| Swann | 16 | Consumer, AU/US/UK |
| ABUS | 15 | Consumer/SMB GDPR-first, DE/AT/CH |
| CP Plus | 15 | India #2 brand, IN |
| CP Plus | 14 | India #2 brand, IN |
| GeoVision | 15 | Enterprise, TW/Asia/global |
| IMOU (Dahua) | 15 | Consumer, global |
| Milesight | 15 | Prosumer/Enterprise IoT, global |
Expand All @@ -166,6 +166,7 @@ Or open `data/cameras.csv` in any spreadsheet for a quick browse.
| FLIR (Teledyne) | 12 | Thermal imaging, NA/EU |
| Kedacom | 12 | Enterprise, CN/global |
| Sunell | 12 | Prosumer/Enterprise, CN/global |
| SV3C | 13 | Budget consumer, CN/US |
| Synology | 12 | NAS-native cameras, global |
| TVT Digital | 12 | Prosumer budget, CN/IN/SE Asia |
| Hi-Focus | 10 | Made-in-India, BIS certified, IN |
Expand All @@ -180,10 +181,10 @@ Or open `data/cameras.csv` in any spreadsheet for a quick browse.
| March Networks | 6 | Enterprise retail/banking, NA |
| Netatmo | 6 | Privacy-first no-subscription, EU |
| Secureye | 6 | Budget consumer, IN |
| ADT | 5 | Monitored security, US |
| ADT | 4 | Monitored security, US |
| Hive (British Gas) | 5 | Consumer smart home, UK |
| KBvision | 5 | Budget installer, VN |
| Somfy | 5 | Smart home, FR/EU |
| Somfy | 3 | Smart home, FR/EU |
| Godrej | 4 | Consumer, IN |
| Honeywell | 4 | Enterprise, US/IN |
| Qubo (Hero) | 4 | Consumer IoT, IN |
Expand Down
19 changes: 2 additions & 17 deletions cameras/abus/ppic90520.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@
"nvr_compatible": false,
"cloud": false
},
"protocols": [
"rtsp"
],
"protocols": [],
"ip_rating": "IP65",
"audio": {
"microphone": true,
Expand All @@ -72,22 +70,9 @@
"solar"
],
"configs": {
"frigate": {
"detect": {
"width": 640,
"height": 480,
"fps": 5
},
"rtsp_url_template": "rtsp://{user}:{pass}@{ip}:554/Streaming/Channels/101",
"best_substream": "rtsp://{user}:{pass}@{ip}:554/Streaming/Channels/102"
},
"home_assistant": {
"integration": "onvif",
"notes": "Use ONVIF integration."
},
"blue_iris": {
"profile": "Hikvision",
"notes": "Select 'Hikvision' profile. Most ABUS IP cameras use Hikvision protocol."
"notes": "Battery/solar ABUS camera. RTSP/ONVIF support unconfirmed for this battery model. May be app-only."
}
}
}
1 change: 0 additions & 1 deletion cameras/abus/ppic90520.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
| Night vision | ir (8m) |
| Power | Rechargeable battery / optional solar panel (PPIC90650) |
| Storage | microSD ≤ 128GB |
| Protocols | rtsp |
| IP rating | IP65 |
| Two-way audio | Yes |
| Released | 2023 |
Expand Down
1 change: 1 addition & 0 deletions cameras/abus/tvip61600.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"two_way": false
},
"features": [
"pan/tilt/zoom",
"ABUS 1080p 12x PTZ outdoor",
"50m IR",
"H.265",
Expand Down
1 change: 1 addition & 0 deletions cameras/abus/tvip61600.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

## Features

- pan/tilt/zoom
- ABUS 1080p 12x PTZ outdoor
- 50m IR
- H.265
Expand Down
3 changes: 2 additions & 1 deletion cameras/acti/kcm-5611.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,6 @@
"profile": "ACTi",
"notes": "Select 'ACTi' profile. Default RTSP port is 7070."
}
}
},
"status": "discontinued"
}
2 changes: 1 addition & 1 deletion cameras/acti/q416.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"megapixels": 12,
"max_width": 4000,
"max_height": 3000,
"label": "12MP"
"label": "12MP UHD"
},
"sensor": "1/1.7\" CMOS",
"lens": {
Expand Down
2 changes: 1 addition & 1 deletion cameras/acti/q416.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
| Model | Q416 |
| Type | fisheye |
| Connectivity | ethernet |
| Resolution | 12MP (12MP, 4000×3000) |
| Resolution | 12MP UHD (12MP, 4000×3000) |
| Sensor | 1/1.7" CMOS |
| Lens | 1× 1.65 (fisheye)mm |
| Field of view | 180 horizontal° |
Expand Down
3 changes: 3 additions & 0 deletions cameras/adt/command-indoor-cam.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,8 @@
],
"power_source": [
"usb"
],
"markets": [
"US"
]
}
Loading
Loading