143

How do I generate a movie using ffmpeg using a single image (image1.png) for a duration of 15 seconds with a specific resolution so when I play the video, the image will appear on screen for 15 seconds.

mivk
  • 13,452
  • 5
  • 76
  • 69
Dharmesh
  • 1,976
  • 2
  • 14
  • 12

4 Answers4

197
ffmpeg -loop 1 -i image.png -c:v libx264 -t 15 -pix_fmt yuv420p -vf scale=320:240 out.mp4
  • The -t 15 makes it 15 seconds long.
  • The -vf scale=320:240 sets the width/height.

Make sure to use the latest ffmpeg version e.g. http://johnvansickle.com/ffmpeg/

pwkc
  • 479
  • 7
  • 19
Equanox
  • 2,220
  • 1
  • 12
  • 11
  • 1
    `Unable to find a suitable output format for 'scale=1280:1024' scale=1280:1024: Invalid argument` Any idea why? – Agey Jun 23 '15 at 12:45
  • 1
    @Equanox I've had the same issue, but it was caused by the "\" sign when copying and pasting. Removing it solves the issue. – user1319182 Jun 19 '16 at 08:39
  • When I try to run this, I get an error: Option loop not found - I'm using ffmpeg version 2.8.4 on windows – Igor Dvorkin Dec 23 '16 at 05:01
  • 1
    It works when I removed `-c:v libx264` -- it complains not finding the library. – Yan King Yin Jan 21 '17 at 14:15
  • 1
    while using jpeg image it takes a lot of time to execute in android. how can i solve this? – Arpan Dixit Mar 02 '17 at 06:32
  • 2
    @YanKingYin the libx264 is a non GPL library, which might be missing. If you want to install it, you can do so (on mac using mac ports) by: 'port install ffmpeg +nonfree' – andreas Oct 29 '17 at 12:04
  • 6
    It answers the question, but I don't like the use of all those redundant additions in the command. – joey Jun 04 '18 at 21:39
  • 33
    @joey Me neither, especially because OP did not ask for anything specific. You want to make a video from a single pic and don't care about any details at all? `ffmpeg -loop 1 -i image.png -t 5 out.mp4` – Doe Johnson Nov 28 '18 at 05:52
  • Perfect. Worked – WhiteHorse Apr 13 '20 at 14:04
  • 10
    This is great, but...it takes forever and melts my CPU to generate a 40 minute video based on a single 720p PNG image. Is there a way to speed it up? Compression doesn't matter as long as it stays under a couple GB. – HunterZ May 10 '20 at 00:35
  • 2
    Note that if you need to specify the framerate (e.g. you want to concat this with existing video and need them to match) you can add e.g. `-r 30` before output to specify 30 FPS – tobek Nov 04 '20 at 22:52
  • @DoeJohnson YEAH, much simpler command. I think FFmpeg is smart enough to figure out the basics – RealZombs Mar 04 '21 at 11:47
  • `-loop 1` is necessary, otherwise it won't work – Radical Edward Nov 16 '21 at 06:00
  • Be aware to blow your Video Size with just 1 single Image! look at my example below – dazzafact Aug 25 '22 at 11:08
18

Found this to be faster:

ffmpeg -framerate 1/10 -i DJI_0024.JPG -c:v libx264 -t 10 -pix_fmt yuv420p -vf scale=320:240 out.mp4

-t 10 making the video 10 seconds long, and setting -framerate 1/10. Divisor of framerate should be same number as the argument to -t. This made a jpeg with large resolution to be converted to a video in less then a second for me, while the other answer took about 40 sec. Also resulting filesize became slightly smaller. from 3.38MB to 3.17MB

brat
  • 586
  • 5
  • 17
13

For high quality and encoding speed (shown here with HEVC, select the codec and its codec specific settings for compatibility in your use case):

ffmpeg -framerate 30 -i input.jpg -t 15 \
    -c:v libx265 -x265-params lossless=1 \
    -pix_fmt yuv420p -vf "scale=3840:2160,loop=-1:1" \
    -movflags faststart \
    out.mp4
  • -framerate 30 rather than default 25 fps
  • -t 15 video duration 15 seconds
  • -c:v libx265 encode using h.265 (HEVC)
  • -x265-params lossless=1 lossless encoding, prevent artifacts for a still image. Unlike video, the image will be displayed for long enough to notice artifacts
  • -pix_fmt yuv420p set pixel format for compatibility since input is an image (JPEGs are often YUV444, which many decoders will not accept)
  • -vf "<options>" sets video filter
  • scale=3840:2160 specifically scale to 3840x2160 (4K)
    • You will want to use 3840:-1 or -1:2160 if your input is not exactly 16:9 (or whatever your target ratio is). This will prevent significant blurring due to an unintentional aspect ratio change. Look into pad or crop instead, if you must have an exact resolution that does not match the ratio of the input.
  • loop=-1:1 infinitely loop (-1) for groups of 1 frame (1)
  • movflags faststart will put metadata at front of file for faster playback in web browsers.

I am running this in a cloud/serverless environment, so minimizing runtime is key. I tried the low framerate approach, but it did not play in my target environment or locally on VLC.

The -vf loop option is what loops the one frame here. It keeps that frame in memory and is the main reason why this is faster than other answers, while being more compatible than a fractional framerate approach.

Jacob Greenbow
  • 161
  • 1
  • 5
2

Be aware to blow your Video Size with just 1 single Image! Do this: use ffmpeg with the Parameter -r 0.01 for almost no frame rate. This makes the file about 65% smaller But you maybe also need to cut the length with this Paramter -ss 00:00:00 -t 00:00:27

heres my code:

ffmpeg -r 0.01 -loop 1 -i image.jpg -i audio.mp3 -c:v libx264 -tune stillimage -preset  ultrafast -ss 00:00:00 -t 00:00:27   -c:a aac  -b:a 96k -pix_fmt yuv420p  -shortest out.mp4 -y
dazzafact
  • 2,570
  • 3
  • 30
  • 49