/

·

No. 100

How to Make a Seamless Loop for Music or Video Backgrounds

·

by

A turquoise ocean wave curling over

Key takeaways

  • The crossfade-and-swap method works on almost any footage: cut the clip in half, swap the halves and dissolve across the new middle, so the file's end and start are the same frame.

  • Ping-pong loops (forward, then reversed) only look natural for symmetric motion such as waves, smoke or a slow orbit; people walking backward give them away.

  • In Blender, key the last frame plus one to match the first, render one frame short and use the Cycles F-curve modifier for repeating motion.

  • Cut music loops at zero crossings and to a whole number of bars: at 120 BPM in 4/4, one bar is exactly 2 seconds.

  • Export audio loops as WAV or FLAC, not MP3 or AAC, because those formats add padding that leaves a gap at the seam.

What you need

  • Footage or an image that will loop: clouds, water, smoke, a slow pan across a still or an abstract animation work best.

  • DaVinci Resolve (the free version handles up to UHD at 60 fps), FFmpeg or Blender 5.2.

  • Audacity 4 for the audio loop.

  • The target length. Spotify Canvas, for example, needs 3 to 8 seconds in vertical 9:16, at 720 to 1080 pixels tall, as an MP4.

Step 1: Choose the right source

Loops fail when something in the frame can't get back to where it started. Avoid shots where the camera travels, the light changes or a person crosses the frame. Look for continuous, repeating motion such as rain, flames, drifting particles, a rotating object or a locked-off shot of a city at night. A few seconds of good material beats a long clip with a single obvious event in it.

Step 2: Build the loop

Pick one of four methods. A crossfade in an editor works on almost any live-action footage, FFmpeg handles batches, Blender loops exactly and an AI generator makes the footage for you.

In DaVinci Resolve

1. Put the clip on the timeline and trim it to your loop length plus about a second.

2. Use the blade tool to cut it in the middle.

3. Drag the second half to the start of the timeline and the first half after it. The file now begins and ends on frames that were next to each other in the original, so the end of your loop flows into its start.

4. Select the cut between the two halves and add a Cross Dissolve with Cmd+T on a Mac or Ctrl+T on Windows. Each side of the cut needs a few spare frames for the dissolve to work.

5. Lengthen the dissolve until the join disappears, usually 12 to 30 frames.

6. Play it with looping turned on in the viewer and watch the start of the timeline, not just the dissolve.

For a ping-pong loop instead, duplicate the clip, right-click the copy, choose Change Clip Speed, tick Reverse Speed and place it right after the original.

In FFmpeg

FFmpeg does the same thing from the command line, which is handy for batches. For a 10-second clip with a 1-second crossfade, the result is 9 seconds long and its last frame flows into its first:

ffmpeg -i in.mp4 -filter_complex "[0:v]fps=30,format=yuv420p,split[a][b];[a]trim=start=1,setpts=PTS-STARTPTS[main];[b]trim=end=1,setpts=PTS-STARTPTS[head];[main][head]xfade=transition=fade:duration=1:offset=8[v]" -map "[v]" -an -c:v libx264 -crf 18 -pix_fmt yuv420p -movflags +faststart loop.mp4
ffmpeg -i in.mp4 -filter_complex "[0:v]fps=30,format=yuv420p,split[a][b];[a]trim=start=1,setpts=PTS-STARTPTS[main];[b]trim=end=1,setpts=PTS-STARTPTS[head];[main][head]xfade=transition=fade:duration=1:offset=8[v]" -map "[v]" -an -c:v libx264 -crf 18 -pix_fmt yuv420p -movflags +faststart loop.mp4
ffmpeg -i in.mp4 -filter_complex "[0:v]fps=30,format=yuv420p,split[a][b];[a]trim=start=1,setpts=PTS-STARTPTS[main];[b]trim=end=1,setpts=PTS-STARTPTS[head];[main][head]xfade=transition=fade:duration=1:offset=8[v]" -map "[v]" -an -c:v libx264 -crf 18 -pix_fmt yuv420p -movflags +faststart loop.mp4

Set the offset to the clip length minus twice the fade length. The fps step forces the constant frame rate the xfade filter needs, since phone footage often has a variable one.

For a ping-pong loop, trim first, because the reverse filter holds the whole clip in memory:

ffmpeg -i in.mp4 -filter_complex "[0:v]trim=end=4,setpts=PTS-STARTPTS,split[f][r];[r]reverse,trim=start_frame=1,setpts=PTS-STARTPTS[rv];[f][rv]concat=n=2:v=1:a=0[v]" -map "[v]" -c:v libx264 -crf 18 -pix_fmt yuv420p boomerang.mp4
ffmpeg -i in.mp4 -filter_complex "[0:v]trim=end=4,setpts=PTS-STARTPTS,split[f][r];[r]reverse,trim=start_frame=1,setpts=PTS-STARTPTS[rv];[f][rv]concat=n=2:v=1:a=0[v]" -map "[v]" -c:v libx264 -crf 18 -pix_fmt yuv420p boomerang.mp4
ffmpeg -i in.mp4 -filter_complex "[0:v]trim=end=4,setpts=PTS-STARTPTS,split[f][r];[r]reverse,trim=start_frame=1,setpts=PTS-STARTPTS[rv];[f][rv]concat=n=2:v=1:a=0[v]" -map "[v]" -c:v libx264 -crf 18 -pix_fmt yuv420p boomerang.mp4

To turn a finished loop into a long file for a stream, repeat it without re-encoding. This plays it 60 times:

ffmpeg -stream_loop 59 -i loop.mp4 -c copy loop_x60.mp4
ffmpeg -stream_loop 59 -i loop.mp4 -c copy loop_x60.mp4
ffmpeg -stream_loop 59 -i loop.mp4 -c copy loop_x60.mp4

In Blender

Animation can loop exactly, with no dissolve at all.

1. Set the frame range, for example 1 to 240 for 10 seconds at 24 fps.

2. Key your object at frame 1, then key frame 241 with the identical values, one frame past the end. Rendering 1 to 240 then avoids showing the same pose twice at the seam.

3. For constant spin or drift, set the keys to linear interpolation so motion doesn't ease in and out at the ends.

4. For repeating motion, open the Graph Editor and add a Cycles modifier to the F-curve, making sure it's first in the modifier stack. Its default settings make the curve cyclic, so handles smooth across the seam.

5. If you use the Noise modifier for camera shake, restrict it to a frame range and blend it in and out so it's zero at both ends. Its Phase setting only changes the random seed and does not make the noise repeat.

With an AI generator

AI video generators rarely have a loop button, but the same image used as both the first and last frame gets close. MiniMax H3 in Hailuo takes a first and last frame for 4- to 15-second clips, and Vidu's start-to-end mode does the same. Describe motion that can return to where it began, such as "gentle waves, locked-off camera" rather than "camera flies forward." Some models drift in color when both frames are identical, so bring the result into Resolve and add a short crossfade if the seam shows.

Step 3: Make the music bed loop

A visual loop under a music track that clicks at the seam still sounds broken.

1. Pick a loop length that's a whole number of bars. One bar in 4/4 is 240 divided by the BPM in seconds, so at 120 BPM four bars last 8 seconds, which also fits the Spotify Canvas limit.

2. In Audacity 4, select the section, then press Z to snap the cursor to the nearest zero crossing at each end, where the waveform crosses the center line. Cutting there avoids a click.

3. Set the loop region with Shift+L and play it with L to hear the seam.

4. If the ends still don't match, crossfade them in FFmpeg with the audio version of the swap trick:

ffmpeg -i bed.wav -filter_complex "[0:a]asplit[a][b];[a]atrim=start=2,asetpts=PTS-STARTPTS[main];[b]atrim=end=2,asetpts=PTS-STARTPTS[head];[main][head]acrossfade=d=2:c1=tri:c2=tri[out]" -map "[out]" -c:a pcm_s16le bed_loop.wav
ffmpeg -i bed.wav -filter_complex "[0:a]asplit[a][b];[a]atrim=start=2,asetpts=PTS-STARTPTS[main];[b]atrim=end=2,asetpts=PTS-STARTPTS[head];[main][head]acrossfade=d=2:c1=tri:c2=tri[out]" -map "[out]" -c:a pcm_s16le bed_loop.wav
ffmpeg -i bed.wav -filter_complex "[0:a]asplit[a][b];[a]atrim=start=2,asetpts=PTS-STARTPTS[main];[b]atrim=end=2,asetpts=PTS-STARTPTS[head];[main][head]acrossfade=d=2:c1=tri:c2=tri[out]" -map "[out]" -c:a pcm_s16le bed_loop.wav

5. Export as WAV or FLAC. MP3 and AAC add silent padding at the start and end, which turns into a gap every time the loop restarts.

If the video and music loop together, match their lengths exactly. At 30 fps, frames per bar equal 30 times the beats per bar times 60, divided by the BPM, so a 120 BPM bar is 60 frames.

Step 4: Export for where it will play

Destination

Format

Notes

Spotify Canvas

MP4, 9:16, 720 to 1080 px tall, 3 to 8 seconds

Spotify loops it automatically; only text relevant to the track is allowed, with no logos, links or calls to action

Website background

WebM first, MP4 (H.264) fallback

Use autoplay, muted, loop and playsinline, strip the audio track, add a poster image and keep the file to a few MB

Resolume and VJ software

DXV 3 or HAP

Intra-frame codecs loop and seek instantly; Resolume advises against H.264 for live playback

Livestream or long background file

H.264 MP4 at a constant frame rate

Repeat the loop with -stream_loop, or set your streaming software's media source to loop

For web video, this FFmpeg line makes a small, silent MP4 that starts playing before it finishes downloading:

ffmpeg -i loop.mov -an -vf scale=1280:-2 -c:v libx264 -crf 26 -preset slow -pix_fmt yuv420p -movflags +faststart hero.mp4
ffmpeg -i loop.mov -an -vf scale=1280:-2 -c:v libx264 -crf 26 -preset slow -pix_fmt yuv420p -movflags +faststart hero.mp4
ffmpeg -i loop.mov -an -vf scale=1280:-2 -c:v libx264 -crf 26 -preset slow -pix_fmt yuv420p -movflags +faststart hero.mp4

Common problems and fixes

  • Jump at the seam: the first and last frames are the same frame shown twice, or the motion changes speed. Remove the duplicate frame and use linear motion.

  • Flash or pop: exposure or color shifts across the clip. Grade both halves to match before adding the dissolve.

  • Ghosted dissolve: the crossfade is too long for fast motion. Shorten it, or pick a calmer section.

  • Click in the audio: the cut isn't on a zero crossing, or the file is MP3 or AAC.

  • Stutter in the browser or on stage: the frame rate is variable or the keyframes are far apart. Re-encode at a constant frame rate with a short keyframe interval.

Frequently asked questions

How do you make a video loop seamlessly?

Cut the clip in half, swap the two halves and add a cross dissolve where they meet. The file then starts and ends on frames that were next to each other in the original, so the loop flows without a jump. DaVinci Resolve and FFmpeg both do this.

What's the difference between a crossfade loop and a ping-pong loop?

A crossfade loop blends the end of a clip into its start and suits most footage. A ping-pong loop plays the clip forward, then in reverse, which looks natural only for symmetric motion such as waves or smoke.

How long should a background loop be?

Spotify Canvas allows 3 to 8 seconds. For streams and websites, 6 to 15 seconds keeps the file small while making the repetition harder to notice. For music, match the loop to a whole number of bars.

How do I stop a looping audio file from clicking?

Cut it at zero crossings, keep its length to whole bars and export it as WAV or FLAC. MP3 and AAC add padding that creates a gap at the loop point.

Can AI make a seamless loop?

Yes, with first and last frame support. Give a generator such as Hailuo or Vidu the same image as the first and last frame and describe motion that returns to its starting point, then crossfade the seam in an editor if it still shows.