Prompt Schedule Converter
Prompt travel without the spreadsheet math
- formatted_text
This is the node that turns a timestamped transcription into an actual prompt schedule, which is the whole point of Schedulizer. You've seen music-video workflows where the prompt morphs to match each lyric - "drive you through the night" shows a car on a dark highway, then the next line flips the scene. Making that by hand means transcribing the song, computing which frame each line lands on at your frame rate, and typing out a schedule. This node does that last step for you, and it's the boring one you'd never want to do by hand.
What it actually does
Feed it the text_with_timestamps output from the pack's Whisper Node (or any text in the same [0.00s - 5.32s] lyric format) plus your frame rate, and it emits a ready-to-paste prompt schedule in FizzNodes' "frame" : "prompt" format - the syntax the FizzNodes BatchPromptSchedule node (and friends) consume to drive prompt travel over video frames. It's the "Schedulizer" half of the pack: transcriptions go in, a schedule you can wire straight into a video workflow comes out.
Under the hood it's a regex. It matches lines shaped [start s - end s] text, converts each start time to a frame number with int(time * fps), and emits "328" : "I want to drive you through the night"-style entries. Two behaviors worth knowing:
- The first entry is always forced to frame
"0", even if the first lyric doesn't start until a few seconds in. The schedule just holds that first line from frame zero, which is fine for interpolation, but if your song has a long instrumental intro you'll want to trim the early frames manually. - Repeated lines only get an entry if they're consecutive. A repeated chorus gets its own entry each time it comes back around, so the prompt properly flips back and forth. The dedup only kicks in for back-to-back duplicates.
One detail that surprises people: it uses the start time only. The end time has to be there for the regex to match, but it's ignored for the math. So when a line runs long, the next line's start time decides when the prompt switches - which is exactly how prompt schedules work anyway.
The two inputs that matter
text_with_timestamps(STRING): must be the[seconds s - seconds s] textformat, one line per segment. The Whisper Node outputs exactly this, so the two were built as a pair. Paste in an.srtor plain text and you get nothing.fps(FLOAT): match this to the frame rate of the video or AnimateDiff sequence you're driving. The pack's own example workflow runs the same lyrics through three converters at 8, 24, and 30 fps so you can grab whichever matches your project.
The single output is formatted_text (STRING) - wire it into FizzNodes BatchPromptSchedule's text input, or just copy it out of a text-display node (the shipped workflow uses JjkShowText as a preview). Either way, it's plain text you can also save for later.
Installing it
Install the pack once and you get both nodes. In ComfyUI Manager, search "Schedulizer" and hit install, or:
cd ComfyUI/custom_nodes
git clone https://github.com/DoctorDiffusion/ComfyUI-Schedulizer.git
cd ComfyUI-Schedulizer
pip install -r requirements.txt
Restart ComfyUI after. If you only want this converter and not the Whisper Node, you can skip the dependency install entirely - this node is pure stdlib re and needs nothing extra. The pack's last commit is from late 2024, but a regex that multiplies two numbers doesn't rot; it still works fine on current ComfyUI.
When it bites you
The regex is picky. [12.34s - 56.78s] text matches; [12:34 - 56:78] text (subtitle-style) does not. When nothing matches, the node just returns "No valid input detected." instead of an error, which is easy to miss if the text widget is folded. If you see that, your timestamps aren't in the expected format. And remember the first-line-to-frame-0 behavior - if your render starts with 30 seconds of silence, nudge that first entry to the real start frame before you render.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| text_with_timestamps | STRING | — | |
| fps | FLOAT | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| formatted_text | STRING | — |