Loop needs the video to be longer than the track by at least 30 seconds. As a guideline it
is for clips over 4 minutes. For shorter clips the track can play straight. See
Find where to cut. Soundstripe tracks only.
Loop a track
Pass avideo_id you’ve already ingested and a track_id from a match.
200 from its loop-plan cache. The first time you loop a given track against a
given video there is nothing cached, so the plan is built as a job:
202 first time
202, with no job_id and a
poll of /v1/videos/{video_id}. Poll the video to ready, then call /v1/loop again.
Poll the loop job until it’s complete:
200 the loop plan
200 straight from POST /v1/loop carries the same body without job_id, status and
cached. track is on every loop response: the song id is the work, the audio-file id is the
specific render you fetch, and they are not interchangeable. The audio-file id is resolved
best-effort and is null when the catalog lookup fails.
Reading the plan
segments is the authoritative playback path: the ordered ranges of the song to play back to
back. Video time is music_in plus the cumulative length of the segments played so far. Read
segments first. The flat fields below describe the same loop but cannot express a final pass
that exits into a come-down outro instead of being truncated mid-body.
Apply
seam_fades, seam_curves and the per-segment gains, or the seams click and step in level.
Full assembly steps are in Render under your own license. They apply whether or
not you hold the license.
The plan carries more than the table above: seam_times, song_start, song_duration,
window_end, music_end, tail_seconds, sections_covered, end_label, an outro_start /
outro_end pair when the plan resolves on an outro, and an options array holding up to four
self-contained alternate plans, best first, with the served plan as options[0]. Treat anything
not in the table as informational.
When a loop isn’t applicable
If there’s nothing to loop,applicable is false, the plan carries a reason, and nothing is
billed:
retryable is the field to branch on. true means the analysis didn’t finish on this request and
nothing was cached against the pairing, so calling again in a few seconds normally reads back work
that completed in the background. false means it’s settled: pick another track.
video_seconds, track_seconds and required_excess_seconds let you solve for the ceiling
yourself. For the clip above, any track under 227s qualifies. Screening on those numbers
before you call is free. Calling and being refused is also free, but it costs a round trip per
track.
Duck under voiceover (auto-mix)
If your video has narration or dialogue, you’ll want the music to dip under the voice. Pass"auto_mix": true and an applicable loop comes back with a mix block telling you how to
duck the music, using the same numbers the Cue app uses, so your render matches the app. There is no
mix key on a not-applicable result, and none when the measurement can’t be read.
mix (on an applicable loop)
How to render it
Four steps, in this order. It is what Cue’s own export does:- Take the footage’s own audio and apply
video_gain_db. - Take the music and apply
music_gain_db. - On the music only, apply
envelope_pointsas additional attenuation. - Sum the two, then limit.
envelope_points is [[t_seconds, gain_db], …] and it is the authoritative curve. It is
literally the automation Cue’s own renderer replays. Read it as a positive amount to pull the
music down at that instant: 0 means untouched, 20 means 20 dB below where step 2 left it.
Interpolate linearly between points. That reproduces Cue’s curve exactly, and no point of it
is approximated away. Points are emitted only where the curve moves, so long held passages cost
nothing: a real 257-second clip came to about 390 points.
When the clip has no voiceover you get { "voiceover": false, "classification": …, "duck": null }. There is nothing to duck, so play the music as planned, and music_gain_db and
video_gain_db are absent. Auto-mix reads the measurement warmed at ingest, so it adds no extra charge. The same
auto_mix flag works on /v1/align.
What it costs
The cold build is billed per(video_id, track_id) pair, not once per track: looping the same
track over a second video builds a second plan and is charged at the cold rate again. Every later
loop of that same pairing is the warm rate. A not-applicable result bills nothing and auto_mix
adds no charge.
There is no cached field on a 200 straight from POST /v1/loop, because that 200 is served
from the plan cache by definition and is always the warm rate. cached appears on the completed
job instead, and there it is the field to read: a job normally builds the plan and bills cold, but
if another call cached the same pairing while it queued it comes back cached: true at the warm
rate. See Metering & pricing.