ipycam 1.2.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 (59) hide show
  1. ipycam-1.2.0/LICENSE +21 -0
  2. ipycam-1.2.0/PKG-INFO +305 -0
  3. ipycam-1.2.0/README.md +275 -0
  4. ipycam-1.2.0/ipycam/__init__.py +68 -0
  5. ipycam-1.2.0/ipycam/__main__.py +327 -0
  6. ipycam-1.2.0/ipycam/__version__.py +1 -0
  7. ipycam-1.2.0/ipycam/camera.py +558 -0
  8. ipycam-1.2.0/ipycam/config.py +161 -0
  9. ipycam-1.2.0/ipycam/discovery.py +84 -0
  10. ipycam-1.2.0/ipycam/http.py +632 -0
  11. ipycam-1.2.0/ipycam/mjpeg.py +280 -0
  12. ipycam-1.2.0/ipycam/onvif.py +416 -0
  13. ipycam-1.2.0/ipycam/ptz.py +486 -0
  14. ipycam-1.2.0/ipycam/rtsp.py +973 -0
  15. ipycam-1.2.0/ipycam/static/css/style.css +572 -0
  16. ipycam-1.2.0/ipycam/static/index.html +196 -0
  17. ipycam-1.2.0/ipycam/static/js/app.js +808 -0
  18. ipycam-1.2.0/ipycam/static/soap/envelope.xml +9 -0
  19. ipycam-1.2.0/ipycam/static/soap/fault.xml +9 -0
  20. ipycam-1.2.0/ipycam/static/soap/get_audio_decoder_configurations.xml +2 -0
  21. ipycam-1.2.0/ipycam/static/soap/get_capabilities.xml +21 -0
  22. ipycam-1.2.0/ipycam/static/soap/get_device_information.xml +7 -0
  23. ipycam-1.2.0/ipycam/static/soap/get_profiles.xml +77 -0
  24. ipycam-1.2.0/ipycam/static/soap/get_scopes.xml +5 -0
  25. ipycam-1.2.0/ipycam/static/soap/get_services.xml +18 -0
  26. ipycam-1.2.0/ipycam/static/soap/get_snapshot_uri.xml +8 -0
  27. ipycam-1.2.0/ipycam/static/soap/get_stream_uri.xml +8 -0
  28. ipycam-1.2.0/ipycam/static/soap/get_system_date_time.xml +19 -0
  29. ipycam-1.2.0/ipycam/static/soap/get_users.xml +6 -0
  30. ipycam-1.2.0/ipycam/static/soap/get_video_encoder_configuration.xml +16 -0
  31. ipycam-1.2.0/ipycam/static/soap/get_video_source_configuration.xml +8 -0
  32. ipycam-1.2.0/ipycam/static/soap/probe_match.xml +22 -0
  33. ipycam-1.2.0/ipycam/static/soap/ptz_absolute_move.xml +1 -0
  34. ipycam-1.2.0/ipycam/static/soap/ptz_continuous_move.xml +1 -0
  35. ipycam-1.2.0/ipycam/static/soap/ptz_get_configurations.xml +30 -0
  36. ipycam-1.2.0/ipycam/static/soap/ptz_get_node.xml +37 -0
  37. ipycam-1.2.0/ipycam/static/soap/ptz_get_nodes.xml +37 -0
  38. ipycam-1.2.0/ipycam/static/soap/ptz_get_presets.xml +3 -0
  39. ipycam-1.2.0/ipycam/static/soap/ptz_get_service_capabilities.xml +4 -0
  40. ipycam-1.2.0/ipycam/static/soap/ptz_get_status.xml +13 -0
  41. ipycam-1.2.0/ipycam/static/soap/ptz_goto_home.xml +1 -0
  42. ipycam-1.2.0/ipycam/static/soap/ptz_goto_preset.xml +1 -0
  43. ipycam-1.2.0/ipycam/static/soap/ptz_relative_move.xml +1 -0
  44. ipycam-1.2.0/ipycam/static/soap/ptz_set_preset.xml +3 -0
  45. ipycam-1.2.0/ipycam/static/soap/ptz_stop.xml +1 -0
  46. ipycam-1.2.0/ipycam/streamer.py +565 -0
  47. ipycam-1.2.0/ipycam/webrtc.py +503 -0
  48. ipycam-1.2.0/ipycam.egg-info/PKG-INFO +305 -0
  49. ipycam-1.2.0/ipycam.egg-info/SOURCES.txt +57 -0
  50. ipycam-1.2.0/ipycam.egg-info/dependency_links.txt +1 -0
  51. ipycam-1.2.0/ipycam.egg-info/entry_points.txt +2 -0
  52. ipycam-1.2.0/ipycam.egg-info/requires.txt +12 -0
  53. ipycam-1.2.0/ipycam.egg-info/top_level.txt +1 -0
  54. ipycam-1.2.0/pyproject.toml +64 -0
  55. ipycam-1.2.0/setup.cfg +4 -0
  56. ipycam-1.2.0/tests/test_config.py +301 -0
  57. ipycam-1.2.0/tests/test_mjpeg.py +306 -0
  58. ipycam-1.2.0/tests/test_onvif.py +377 -0
  59. ipycam-1.2.0/tests/test_ptz.py +394 -0
ipycam-1.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Oliver Hamilton
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
ipycam-1.2.0/PKG-INFO ADDED
@@ -0,0 +1,305 @@
1
+ Metadata-Version: 2.4
2
+ Name: ipycam
3
+ Version: 1.2.0
4
+ Summary: Pure Python Virtual IP Camera with ONVIF support
5
+ Author-email: Oliver Hamilton <oliver9523@gmail.com>
6
+ License-Expression: MIT
7
+ Keywords: camera,onvif,rtsp,streaming,virtual-camera
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.8
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Requires-Python: >=3.8
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: numpy>=1.24.0
20
+ Requires-Dist: opencv-python>=4.8.0
21
+ Requires-Dist: aiohttp>=3.9.0
22
+ Requires-Dist: aiortc>=1.14.0
23
+ Provides-Extra: camera360
24
+ Requires-Dist: framesource>=0.3.0; extra == "camera360"
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
27
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
28
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ # IPyCam - Pure Python Virtual IP Camera
32
+
33
+ A lightweight, pure Python virtual IP camera that provides ONVIF discovery, RTSP streaming, and PTZ controls. Perfect for testing, development, or creating custom camera solutions.
34
+
35
+ ## 📺 Demo Video
36
+ https://github.com/user-attachments/assets/1d3afd23-1ab8-40f6-876c-3f3f9a0089fe
37
+
38
+ [YouTube](https://www.youtube.com/watch?v=9AkqjnZRQTE)
39
+
40
+ ## Features
41
+
42
+ - **ONVIF Compliance**: Full WS-Discovery support for automatic camera detection
43
+ - **RTSP Streaming**: High-performance video streaming via go2rtc (optional) or native Python fallback
44
+ - **WebRTC Support**: Direct browser streaming with native Python implementation
45
+ - **PTZ Controls**: Digital Pan-Tilt-Zoom with preset positions
46
+ - **Hardware Acceleration**: Automatic detection and use of NVENC, QSV, or CPU encoding (with go2rtc)
47
+ - **Native Fallback**: Pure Python streaming (WebRTC, MJPEG) when go2rtc is not available
48
+ - **Web Interface**: Built-in configuration and live preview
49
+ - **Low Latency**: Optimized async frame pipeline for real-time streaming
50
+ - **Flexible Input**: Accept frames from any source (webcam, video file, generated content)
51
+
52
+ ## Requirements
53
+
54
+ - Python 3.8+
55
+ - **Optional**: FFmpeg + go2rtc for hardware-accelerated encoding (recommended for high performance)
56
+ - **Optional**: aiortc (`pip install aiortc`) for native WebRTC streaming fallback
57
+
58
+ > **Note**: IPyCam can run without go2rtc using pure Python streaming. However, go2rtc + FFmpeg provides significantly better performance, especially for high-resolution streams.
59
+
60
+ ## Quick Start
61
+
62
+ Clone the repo:
63
+ ```bash
64
+ git clone https://github.com/olkham/IPyCam.git
65
+ ```
66
+
67
+ ### Setup Scripts (Windows and Linux)
68
+
69
+ If you prefer a guided setup, use the provided scripts. They install dependencies and prepare the environment for running the examples.
70
+
71
+ **Windows (PowerShell or Command Prompt):**
72
+ ```bat
73
+ setup.bat
74
+ ```
75
+
76
+ **Linux/macOS (bash):**
77
+ ```bash
78
+ chmod +x setup.sh
79
+ ./setup.sh
80
+ ```
81
+
82
+ > **Tip**: Run the script from the project root (the folder that contains `setup.bat` and `setup.sh`).
83
+
84
+
85
+ ### Installation
86
+
87
+ Install directly from GitHub:
88
+ ```bash
89
+ pip install git+https://github.com/olkham/IPyCam.git
90
+ ```
91
+
92
+ Or install from source:
93
+ ```bash
94
+ git clone https://github.com/olkham/IPyCam.git
95
+ cd ipycam
96
+ pip install -e .
97
+ ```
98
+
99
+ **Optional: Enhanced Streaming Performance (Recommended)**
100
+
101
+ For hardware-accelerated encoding with go2rtc:
102
+
103
+ 1. **Install go2rtc**: Download from [go2rtc releases](https://github.com/AlexxIT/go2rtc/releases)
104
+ 2. **Start go2rtc** with IPyCam configuration:
105
+ ```bash
106
+ go2rtc.exe --config ipycam\go2rtc.yaml
107
+ ```
108
+ Keep this running in a separate terminal.
109
+
110
+ Without go2rtc, IPyCam will automatically fall back to native Python streaming.
111
+
112
+ **Optional: 360° Camera Support**
113
+
114
+ For the `360_ptz.py` example with equirectangular projection:
115
+ ```bash
116
+ pip install "ipycam[camera360]"
117
+ ```
118
+ or install FrameSource separately:
119
+ ```bash
120
+ pip install framesource
121
+ ```
122
+
123
+ ### Basic Usage
124
+
125
+ ```python
126
+ import cv2
127
+ from ipycam import IPCamera, CameraConfig
128
+
129
+ # Create camera with custom config
130
+ config = CameraConfig(
131
+ name="My Virtual Camera",
132
+ main_width=1920,
133
+ main_height=1080,
134
+ main_fps=30,
135
+ )
136
+
137
+ camera = IPCamera(config)
138
+ camera.start()
139
+
140
+ # Stream from webcam
141
+ cap = cv2.VideoCapture(0)
142
+
143
+ try:
144
+ while camera.is_running:
145
+ ret, frame = cap.read()
146
+ if ret:
147
+ camera.stream(frame)
148
+ except KeyboardInterrupt:
149
+ pass
150
+ finally:
151
+ cap.release()
152
+ camera.stop()
153
+ ```
154
+
155
+ ### Running as a Module
156
+
157
+ ```bash
158
+ python -m ipycam
159
+ ```
160
+
161
+ Then access:
162
+ - **Web UI**: http://localhost:8080/
163
+ - **RTSP Main Stream**: rtsp://localhost:8554/video_main
164
+ - **RTSP Sub Stream**: rtsp://localhost:8554/video_sub
165
+ - **ONVIF Service**: http://localhost:8080/onvif/device_service
166
+
167
+ ### Testing the Stream
168
+
169
+ Test the RTSP streams using ffplay:
170
+ ```bash
171
+ # Test main stream
172
+ ffplay rtsp://localhost:8554/video_main
173
+
174
+ # Test sub stream
175
+ ffplay rtsp://localhost:8554/video_sub
176
+ ```
177
+
178
+ ## Configuration
179
+
180
+ Configuration is stored in `camera_config.json`:
181
+
182
+ ```json
183
+ {
184
+ "name": "Virtual Camera",
185
+ "manufacturer": "PythonCam",
186
+ "model": "VirtualCam-1",
187
+ "main_width": 1920,
188
+ "main_height": 1080,
189
+ "main_fps": 30,
190
+ "main_bitrate": "4M",
191
+ "sub_width": 640,
192
+ "sub_height": 360,
193
+ "native_width": 640,
194
+ "native_height": 480,
195
+ "native_fps": 15,
196
+ "native_bitrate": "500K",
197
+ "hw_accel": "auto"
198
+ }
199
+ ```
200
+
201
+ Hardware acceleration options (go2rtc only):
202
+ - `"auto"` - Try NVENC → QSV → CPU (default)
203
+ - `"nvenc"` - NVIDIA GPU encoding
204
+ - `"qsv"` - Intel Quick Sync Video
205
+ - `"cpu"` - Software encoding (libx264)
206
+
207
+ Native fallback settings:
208
+ - `native_width/height/fps/bitrate` - Used when go2rtc is not available
209
+ - Lower resolution recommended for software encoding performance
210
+
211
+ ## PTZ Controls
212
+
213
+ The camera includes digital PTZ (Pan-Tilt-Zoom) support:
214
+
215
+ ```python
216
+ # Access PTZ through ONVIF or directly
217
+ camera.ptz.continuous_move(pan_speed=0.5, tilt_speed=0.0, zoom_speed=0.0)
218
+ camera.ptz.stop()
219
+ camera.ptz.goto_preset(preset_token="preset1")
220
+ ```
221
+
222
+ PTZ presets are stored in `ptz_presets.json`.
223
+
224
+ ## Performance Tips
225
+
226
+ 1. **Use hardware acceleration**: Enable NVENC (NVIDIA) or QSV (Intel) for best performance
227
+ 2. **Match resolutions**: Set camera input to match streaming resolution to avoid resize overhead
228
+ 3. **Adjust FPS**: Most webcams are limited to 30fps
229
+ 4. **Disable PTZ**: Set camera to home position (0,0,0) to skip PTZ transforms
230
+
231
+ ## Architecture
232
+
233
+ ```
234
+ ipycam/
235
+ ├── __init__.py # Package exports
236
+ ├── __main__.py # CLI entry point
237
+ ├── camera.py # Main IPCamera class
238
+ ├── config.py # CameraConfig dataclass
239
+ ├── streamer.py # Video encoding and streaming pipeline
240
+ ├── ptz.py # Digital PTZ implementation
241
+ ├── onvif.py # ONVIF SOAP service
242
+ ├── discovery.py # WS-Discovery server
243
+ ├── http.py # HTTP request handler
244
+ └── static/ # Web UI and SOAP templates
245
+ ```
246
+
247
+ ## Development
248
+
249
+ ### Running Tests
250
+
251
+ IPyCam includes a comprehensive test suite using pytest. To run the tests:
252
+
253
+ ```bash
254
+ # Install dev dependencies
255
+ pip install -e ".[dev]"
256
+
257
+ # Run all tests
258
+ pytest
259
+
260
+ # Run with verbose output
261
+ pytest -v
262
+
263
+ # Run with coverage report
264
+ pytest --cov=ipycam --cov-report=term-missing
265
+
266
+ # Run specific test file
267
+ pytest tests/test_config.py
268
+ pytest tests/test_ptz.py
269
+ pytest tests/test_mjpeg.py
270
+ pytest tests/test_onvif.py
271
+ ```
272
+
273
+ The test suite covers:
274
+ - **CameraConfig**: Configuration serialization, URL generation, hardware acceleration settings
275
+ - **PTZController**: Positioning, presets, hardware handler callbacks, frame transforms
276
+ - **MJPEGStreamer**: Client management, frame streaming, statistics
277
+ - **ONVIFService**: SOAP response generation, PTZ command parsing, device info
278
+
279
+ ## Troubleshooting
280
+
281
+ ### Camera freezes after a few frames
282
+ - **With go2rtc**: Check FFmpeg is installed and in PATH, verify go2rtc.exe is running
283
+ - **Native mode**: Install PyAV (`pip install av`) for RTSP or aiortc for WebRTC
284
+ - Check hardware encoder availability (go2rtc only)
285
+
286
+ ### Low FPS performance
287
+ - **Recommended**: Use go2rtc with hardware acceleration
288
+ - **Native mode**: Reduce `native_width`, `native_height`, and `native_fps` in config
289
+ - Check CPU/GPU usage
290
+ - Ensure webcam supports requested FPS
291
+
292
+ ### ONVIF discovery not working
293
+ - Check firewall allows UDP port 3702
294
+ - Verify local network allows multicast
295
+ - Use ONVIF Device Manager to test
296
+
297
+ ## License
298
+
299
+ MIT License - see LICENSE file for details
300
+
301
+ ## Credits
302
+
303
+ - Built with Python, NumPy, and OpenCV
304
+ - Uses [go2rtc](https://github.com/AlexxIT/go2rtc) for RTSP streaming
305
+ - ONVIF protocol implementation based on WS-Discovery specs
ipycam-1.2.0/README.md ADDED
@@ -0,0 +1,275 @@
1
+ # IPyCam - Pure Python Virtual IP Camera
2
+
3
+ A lightweight, pure Python virtual IP camera that provides ONVIF discovery, RTSP streaming, and PTZ controls. Perfect for testing, development, or creating custom camera solutions.
4
+
5
+ ## 📺 Demo Video
6
+ https://github.com/user-attachments/assets/1d3afd23-1ab8-40f6-876c-3f3f9a0089fe
7
+
8
+ [YouTube](https://www.youtube.com/watch?v=9AkqjnZRQTE)
9
+
10
+ ## Features
11
+
12
+ - **ONVIF Compliance**: Full WS-Discovery support for automatic camera detection
13
+ - **RTSP Streaming**: High-performance video streaming via go2rtc (optional) or native Python fallback
14
+ - **WebRTC Support**: Direct browser streaming with native Python implementation
15
+ - **PTZ Controls**: Digital Pan-Tilt-Zoom with preset positions
16
+ - **Hardware Acceleration**: Automatic detection and use of NVENC, QSV, or CPU encoding (with go2rtc)
17
+ - **Native Fallback**: Pure Python streaming (WebRTC, MJPEG) when go2rtc is not available
18
+ - **Web Interface**: Built-in configuration and live preview
19
+ - **Low Latency**: Optimized async frame pipeline for real-time streaming
20
+ - **Flexible Input**: Accept frames from any source (webcam, video file, generated content)
21
+
22
+ ## Requirements
23
+
24
+ - Python 3.8+
25
+ - **Optional**: FFmpeg + go2rtc for hardware-accelerated encoding (recommended for high performance)
26
+ - **Optional**: aiortc (`pip install aiortc`) for native WebRTC streaming fallback
27
+
28
+ > **Note**: IPyCam can run without go2rtc using pure Python streaming. However, go2rtc + FFmpeg provides significantly better performance, especially for high-resolution streams.
29
+
30
+ ## Quick Start
31
+
32
+ Clone the repo:
33
+ ```bash
34
+ git clone https://github.com/olkham/IPyCam.git
35
+ ```
36
+
37
+ ### Setup Scripts (Windows and Linux)
38
+
39
+ If you prefer a guided setup, use the provided scripts. They install dependencies and prepare the environment for running the examples.
40
+
41
+ **Windows (PowerShell or Command Prompt):**
42
+ ```bat
43
+ setup.bat
44
+ ```
45
+
46
+ **Linux/macOS (bash):**
47
+ ```bash
48
+ chmod +x setup.sh
49
+ ./setup.sh
50
+ ```
51
+
52
+ > **Tip**: Run the script from the project root (the folder that contains `setup.bat` and `setup.sh`).
53
+
54
+
55
+ ### Installation
56
+
57
+ Install directly from GitHub:
58
+ ```bash
59
+ pip install git+https://github.com/olkham/IPyCam.git
60
+ ```
61
+
62
+ Or install from source:
63
+ ```bash
64
+ git clone https://github.com/olkham/IPyCam.git
65
+ cd ipycam
66
+ pip install -e .
67
+ ```
68
+
69
+ **Optional: Enhanced Streaming Performance (Recommended)**
70
+
71
+ For hardware-accelerated encoding with go2rtc:
72
+
73
+ 1. **Install go2rtc**: Download from [go2rtc releases](https://github.com/AlexxIT/go2rtc/releases)
74
+ 2. **Start go2rtc** with IPyCam configuration:
75
+ ```bash
76
+ go2rtc.exe --config ipycam\go2rtc.yaml
77
+ ```
78
+ Keep this running in a separate terminal.
79
+
80
+ Without go2rtc, IPyCam will automatically fall back to native Python streaming.
81
+
82
+ **Optional: 360° Camera Support**
83
+
84
+ For the `360_ptz.py` example with equirectangular projection:
85
+ ```bash
86
+ pip install "ipycam[camera360]"
87
+ ```
88
+ or install FrameSource separately:
89
+ ```bash
90
+ pip install framesource
91
+ ```
92
+
93
+ ### Basic Usage
94
+
95
+ ```python
96
+ import cv2
97
+ from ipycam import IPCamera, CameraConfig
98
+
99
+ # Create camera with custom config
100
+ config = CameraConfig(
101
+ name="My Virtual Camera",
102
+ main_width=1920,
103
+ main_height=1080,
104
+ main_fps=30,
105
+ )
106
+
107
+ camera = IPCamera(config)
108
+ camera.start()
109
+
110
+ # Stream from webcam
111
+ cap = cv2.VideoCapture(0)
112
+
113
+ try:
114
+ while camera.is_running:
115
+ ret, frame = cap.read()
116
+ if ret:
117
+ camera.stream(frame)
118
+ except KeyboardInterrupt:
119
+ pass
120
+ finally:
121
+ cap.release()
122
+ camera.stop()
123
+ ```
124
+
125
+ ### Running as a Module
126
+
127
+ ```bash
128
+ python -m ipycam
129
+ ```
130
+
131
+ Then access:
132
+ - **Web UI**: http://localhost:8080/
133
+ - **RTSP Main Stream**: rtsp://localhost:8554/video_main
134
+ - **RTSP Sub Stream**: rtsp://localhost:8554/video_sub
135
+ - **ONVIF Service**: http://localhost:8080/onvif/device_service
136
+
137
+ ### Testing the Stream
138
+
139
+ Test the RTSP streams using ffplay:
140
+ ```bash
141
+ # Test main stream
142
+ ffplay rtsp://localhost:8554/video_main
143
+
144
+ # Test sub stream
145
+ ffplay rtsp://localhost:8554/video_sub
146
+ ```
147
+
148
+ ## Configuration
149
+
150
+ Configuration is stored in `camera_config.json`:
151
+
152
+ ```json
153
+ {
154
+ "name": "Virtual Camera",
155
+ "manufacturer": "PythonCam",
156
+ "model": "VirtualCam-1",
157
+ "main_width": 1920,
158
+ "main_height": 1080,
159
+ "main_fps": 30,
160
+ "main_bitrate": "4M",
161
+ "sub_width": 640,
162
+ "sub_height": 360,
163
+ "native_width": 640,
164
+ "native_height": 480,
165
+ "native_fps": 15,
166
+ "native_bitrate": "500K",
167
+ "hw_accel": "auto"
168
+ }
169
+ ```
170
+
171
+ Hardware acceleration options (go2rtc only):
172
+ - `"auto"` - Try NVENC → QSV → CPU (default)
173
+ - `"nvenc"` - NVIDIA GPU encoding
174
+ - `"qsv"` - Intel Quick Sync Video
175
+ - `"cpu"` - Software encoding (libx264)
176
+
177
+ Native fallback settings:
178
+ - `native_width/height/fps/bitrate` - Used when go2rtc is not available
179
+ - Lower resolution recommended for software encoding performance
180
+
181
+ ## PTZ Controls
182
+
183
+ The camera includes digital PTZ (Pan-Tilt-Zoom) support:
184
+
185
+ ```python
186
+ # Access PTZ through ONVIF or directly
187
+ camera.ptz.continuous_move(pan_speed=0.5, tilt_speed=0.0, zoom_speed=0.0)
188
+ camera.ptz.stop()
189
+ camera.ptz.goto_preset(preset_token="preset1")
190
+ ```
191
+
192
+ PTZ presets are stored in `ptz_presets.json`.
193
+
194
+ ## Performance Tips
195
+
196
+ 1. **Use hardware acceleration**: Enable NVENC (NVIDIA) or QSV (Intel) for best performance
197
+ 2. **Match resolutions**: Set camera input to match streaming resolution to avoid resize overhead
198
+ 3. **Adjust FPS**: Most webcams are limited to 30fps
199
+ 4. **Disable PTZ**: Set camera to home position (0,0,0) to skip PTZ transforms
200
+
201
+ ## Architecture
202
+
203
+ ```
204
+ ipycam/
205
+ ├── __init__.py # Package exports
206
+ ├── __main__.py # CLI entry point
207
+ ├── camera.py # Main IPCamera class
208
+ ├── config.py # CameraConfig dataclass
209
+ ├── streamer.py # Video encoding and streaming pipeline
210
+ ├── ptz.py # Digital PTZ implementation
211
+ ├── onvif.py # ONVIF SOAP service
212
+ ├── discovery.py # WS-Discovery server
213
+ ├── http.py # HTTP request handler
214
+ └── static/ # Web UI and SOAP templates
215
+ ```
216
+
217
+ ## Development
218
+
219
+ ### Running Tests
220
+
221
+ IPyCam includes a comprehensive test suite using pytest. To run the tests:
222
+
223
+ ```bash
224
+ # Install dev dependencies
225
+ pip install -e ".[dev]"
226
+
227
+ # Run all tests
228
+ pytest
229
+
230
+ # Run with verbose output
231
+ pytest -v
232
+
233
+ # Run with coverage report
234
+ pytest --cov=ipycam --cov-report=term-missing
235
+
236
+ # Run specific test file
237
+ pytest tests/test_config.py
238
+ pytest tests/test_ptz.py
239
+ pytest tests/test_mjpeg.py
240
+ pytest tests/test_onvif.py
241
+ ```
242
+
243
+ The test suite covers:
244
+ - **CameraConfig**: Configuration serialization, URL generation, hardware acceleration settings
245
+ - **PTZController**: Positioning, presets, hardware handler callbacks, frame transforms
246
+ - **MJPEGStreamer**: Client management, frame streaming, statistics
247
+ - **ONVIFService**: SOAP response generation, PTZ command parsing, device info
248
+
249
+ ## Troubleshooting
250
+
251
+ ### Camera freezes after a few frames
252
+ - **With go2rtc**: Check FFmpeg is installed and in PATH, verify go2rtc.exe is running
253
+ - **Native mode**: Install PyAV (`pip install av`) for RTSP or aiortc for WebRTC
254
+ - Check hardware encoder availability (go2rtc only)
255
+
256
+ ### Low FPS performance
257
+ - **Recommended**: Use go2rtc with hardware acceleration
258
+ - **Native mode**: Reduce `native_width`, `native_height`, and `native_fps` in config
259
+ - Check CPU/GPU usage
260
+ - Ensure webcam supports requested FPS
261
+
262
+ ### ONVIF discovery not working
263
+ - Check firewall allows UDP port 3702
264
+ - Verify local network allows multicast
265
+ - Use ONVIF Device Manager to test
266
+
267
+ ## License
268
+
269
+ MIT License - see LICENSE file for details
270
+
271
+ ## Credits
272
+
273
+ - Built with Python, NumPy, and OpenCV
274
+ - Uses [go2rtc](https://github.com/AlexxIT/go2rtc) for RTSP streaming
275
+ - ONVIF protocol implementation based on WS-Discovery specs
@@ -0,0 +1,68 @@
1
+ """
2
+ IPyCam - Pure Python Virtual IP Camera
3
+
4
+ A virtual IP camera that:
5
+ - Is discoverable via ONVIF (WS-Discovery)
6
+ - Provides RTSP streams via go2rtc
7
+ - Has a web interface for configuration and live preview
8
+ - Accepts frames from any source
9
+ - Supports digital PTZ (ePTZ) via ONVIF
10
+
11
+ Usage:
12
+ from ipycam import IPCamera, CameraConfig
13
+
14
+ config = CameraConfig(name="My Camera")
15
+ camera = IPCamera(config)
16
+ camera.start()
17
+
18
+ while camera.is_running:
19
+ frame = get_frame() # Your frame source
20
+ camera.stream(frame)
21
+
22
+ camera.stop()
23
+ """
24
+
25
+ from .__version__ import __version__
26
+
27
+ from .config import CameraConfig
28
+ from .camera import IPCamera
29
+ from .streamer import VideoStreamer, StreamConfig, StreamStats, HWAccel
30
+ from .ptz import PTZController, PTZState, PTZPreset, PTZHardwareHandler, PTZVelocity
31
+ from .onvif import ONVIFService
32
+ from .discovery import WSDiscoveryServer
33
+ from .http import IPCameraHTTPHandler
34
+ from .mjpeg import MJPEGStreamer, check_go2rtc_running, check_rtsp_port_available
35
+ from .webrtc import NativeWebRTCStreamer, WebRTCStats, is_webrtc_available
36
+ from .rtsp import NativeRTSPServer, is_native_rtsp_available
37
+
38
+ __all__ = [
39
+ # Main classes
40
+ "IPCamera",
41
+ "CameraConfig",
42
+ # Streaming
43
+ "VideoStreamer",
44
+ "StreamConfig",
45
+ "StreamStats",
46
+ "HWAccel",
47
+ # MJPEG fallback
48
+ "MJPEGStreamer",
49
+ "check_go2rtc_running",
50
+ "check_rtsp_port_available",
51
+ # Native WebRTC fallback
52
+ "NativeWebRTCStreamer",
53
+ "WebRTCStats",
54
+ "is_webrtc_available",
55
+ # Native RTSP fallback
56
+ "NativeRTSPServer",
57
+ "is_native_rtsp_available",
58
+ # PTZ
59
+ "PTZController",
60
+ "PTZState",
61
+ "PTZPreset",
62
+ "PTZVelocity",
63
+ "PTZHardwareHandler",
64
+ # ONVIF
65
+ "ONVIFService",
66
+ "WSDiscoveryServer",
67
+ "IPCameraHTTPHandler",
68
+ ]