Nodes/CoachBate/CoachBate Shot Audio Tail
ComfyUI Node

CoachBate Shot Audio Tail

Silence at the end of a shot, on purpose, from a JSON field

By CoachBate·Created 3 months ago·Updated 21 days ago· 2
CoachBate Shot Audio Tail
  • audio
  • AUDIO
◄shot_payload—►

A one-trick node, and a useful trick

CoachBate Shot Audio Tail takes audio and a shot_payload, and returns AUDIO. That's all it does. If the shot's JSON has an output_audio_tail object, it keeps the first N seconds of the speech, appends M seconds of silence, and hands you the result. If the shot's JSON doesn't have that field, the audio passes straight through untouched - an identity node, no cost.

Why would you want that? Because the end of a generated shot is where audio tends to be weakest. H3 with a song mask will happily keep producing plausible dialogue right to the last frame, and if your editorial plan is "shot ends, beat of silence, cut to the next scene," generating that silence inside the model gives you whatever the model thinks should follow the line. Cutting it and replacing it with true digital silence is deterministic, and it's the same every time you re-render the shot.

The exact field contract

The output_audio_tail object is strict - it accepts exactly four keys and rejects anything else, including a misspelling:

{
  "shot_id": "014",
  "duration_seconds": 8,
  "video_prompt": "...",
  "output_audio_tail": {
    "keep_seconds": 6.5,
    "silence_seconds": 1.5,
    "sample_rate": 32000,
    "channels": 2
  }
}

keep_seconds and silence_seconds must be positive finite numbers; sample_rate and channels must be positive integers. The node trims with TrimAudioDuration (starting at 0), builds the tail with EmptyAudio, and joins them with AudioConcat in the after direction - all existing installed audio nodes, no bespoke DSP hiding in the pack.

Note the doc's own warning: this affects generated output only, never the source file. And the README is blunt that you shouldn't add the field unless you mean it, because a silent tail is an editorial decision that survives every re-render, which cuts both ways. If you add it to a shot and then wonder months later why that one shot has a beat of nothing at the end - that's this node, and the answer is in the JSON.

Where it sits: after the audio comes back from the decode, before you mux. It works on any AUDIO stream, so it's just as happy on a ComfyUI-loaded song as on generated H3 audio.

Inputs and outputs

Required: audio (AUDIO), shot_payload (STRING, forced input - wire it from CoachBateShotLoader so both stay in sync). Output: AUDIO.

That's the entire node. There are no widgets, which is worth saying plainly because it looks alarming in the node list: everything it needs is in the shot record.

Install

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

Or ComfyUI Manager → search "CoachBate" → restart ComfyUI. Category CoachBate / H3. It calls the installed TrimAudioDuration, EmptyAudio and AudioConcat nodes, which ship with modern ComfyUI, so keep your install reasonably current. No extra pip dependencies.

Where people get burned

  • "output_audio_tail requires keep_seconds, silence_seconds, sample_rate, channels." - the object has a missing or extra key. It's an exact set match.
  • "output_audio_tail keep_seconds must be positive and finite." - a zero, a negative, or a string. JSON numbers only, and both time values have to be > 0.
  • Wrong-sounding result after the join. Check that sample_rate and channels match the audio you're feeding in - the silence is built at whatever you specify, and a mismatch is the one way to get an audible artefact out of a node that's supposed to be inaudible.
CategoryCoachBate/H3

Inputs (2)

NameTypeDefaultDescription
audioAUDIO—
shot_payloadSTRING—

Outputs (1)

NameTypeDescription
AUDIOAUDIO—