Insert background image using FFmpeg

I've just started using FFMpeg and I'm trying to create a video slideshow from images with a background image. The background would not change only the image.

Similar to this:

enter image description here

I have the following

"ffmpeg -framerate 1/5 \
-start_number 1 \
-i "C:/test/%03d.jpg" \
-c:v libx264 \
-r 30 "C:/test/video.mp4"

And that works perfectly to create slideshow with the pictures but when I try to add a background image for each picture using the following command (overlay).

"ffmpeg -framerate 1/5 \
-start_number 1 \
-i "C:/test/%03d.jpg" \
-vf 'movie=C:/test/bg.jpg [over], [in][over] overlay'
-c:v libx264 \
-r 30 "C:/test/video.mp4"

This is my error log:

    ffmpeg version N-69587-g15a8846 Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 4.9.2 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-

    bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-lzma --enable-decklink --enable-zlib
      libavutil      54. 18.100 / 54. 18.100
      libavcodec     56. 21.102 / 56. 21.102
      libavformat    56. 19.100 / 56. 19.100
      libavdevice    56.  4.100 / 56.  4.100
      libavfilter     5.  9.103 /  5.  9.103
      libswscale      3.  1.101 /  3.  1.101
      libswresample   1.  1.100 /  1.  1.100
      libpostproc    53.  3.100 / 53.  3.100
    Trailing options were found on the commandline.
    Input #0, image2, from 'C:/test/%03d.jpg':
      Duration: 00:00:15.00, start: 0.000000, bitrate: N/A
        Stream #0:0: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 768x1024 [SAR 1:1 DAR 3:4], 0.20 fps, 0.20 tbr, 0.20 tbn, 0.20 tbc
    At least one output file must be specified

Update from answer:

<cfscript>
    try {
        runtime = createObject("java", "java.lang.Runtime").getRuntime();
        command = '#ffmpegPath#' &
        ' -loop 1' &
        ' -framerate 1' &
        ' -i "C:/test/bg.jpg"' & 
        ' -framerate 1/5 -start_number 1' &
        ' -i "C:/test/%03d.jpg"' & 
        ' -filter_complex "overlay=(W-w)/2:(H-h)/2,format=yuv420p"' &
        ' -c:v libx264' &
        ' -r 30' &
        ' -movflags +faststart' &
        ' -shortest' &
        ' "C:/test/out.mp4"'; 
        process = runtime.exec(#command#);
        results.errorLogSuccess = processStream(process.getErrorStream(), errorLog);
        results.resultLogSuccess = processStream(process.getInputStream(), resultLog);
        results.exitCode = process.waitFor();
    }
    catch(exception e) {
        results.status = e;    
    }
</cfscript>

Solution 1:

Slideshow with static image background

pug life

You don't need to use the movie source filter, and use -filter_complex instead of -vf.

ffmpeg \
-loop 1 \
-framerate 1 \
-i bg.jpg \
-framerate 1/5 \
-i "C:/test/%03d.jpg" \
-filter_complex "overlay=(W-w)/2:(H-h)/2:shortest=1,format=yuv420p" \
-c:v libx264 \
-r 30 \
-movflags +faststart \
output.mp4
  • format=yuv420p will ensure a widely compatible "pixel format" or chroma subsampling scheme which is useful to add when using libx264.

  • -movflags +faststart will relocate some data after encoding is finished which will allow viewers to begin playback before the file is completely downloaded. Useful for example if you're hosting it yourself and putting it on a web site.

With audio

ffmpeg \
-loop 1 \
-framerate 1 \
-i bg.jpg \
-framerate 1/5 \
-i "C:/test/%03d.jpg" \
-i audio.mp3 \
-filter_complex "overlay=(W-w)/2:(H-h)/2:shortest=1,format=yuv420p" \
-c:v libx264 \
-r 30 \
-c:a aac -strict experimental \
-b:a 192k \
-movflags +faststart \
-shortest
output.mp4

With text

Text can be added with the drawtext filter.

ffmpeg \
-loop 1 \
-framerate 1 \
-i bg.jpg \
-framerate 1/5 \
-i "C:/test/%03d.jpg" \
-i audio.mp3 \
-filter_complex "overlay=(W-w)/2:(H-h)/2:shortest=1,drawtext=fontsize=30:fontfile=FreeSerif.ttf:text='hello world':x=(w-text_w)/2:y=10,format=yuv420p" \
-c:v libx264 \
-r 30 \
-c:a aac -strict experimental \
-b:a 192k \
-movflags +faststart \
-shortest \
output.mp4

See the drawtext filter documentation for many more options.

With a border

The drawbox filter can be used to draw a white border around the overlaid image. Notice that I started naming the inputs and outputs from each filter, then I referenced the final filter results with -map.

ffmpeg \
-loop 1 \
-framerate 1 \
-i bg.jpg \
-framerate 1/5 \
-i "C:/test/%03d.jpg" \
-i audio.mp3 \
-filter_complex "[1:v]drawbox=t=5:c=white[fg];[0:v][fg]overlay=(W-w)/2:(H-h)/2:shortest=1,drawtext=fontsize=30:fontfile=FreeSerif.ttf:text='hello world':x=(w-text_w)/2:y=10,format=yuv420p[v]" \
-map "[v]"
-map 0:a
-c:v libx264 \
-r 30 \
-c:a aac -strict experimental \
-b:a 192k \
-movflags +faststart \
-shortest \
output.mp4

Also see

  • FFmpeg Wiki: H.264 Video Encoding Guide
  • FFmpeg Wiki: AAC Audio Encoding Guide
  • FFmpeg Wiki: Create a video slideshow from images