hikcloudstream 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. hikcloudstream-0.1.0/.env.example +3 -0
  2. hikcloudstream-0.1.0/.github/workflows/ci.yml +36 -0
  3. hikcloudstream-0.1.0/.gitignore +14 -0
  4. hikcloudstream-0.1.0/.python-version +1 -0
  5. hikcloudstream-0.1.0/AGENT.md +88 -0
  6. hikcloudstream-0.1.0/CHANGELOG.md +16 -0
  7. hikcloudstream-0.1.0/CONTRIBUTING.md +45 -0
  8. hikcloudstream-0.1.0/LICENSE +0 -0
  9. hikcloudstream-0.1.0/NOTICE +12 -0
  10. hikcloudstream-0.1.0/PKG-INFO +148 -0
  11. hikcloudstream-0.1.0/README.md +108 -0
  12. hikcloudstream-0.1.0/docs/MAINTAINER_BLUEPRINT.md +55 -0
  13. hikcloudstream-0.1.0/docs/architecture.md +45 -0
  14. hikcloudstream-0.1.0/docs/limitations.md +24 -0
  15. hikcloudstream-0.1.0/docs/quickstart.md +70 -0
  16. hikcloudstream-0.1.0/docs/streaming.md +56 -0
  17. hikcloudstream-0.1.0/examples/cloud_snapshot.py +31 -0
  18. hikcloudstream-0.1.0/examples/list_cameras.py +25 -0
  19. hikcloudstream-0.1.0/examples/live_frame.py +31 -0
  20. hikcloudstream-0.1.0/examples/mjpeg_proxy.py +30 -0
  21. hikcloudstream-0.1.0/examples/record_clip.py +31 -0
  22. hikcloudstream-0.1.0/pyproject.toml +83 -0
  23. hikcloudstream-0.1.0/src/hikcloudstream/__init__.py +39 -0
  24. hikcloudstream-0.1.0/src/hikcloudstream/_config.py +15 -0
  25. hikcloudstream-0.1.0/src/hikcloudstream/auth.py +30 -0
  26. hikcloudstream-0.1.0/src/hikcloudstream/capture.py +37 -0
  27. hikcloudstream-0.1.0/src/hikcloudstream/cli/__init__.py +1 -0
  28. hikcloudstream-0.1.0/src/hikcloudstream/cli/_common.py +140 -0
  29. hikcloudstream-0.1.0/src/hikcloudstream/cli/snapshot.py +125 -0
  30. hikcloudstream-0.1.0/src/hikcloudstream/cli/stream.py +226 -0
  31. hikcloudstream-0.1.0/src/hikcloudstream/client.py +296 -0
  32. hikcloudstream-0.1.0/src/hikcloudstream/exceptions.py +48 -0
  33. hikcloudstream-0.1.0/src/hikcloudstream/models.py +48 -0
  34. hikcloudstream-0.1.0/src/hikcloudstream/py.typed +0 -0
  35. hikcloudstream-0.1.0/src/hikcloudstream/stream/__init__.py +26 -0
  36. hikcloudstream-0.1.0/src/hikcloudstream/stream/adapter.py +123 -0
  37. hikcloudstream-0.1.0/src/hikcloudstream/stream/crypto.py +178 -0
  38. hikcloudstream-0.1.0/src/hikcloudstream/stream/probe.py +62 -0
  39. hikcloudstream-0.1.0/src/hikcloudstream/stream/rtp.py +31 -0
  40. hikcloudstream-0.1.0/src/hikcloudstream/stream/session.py +391 -0
  41. hikcloudstream-0.1.0/src/hikcloudstream/stream/sinks/__init__.py +1 -0
  42. hikcloudstream-0.1.0/src/hikcloudstream/stream/sinks/annex_b.py +76 -0
  43. hikcloudstream-0.1.0/src/hikcloudstream/stream/sinks/http.py +250 -0
  44. hikcloudstream-0.1.0/src/hikcloudstream/stream/sinks/mjpeg.py +126 -0
  45. hikcloudstream-0.1.0/src/hikcloudstream/stream/sinks/mpegts.py +167 -0
  46. hikcloudstream-0.1.0/src/hikcloudstream/stream/tokens.py +107 -0
  47. hikcloudstream-0.1.0/tests/unit/test_crypto.py +35 -0
  48. hikcloudstream-0.1.0/tests/unit/test_probe.py +22 -0
  49. hikcloudstream-0.1.0/tests/unit/test_rtp.py +34 -0
  50. hikcloudstream-0.1.0/uv.lock +1057 -0
@@ -0,0 +1,3 @@
1
+ HIK_CONNECT_USER=
2
+ HIK_CONNECT_PASSWORD=
3
+ HIK_CONNECT_VALIDATE_CODE=
@@ -0,0 +1,36 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.11", "3.12", "3.13"]
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - name: Install uv
19
+ uses: astral-sh/setup-uv@v5
20
+ with:
21
+ enable-cache: true
22
+
23
+ - name: Set up Python
24
+ run: uv python install ${{ matrix.python-version }}
25
+
26
+ - name: Install dependencies
27
+ run: uv sync --all-extras --python ${{ matrix.python-version }}
28
+
29
+ - name: Ruff
30
+ run: uv run ruff check src tests
31
+
32
+ - name: Unit tests
33
+ run: uv run pytest tests/unit -v
34
+
35
+ - name: Build wheel
36
+ run: uv build
@@ -0,0 +1,14 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .env
8
+ .pytest_cache/
9
+ .mypy_cache/
10
+ .ruff_cache/
11
+ *.ts
12
+ examples/output/
13
+ *.jpg
14
+ !tests/fixtures/*.jpg
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,88 @@
1
+ # Agent directives
2
+
3
+ > **Entry point for LLM agents and contributors working in this repository.**
4
+
5
+ ## What this repo is
6
+
7
+ **hikcloudstream** is an unofficial Python SDK for **Hik-Connect cloud cameras**:
8
+
9
+ - REST login, device list, cloud snapshots
10
+ - Live video via **cloud VTM relay** (not LAN RTSP, not P2P)
11
+
12
+ It is a **public open-source library** (Apache-2.0), not a sandbox experiment.
13
+
14
+ ## Language policy (non-negotiable)
15
+
16
+ **All code artifacts must be in English:**
17
+
18
+ - Identifiers, docstrings, comments, CLI help, error messages, HTTP viewer HTML
19
+ - README and docs inside the repo
20
+ - Commit messages (Conventional Commits)
21
+
22
+ You may chat with the user in their language; never mirror it in the codebase.
23
+
24
+ ## Sensitive data policy
25
+
26
+ **Never commit:**
27
+
28
+ - Real usernames, passwords, device serials, validate codes
29
+ - APK decompile trees or proprietary SDK blobs
30
+ - Condominium-specific names or private regional host examples beyond public `api.hik-connect.com`
31
+
32
+ Use `.env` locally (gitignored). Examples use `user@example.com` placeholders only.
33
+
34
+ ## Architecture map
35
+
36
+ | Module | Responsibility |
37
+ |--------|----------------|
38
+ | `src/hikcloudstream/client.py` | REST API, login, list, snapshot |
39
+ | `src/hikcloudstream/capture.py` | Cloud snapshot AES decrypt |
40
+ | `src/hikcloudstream/stream/session.py` | VTM session, `LiveStreamSession`, record/capture helpers |
41
+ | `src/hikcloudstream/stream/probe.py` | Auto stream type (substream vs main) |
42
+ | `src/hikcloudstream/stream/rtp.py` | RTP → Annex B |
43
+ | `src/hikcloudstream/stream/crypto.py` | Encrypted NAL decrypt |
44
+ | `src/hikcloudstream/stream/sinks/` | MPEG-TS, MJPEG, HTTP viewer |
45
+ | `src/hikcloudstream/cli/` | Thin CLI over public API only |
46
+
47
+ Stable exports live in `src/hikcloudstream/__init__.py` and `src/hikcloudstream/stream/__init__.py`.
48
+
49
+ ## How to change things safely
50
+
51
+ 1. Read surrounding code; match naming and patterns.
52
+ 2. Keep CLI and examples on the **public API** — no direct `pyezvizapi` in `cli/`.
53
+ 3. Breaking API changes → update `CHANGELOG.md` and README examples.
54
+ 4. Prefer typed exceptions from `exceptions.py` over bare `RuntimeError`.
55
+ 5. Unit-test protocol logic (RTP, crypto) with redacted fixtures — no live credentials in CI.
56
+
57
+ ## Common pitfalls
58
+
59
+ | Issue | Cause | Note |
60
+ |-------|-------|------|
61
+ | Black video on main stream | Proprietary RTP on some DVR channels | Auto substream (`stream=2`) |
62
+ | VTDU token failure | Wrong auth path for Hik-Connect | Primary: `POST /api/user/token/get` |
63
+ | MJPEG viewer + encryption | Decrypt not wired in viewer | Use `validate_code` with record/snapshot only |
64
+ | N viewers = N VTM sessions | One TCP session per consumer | Document fan-out / HLS for scale |
65
+
66
+ ## Testing expectations
67
+
68
+ - `tests/unit/` must pass in CI without secrets
69
+ - Integration tests: `@pytest.mark.integration`, env-gated only
70
+ - Run `uv run ruff check src tests` before finishing
71
+
72
+ ## Routing
73
+
74
+ | Need | Go to |
75
+ |------|--------|
76
+ | User-facing overview | [README.md](README.md) |
77
+ | Streaming API detail | [docs/streaming.md](docs/streaming.md) |
78
+ | Maintainer blueprint | [docs/MAINTAINER_BLUEPRINT.md](docs/MAINTAINER_BLUEPRINT.md) |
79
+ | Legal / OSS notes | MAINTAINER_BLUEPRINT § License |
80
+
81
+ ## Conflict resolution
82
+
83
+ 1. User explicit choice
84
+ 2. This `AGENT.md` for repo-specific rules
85
+ 3. Target module conventions
86
+ 4. Generic best practice
87
+
88
+ If the developer also uses the **pkb** workspace, engineering discipline from `pkb/CLAUDE.md` applies unless it conflicts with this file.
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2026-06-09
9
+
10
+ ### Added
11
+
12
+ - Initial public release migrated from sandbox prototype
13
+ - `HikConnectClient` — login, list cameras, cloud snapshot
14
+ - `hikcloudstream.stream` — VTM live sessions, auto stream probe, MPEG-TS record, MJPEG viewer
15
+ - CLI: `hikcloudstream-snapshot`, `hikcloudstream-stream`
16
+ - Examples, docs, unit tests, GitHub Actions CI
@@ -0,0 +1,45 @@
1
+ # Contributing
2
+
3
+ Thanks for helping improve **hikcloudstream**. This project is early-stage (0.x); APIs may change.
4
+
5
+ ## Setup
6
+
7
+ ```bash
8
+ git clone https://github.com/cristianojmiranda/hikcloudstream.git
9
+ cd hikcloudstream
10
+ uv sync --all-extras
11
+ ```
12
+
13
+ ## Run tests
14
+
15
+ ```bash
16
+ uv run pytest tests/unit -v
17
+ uv run ruff check src tests
18
+ uv run mypy src/hikcloudstream
19
+ ```
20
+
21
+ Integration tests (live Hik-Connect account) are optional:
22
+
23
+ ```bash
24
+ export HIK_CONNECT_USER=...
25
+ export HIK_CONNECT_PASSWORD=...
26
+ uv run pytest -m integration # when added
27
+ ```
28
+
29
+ Never commit credentials or device serials from your environment.
30
+
31
+ ## Pull request checklist
32
+
33
+ - [ ] English for code, comments, CLI help, and user-facing errors
34
+ - [ ] No secrets, real account names, or private URLs in the diff
35
+ - [ ] Unit tests for behavior changes (rtp, crypto, probe logic)
36
+ - [ ] Public API changes documented in `CHANGELOG.md`
37
+ - [ ] `uv run ruff check` and `uv run pytest tests/unit` pass
38
+
39
+ ## Commits
40
+
41
+ Use [Conventional Commits](https://www.conventionalcommits.org/): `feat:`, `fix:`, `docs:`, `test:`, `refactor:`, etc.
42
+
43
+ ## AI-assisted changes
44
+
45
+ Read [AGENT.md](AGENT.md) before editing. Keep diffs focused; match existing module layout.
File without changes
@@ -0,0 +1,12 @@
1
+ hikcloudstream
2
+ Copyright 2026 Cristiano Miranda
3
+
4
+ Licensed under the Apache License, Version 2.0.
5
+
6
+ This project depends on:
7
+
8
+ - pyezvizapi (Apache-2.0) — https://github.com/RenierM26/pyEzvizApi
9
+ - httpx (BSD-3-Clause) — https://github.com/encode/httpx
10
+ - pycryptodome (BSD) — https://github.com/Legrandin/pycryptodome
11
+ - pillow (MIT-CMU) — optional extra [cli]/[viewer]
12
+ - av / PyAV (BSD-3-Clause) — optional extra [viewer]
@@ -0,0 +1,148 @@
1
+ Metadata-Version: 2.4
2
+ Name: hikcloudstream
3
+ Version: 0.1.0
4
+ Summary: Unofficial Python SDK for Hik-Connect cloud cameras: list devices, snapshots, and live VTM streaming
5
+ Project-URL: Homepage, https://github.com/cristianojmiranda/hikcloudstream
6
+ Project-URL: Documentation, https://github.com/cristianojmiranda/hikcloudstream#readme
7
+ Project-URL: Repository, https://github.com/cristianojmiranda/hikcloudstream
8
+ Project-URL: Issues, https://github.com/cristianojmiranda/hikcloudstream/issues
9
+ Author: Cristiano Miranda
10
+ License-Expression: Apache-2.0
11
+ License-File: LICENSE
12
+ License-File: NOTICE
13
+ Keywords: camera,cctv,cloud,ezviz,hik-connect,hikvision,nvr,streaming,vtm
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: Apache Software License
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Multimedia :: Video :: Capture
21
+ Classifier: Topic :: System :: Networking
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.11
24
+ Requires-Dist: httpx>=0.28.0
25
+ Requires-Dist: pycryptodome>=3.21.0
26
+ Requires-Dist: pyezvizapi>=1.0.4.5
27
+ Provides-Extra: cli
28
+ Requires-Dist: pillow>=11.0.0; extra == 'cli'
29
+ Provides-Extra: dev
30
+ Requires-Dist: av>=17.1.0; extra == 'dev'
31
+ Requires-Dist: mypy>=1.13; extra == 'dev'
32
+ Requires-Dist: pillow>=11.0.0; extra == 'dev'
33
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
34
+ Requires-Dist: pytest>=8.0; extra == 'dev'
35
+ Requires-Dist: ruff>=0.8; extra == 'dev'
36
+ Provides-Extra: viewer
37
+ Requires-Dist: av>=17.1.0; extra == 'viewer'
38
+ Requires-Dist: pillow>=11.0.0; extra == 'viewer'
39
+ Description-Content-Type: text/markdown
40
+
41
+ # hikcloudstream
42
+
43
+ [![CI](https://github.com/cristianojmiranda/hikcloudstream/actions/workflows/ci.yml/badge.svg)](https://github.com/cristianojmiranda/hikcloudstream/actions/workflows/ci.yml)
44
+ ![Python](https://img.shields.io/badge/python-3.11%2B-blue)
45
+ ![License](https://img.shields.io/badge/license-Apache--2.0-green)
46
+
47
+ **Unofficial** Python SDK for **Hik-Connect cloud cameras** — list devices, cloud snapshots, and live streaming over the VTM relay.
48
+
49
+ > If you have Hik-Connect cameras in the cloud (condo, shared NVR, no RTSP URL) and found almost nothing on GitHub — that's why this exists. This is a **community library**, not an official Hikvision or EZVIZ product. APIs can change without notice.
50
+
51
+ ## What it does
52
+
53
+ - Log in with your Hik-Connect account (same credentials as the mobile app)
54
+ - List cameras and channels on the account
55
+ - Cloud snapshot (~352×288 thumbnail via API)
56
+ - **Live stream** via cloud VTM relay (H.264 → Annex B, MPEG-TS, MJPEG viewer)
57
+ - Auto-select substream vs main stream per camera
58
+
59
+ ## What it does **not** do
60
+
61
+ - LAN RTSP / ONVIF / ISAPI (use FFmpeg, go2rtc, or HCNetSDK for local NVR access)
62
+ - P2P hole-punching (the app uses P2P at home; remote cloud preview uses **VTM relay** — same path as this library)
63
+ - Official support or guaranteed API stability
64
+
65
+ ## Quick start
66
+
67
+ ```bash
68
+ git clone https://github.com/cristianojmiranda/hikcloudstream.git
69
+ cd hikcloudstream
70
+ uv sync --extra viewer
71
+ ```
72
+
73
+ ```python
74
+ from hikcloudstream import Credentials, HikConnectClient
75
+
76
+ with HikConnectClient() as client:
77
+ client.login(Credentials("user@example.com", "your_password"))
78
+ for cam in client.list_cameras():
79
+ print(cam.index, cam.name, cam.device_serial, cam.channel_no)
80
+ ```
81
+
82
+ ## Install
83
+
84
+ | Extra | Purpose | Command |
85
+ |-------|---------|---------|
86
+ | core | API + streaming protocol | `pip install hikcloudstream` or `uv sync` |
87
+ | `cli` | Command-line tools + Pillow | `uv sync --extra cli` |
88
+ | `viewer` | MJPEG HTTP viewer (PyAV) | `uv sync --extra viewer` |
89
+ | `dev` | Tests, ruff, mypy | `uv sync --extra dev` |
90
+
91
+ **System dependency:** [FFmpeg](https://ffmpeg.org/) (`ffmpeg` on PATH) for recording, HD frame capture, and MPEG-TS remux.
92
+
93
+ ## CLI
94
+
95
+ ```bash
96
+ export HIK_CONNECT_USER="user@example.com"
97
+ export HIK_CONNECT_PASSWORD="your_password"
98
+
99
+ uv run hikcloudstream-snapshot "$HIK_CONNECT_USER" "$HIK_CONNECT_PASSWORD" --list
100
+ uv run hikcloudstream-snapshot "$HIK_CONNECT_USER" "$HIK_CONNECT_PASSWORD" 1 -o thumb.jpg
101
+ uv run hikcloudstream-stream "$HIK_CONNECT_USER" "$HIK_CONNECT_PASSWORD" 1 --proxy
102
+ uv run hikcloudstream-stream "$HIK_CONNECT_USER" "$HIK_CONNECT_PASSWORD" 1 -o frame.jpg --duration 6s
103
+ ```
104
+
105
+ Open `http://127.0.0.1:8558/` in a browser when using `--proxy`.
106
+
107
+ ## Stream types
108
+
109
+ | `stream=` | Typical use |
110
+ |-----------|-------------|
111
+ | **2** (substream) | Lower bandwidth, standard H.264 — works on most DVR channels |
112
+ | **1** (main) | Higher resolution; some cameras only expose this stream |
113
+ | **auto** (default) | Probes substream for 5s, falls back to main |
114
+
115
+ Force main stream in Python: `StreamType.MAIN`. In CLI: `--main-stream`.
116
+
117
+ ## Examples
118
+
119
+ See [`examples/`](examples/) — each script documents required extras and env vars.
120
+
121
+ ## Documentation
122
+
123
+ - [Quickstart](docs/quickstart.md)
124
+ - [Streaming API](docs/streaming.md)
125
+ - [Limitations](docs/limitations.md)
126
+ - [Architecture](docs/architecture.md)
127
+
128
+ ## Origin
129
+
130
+ Live streaming was reverse-engineered from the **Hik-Connect for End User** mobile app and aligned with [pyezvizapi](https://github.com/RenierM26/pyEzvizApi). The implementation uses the **cloud VTM relay protocol**.
131
+
132
+ ## Related projects
133
+
134
+ - [pyezvizapi](https://github.com/RenierM26/pyEzvizApi) — VTM protocol (Apache-2.0)
135
+ - [Home Assistant EZVIZ](https://www.home-assistant.io/integrations/ezviz/) — integration using pyezvizapi
136
+ - [go2rtc](https://github.com/AlexxIT/go2rtc) — LAN RTSP/WebRTC aggregator
137
+
138
+ ## Contributing
139
+
140
+ See [CONTRIBUTING.md](CONTRIBUTING.md). AI agents: read [AGENT.md](AGENT.md) first.
141
+
142
+ ## Legal disclaimer
143
+
144
+ This is an **unofficial** community project. It is **not** affiliated with, endorsed by, or supported by Hangzhou Hikvision Digital Technology Co., Ltd. or EZVIZ. Use at your own risk. You are responsible for complying with Hik-Connect / EZVIZ Terms of Service and applicable law. Trademarks belong to their respective owners.
145
+
146
+ ## License
147
+
148
+ Apache-2.0 — see [LICENSE](LICENSE) and [NOTICE](NOTICE).
@@ -0,0 +1,108 @@
1
+ # hikcloudstream
2
+
3
+ [![CI](https://github.com/cristianojmiranda/hikcloudstream/actions/workflows/ci.yml/badge.svg)](https://github.com/cristianojmiranda/hikcloudstream/actions/workflows/ci.yml)
4
+ ![Python](https://img.shields.io/badge/python-3.11%2B-blue)
5
+ ![License](https://img.shields.io/badge/license-Apache--2.0-green)
6
+
7
+ **Unofficial** Python SDK for **Hik-Connect cloud cameras** — list devices, cloud snapshots, and live streaming over the VTM relay.
8
+
9
+ > If you have Hik-Connect cameras in the cloud (condo, shared NVR, no RTSP URL) and found almost nothing on GitHub — that's why this exists. This is a **community library**, not an official Hikvision or EZVIZ product. APIs can change without notice.
10
+
11
+ ## What it does
12
+
13
+ - Log in with your Hik-Connect account (same credentials as the mobile app)
14
+ - List cameras and channels on the account
15
+ - Cloud snapshot (~352×288 thumbnail via API)
16
+ - **Live stream** via cloud VTM relay (H.264 → Annex B, MPEG-TS, MJPEG viewer)
17
+ - Auto-select substream vs main stream per camera
18
+
19
+ ## What it does **not** do
20
+
21
+ - LAN RTSP / ONVIF / ISAPI (use FFmpeg, go2rtc, or HCNetSDK for local NVR access)
22
+ - P2P hole-punching (the app uses P2P at home; remote cloud preview uses **VTM relay** — same path as this library)
23
+ - Official support or guaranteed API stability
24
+
25
+ ## Quick start
26
+
27
+ ```bash
28
+ git clone https://github.com/cristianojmiranda/hikcloudstream.git
29
+ cd hikcloudstream
30
+ uv sync --extra viewer
31
+ ```
32
+
33
+ ```python
34
+ from hikcloudstream import Credentials, HikConnectClient
35
+
36
+ with HikConnectClient() as client:
37
+ client.login(Credentials("user@example.com", "your_password"))
38
+ for cam in client.list_cameras():
39
+ print(cam.index, cam.name, cam.device_serial, cam.channel_no)
40
+ ```
41
+
42
+ ## Install
43
+
44
+ | Extra | Purpose | Command |
45
+ |-------|---------|---------|
46
+ | core | API + streaming protocol | `pip install hikcloudstream` or `uv sync` |
47
+ | `cli` | Command-line tools + Pillow | `uv sync --extra cli` |
48
+ | `viewer` | MJPEG HTTP viewer (PyAV) | `uv sync --extra viewer` |
49
+ | `dev` | Tests, ruff, mypy | `uv sync --extra dev` |
50
+
51
+ **System dependency:** [FFmpeg](https://ffmpeg.org/) (`ffmpeg` on PATH) for recording, HD frame capture, and MPEG-TS remux.
52
+
53
+ ## CLI
54
+
55
+ ```bash
56
+ export HIK_CONNECT_USER="user@example.com"
57
+ export HIK_CONNECT_PASSWORD="your_password"
58
+
59
+ uv run hikcloudstream-snapshot "$HIK_CONNECT_USER" "$HIK_CONNECT_PASSWORD" --list
60
+ uv run hikcloudstream-snapshot "$HIK_CONNECT_USER" "$HIK_CONNECT_PASSWORD" 1 -o thumb.jpg
61
+ uv run hikcloudstream-stream "$HIK_CONNECT_USER" "$HIK_CONNECT_PASSWORD" 1 --proxy
62
+ uv run hikcloudstream-stream "$HIK_CONNECT_USER" "$HIK_CONNECT_PASSWORD" 1 -o frame.jpg --duration 6s
63
+ ```
64
+
65
+ Open `http://127.0.0.1:8558/` in a browser when using `--proxy`.
66
+
67
+ ## Stream types
68
+
69
+ | `stream=` | Typical use |
70
+ |-----------|-------------|
71
+ | **2** (substream) | Lower bandwidth, standard H.264 — works on most DVR channels |
72
+ | **1** (main) | Higher resolution; some cameras only expose this stream |
73
+ | **auto** (default) | Probes substream for 5s, falls back to main |
74
+
75
+ Force main stream in Python: `StreamType.MAIN`. In CLI: `--main-stream`.
76
+
77
+ ## Examples
78
+
79
+ See [`examples/`](examples/) — each script documents required extras and env vars.
80
+
81
+ ## Documentation
82
+
83
+ - [Quickstart](docs/quickstart.md)
84
+ - [Streaming API](docs/streaming.md)
85
+ - [Limitations](docs/limitations.md)
86
+ - [Architecture](docs/architecture.md)
87
+
88
+ ## Origin
89
+
90
+ Live streaming was reverse-engineered from the **Hik-Connect for End User** mobile app and aligned with [pyezvizapi](https://github.com/RenierM26/pyEzvizApi). The implementation uses the **cloud VTM relay protocol**.
91
+
92
+ ## Related projects
93
+
94
+ - [pyezvizapi](https://github.com/RenierM26/pyEzvizApi) — VTM protocol (Apache-2.0)
95
+ - [Home Assistant EZVIZ](https://www.home-assistant.io/integrations/ezviz/) — integration using pyezvizapi
96
+ - [go2rtc](https://github.com/AlexxIT/go2rtc) — LAN RTSP/WebRTC aggregator
97
+
98
+ ## Contributing
99
+
100
+ See [CONTRIBUTING.md](CONTRIBUTING.md). AI agents: read [AGENT.md](AGENT.md) first.
101
+
102
+ ## Legal disclaimer
103
+
104
+ This is an **unofficial** community project. It is **not** affiliated with, endorsed by, or supported by Hangzhou Hikvision Digital Technology Co., Ltd. or EZVIZ. Use at your own risk. You are responsible for complying with Hik-Connect / EZVIZ Terms of Service and applicable law. Trademarks belong to their respective owners.
105
+
106
+ ## License
107
+
108
+ Apache-2.0 — see [LICENSE](LICENSE) and [NOTICE](NOTICE).
@@ -0,0 +1,55 @@
1
+ # Maintainer blueprint
2
+
3
+ Internal planning notes for **hikcloudstream** maintainers. The public README is the user-facing source of truth.
4
+
5
+ ## Protocol clarification
6
+
7
+ Live video uses **cloud VTM relay**, not LAN RTSP and not classic P2P hole-punching:
8
+
9
+ ```
10
+ Account login (REST)
11
+ → device/channel discovery (pagelist + VTM metadata)
12
+ → VTDU stream tokens
13
+ → TCP session to regional VTM server (ysproto://…)
14
+ → RTP carrying H.264
15
+ → depacketize / decode / remux
16
+ ```
17
+
18
+ The Hik-Connect mobile app also uses VTM for remote preview when P2P/LAN is unavailable. Do **not** describe this project as a “P2P stream fix.”
19
+
20
+ ## Trade-offs
21
+
22
+ | Decision | Pros | Cons |
23
+ |----------|------|------|
24
+ | Build on pyezvizapi | Battle-tested VTM framing | Hik-Connect adapter layer forever |
25
+ | VTM-only (no P2P) | Matches cloud condo use case | No LAN optimizations |
26
+ | PyAV for MJPEG | Low latency | Heavy optional dep; CPU per viewer |
27
+ | Auto stream probe | Works across DVR channels | ~5s connect delay |
28
+ | Alpha 0.x semver | API flexibility | Breaking changes possible |
29
+
30
+ ## License, copyright, and open-source safety
31
+
32
+ > Not legal advice.
33
+
34
+ Publishing as unofficial OSS is **reasonable** (same category as pyezvizapi, Home Assistant EZVIZ). Main risks: **ToS**, **trademark**, **secrets in repo** — not “you cannot copyright your Python.”
35
+
36
+ | Do | Don't |
37
+ |----|-------|
38
+ | Apache-2.0 + NOTICE | APK decompile, SDK blobs |
39
+ | README disclaimer | Official logos / “Hikvision SDK” naming |
40
+ | Placeholder examples | Real credentials or device serials |
41
+
42
+ See README legal disclaimer. Confirm employer IP if applicable.
43
+
44
+ ## Deferred (post-0.1.0)
45
+
46
+ - PyPI publish
47
+ - Async API (`httpx.AsyncClient`)
48
+ - P2P / LAN RTSP
49
+ - Encrypted live MJPEG viewer
50
+ - Home Assistant integration
51
+ - Dependabot, SECURITY.md, integration CI nightly
52
+
53
+ ## Public API stability
54
+
55
+ Exports in `hikcloudstream/__init__.py` and `hikcloudstream/stream/__init__.py` are the stable surface for 0.1.x. Breaking changes require CHANGELOG entry.
@@ -0,0 +1,45 @@
1
+ # Architecture
2
+
3
+ High-level data flow (no internal endpoint catalog):
4
+
5
+ ```
6
+ ┌─────────────┐ REST ┌──────────────────┐
7
+ │ Your app │ ────────────► │ HikConnectClient │
8
+ │ or CLI │ │ (httpx) │
9
+ └──────┬──────┘ └────────┬─────────┘
10
+ │ │
11
+ │ stream │ sessionId
12
+ ▼ ▼
13
+ ┌──────────────────┐ VTDU tokens ┌─────────────────┐
14
+ │ LiveStreamSession│ ◄──────────── │ stream/adapter │
15
+ └────────┬─────────┘ └─────────────────┘
16
+ │ ysproto://VTM:8554
17
+
18
+ ┌──────────────────┐ RTP H.264 ┌──────────────────┐
19
+ │ pyezvizapi VTM │ ────────────► │ stream/rtp │
20
+ │ client │ │ stream/sinks/* │
21
+ └──────────────────┘ └──────────────────┘
22
+ ```
23
+
24
+ ## Package layout
25
+
26
+ ```
27
+ src/hikcloudstream/
28
+ ├── client.py # REST API
29
+ ├── capture.py # Snapshot decrypt
30
+ ├── stream/
31
+ │ ├── session.py # VTM lifecycle
32
+ │ ├── probe.py # Auto stream type
33
+ │ ├── rtp.py # Depacketization
34
+ │ ├── crypto.py # Encrypted NAL
35
+ │ └── sinks/ # MPEG-TS, MJPEG, HTTP
36
+ └── cli/ # Optional commands
37
+ ```
38
+
39
+ ## Dependencies
40
+
41
+ - **httpx** — REST
42
+ - **pyezvizapi** — VTM TCP protocol
43
+ - **pycryptodome** — AES for snapshots and encrypted streams
44
+ - **av** (optional) — PyAV MJPEG decoder
45
+ - **FFmpeg** (system) — remux and frame extract
@@ -0,0 +1,24 @@
1
+ # Limitations
2
+
3
+ | Issue | Impact | Workaround |
4
+ |-------|--------|------------|
5
+ | Unofficial API | Endpoints may change | Pin `ClientConfig.client_version`; watch app updates |
6
+ | VTM session limits | N viewers = N cloud connections | Single ingest + HLS/WebRTC fan-out |
7
+ | Encrypted live MJPEG | Viewer raises error | `validate_code` on record/snapshot only |
8
+ | Proprietary RTP on main | Some channels black on `stream=1` | Auto substream (`stream=2`) |
9
+ | Channels without VTM | `Could not find VTM resource` | Channel offline or unlicensed |
10
+ | Cloud snapshot resolution | Fixed ~352×288 | Live frame capture for HD |
11
+ | CAPTCHA / 2FA | Login fails | Log in via official app first |
12
+ | No P2P / LAN RTSP | No direct NVR URL | Use go2rtc / RTSP for local access |
13
+ | Token / firewall | VTDU auth blocked | Ensure outbound HTTPS to Hik-Connect auth hosts |
14
+
15
+ ## Performance (single viewer)
16
+
17
+ Approximate values — vary by CPU, camera, and stream type:
18
+
19
+ | Profile | RAM | Egress |
20
+ |---------|-----|--------|
21
+ | Substream MJPEG | ~65 MB | ~0.7 Mbps |
22
+ | Main HD MJPEG | ~100 MB | ~10–15 Mbps |
23
+
24
+ Not suitable for 50+ viewers without architecture change — see [streaming.md](streaming.md).
@@ -0,0 +1,70 @@
1
+ # Quickstart
2
+
3
+ ## Install
4
+
5
+ ```bash
6
+ uv sync --extra viewer
7
+ # or: pip install "hikcloudstream[viewer]"
8
+ ```
9
+
10
+ Install [FFmpeg](https://ffmpeg.org/) for recording and HD frame capture.
11
+
12
+ ## Environment (optional)
13
+
14
+ ```bash
15
+ cp .env.example .env
16
+ # fill HIK_CONNECT_USER and HIK_CONNECT_PASSWORD
17
+ ```
18
+
19
+ ## List cameras
20
+
21
+ ```python
22
+ from hikcloudstream import Credentials, HikConnectClient
23
+
24
+ with HikConnectClient() as client:
25
+ client.login(Credentials("user@example.com", "your_password"))
26
+ for cam in client.list_cameras():
27
+ print(cam.index, cam.name, cam.device_serial, cam.channel_no)
28
+ ```
29
+
30
+ ## Cloud snapshot
31
+
32
+ ```python
33
+ from pathlib import Path
34
+ from hikcloudstream import Credentials, HikConnectClient
35
+
36
+ with HikConnectClient() as client:
37
+ client.login(Credentials("user@example.com", "your_password"))
38
+ cameras = client.list_cameras()
39
+ jpeg = client.capture_snapshot(cameras[0])
40
+ Path("thumb.jpg").write_bytes(jpeg)
41
+ ```
42
+
43
+ Resolution is capped at **352×288** by the Hik-Connect cloud API.
44
+
45
+ ## Live stream frame (HD)
46
+
47
+ ```python
48
+ from pathlib import Path
49
+ from hikcloudstream import Credentials, HikConnectClient
50
+ from hikcloudstream.stream import capture_live_snapshot
51
+
52
+ with HikConnectClient() as client:
53
+ client.login(Credentials("user@example.com", "your_password"))
54
+ cameras = client.list_cameras()
55
+ capture_live_snapshot(client, cameras[0], Path("frame.jpg"), warmup_seconds=6.0)
56
+ ```
57
+
58
+ ## MJPEG browser viewer
59
+
60
+ ```python
61
+ from hikcloudstream import Credentials, HikConnectClient
62
+ from hikcloudstream.stream import MjpegServer
63
+
64
+ with HikConnectClient() as client:
65
+ client.login(Credentials("user@example.com", "your_password"))
66
+ cameras = client.list_cameras()
67
+ MjpegServer(client, cameras[0], host="127.0.0.1", port=8558).serve_forever()
68
+ ```
69
+
70
+ Open `http://127.0.0.1:8558/`.