Nodes/ComfyUI-AceStep_SFT/AceStep 1.5 SFT Audio Duration
ComfyUI Node

AceStep 1.5 SFT Audio Duration

The boring node that stops your cover rendering at 60 seconds

By jeankassio·Created 8 months ago·Updated 7 days ago· 65
AceStep 1.5 SFT Audio Duration
  • audio
  • duration_seconds

One input, one output, no model load. You hand it any ComfyUI AUDIO, it hands back duration_seconds as an integer, rounded to the nearest second. That's the whole node.

Which raises the obvious question: why does this exist? Because duration is a widget you have to fill in by hand, and Generate defaults it to 60. Feed a 3:40 track through the legacy latent_or_audio img2img path - or wire up an audio source to any workflow where the duration isn't implied - and you get a clean, confident, completely wrong 60-second render. This node is how you stop guessing and read the number that's actually in the waveform.

How it works

It doesn't decode anything, doesn't shell out to ffprobe, doesn't touch librosa. The AUDIO value in ComfyUI is a dict holding a waveform tensor and a sample rate; the node reads those directly, divides sample count by sample rate, and returns int(math.floor(duration + 0.5)). That last bit matters more than it looks: it rounds to the nearest whole second rather than truncating, so 4.6 s comes back as 5, not 4.

Because there's no file involved, it's instant and it works on audio you just generated and never saved. It validates before it answers - if the input isn't a real AUDIO payload with a usable waveform and a positive sample rate, it raises instead of returning a zero you'd then feed into a sampler.

The bits you actually wire up

  • audio (AUDIO, required) - the thing to measure. Drop a Load Audio on it, or the audio output of Generate / the SFT Audio Duration's neighbours in the pack.
  • duration_seconds (INT) - the only output. Send it to TextEncode's duration or Generate's duration; ComfyUI's implicit number conversion takes an INT into a FLOAT widget without complaint.

That's the whole use: keep TextEncode and Generate agreeing on how long the song is, without typing it. The pack's own docs are blunt about why - if duration drifts between the two, the LM codes were generated for a different length than the diffusion run, and you get a console warning when they differ by more than a second. Matching them (or setting Generate's duration to 0 so it inherits the encoded length) avoids the whole class of problem.

Install

Same pack as the rest of the suite - it's all one repo. Via ComfyUI Manager, search for ComfyUI-AceStep_SFT and install, or do it by hand:

cd ComfyUI/custom_nodes
git clone https://github.com/jeankassio/ComfyUI-AceStep_SFT.git

Then install its requirements into the same Python that runs ComfyUI (transformers>=4.52.0, torchaudio, librosa, soundfile, numpy, pyyaml) and restart. On Windows portable:

.\python_embeded\python.exe -m pip install -r .\ComfyUI\custom_nodes\ComfyUI-AceStep_SFT\requirements.txt

You still need the models - acestep_v1.5_sft.safetensors (or the merged SFT+Turbo), the Qwen text encoders, and ace_1.5_vae.safetensors - but not for this node. It's the one node in the pack that runs happily with zero models loaded, which makes it handy for checking a stray audio file without a generation queue behind it.

Where it trips people up

It takes AUDIO only, not LATENT. The Cover/Remix and Inpaint/Repaint task nodes accept AUDIO,LATENT, so it's easy to assume this one does too. It doesn't - if all you have is a latent, you need to VAE-decode it to audio first.

It rounds. Great for filling in a duration field, useless if you need precision. For a repaint window, the start_seconds / end_seconds fields are where exact numbers belong, and those are FLOATs you set yourself.

Everything else in the pack needs a ComfyUI build with native ACE-Step 1.5 support. This node doesn't, but the moment you use it inside a real music graph, the sampler side of the suite does.

Categoryaudio/AceStep SFT

Inputs (1)

NameTypeDefaultDescription
audioAUDIOAudio whose duration will be measured. A disabled reference returns 0 seconds.

Outputs (1)

NameTypeDescription
duration_secondsINT—