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.
I wanted to pick a random music file from a directory for the first part 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
- I pass in the directory to use
- I list out of contents of that directory using
- I pipe that output to
shuf, which randomizes the list of files. With the
-n 1flag, it will output only the first line
- I write the output of all that to a text file for reference later, as well as using
headto list that file to stdout
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"
- 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
- We get the music file to load in using the random_music script and save it for later
- 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
volumefilter 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
-shortesttells 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.
Be sure to check out the rest of my FFmpeg related posts here