JupyterLab extension that captures microphone audio in the browser and streams it to a server-side bridge, exposing it as a virtual audio source so terminal applications running in the container (such as Claude Code voice mode) can record from the user's microphone
Project description
jupyterlab_voice_capture_extension
Capture microphone audio in the JupyterLab browser tab and stream it to a server-side FIFO, so terminal applications running inside the container - notably Claude Code voice mode - can record from a microphone the container itself has no access to.
The container has no capture device; the browser does. This extension bridges that gap: the browser captures the mic, ships the audio over an authenticated websocket to a Jupyter server handler, and the handler writes raw PCM to a named pipe. A separate, out-of-scope plumbing layer (PulseAudio module-pipe-source + SoX) turns that pipe into the system default audio source.
How it works
- Capture - a microphone toggle in the status bar calls
getUserMedia; an AudioWorklet resamples to 16 kHz mono and encodes signed 16-bit little-endian PCM off the UI thread - Transport - 20 ms PCM frames (640 bytes) are sent as binary websocket messages to
…/jupyterlab-voice-capture-extension/stream, which lives under the Jupyter base URL and inherits Jupyter token auth - no new port is opened - Sink - the server handler writes each frame, in order, to a FIFO (default
/tmp/voice.fifo); it creates the pipe if absent and tolerates a not-yet-attached reader without blocking the server - Out of scope - the extension does not manage PulseAudio, invoke SoX or any recorder, or perform speech-to-text; its responsibility ends at delivering correct PCM to the FIFO
Chain: browser mic → AudioWorklet (16 kHz mono s16le) → websocket → server handler → FIFO → (PulseAudio + SoX, out of scope) → terminal app.
Requirements
- JupyterLab >= 4.0.0
- A secure context (https or
localhost) - browsers only expose the microphone over a secure origin
Install
pip install jupyterlab-voice-capture-extension
Dependencies
- Python:
jupyter_serverandtraitlets, installed automatically with the package - System (only for the full voice chain into a terminal app): PulseAudio + SoX. Provision and verify them with the bundled CLI:
jupyterlab_voice_capture_extension install # set up the PulseAudio + SoX bridge
jupyterlab_voice_capture_extension validate # check every component, print what to fix
See docs/jupyterlab-enable-claude-voice.md for the full setup, the start / stop daemon commands, and troubleshooting.
Usage
- Click the microphone icon in the status bar (or run Toggle Voice Capture from the command palette) to start capture
- On the first start the browser asks for microphone permission; the status label moves Disconnected → Connecting → Connected, the icon glows green while streaming, and the browser shows its active-microphone indicator
- Click again to stop - capture tracks are released and the browser indicator clears
- Only one tab streams at a time: starting capture in a second tab takes over and stops the first
Configuration
The sink FIFO path defaults to /tmp/voice.fifo and is overridable via Jupyter server config:
c.VoiceCapture.sink_path = "/run/voice/voice.fifo"
Uninstall
pip uninstall jupyterlab-voice-capture-extension
Troubleshoot
If you see the frontend extension but it is not working, check that the server extension is enabled:
jupyter server extension list
If the server extension is installed and enabled but you do not see the frontend extension, check the frontend extension is installed:
jupyter labextension list
Contributing
If you would like to contribute to this extension, please refer to the Contributing Guide.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jupyterlab_voice_capture_extension-1.0.2.tar.gz.
File metadata
- Download URL: jupyterlab_voice_capture_extension-1.0.2.tar.gz
- Upload date:
- Size: 322.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c0a8df184ef8e93db35c05bff1621d42a370adc12576b0e3e8e9066d69bbf291
|
|
| MD5 |
84a02d14d0c03a0b3c65907f0d27785c
|
|
| BLAKE2b-256 |
65548a18b16e6dfe4b2ab41e9d330e45e9795a72a22a1123262823661e43392a
|
File details
Details for the file jupyterlab_voice_capture_extension-1.0.2-py3-none-any.whl.
File metadata
- Download URL: jupyterlab_voice_capture_extension-1.0.2-py3-none-any.whl
- Upload date:
- Size: 63.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3e83e268f4d07792f360c3a1db4e16ed26ff8d815968b34b4ea0f0e17b4ceb38
|
|
| MD5 |
53c1c4304fa58d31a73e336cc3b49142
|
|
| BLAKE2b-256 |
ddf65ace7c0a018941a76b8062a0dc751d893240c0c9f3c6616222019ef09462
|