Lyrics JSON Parser
An LLM handed you music metadata as JSON. Now actually use it.
- lyrics
- bpm
- key
- keyscale
- caption
- duration_sec
If you're making music videos with LTX-2.3, you've probably discovered the awkward middle step: you ask an LLM to write lyrics and describe the song, and it hands you a JSON blob. Now what? You could paste the whole thing into a CLIP text encode, but that's ugly and mixes data types. Lyrics JSON Parser is the glue: it takes a JSON string containing music metadata and splits it into six typed outputs your graph can actually wire around.
It's a narrow node with one job, and it does that job cleanly. The author built it for his own music-video production pipeline, where an LLM authors the track metadata and this node turns it into usable values.
How it works
The JSON input accepts either raw JSON or a markdown-fenced code block - so you can paste an LLM's entire ```json ... ``` response straight in without stripping the fences first. It decodes the payload and validates a fixed schema. Required fields: lyrics, bpm, key, caption, and duration_sec. One optional field, keyscale, defaults to the value of key when missing. Validation is loud: missing fields, non-object payloads, and wrong types all raise clear errors instead of silently producing garbage.
The input
One socket, JSON (multiline STRING). The default shows the exact expected shape:
{
"lyrics": "",
"bpm": 120,
"key": "C major",
"caption": "",
"duration_sec": 180
}
The outputs
Six typed sockets, ready to plug in anywhere:
lyrics(STRING) - the lyrics text. Into a CLIP text encode, or into a save/caption node for a sidecar file.bpm(INT) - beats per minute.key(STRING) - musical key, e.g. "C major".keyscale(STRING/COMBO) - key with scale; falls back tokeyif not provided.caption(STRING) - short description of the music. Handy as a filename fragment or a metadata tag.duration_sec(FLOAT) - track length in seconds. Useful for timing math against your video pipeline.
The value of the typed outputs shows up the moment you start building: bpm and duration_sec can feed timing calculations or audio nodes directly, lyrics goes to the prompt side, and caption rides along as your file label - all without a string-parsing detour.
Common issues
- "JSON input is empty" - nothing connected, or an empty string. This is an input node; it needs data.
- "missing required field(s)" - the LLM didn't emit one of the five required keys. The error names them; fix the prompt or the JSON.
- "must be an integer / must be numeric" - an LLM occasionally writes
"bpm": "120"as a string. Fix the type in the JSON. - Must decode to an object - a bare list or string won't parse. It has to be a
{...}object.
Installation
Install via ComfyUI Manager (search "CoachBate") or:
cd ComfyUI/custom_nodes
git clone https://github.com/CoachBate/ComfyUI-CoachBate.git
Restart ComfyUI; it appears under CoachBate in Add Node. No Python dependencies, no model files. Alpha-stage pack, but this node is about as simple as custom nodes get - just JSON validation and six wires.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| JSON | STRING | { "lyrics": "", "bpm": 120, "key": "C major", "caption": "", "duration_sec": 180 } | JSON string containing lyrics, bpm, key, optional keyscale, caption, and duration_sec. |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| lyrics | STRING | — |
| bpm | INT | — |
| key | STRING | — |
| keyscale | COMBO | — |
| caption | STRING | — |
| duration_sec | FLOAT | — |