Audio Mood Analyzer (Timeline)
Audio Mood Analyzer (Timeline) For Image Sequences
- audio
- prompt_sequence_json
- merge_prompts
- environment_prompts
- subject_prompt
A three-minute song doesn't have one mood. It has an intro that's sparse, a middle that's tense, a climax that's loud, an outro that falls apart - and if your prompt reflects none of that arc, you're throwing away the best thing audio has to offer image generation. Audio Mood Analyzer (Timeline) is the base node split into time. It divides your audio into N equal segments, runs the full analysis-and-prompt pipeline on each segment, and hands you one set of prompts per slice of the song. It's the node you reach for when the goal is a sequence of images that follows the music, not a single still.
How it works
Mechanically it's simple: the audio is sliced into n_segments equal chunks (default 8, range 2–32), and each chunk gets the same treatment as the base node - librosa feature extraction, an Ollama mood analysis call, and environment/merge prompt calls per segment. Two things are deliberately not per-segment. Subject analysis runs once from the lyrics or text (the subject doesn't change just because the song got loud), and the resulting subject prompt is shared across all segments.
The outputs:
prompt_sequence_json- a JSON array, one object per segment withsegment,start_s,end_s,mood_json,environment_prompt,subject_prompt, andmerge_prompt. This is the structured version, and it's what the AnimateDiff Schedule Formatter consumes.merge_prompts- merge prompts only, one per line. The README calls this the most useful output, and it's right: newline-separated prompts line up with image batch nodes cleanly.environment_prompts- same thing, environment prompts only.subject_prompt- the single shared subject prompt.
All the base node's inputs apply (audio, model, temperatures, style presets, lyrics fields, the three output toggles), plus n_segments.
The cost, and it's the real one
This node is expensive in the literal sense of time. At n_segments=8 with all three toggles on, a run makes up to 26 Ollama calls: 2 shared subject calls plus 3 per-segment calls × 8 segments. Each call is a local LLM generating text. That's not a bug - it's the design - but if you're on a small model on a CPU, a single timeline run can take a long while, and it's worth dialing n_segments down to 4 or 6 while you iterate on prompts before committing to the full run. The per-segment environment and merge calls also sit in try/except blocks in the source, so one bad segment logs a warning and the run continues rather than dying - but a segment that failed will show up as an empty prompt, which is exactly why the formatter node skips empties.
Where it fits
The intended downstream is image-sequence and video work. The pack's example workflow wires merge_prompts into a single-image sanity check, and the timeline→formatter path feeds AnimateDiff-style prompt travel. One honest note, though: the KB's own verdict on AnimateDiff is that it's superseded for general video - Wan-based tooling has matched every capability it was kept around for - so before you build a whole music-video pipeline on this, decide whether you want the AnimateDiff morph aesthetic specifically or just prompt-per-frame control. Either way, the timeline node's output is format-agnostic: newline-separated prompts work with any batch workflow, AnimateDiff or not.
Install
Same pack, same everything:
cd ComfyUI/custom_nodes
git clone https://github.com/andrea-spoldi/ComfyUI-AudioMoodAnalyzer.git
pip install -r ComfyUI-AudioMoodAnalyzer/requirements.txt
Restart, find it under audio/analysis, and make sure Ollama is running with a model pulled (ollama pull qwen3:14b). No API key, no cloud - the only thing you're spending is patience while the local model writes 26 mini-prompts.
Inputs (17)
| Name | Type | Default | Description |
|---|---|---|---|
| audio | AUDIO | — | |
| ollama_url | STRING | http://localhost:11434/api/generate | — |
| model | STRING | qwen3:14b | — |
| analysis_temperature | FLOAT | 0.40–1.5 | — |
| prompt_temperature | FLOAT | 0.80–1.5 | — |
| custom_context | STRING | Analyze the music as pure sound, not lyrics. Translate sonic qualities into emotional visual direction. | — |
| lyrics_or_text | STRING | — | |
| focus_fragment | STRING | — | |
| song_title | STRING | — | |
| song_description | STRING | — | |
| song_genre | STRING | — | |
| style_preset | COMBO | painterly | 5 options: painterly, cinematic, raw, abstract, custom |
| style_notes | STRING | — | |
| n_segments | INT | 82–32 | — |
| generate_environment_prompt | BOOLEAN | true | — |
| generate_subject_prompt | BOOLEAN | true | — |
| generate_merge_prompt | BOOLEAN | true | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| prompt_sequence_json | STRING | — |
| merge_prompts | STRING | — |
| environment_prompts | STRING | — |
| subject_prompt | STRING | — |