# ComfyUI-VideoToText > Video β†’ audio β†’ JSON transcript pipeline for ComfyUI. Pairs with [**ComfyUI-MiMoASR**](https://github.com/aadebuger/ComfyUI-MiMoASR) (Xiaomi MiMo-V2.5-ASR) for the ASR step. This pack provides the **non-ASR** pieces of a video-to-text workflow: video loading, audio extraction (`ffmpeg`), `AUDIO` dict bridging, JSON packaging, and disk persistence. The ASR itself is delegated to MiMoASR, which gives you strong Mandarin / English code-switching, dialect support (Wu, Cantonese, Hokkien, Sichuanese, Henan, Northeastern Mandarin), and noisy-audio robustness. | Node | Purpose | | --- | --- | | πŸŽ™οΈ **Load Video (ASR)** | Pick a video from `ComfyUI/input/` or pass an absolute path. | | πŸŽ™οΈ **Extract Audio (ffmpeg)** | Demux audio track to a 16 kHz mono WAV. On-disk cache keyed by mtime + params. | | πŸŽ™οΈ **Audio From Path** | Bridge: WAV file β†’ ComfyUI `AUDIO` dict. Optional resample / mono. Also reports duration. | | πŸŽ™οΈ **Build Transcript JSON** | Wrap ASR text + source metadata into a structured v2.0 JSON. | | πŸŽ™οΈ **Save Transcript JSON** | Validate + write JSON to `ComfyUI/output/` with timestamped filename. | --- ## ⚠️ Read this before installing This pack does **not** ship an ASR model. Three things must be true before you can run a workflow: 1. **[ComfyUI-MiMoASR](https://github.com/aadebuger/ComfyUI-MiMoASR) installed and working** β€” including its `transformers==4.49.0` downgrade and `flash-attn` build. Verify those nodes register before you even start with this pack. 2. **`ffmpeg` on your server's `PATH`** β€” `$ which ffmpeg` must return a path. 3. **`torchaudio` in ComfyUI's venv** β€” installed in Step 2 below. Quick gut check: | | Required | How to check | | --- | --- | --- | | `ffmpeg` | any recent | `$ ffmpeg -version` | | `torchaudio` | any | `$ python -c "import torchaudio; print(torchaudio.__version__)"` | | ComfyUI-MiMoASR | installed | `$ curl -s http://SERVER:8188/object_info \| grep -o MiMoASRLoader` | | `PreviewAny` (from rgthree-comfy) | installed | `$ curl -s http://SERVER:8188/object_info \| grep -o PreviewAny` | --- ## Install (the proven order) Each step has a verification at the end. Don't skip the verifications. ### 1. Install MiMoASR first This pack depends on `MiMoASRLoader` and `MiMoASRTranscribe` from a separate repo. Follow [its full install guide](https://github.com/aadebuger/ComfyUI-MiMoASR#install-the-proven-order) before continuing here. **Stop and verify**: ```bash $ curl -s http://SERVER:8188/object_info | python3 -c " import json, sys d = json.load(sys.stdin) for n in ('MiMoASRLoader', 'MiMoASRTranscribe'): print(f' {n}: {\"OK\" if n in d else \"MISSING\"}')" ``` Both must print `OK`. If `MISSING`, fix MiMoASR before continuing. ### 2. Clone this node pack ```bash $ cd ComfyUI/custom_nodes $ git clone https://github.com/aadebuger/ComfyUI-VideoToText.git ``` Or, if installing from a tarball release: ```bash $ cd ComfyUI/custom_nodes $ tar xzf /path/to/ComfyUI-VideoToText-v0.2.0.tar.gz ``` Verify: ```bash $ ls ComfyUI/custom_nodes/ComfyUI-VideoToText/__init__.py # Must exist. If it's nested inside ComfyUI-VideoToText/ComfyUI-VideoToText/, you have a double-wrap β€” flatten it. ``` ### 3. Install Python deps (in ComfyUI's venv) ```bash $ cd ComfyUI && source .venv/bin/activate $ uv pip install torchaudio ``` Verify: ```bash $ python -c "import torchaudio; print('torchaudio', torchaudio.__version__)" # Must print a version string. Errors here β†’ re-run install. ``` ### 4. Install `ffmpeg` on the server (if missing) ```bash $ which ffmpeg || sudo apt install ffmpeg $ ffmpeg -version ``` ### 5. Restart ComfyUI The same launch incantation MiMoASR needs β€” both `HF_HOME` and `MIMO_ASR_REPO` env vars must be set: ```bash $ pkill -9 -f main.py; sleep 3 $ cd ComfyUI && source .venv/bin/activate $ export HF_HOME=/big_disk/hf_cache $ export MIMO_ASR_REPO=/opt/repos/MiMo-V2.5-ASR $ nohup python main.py --listen 0.0.0.0 --port 8188 > ~/comfy_start.log 2>&1 & $ sleep 30 $ grep -iE "IMPORT FAILED|VideoToText|MiMo" ~/comfy_start.log | head -20 ``` ### 6. Verify all 9 required nodes are registered ```bash $ curl -s http://SERVER:8188/object_info | python3 -c " import json, sys d = json.load(sys.stdin) for n in ('VTT_LoadVideo','VTT_ExtractAudio','VTT_AudioFromPath', 'VTT_BuildTranscriptJSON','VTT_SaveTranscript', 'MiMoASRLoader','MiMoASRTranscribe','PreviewAny','LoadAudio'): print(f' {n}: {\"OK\" if n in d else \"MISSING\"}')" ``` All 9 should show `OK`. If `PreviewAny` is missing, install [rgthree-comfy](https://github.com/rgthree/rgthree-comfy). --- ## Usage ### Minimal workflow ``` VTT_LoadVideo β†’ VTT_ExtractAudio β†’ VTT_AudioFromPath ─┐ β”œβ”€β”€β–Ί MiMoASRTranscribe β†’ text MiMoASRLoader β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό VTT_BuildTranscriptJSON β†’ STRING β”‚ β–Ό VTT_SaveTranscript β†’ ComfyUI/output/*.json ``` **Required fields**: - **MiMoASRLoader** (absolute paths!): - `model_path` = `/big_disk/models/MiMo-V2.5-ASR` - `tokenizer_path` = `/big_disk/models/MiMo-Audio-Tokenizer` - `repo_path` = leave blank if `MIMO_ASR_REPO` env var is set - **MiMoASRTranscribe**: - `language` = `Auto` (code-switched), `Chinese`, or `English` The first run loads the 8B MiMo model into VRAM (30–60s). Subsequent runs in the same ComfyUI session are instant β€” MiMo's loader has a process-wide cache. An API-format example workflow ships at [`example_workflows/video_to_json.json`](example_workflows/video_to_json.json). Edit the three MiMo paths to match your server before loading it in the UI. ### CLI A single-file CLI uploads a local video, drives the workflow over ComfyUI's HTTP + WebSocket API, and dumps the JSON transcript locally: ```bash $ uv pip install --system websocket-client requests $ uv run python cli/video_to_text_cli.py /path/to/lecture.mp4 \ --ip 10.8.0.12 \ --model-path /big_disk/models/MiMo-V2.5-ASR \ --tokenizer-path /big_disk/models/MiMo-Audio-Tokenizer \ --repo-path /opt/repos/MiMo-V2.5-ASR \ --language Auto ``` A wrapper alias to skip retyping paths every time: ```bash # ~/.bashrc alias v2t='uv run python /path/to/ComfyUI-VideoToText/cli/video_to_text_cli.py \ --ip 10.8.0.12 \ --model-path /big_disk/models/MiMo-V2.5-ASR \ --tokenizer-path /big_disk/models/MiMo-Audio-Tokenizer \ --repo-path /opt/repos/MiMo-V2.5-ASR' # Then: $ v2t my_video.mp4 --language Chinese $ v2t lecture.mp4 --language Auto --out ./transcripts ``` See [`cli/README.md`](cli/README.md) for all flags. --- ## JSON schema v2.0 ```json { "schema_version": "2.0", "source": { "audio_path": "/tmp/comfyui_vtt/lecture_abc123.wav", "duration_sec": 1834.512, "video_path": "/path/to/lecture.mp4" }, "model": { "name": "MiMo-V2.5-ASR", "tokenizer": "MiMo-Audio-Tokenizer", "language": "Auto" }, "text": "δ½ ε₯½οΌŒδ»Šε€©ζˆ‘δ»¬θŠδΈ€δΈ‹ ESP32 塌ε…₯式开发……" } ``` ### Trade-off vs faster-whisper MiMo-V2.5-ASR returns a **single plain-text transcript** β€” no word/segment timestamps, no confidence scores. Schema v2.0 reflects this: top-level `text` only, no `segments[]`. If you need time-aligned subtitles, run a different ASR backend (or wait for the planned v0.3.0 hybrid mode that pairs MiMo for text quality with faster-whisper for time alignment). --- ## Tips - **Pure-language audio**: setting `language=Chinese` or `English` is slightly more accurate than `Auto`. Use `Auto` only for code-switched content. - **GPU pinning**: on dual-GPU rigs, `$ export CUDA_VISIBLE_DEVICES=1` before launching ComfyUI keeps MiMo from fighting image models on `cuda:0`. - **Audio cache**: `VTT_ExtractAudio` writes to `$TMPDIR/comfyui_vtt/` keyed by source mtime + sample rate + mono flag. Re-runs on the same video skip `ffmpeg` entirely. Nuke with `$ rm -rf /tmp/comfyui_vtt`. - **Long audio**: MiMo handles multi-hour lectures in a single call. No manual chunking needed at typical podcast / lecture lengths. For 6h+ recordings, consider splitting at silence with `ffmpeg`. --- ## Troubleshooting | Symptom | Likely cause | Fix | | --- | --- | --- | | `VTT_*` nodes show `MISSING` in `/object_info` | Pack not loaded; ComfyUI didn't restart; or `IMPORT FAILED` | Check `~/comfy_start.log` for `IMPORT FAILED ComfyUI-VideoToText` traceback | | `MiMoASRLoader: MISSING` | MiMoASR not installed | See [its README](https://github.com/aadebuger/ComfyUI-MiMoASR) | | `PreviewAny: MISSING` | rgthree-comfy not installed | `$ git clone https://github.com/rgthree/rgthree-comfy.git` into `custom_nodes/` | | `RuntimeError: ffmpeg not found on PATH` | ffmpeg missing on the server | `$ sudo apt install ffmpeg` | | `RuntimeError: torchaudio is required` | torchaudio missing in ComfyUI's venv | `$ uv pip install torchaudio` in the right venv | | `RuntimeError: MiMo ASR repo path is empty` | `MIMO_ASR_REPO` env var not set | Set it before launching ComfyUI, OR pass `repo_path` in the workflow | | MiMoASRLoader: "model path does not exist" | Relative path in the workflow | Always use absolute paths | | `IMPORT FAILED ComfyUI-VideoToText` with `No module named 'folder_paths'` | Pack at wrong location | Must be in `ComfyUI/custom_nodes/`, not elsewhere | | CUDA OOM on transcribe | GPU 0 held by image models | `$ export CUDA_VISIBLE_DEVICES=1` before launching ComfyUI | See [`INSTALL_NOTES.md`](INSTALL_NOTES.md) for the full debug log of real-world install gotchas. --- ## Compatibility | | Required | Tested with | | --- | --- | --- | | Python | 3.10+ | 3.13 | | PyTorch | matches ComfyUI's | 2.11.0+cu126 | | `torchaudio` | any | matches torch | | `transformers` | **4.49.0** (MiMo pin) | 4.49.0 | | CUDA | β‰₯12.0 | 12.6 | | GPU VRAM | 24 GB (MiMo needs it) | 2Γ— RTX 3090 | | OS | Linux | Ubuntu 22.04 | > ⚠️ The `transformers==4.49.0` pin (required by MiMo) will break `Sonic`, `Qwen3TTS`, and recent `VibeVoice` builds β€” they want `>=4.57`. If you need both, run MiMo + VideoToText on a dedicated ComfyUI instance. --- ## Links - πŸ€— MiMo-V2.5-ASR weights: - πŸ€— MiMo-Audio-Tokenizer: - MiMo upstream repo: - MiMo ComfyUI nodes: - Blog: --- ## License MIT β€” see [LICENSE](LICENSE). MiMoASR upstream is Apache-2.0; MiMo-V2.5-ASR weights are MIT (Xiaomi).