capture-helper 0.2.2__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.
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Warith HARCHAOUI
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,193 @@
1
+ Metadata-Version: 2.4
2
+ Name: capture-helper
3
+ Version: 0.2.2
4
+ Summary: Capture Helper โ€” OBS-inspired (no GUI) capture, processing, and publishing for the AI Helpers stack. Multi-surface: library + argparse CLI + click CLI + FastAPI HTTP surface + MCP tools over the INPUT layer (cameras / microphones).
5
+ Author-email: Warith HARCHAOUI <warithmetics@deraison.ai>
6
+ License: BSD-3-Clause
7
+ Project-URL: Homepage, https://github.com/warith-harchaoui/capture-helper
8
+ Project-URL: Issues, https://github.com/warith-harchaoui/capture-helper/issues
9
+ Keywords: capture,ffmpeg,camera,microphone,screen,obs,rtmp,hls
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: BSD License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Multimedia :: Video :: Capture
20
+ Classifier: Topic :: Multimedia :: Sound/Audio :: Capture/Recording
21
+ Requires-Python: <3.14,>=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: os-helper>=1.4.2
25
+ Requires-Dist: numpy>=1.23
26
+ Provides-Extra: cli
27
+ Requires-Dist: click<9,>=8.1; extra == "cli"
28
+ Provides-Extra: api
29
+ Requires-Dist: fastapi<1,>=0.111; extra == "api"
30
+ Requires-Dist: uvicorn<1,>=0.30; extra == "api"
31
+ Requires-Dist: python-multipart<1,>=0.0.9; extra == "api"
32
+ Provides-Extra: mcp
33
+ Requires-Dist: fastapi-mcp<1,>=0.3; extra == "mcp"
34
+ Requires-Dist: fastapi<1,>=0.111; extra == "mcp"
35
+ Requires-Dist: uvicorn<1,>=0.30; extra == "mcp"
36
+ Requires-Dist: python-multipart<1,>=0.0.9; extra == "mcp"
37
+ Provides-Extra: dev
38
+ Requires-Dist: pytest>=8; extra == "dev"
39
+ Requires-Dist: httpx>=0.27; extra == "dev"
40
+ Requires-Dist: click<9,>=8.1; extra == "dev"
41
+ Requires-Dist: fastapi<1,>=0.111; extra == "dev"
42
+ Requires-Dist: python-multipart<1,>=0.0.9; extra == "dev"
43
+ Requires-Dist: fastapi-mcp<1,>=0.3; extra == "dev"
44
+ Dynamic: license-file
45
+
46
+ # Capture Helper
47
+
48
+ [๐Ÿ‡ซ๐Ÿ‡ท](https://github.com/warith-harchaoui/capture-helper/blob/main/LISEZMOI.md) ยท [๐Ÿ‡ฌ๐Ÿ‡ง](https://github.com/warith-harchaoui/capture-helper/blob/main/README.md)
49
+
50
+ [![CI](https://github.com/warith-harchaoui/capture-helper/actions/workflows/ci.yml/badge.svg)](https://github.com/warith-harchaoui/capture-helper/actions/workflows/ci.yml) [![License: BSD-3-Clause](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://github.com/warith-harchaoui/capture-helper/blob/main/LICENSE) [![Python](https://img.shields.io/badge/python-3.10%E2%80%933.13-blue.svg)](#)
51
+
52
+ `Capture Helper` belongs to a collection of libraries called `AI Helpers` developed for building Artificial Intelligence.
53
+
54
+ **OBS-inspired** (no GUI) capture + processing + publishing layer for the AI Helpers stack. Library-shaped: cross-platform camera / microphone / screen / window / application-audio sources, composable filter chains, multi-source mixing, and emit-to-publish primitives for live YouTube / Twitch RTMP, HLS, and Icecast โ€” designed to plug into [video-helper](https://github.com/warith-harchaoui/video-helper) and [podcast-helper](https://github.com/warith-harchaoui/podcast-helper) for downstream frame / PCM contracts.
55
+
56
+ [๐ŸŒ AI Helpers](https://harchaoui.org/warith/ai-helpers)
57
+
58
+ [![logo](https://raw.githubusercontent.com/warith-harchaoui/capture-helper/main/assets/logo.png)](https://harchaoui.org/warith/ai-helpers)
59
+
60
+ ## Status โ€” v0.1.0 INPUT layer
61
+
62
+ What ships today:
63
+
64
+ - `SourceKind` literal (`"camera"` | `"microphone"`)
65
+ - `Source` typed dict (kind, name, index, platform, driver)
66
+ - `MicFrame` typed dict (mirrors [`podcast_helper.PcmFrame`](https://github.com/warith-harchaoui/podcast-helper))
67
+ - `list_sources(kind=None)` โ€” cross-platform device enumeration via `ffmpeg -list_devices` (macOS avfoundation / Windows dshow / Linux v4l2 + pulse)
68
+ - `pick_source(kind, *, name_substring=..., index=...)` โ€” pick the first matching device, raises `ValueError` if nothing matches
69
+ - `iter_camera_frames(source, *, width=..., height=..., output_width=..., output_height=..., fps=..., max_frames=...)` โ€” yields **`(H, W, 3)` BGR uint8 numpy arrays**, same contract as `video_helper.extract_frames`
70
+ - `iter_mic_audio(source, *, target_sample_rate=16000, to_mono=True, frame_ms=20)` โ€” async iterator yielding `MicFrame`s, same contract as `podcast_helper.extract_audio_stream`
71
+ - `ffmpeg_input_args(source)` โ€” exposed low-level helper for users wiring their own ffmpeg pipelines
72
+
73
+ ```python
74
+ import asyncio
75
+ import capture_helper as ch
76
+
77
+ # Enumerate available devices
78
+ for s in ch.list_sources():
79
+ print(f"{s['kind']:10s} [{s['index']}] {s['name']:40s} (driver={s['driver']})")
80
+ # camera [0] FaceTime HD Camera (driver=avfoundation)
81
+ # microphone [0] Built-in Microphone (driver=avfoundation)
82
+
83
+ # Camera โ†’ numpy BGR frames (drop-in for video_helper.extract_frames)
84
+ cam = ch.pick_source("camera")
85
+ for frame in ch.iter_camera_frames(cam, output_width=640, output_height=360,
86
+ fps=30, max_frames=300):
87
+ # frame.shape == (360, 640, 3), dtype uint8, BGR.
88
+ do_something(frame)
89
+
90
+ # Microphone โ†’ async PCM stream (drop-in for podcast_helper.extract_audio_stream)
91
+ async def listen():
92
+ mic = ch.pick_source("microphone")
93
+ async for f in ch.iter_mic_audio(mic, target_sample_rate=16000,
94
+ to_mono=True, frame_ms=20):
95
+ # f["pcm"].shape == (320,) โ€” 20ms @ 16kHz mono.
96
+ await asr.feed(f["pcm"])
97
+ asyncio.run(listen())
98
+ ```
99
+
100
+ ## Roadmap
101
+
102
+ | Version | Layer | Scope |
103
+ |---|---|---|
104
+ | v0.0.1 | INPUT scaffold | `list_sources` + types |
105
+ | **v0.1.0** (this release) | INPUT | `pick_source(...)` + `iter_camera_frames(source, ...)` + `iter_mic_audio(source, ...)` โ€” composes with video-helper / podcast-helper contracts |
106
+ | **v0.2.0** | INPUT extended | Screen / window capture; basic filter chain (noise gate, gain, scale) |
107
+ | **v0.3.0** | PROCESS | Scenes / mixer โ€” `mix_audio([sources], levels=[...])` + `compose_video([sources], layout=...)` |
108
+ | **v0.4.0** | PUBLISH | `emit_to_youtube_live(...)`, `emit_to_twitch_live(...)`, `emit_to_rtmp(...)`, `emit_to_hls(...)`, `emit_audio_to_icecast(...)` |
109
+ | **v0.5.0** | OUTPUT virtual | `output_to_virtual_camera(...)` (pyvirtualcam etc.), `output_to_virtual_mic(...)` |
110
+ | **v0.6.0** | OBS integration | OBS WebSocket client (react to scene / stream events) |
111
+
112
+ For a full cookbook (per-OS ffmpeg input strings, snapshot capture, live preview, ASR / VAD wiring), see [๐Ÿ“‹ EXAMPLES.md](https://github.com/warith-harchaoui/capture-helper/blob/main/EXAMPLES.md).
113
+
114
+ ## Multi-surface exposure
115
+
116
+ `capture-helper` ships the same INPUT layer through **five surfaces**
117
+ so it plugs in wherever you already work โ€” no rewrite needed.
118
+
119
+ | Surface | Install | Entry point | Use case |
120
+ | --- | --- | --- | --- |
121
+ | **Python library** | `pip install โ€ฆ@v0.2.0` | `import capture_helper as ch` | Notebooks, scripts, other AI Helpers |
122
+ | **argparse CLI** | *(no extra)* | `capture-helper โ€ฆ` | Shells, cron, CI, container CMD |
123
+ | **click CLI** | `[cli]` extra | `capture-helper-click โ€ฆ` | Users on a click-native stack (completion, colored `--help`) |
124
+ | **FastAPI HTTP** | `[api]` extra | `uvicorn capture_helper.api:app` | Reverse-proxied service, JSON / multipart clients |
125
+ | **MCP tools** | `[api,mcp]` extras | `capture-helper-mcp` | LLM agents (Claude Desktop, custom MCP clients) |
126
+
127
+ ```bash
128
+ # CLI (argparse โ€” always available)
129
+ capture-helper list-sources
130
+ capture-helper pick-source --kind camera --name FaceTime
131
+ capture-helper capture-mic --output mic.wav --seconds 3
132
+
133
+ # CLI (click twin โ€” same subcommands)
134
+ capture-helper-click list-sources
135
+ capture-helper-click capture-camera --output-dir frames/ \
136
+ --output-width 640 --output-height 360 --max-frames 30
137
+
138
+ # HTTP surface
139
+ uvicorn capture_helper.api:app --host 0.0.0.0 --port 8000
140
+ curl http://localhost:8000/sources
141
+ curl -o frames.zip \
142
+ 'http://localhost:8000/capture/camera?output_width=320&output_height=240&max_frames=10'
143
+
144
+ # MCP surface (FastAPI + fastapi-mcp)
145
+ capture-helper-mcp # serves HTTP routes + MCP endpoint on :8000
146
+
147
+ # Docker (ships FastAPI + MCP by default)
148
+ docker build -t capture-helper .
149
+ docker run --rm -p 8000:8000 capture-helper
150
+ ```
151
+
152
+ For a GUI vision (device wall + PGM/PVW cueing, not a CLI mirror),
153
+ see [๐Ÿ“‹ GUI.md](https://github.com/warith-harchaoui/capture-helper/blob/main/GUI.md). For a competitive comparison against
154
+ OpenCV / PyAV / sounddevice / OBS / FFmpeg CLI / GStreamer, see
155
+ [๐Ÿ“‹ LANDSCAPE.md](https://github.com/warith-harchaoui/capture-helper/blob/main/LANDSCAPE.md).
156
+
157
+ ## Installation
158
+
159
+ **Prerequisites** โ€” **Python 3.10โ€“3.13** and **git**, **ffmpeg**, **PortAudio**, cross-platform:
160
+
161
+ - ๐ŸŽ **macOS** ([Homebrew](https://brew.sh)): `brew install python git ffmpeg portaudio`
162
+ - ๐Ÿง **Ubuntu/Debian**: `sudo apt update && sudo apt install -y python3 python3-pip git ffmpeg portaudio19-dev`
163
+ - ๐ŸชŸ **Windows** (PowerShell): `winget install Python.Python.3.12 Git.Git Gyan.FFmpeg` (PortAudio ships inside the Python wheels)
164
+
165
+ Then install the package:
166
+
167
+
168
+ ```bash
169
+ pip install --force-reinstall --no-cache-dir \
170
+ git+https://github.com/warith-harchaoui/capture-helper.git@v0.2.2
171
+ ```
172
+
173
+ Optional extras (pick what you need):
174
+
175
+ ```bash
176
+ pip install 'capture-helper[cli] @ git+โ€ฆ@v0.2.0' # click CLI
177
+ pip install 'capture-helper[api] @ git+โ€ฆ@v0.2.0' # FastAPI HTTP
178
+ pip install 'capture-helper[api,mcp] @ git+โ€ฆ@v0.2.0' # MCP tools
179
+ ```
180
+
181
+ You still need `ffmpeg` on PATH for device enumeration and live capture to return anything:
182
+
183
+ - macOS ๐ŸŽ : `brew install ffmpeg`
184
+
185
+ (install `brew` thanks to [brew.sh](https://brew.sh/))
186
+ - Ubuntu ๐Ÿง : `sudo apt install ffmpeg`
187
+ - Windows ๐ŸชŸ : grab a build from [ffmpeg.org/download.html](https://ffmpeg.org/download.html) and add it to `PATH`.
188
+
189
+ # Author
190
+ - [Warith HARCHAOUI](https://linkedin.com/in/warith-harchaoui)
191
+
192
+ # Acknowledgements
193
+ Special thanks to [Mohamed Chelali](https://mchelali.github.io) and [Bachir Zerroug](https://www.linkedin.com/in/bachirzerroug) for fruitful discussions.
@@ -0,0 +1,148 @@
1
+ # Capture Helper
2
+
3
+ [๐Ÿ‡ซ๐Ÿ‡ท](https://github.com/warith-harchaoui/capture-helper/blob/main/LISEZMOI.md) ยท [๐Ÿ‡ฌ๐Ÿ‡ง](https://github.com/warith-harchaoui/capture-helper/blob/main/README.md)
4
+
5
+ [![CI](https://github.com/warith-harchaoui/capture-helper/actions/workflows/ci.yml/badge.svg)](https://github.com/warith-harchaoui/capture-helper/actions/workflows/ci.yml) [![License: BSD-3-Clause](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://github.com/warith-harchaoui/capture-helper/blob/main/LICENSE) [![Python](https://img.shields.io/badge/python-3.10%E2%80%933.13-blue.svg)](#)
6
+
7
+ `Capture Helper` belongs to a collection of libraries called `AI Helpers` developed for building Artificial Intelligence.
8
+
9
+ **OBS-inspired** (no GUI) capture + processing + publishing layer for the AI Helpers stack. Library-shaped: cross-platform camera / microphone / screen / window / application-audio sources, composable filter chains, multi-source mixing, and emit-to-publish primitives for live YouTube / Twitch RTMP, HLS, and Icecast โ€” designed to plug into [video-helper](https://github.com/warith-harchaoui/video-helper) and [podcast-helper](https://github.com/warith-harchaoui/podcast-helper) for downstream frame / PCM contracts.
10
+
11
+ [๐ŸŒ AI Helpers](https://harchaoui.org/warith/ai-helpers)
12
+
13
+ [![logo](https://raw.githubusercontent.com/warith-harchaoui/capture-helper/main/assets/logo.png)](https://harchaoui.org/warith/ai-helpers)
14
+
15
+ ## Status โ€” v0.1.0 INPUT layer
16
+
17
+ What ships today:
18
+
19
+ - `SourceKind` literal (`"camera"` | `"microphone"`)
20
+ - `Source` typed dict (kind, name, index, platform, driver)
21
+ - `MicFrame` typed dict (mirrors [`podcast_helper.PcmFrame`](https://github.com/warith-harchaoui/podcast-helper))
22
+ - `list_sources(kind=None)` โ€” cross-platform device enumeration via `ffmpeg -list_devices` (macOS avfoundation / Windows dshow / Linux v4l2 + pulse)
23
+ - `pick_source(kind, *, name_substring=..., index=...)` โ€” pick the first matching device, raises `ValueError` if nothing matches
24
+ - `iter_camera_frames(source, *, width=..., height=..., output_width=..., output_height=..., fps=..., max_frames=...)` โ€” yields **`(H, W, 3)` BGR uint8 numpy arrays**, same contract as `video_helper.extract_frames`
25
+ - `iter_mic_audio(source, *, target_sample_rate=16000, to_mono=True, frame_ms=20)` โ€” async iterator yielding `MicFrame`s, same contract as `podcast_helper.extract_audio_stream`
26
+ - `ffmpeg_input_args(source)` โ€” exposed low-level helper for users wiring their own ffmpeg pipelines
27
+
28
+ ```python
29
+ import asyncio
30
+ import capture_helper as ch
31
+
32
+ # Enumerate available devices
33
+ for s in ch.list_sources():
34
+ print(f"{s['kind']:10s} [{s['index']}] {s['name']:40s} (driver={s['driver']})")
35
+ # camera [0] FaceTime HD Camera (driver=avfoundation)
36
+ # microphone [0] Built-in Microphone (driver=avfoundation)
37
+
38
+ # Camera โ†’ numpy BGR frames (drop-in for video_helper.extract_frames)
39
+ cam = ch.pick_source("camera")
40
+ for frame in ch.iter_camera_frames(cam, output_width=640, output_height=360,
41
+ fps=30, max_frames=300):
42
+ # frame.shape == (360, 640, 3), dtype uint8, BGR.
43
+ do_something(frame)
44
+
45
+ # Microphone โ†’ async PCM stream (drop-in for podcast_helper.extract_audio_stream)
46
+ async def listen():
47
+ mic = ch.pick_source("microphone")
48
+ async for f in ch.iter_mic_audio(mic, target_sample_rate=16000,
49
+ to_mono=True, frame_ms=20):
50
+ # f["pcm"].shape == (320,) โ€” 20ms @ 16kHz mono.
51
+ await asr.feed(f["pcm"])
52
+ asyncio.run(listen())
53
+ ```
54
+
55
+ ## Roadmap
56
+
57
+ | Version | Layer | Scope |
58
+ |---|---|---|
59
+ | v0.0.1 | INPUT scaffold | `list_sources` + types |
60
+ | **v0.1.0** (this release) | INPUT | `pick_source(...)` + `iter_camera_frames(source, ...)` + `iter_mic_audio(source, ...)` โ€” composes with video-helper / podcast-helper contracts |
61
+ | **v0.2.0** | INPUT extended | Screen / window capture; basic filter chain (noise gate, gain, scale) |
62
+ | **v0.3.0** | PROCESS | Scenes / mixer โ€” `mix_audio([sources], levels=[...])` + `compose_video([sources], layout=...)` |
63
+ | **v0.4.0** | PUBLISH | `emit_to_youtube_live(...)`, `emit_to_twitch_live(...)`, `emit_to_rtmp(...)`, `emit_to_hls(...)`, `emit_audio_to_icecast(...)` |
64
+ | **v0.5.0** | OUTPUT virtual | `output_to_virtual_camera(...)` (pyvirtualcam etc.), `output_to_virtual_mic(...)` |
65
+ | **v0.6.0** | OBS integration | OBS WebSocket client (react to scene / stream events) |
66
+
67
+ For a full cookbook (per-OS ffmpeg input strings, snapshot capture, live preview, ASR / VAD wiring), see [๐Ÿ“‹ EXAMPLES.md](https://github.com/warith-harchaoui/capture-helper/blob/main/EXAMPLES.md).
68
+
69
+ ## Multi-surface exposure
70
+
71
+ `capture-helper` ships the same INPUT layer through **five surfaces**
72
+ so it plugs in wherever you already work โ€” no rewrite needed.
73
+
74
+ | Surface | Install | Entry point | Use case |
75
+ | --- | --- | --- | --- |
76
+ | **Python library** | `pip install โ€ฆ@v0.2.0` | `import capture_helper as ch` | Notebooks, scripts, other AI Helpers |
77
+ | **argparse CLI** | *(no extra)* | `capture-helper โ€ฆ` | Shells, cron, CI, container CMD |
78
+ | **click CLI** | `[cli]` extra | `capture-helper-click โ€ฆ` | Users on a click-native stack (completion, colored `--help`) |
79
+ | **FastAPI HTTP** | `[api]` extra | `uvicorn capture_helper.api:app` | Reverse-proxied service, JSON / multipart clients |
80
+ | **MCP tools** | `[api,mcp]` extras | `capture-helper-mcp` | LLM agents (Claude Desktop, custom MCP clients) |
81
+
82
+ ```bash
83
+ # CLI (argparse โ€” always available)
84
+ capture-helper list-sources
85
+ capture-helper pick-source --kind camera --name FaceTime
86
+ capture-helper capture-mic --output mic.wav --seconds 3
87
+
88
+ # CLI (click twin โ€” same subcommands)
89
+ capture-helper-click list-sources
90
+ capture-helper-click capture-camera --output-dir frames/ \
91
+ --output-width 640 --output-height 360 --max-frames 30
92
+
93
+ # HTTP surface
94
+ uvicorn capture_helper.api:app --host 0.0.0.0 --port 8000
95
+ curl http://localhost:8000/sources
96
+ curl -o frames.zip \
97
+ 'http://localhost:8000/capture/camera?output_width=320&output_height=240&max_frames=10'
98
+
99
+ # MCP surface (FastAPI + fastapi-mcp)
100
+ capture-helper-mcp # serves HTTP routes + MCP endpoint on :8000
101
+
102
+ # Docker (ships FastAPI + MCP by default)
103
+ docker build -t capture-helper .
104
+ docker run --rm -p 8000:8000 capture-helper
105
+ ```
106
+
107
+ For a GUI vision (device wall + PGM/PVW cueing, not a CLI mirror),
108
+ see [๐Ÿ“‹ GUI.md](https://github.com/warith-harchaoui/capture-helper/blob/main/GUI.md). For a competitive comparison against
109
+ OpenCV / PyAV / sounddevice / OBS / FFmpeg CLI / GStreamer, see
110
+ [๐Ÿ“‹ LANDSCAPE.md](https://github.com/warith-harchaoui/capture-helper/blob/main/LANDSCAPE.md).
111
+
112
+ ## Installation
113
+
114
+ **Prerequisites** โ€” **Python 3.10โ€“3.13** and **git**, **ffmpeg**, **PortAudio**, cross-platform:
115
+
116
+ - ๐ŸŽ **macOS** ([Homebrew](https://brew.sh)): `brew install python git ffmpeg portaudio`
117
+ - ๐Ÿง **Ubuntu/Debian**: `sudo apt update && sudo apt install -y python3 python3-pip git ffmpeg portaudio19-dev`
118
+ - ๐ŸชŸ **Windows** (PowerShell): `winget install Python.Python.3.12 Git.Git Gyan.FFmpeg` (PortAudio ships inside the Python wheels)
119
+
120
+ Then install the package:
121
+
122
+
123
+ ```bash
124
+ pip install --force-reinstall --no-cache-dir \
125
+ git+https://github.com/warith-harchaoui/capture-helper.git@v0.2.2
126
+ ```
127
+
128
+ Optional extras (pick what you need):
129
+
130
+ ```bash
131
+ pip install 'capture-helper[cli] @ git+โ€ฆ@v0.2.0' # click CLI
132
+ pip install 'capture-helper[api] @ git+โ€ฆ@v0.2.0' # FastAPI HTTP
133
+ pip install 'capture-helper[api,mcp] @ git+โ€ฆ@v0.2.0' # MCP tools
134
+ ```
135
+
136
+ You still need `ffmpeg` on PATH for device enumeration and live capture to return anything:
137
+
138
+ - macOS ๐ŸŽ : `brew install ffmpeg`
139
+
140
+ (install `brew` thanks to [brew.sh](https://brew.sh/))
141
+ - Ubuntu ๐Ÿง : `sudo apt install ffmpeg`
142
+ - Windows ๐ŸชŸ : grab a build from [ffmpeg.org/download.html](https://ffmpeg.org/download.html) and add it to `PATH`.
143
+
144
+ # Author
145
+ - [Warith HARCHAOUI](https://linkedin.com/in/warith-harchaoui)
146
+
147
+ # Acknowledgements
148
+ Special thanks to [Mohamed Chelali](https://mchelali.github.io) and [Bachir Zerroug](https://www.linkedin.com/in/bachirzerroug) for fruitful discussions.
@@ -0,0 +1,81 @@
1
+ """
2
+ Capture Helper
3
+ ==============
4
+
5
+ OBS-inspired (no GUI) **capture + process + publish** library for the
6
+ AI Helpers stack. v0.1.0 ships the **INPUT layer**: cross-platform
7
+ device enumeration + selection (cameras / microphones) and a pair of
8
+ iterators that bridge those devices to the rest of the suite's
9
+ contracts.
10
+
11
+ What ships in v0.1.0
12
+ --------------------
13
+ - :class:`SourceKind` โ€” literal ``"camera"`` | ``"microphone"``.
14
+ - :class:`Source` โ€” typed dict describing one device.
15
+ - :class:`MicFrame` โ€” typed dict for one PCM frame (mirrors
16
+ :class:`podcast_helper.streaming.PcmFrame`).
17
+ - :func:`list_sources` โ€” best-effort cross-platform device enumeration
18
+ via ``ffmpeg -list_devices`` (avfoundation / v4l2 / dshow / pulse /
19
+ alsa). Returns ``[]`` rather than raising on unsupported platforms.
20
+ - :func:`pick_source` โ€” pick the first device of a given kind matching
21
+ optional ``name_substring`` / ``index`` filters.
22
+ - :func:`iter_camera_frames` โ€” synchronous generator yielding
23
+ ``(H, W, 3)`` BGR uint8 numpy arrays โ€” same shape and dtype as
24
+ :func:`video_helper.extract_frames`.
25
+ - :func:`iter_mic_audio` โ€” async generator yielding
26
+ :class:`MicFrame` โ€” same shape as
27
+ :func:`podcast_helper.extract_audio_stream`.
28
+
29
+ What lands next
30
+ ---------------
31
+ See :doc:`README` roadmap. v0.2.0 brings screen / window capture and a
32
+ basic filter chain; v0.3.0 brings multi-source mixing; v0.4.0 brings
33
+ RTMP / HLS / Icecast publish.
34
+
35
+ Usage example
36
+ -------------
37
+ >>> import asyncio, capture_helper as ch
38
+ >>> cam = ch.pick_source("camera")
39
+ >>> for frame in ch.iter_camera_frames(cam, output_width=640, output_height=360,
40
+ ... fps=30, max_frames=300):
41
+ ... # frame.shape == (360, 640, 3), dtype uint8, BGR.
42
+ ... do_something(frame)
43
+ >>>
44
+ >>> async def listen():
45
+ ... mic = ch.pick_source("microphone")
46
+ ... async for f in ch.iter_mic_audio(mic, target_sample_rate=16000, frame_ms=20):
47
+ ... # f["pcm"].shape == (320,) โ€” 20ms @ 16kHz mono.
48
+ ... await asr.feed(f["pcm"])
49
+ >>> asyncio.run(listen())
50
+
51
+ Author
52
+ ------
53
+ Warith Harchaoui, Ph.D. โ€” https://linkedin.com/in/warith-harchaoui/
54
+ """
55
+
56
+ # Package-level attribution โ€” kept here so tooling that reads
57
+ # ``capture_helper.__author__`` gets the canonical value. Email lives
58
+ # ONLY here (never in module-level docstrings) to keep source files
59
+ # scrapeable without leaking the mailbox to search engines.
60
+ __author__ = "Warith Harchaoui, Ph.D."
61
+ __email__ = "warithmetics@deraison.ai"
62
+
63
+ __all__ = [
64
+ # types
65
+ "SourceKind",
66
+ "Source",
67
+ "MicFrame",
68
+ # device enumeration + selection
69
+ "list_sources",
70
+ "pick_source",
71
+ # low-level helper exposed because some callers want to splice the
72
+ # per-OS ffmpeg input args into their own pipelines.
73
+ "ffmpeg_input_args",
74
+ # live capture iterators
75
+ "iter_camera_frames",
76
+ "iter_mic_audio",
77
+ ]
78
+
79
+ from .camera import iter_camera_frames
80
+ from .mic import MicFrame, iter_mic_audio
81
+ from .sources import Source, SourceKind, ffmpeg_input_args, list_sources, pick_source