Add Random Looping Background Music Using FFmpeg

So recently I decided to try adding some background music to my videos so it isn't just me blathering the whole time. Naturally, I turn to my weapon of choice in these cases, FFmpeg.

The music I use for this is from a project called StreamBeats, you should check it out.

Select Random Music

For the first part, I wanted to pick a random music file from a directory and use it later. For this, I wrote a simple script:

#!/usr/bin/env sh

dir=$1
find "$dir" | shuf -n 1 > tracklist.txt

head tracklist.txt
  1. I pass in the directory to use
  2. I list out of contents of that directory using find
  3. I pipe that output to shuf, which randomizes the list of files. With the -n 1 flag, it will output only the first line
  4. I write the output of all that to a text file for reference later, as well as using head to list that file to stdout

Add Music

Time for the FFmpeg magic:

#!/usr/bin/env sh

video=$1
bgm_dir=$2
output=$3
bgm="$(random_music "$bgm_dir")"

ffmpeg -i "$video" -filter_complex \
    "amovie=$bgm:loop=0,volume=0.03[bgm];
    [0:a][bgm]amix[audio]" \
    -map 0:v -map "[audio]" -shortest -c:v copy "$output"
  1. I have three arguments here
  • The video to add the music to
  • The directory you want to pick the random music from
  • The path to write the new file to
  1. We get the music file to load in using the random_music script and save it for later
  2. I'll talk about the important parts of this FFmpeg command
  • amovie=$bgm:loop=0,volume=0.03[bgm]; - this loads the randomly chosen music file to make its audio stream available and with the loop argument set to 0, loops it indefinitely. The volume filter is used to adjust the volume of the music to be more "background music" appropriate
  • [0:a][bgm]amix[audio] - combines the audio from the video and the newly loaded background music into one audio stream
  • -shortest tells FFmpeg to stop writing data to the file when the shortest stream ends, which, in this case, is our video stream. The audio stream technically never ends since it loops forever.

Tada, you should have a new version of your video with the randomly chosen music looping for the duration of the video.

22