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:
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
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 usinglibx264
.-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