Nemotron ASR Live Microphone
Queue it, talk, watch the words land
- transcription
- captured_audio
Some nodes are plumbing; this one is a demo, and it's the reason anyone installs the pack in the first place. You queue the graph, you talk at your computer, and words show up on the node while you're still saying them. It is genuinely fun, which is not a word you use about custom-node workflows often.
It's also the only node in the pack with a hard dependency, and the only one that can fail for reasons that have nothing to do with Python. Read the install section before you decide it's broken.
What it's doing
Two moving parts, tidily separated. sounddevice - which wraps the PortAudio library - opens a mono int16 input stream from your default recording device in non-blocking callback mode. A PortAudio thread appends whatever it hears into a buffer, and the node's async loop drains that buffer every few tens of milliseconds. Whatever it drains gets pushed straight out over the same realtime WebSocket endpoint the streaming node uses: session.update to announce the actual capture rate and the language, then raw PCM16 frames, then input_audio_buffer.commit when the recording window closes. The server's partial transcriptions come back as deltas and get painted onto the node live.
No resampling in the mic path, deliberately: the endpoint accepts PCM16 from 8 to 96 kHz, so the node captures at whatever the device gives it and announces that rate.
When the window ends, the utterance is committed and you get the final transcript, plus the captured audio as a normal AUDIO dict - float32 in [-1, 1], shaped [1, N], tagged with the real mic rate.
The inputs that matter
duration- how many seconds to record, default 5, up to an hour. The queue stays busy for exactly this long, and five seconds is shorter than you think - still mid-sentence when the window closes and you've lost the tail.sample_rate- 16000 by default. If your device refuses it, the node retries at 44.1k and 48k and configures the session to match, so a mic that only speaks 48 k is not a problem here. Change it only if you know your interface.language- defaultEnglish (en-US). Set it. Auto-detect on a five-second clip is exactly the case that produces junk prefixes.show_live_preview- on. Turning it off makes the node silent while it waits, which is worse.
The two outputs are transcription (the final STRING, plus the inline preview) and captured_audio, which is a normal AUDIO output - wire it into Save Audio and you've recorded your own voice into the workflow while also having the text. That pairing is the useful trick: speak a prompt, get the text into CLIP Text Encode and keep the take.
Install - and the one line everybody misses
The pack installs normally. Manager → search comfyui_nemotron_asr → restart, or by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/Rakeshcool/comfyui_nemotron_asr
The mic node needs sounddevice, and ComfyUI Manager does not install it for you. Put it in the same Python ComfyUI runs with:
# portable install
python_embeded/python.exe -m pip install sounddevice
# any other install
python -m pip install sounddevice
Forget that and you get a node that imports fine and then refuses to record. Start the ASR server yourself too - as with every node in this pack, nothing here starts or stops it.
Failure modes worth knowing before you debug
Could not open a microphone input stream... - no input device, or something else has it exclusively. Windows in particular will let an app grab a mic and lock you out. Test with any other recording app first; if that fails too, it wasn't ComfyUI.
It records on the machine running ComfyUI, not in your browser. That's the difference between this node and anything frontend-side: if your ComfyUI is in a container, a VM, or on another box in the house, there is no microphone for it to find, and no amount of clicking will fix that.
No silence detection, no early stop. The node streams for the whole duration window whether you're talking or not. There's no endpointing wired up here, so pick a duration you can fill and just let the tail be silence.
Talk too early and you clip the first word. Recording starts when the queue reaches the node, and there's a moment of setup before audio flows. Queue, wait for the [listening ...] indicator on the node, then speak.
A quiet take is a bad take. Mumbling at 2 a.m. is the classic way to conclude the model is bad when the model is fine. Sit closer.
One last thing worth checking, since this is a server-side process opening a hardware device: the frames go to the server_url you typed and nowhere else.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| duration | FLOAT | 5.01–3600 | How long to record from the microphone, in seconds. The queue stays busy for this long. |
| server_url | STRING | http://127.0.0.1:8080 | Base URL of the NeMo-Speech.cpp server. |
| language | COMBO | English (en-US) | Languages supported by Nemotron ASR. '(auto-detect)' lets the server decide. |
| sample_rate | INT | 160008000–96000 | Mic capture rate. If the device rejects it, 44.1k/48k are tried and the session is configured to match. |
| chunk_ms | INT | 10020–1000 | Milliseconds of mic audio per streamed WebSocket chunk. |
| show_live_preview | BOOLEAN | true | Show partial transcription live on the node while you speak. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| transcription | STRING | — |
| captured_audio | AUDIO | — |