Skip to content
streamneo.
Setup Guides13 min read

How to Add Background Music to an FFmpeg YouTube Loop Stream

Learn how to loop video and music in FFmpeg, preserve or replace audio, mix streams, and test the result before YouTube Live.

sn.
StreamNeoPublished 4 October 2026
Worth sharing?

FFmpeg can send a looping video to YouTube Live with background music, but there is no single command that fits every file. The correct media graph depends on whether the video already has audio, whether you repeat the whole input or decoded frames, and whether the music should end with the video or continue beneath it.

Start by inspecting both files, decide which audio should reach YouTube, then build and test the graph locally before publishing. The examples below are templates to adapt, not commands that have been executed or validated on your files.

Check the video's existing audio

Before writing a filter graph, inspect the streams in the video and music files. A video may contain one video stream and one audio stream, several audio tracks, or no audio at all. The difference matters because a graph that refers to [0:a] cannot work if input zero has no audio stream.

You can inspect a file with ffprobe, which is normally distributed with FFmpeg:

ffprobe -hide_banner loop.mp4
ffprobe -hide_banner music.mp3

Look for the stream type, codec, channel layout, sample rate, duration and stream index. You are trying to answer practical questions rather than collect every metadata field:

  • Does loop.mp4 contain an audio stream at all?
  • Is the existing audio speech, room sound, devotional singing, or something you intend to retain?
  • Does the music file contain one usable audio stream?
  • Are either files variable in length or unusually encoded?

If the source has several audio tracks, do not assume that 0:a:0 is the track you want. Listen to each candidate or identify it from the metadata before mapping it. For a simple file, 0:v:0 means the first video stream and 0:a:0 means the first audio stream from input zero.

This first check prevents one of the most common overnight failures: a command is written for a video with audio, but the actual loop file is silent. If you are moving from a graphical setup to command-line streaming, the explanation in how to loop a video live on YouTube with OBS can also help you compare the media assumptions made by different tools.

Choose what to preserve or replace

There are three useful outcomes. You can keep the video's original audio, replace it with music, or mix both. Decide this before choosing filters.

Keep the original audio when the file already contains the sound you want and the music is not required. You may not need a music input or an audio filter at all. Map the video's audio stream directly, while still checking that its format is accepted by your chosen output settings.

Replace the original audio when the video is silent, when its sound is unwanted, or when the music should be the only audible layer. In that case, map the video from input zero and the music from input one. There is no reason to feed the unwanted source audio into amix.

Mix both when the original contains speech, natural sound, or a devotional vocal that should remain under a quieter music bed. This requires a deliberate level choice. The weights option changes the relative contribution of the inputs, but it is not a substitute for listening. A source recorded much louder than another may still dominate after a modest weight is applied.

The FFmpeg amix documentation shows weighted inputs and explains its duration and normalisation options. Its example is an illustration, not a recommended level for every channel. The FFmpeg filter documentation is the primary reference for amix, aloop, and the video loop filter.

Also consider the archive. If YouTube keeps a recording of the live broadcast, the combined audio is part of that recording. A music licence must cover the uses you actually intend, which may include live streaming and an archived copy. YouTube says live streams are scanned for third-party content, and a stream can be interrupted when protected material is detected. It also states that a channel may need to be added to the rights holder's allowlist even when you have obtained a licence. Check YouTube's guidance on copyright issues with live streams and confirm the exact position with the rights owner.

A technically valid MP3 or WAV file is not automatically permitted music. YouTube's live-stream terms refer to the necessary rights, including music licensing rights from artists, record labels, publishers and other royalty participants. Treat rights checking as a separate task from encoding.

Loop video and music to the intended duration

Video looping and music looping are separate jobs. FFmpeg can repeat a complete input file with -stream_loop, or loop decoded video frames with the loop video filter. For audio, you can repeat a complete music input or use the aloop audio filter for decoded samples.

Repeating the whole video input is the simpler pattern when the same complete file should replay:

ffmpeg -stream_loop -1 -re -i loop.mp4 \
  -stream_loop -1 -re -i music.mp3 \
  ...

Here, -stream_loop -1 requests indefinite repetition for the relevant input. Keep each option associated with the input it controls. The -re option asks FFmpeg to read at a native rate rather than consuming the file as quickly as possible, which is generally relevant when a file is being used as a live source.

The input-level approach repeats the complete file. If a music track has a long silence at the end, that silence is repeated too. If its beginning and end do not join smoothly, you will hear a seam each time it restarts. Prepare a clean loop or accept the transition as part of the programme.

A filter-based approach is useful when the loop belongs inside a larger media graph. The video filter has options for selecting a starting frame and a number of frames, while the audio aloop filter repeats samples. A conceptual audio fragment looks like this:

[1:a]aloop=loop=-1:size=<appropriate-sample-count>[music]

Do not copy the placeholder as a finished command. The size value controls the number of samples in the loop, so it must correspond to the segment you intend to repeat. A whole-file repeat and a selected-sample loop are different operations. Consult the local filter help and inspect the source before choosing the value.

The FFmpeg command-line documentation covers input stream looping and complex filtergraphs in more detail: FFmpeg command-line documentation.

Choose the loop method according to the job:

Choice When it fits Trade-off
Repeat the complete video input with -stream_loop The same finished video should replay from its first frame Straightforward, but you should inspect timestamps and the join between repetitions
Loop decoded video frames with loop Only a frame segment should repeat, or looping must happen inside a filtergraph More control, but you must manage frame selection and output duration
Repeat the complete music input The entire track is the intended bed Easy to reason about, but the file's silence and edit points repeat
Use aloop A particular decoded audio segment should repeat Requires a meaningful sample size and may expose an audible seam

For an indefinite YouTube channel, “infinite” is not the same as “well behaved”. You still need a stable output duration, valid timestamps, and a clear policy for what happens when one input ends. For a finite test, use a shorter output duration so you can review the joins without waiting through a complete overnight run.

Mix or map audio with FFmpeg

If the source video has audio and you want to mix it with music, a starting pattern is:

ffmpeg -stream_loop -1 -re -i loop.mp4 \
  -stream_loop -1 -re -i music.mp3 \
  -filter_complex "[0:a][1:a]amix=inputs=2:duration=first:weights='1 0.25':normalize=1[aout]" \
  -map 0:v:0 -map "[aout]" \
  -c:v libx264 -preset veryfast -c:a aac -b:a 128k \
  -f flv "rtmp://SERVER/STREAM_KEY"

This illustrates the graph, not a guaranteed copy-and-paste solution. It assumes input zero has an audio stream, input one has usable music, the selected FFmpeg build includes the requested encoders, and the destination accepts the output format. Replace the destination with the server URL and stream key supplied by YouTube. Never publish a real stream key in a script, screenshot or log.

The graph sends the two audio streams into amix. inputs=2 declares how many audio inputs are being combined. weights='1 0.25' gives the second input a lower relative weight in this example. duration=first makes the mixed output follow the first input's duration behaviour. With an indefinitely repeated first input, that does not mean the music can safely be allowed to finish without considering what happens at its end. Repeat the music or choose duration behaviour that matches your programme.

normalize=1 leaves normalisation enabled. FFmpeg documents normalisation as part of amix; disabling it can lead to heavy clipping if levels are not controlled. Even with normalisation enabled, listen for speech becoming buried, music pumping, or peaks that sound distorted. Use a short local render or a private test destination to adjust levels rather than assuming the weights will sound right.

If the video has no audio and music should be the only output, do not reference [0:a] and do not use amix merely because the template contains it. A simpler graph can select and, if needed, process the music input:

[1:a]volume=<chosen-level>[aout]

Then map 0:v:0 and [aout]. If you want to preserve the source audio unchanged, map the source audio instead of creating a mix. The important rule is explicit mapping: select the video stream and the intended final audio stream yourself. Complex filtergraphs and manual mapping are described in FFmpeg's command-line documentation.

For a channel that must keep running while your own computer is switched off, a managed workflow can remove the repeated local process and reconnect work. StreamNeo is designed for the specific pain of uploading the finished video once, adding the YouTube stream key, and having the broadcast monitored and restarted automatically if it drops.

Choose the YouTube ingestion protocol

The destination in the illustrative command uses an RTMP-style FLV output because it is a familiar FFmpeg pattern. YouTube currently recommends RTMPS for secure RTMP ingestion. Select the server URL, protocol and stream settings in YouTube Studio, then make the FFmpeg output agree with them.

YouTube's current encoder guidance lists H.264, H.265 and AV1 for RTMP or RTMPS video, and AAC or MP3 for audio. It also recommends constant bitrate and a keyframe interval of two seconds, with a maximum of four seconds, and supports up to 60 frames per second under the documented conditions. These are platform recommendations, not a promise that every source or encoder preset will produce the same result.

For stereo RTMP or RTMPS audio, YouTube's advanced settings page lists 44.1 kHz and 128 Kbps as example settings. Match the actual audio configuration to the selected resolution, frame rate, codec and protocol. Do not treat one audio bitrate as universal for every YouTube ingestion path.

A practical output section may therefore include an H.264 video encoder, a supported audio encoder, a defined frame rate, a keyframe setting and constant-rate control. The exact video bitrate depends on the output format you choose and should come from YouTube's current encoder guidance, not from an old command copied from a forum.

If you already use a reusable key, keep the credential private and follow the channel setup steps in how to create a reusable YouTube stream key for a 24/7 channel in India. A key identifies where the broadcast goes; it does not correct a broken filtergraph or grant rights to music.

Test sync, levels, and representative playback

Do not infer success from FFmpeg starting without an error. A process can continue while the output has silence, the wrong audio stream, a drifting join, or levels that are painful after several minutes.

First, make a short test with the same video, music, filters, encoders and output settings you intend to use. If the final channel is devotional, include representative vocals and percussion. If it is a study or ambience channel, include the quiet sections as well as louder transitions. A test containing only a loud opening can hide a later problem.

Check the following in order:

  1. Confirm that the picture changes at the expected speed and repeats at the intended point.
  2. Confirm that the music is present and that the source audio is either absent or audible according to your decision.
  3. Listen at the beginning, at the audio loop join, and after the video restarts.
  4. Watch for delayed speech, doubled sound, clicks, clipped peaks and sudden level changes.
  5. Leave the test running long enough to expose a mismatch between the video duration and the music duration.
  6. Stop and start the process again to confirm that the command does not depend on a temporary state.

Audio and video may have different durations even when both files appear to be “the same length” in a media player. A short discrepancy can become obvious at a loop boundary. If speech is important, use headphones and speakers at a sensible level, because one device may conceal a low-frequency hum or clipping that another reveals.

Check the output with ffprobe as well as your ears. Verify that the generated or transmitted output contains one intended video stream and one intended audio stream, with the expected codec and channel arrangement. The goal is not to prove that the file is perfect; it is to catch a mapping mistake before YouTube viewers do.

A graphical fallback can be useful for comparison, especially when you are isolating whether the issue is the media graph or the network. The OBS settings guide for continuous YouTube playlist streaming in India covers a different workflow, but its testing principle is the same: validate the actual audio and video programme rather than relying on a successful start message.

Check YouTube stream health

Once the local test is clean, send a private or otherwise controlled test through YouTube Studio if your channel setup allows it. Use the same representative audio and video that you plan to broadcast. YouTube recommends testing before going live and monitoring stream health and messages during the event.

Watch for dropped frames, unstable bitrate, encoder warnings, audio silence and interruptions. A network that handles a short test may still be affected by congestion later, so leave a test running while you observe the connection rather than stopping at the first successful preview.

YouTube's stream health messages are useful evidence, but they do not replace listening. A stream can be technically connected while the wrong audio is mapped. Conversely, a brief warning may be caused by a temporary network condition rather than the FFmpeg graph. Record the time and message, then change one thing at a time.

The YouTube encoder settings and live-streaming guidance is the current primary reference for supported settings and recommendations. Recheck it before a long-running channel because platform guidance can change. If you are troubleshooting skipped items in a playlist-style broadcast, how to fix a YouTube Live stream that skips podcast episodes may help you separate input sequencing problems from network or output problems.

Before committing, compare the operating options on the pricing page. When the file and channel are ready, start free — 24-hour trial, no card.

FAQ

Can I use one FFmpeg command for every video and music file?

No. The command changes if the video has no audio, if you want to replace rather than mix its audio, or if the video and music use different looping methods. Inspect the streams first and treat the command as a template.

How do I add music when the video is silent?

Loop or otherwise supply the music input, map the video stream from the video file, and map the music as the output audio. Do not reference [0:a] or use amix unless the video actually has an audio stream that you intend to combine.

Why does the music stop before the video?

The music input may have ended, or the graph's duration setting may be allowing the first completed input to determine the mix. Repeat the complete music input with -stream_loop, use an appropriate aloop graph with a meaningful sample size, and test the join before broadcasting.

Does having permission to use a song guarantee an uninterrupted live stream?

No. YouTube says live streams are scanned for third-party content and notes that a licensed channel may still need to be added to the rights owner's allowlist. Confirm that your permission covers live streaming, archiving and the territories involved, then monitor the stream for platform messages.

YOU’VE REACHED THE END

Keep the ideas coming.

More guides, useful tools and a little help for your next broadcast.

Back to the journal ↗
YOUR NEXT READ

A little more to explore.

More Setup Guides guides ↗ · All topics ↗