FFMPEG for animation of image files outputs all-black video

2

1

I am trying to create an animation of a few images ("f_01.png", "f_02.png", ..., "f_08.png") that are each a different solid colour, but it always outputs a video entirely made up of black frames.

What, exactly, do I need to enter to get this to work? (again: images "f_01.png", "f_02.png", ..., "f_08.png")


More background:

I have read some questions on SuperUser about creating videos from images (and am trying to follow this: https://superuser.com/a/318412/219755 ...and this: https://superuser.com/a/53778/219755 ...and another answer I cannot track down again), I have read the FFMPEG help section on creating videos from image files (here: http://ffmpeg.org/faq.html#How-do-I-encode-single-pictures-into-movies_003f), and I have tried various sample command line strings from around the internet, but I cannot get FFMPEG to output anything but an all-black video.

In case it matters, I am playing the videos back with VLC.

The videos are the right length, at least most of the time (I am choosing 1 FPS and most videos output are the correct 8 seconds in length), but I don't see any of what I should be seeing.

Originally the first frame was black, and I thought FFMPEG ignoring other images might be the problem, but I have tried forcing all frames to be keyframes (with -g 1, with -keyint_min 1, and with both), and I have tried making a white image the first frame, but I still got black output videos.

Here are some strings I have tried entering:

ffmpeg -r 1 -i f_%02d.png output.mp4
ffmpeg -r 1 -f image2 -i f_%02d.png output.mp4
ffmpeg -r 1 -f image2 -i f_%02d.png -g 1 -keyint_min 1 output.mp4

In case it matters, the first two commands give me a video where playback time is only 6 seconds, but the third gives me an 8-second video.


As requested, the output from the 1st command is:

G:\FFMPEG>ffmpeg -r 1 -i f_%02d.png output.mp4
ffmpeg version N-55515-gbbbd959 Copyright (c) 2000-2013 the FFmpeg developers
  built on Aug 13 2013 18:01:31 with gcc 4.7.3 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-av
isynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enab
le-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetyp
e --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --ena
ble-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-l
ibopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libsp
eex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-
amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --
enable-libxvid --enable-zlib
  libavutil      52. 42.100 / 52. 42.100
  libavcodec     55. 27.100 / 55. 27.100
  libavformat    55. 13.102 / 55. 13.102
  libavdevice    55.  3.100 / 55.  3.100
  libavfilter     3. 82.100 /  3. 82.100
  libswscale      2.  4.100 /  2.  4.100
  libswresample   0. 17.103 /  0. 17.103
  libpostproc    52.  3.100 / 52.  3.100
Input #0, image2, from 'f_%02d.png':
  Duration: 00:00:00.36, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: png, rgb24, 320x240 [SAR 3779:3779 DAR 4:3], 25 fps, 25
tbr, 25 tbn, 25 tbc
File 'output.mp4' already exists. Overwrite ? [y/N] y
No pixel format specified, yuv444p for H.264 encoding chosen.
Use -pix_fmt yuv420p for compatibility with outdated media players.
[libx264 @ 003ff8e0] using SAR=1/1
[libx264 @ 003ff8e0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 003ff8e0] profile High 4:4:4 Predictive, level 1.2, 4:4:4 8-bit
[libx264 @ 003ff8e0] 264 - core 135 r2345 f0c1c53 - H.264/MPEG-4 AVC codec - Cop
yleft 2003-2013 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deb
lock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 m
e_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chro
ma_qp_offset=4 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 in
terlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b
_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=1 scenecut
=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0
qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'output.mp4':
  Metadata:
    encoder         : Lavf55.13.102
    Stream #0:0: Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv444p, 320x24
0 [SAR 1:1 DAR 4:3], q=-1--1, 16384 tbn, 1 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (png -> libx264)
Press [q] to stop, [?] for help
frame=    9 fps=0.0 q=-1.0 Lsize=       2kB time=00:00:07.00 bitrate=   2.3kbits
/s
video:1kB audio:0kB subtitle:0 global headers:0kB muxing overhead 82.314815%
[libx264 @ 003ff8e0] frame I:1     Avg QP: 2.00  size:    91
[libx264 @ 003ff8e0] frame P:5     Avg QP: 1.00  size:    42
[libx264 @ 003ff8e0] frame B:3     Avg QP: 2.00  size:    18
[libx264 @ 003ff8e0] consecutive B-frames: 33.3% 66.7%  0.0%  0.0%
[libx264 @ 003ff8e0] mb I  I16..4: 100.0%  0.0%  0.0%
[libx264 @ 003ff8e0] mb P  I16..4: 19.9%  0.1%  0.0%  P16..4:  0.0%  0.0%  0.0%
 0.0%  0.0%    skip:80.0%
[libx264 @ 003ff8e0] mb B  I16..4:  0.0%  0.0%  0.0%  B16..8:  0.3%  0.0%  0.0%
 direct: 0.0%  skip:99.7%  L0: 0.0% L1:100.0% BI: 0.0%
[libx264 @ 003ff8e0] 8x8 transform intra:0.2%
[libx264 @ 003ff8e0] coded y,u,v intra: 0.0% 0.0% 0.0% inter: 0.0% 0.0% 0.0%
[libx264 @ 003ff8e0] i16 v,h,dc,p: 93%  0%  7%  0%
[libx264 @ 003ff8e0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu:  0%  0% 100%  0%  0%  0%  0%
  0%  0%
[libx264 @ 003ff8e0] Weighted P-Frames: Y:80.0% UV:0.0%
[libx264 @ 003ff8e0] kb/s:0.31

G:\FFMPEG>

As requested, the original image files:

f_01.png and f_02.png (same image twice) f_01.png and f_02.png
f_03.png and f_04.png (same image twice) f_03.png and f_04.png
f_05.png and f_06.png (same image twice) f_05.png and f_06.png
f_07.png and f_08.png (same image twice) f_07.png and f_08.png

A.M.

Posted 2013-08-15T20:29:17.680

Reputation: 889

Your full, uncut ffmpeg command line output is missing. (The one from the first command you tried should suffice.) Does it work if you add -pix_fmt yuv420p before the output file name? – slhck – 2013-08-15T20:32:46.240

I have added the output. Thanks for the command tip, but it still produces an all-black video (6 seconds in length). – A.M. – 2013-08-15T20:44:18.553

Weird. That should usually fix it. Can you supply those images as a sample for us to test? (By the way, I'm curious – did you notice the message "Use -pix_fmt yuv420p for compatibility with outdated media players." when you ran your previous tests? Or was it not obvious to you what it meant?) – slhck – 2013-08-15T20:51:30.487

I originally just used a solid black image and a solid white image (both 320 x 240 px, created in MS Paint and saved .png files from MS Paint) and just wanted to see a video where the black turned white...but could never get it to happen. I then tried 2 frames of solid black, 2 dark grey, 2 light grey, and 2 white, in case the last frame was getting cut off or something. ...nothing special, just extremely simple images. – A.M. – 2013-08-15T20:59:19.130

I had not noticed that output message ("Use -pix_fmt yuv420p[...]"), but I am running the second-latest version of VLC. – A.M. – 2013-08-15T21:00:20.710

Answers

1

The videos generated with your files and the following commands both play fine for me in ffplay. The one with yuv420p chosen as the pixel format also plays fine in QuickTime.

ffmpeg -r 1 -i f_%02d.png out.mp4
ffmpeg -r 1 -i f_%02d.png -pix_fmt yuv420p out.mp4

Only VLC has troubles displaying the video (download). It'll show me a second of grey and then black, but not for a duration of 8 seconds.*

To produce stable video, you can try to increase the output frame rate, since it's the 1 fps that most players will choke on. The output file will be bigger than needed, of course.

ffmpeg -r 1 -i f_%02d.png -r 25 out.mp4
ffmpeg -r 1 -i f_%02d.png -pix_fmt yuv420p -r 25 out.mp4         <= for older players

Here we've told to read the images at 1 frame per second, but output them (duplicating frames) at 25.

* I consider this a bug with VLC. Since it's based on libavcodec and libavformat (from the FFmpeg project), and ffplay handles the file just fine, VLC should have no major issues with it. I would suggest you create a bug report in VLC – chances are the file isn't parsed correctly.

slhck

Posted 2013-08-15T20:29:17.680

Reputation: 182 472

Thanks for your help, but is there any way to get something that actually plays in VLC? By the way, I just discovered that while adding "-pix_fmt yuv420p" does nothing for VLC playback, it does make things better for Windows Media Player. It's still not quite right, though, in that it spends a long time on the first frame and then flits through the remainder too quickly at the end, partly during the last bit of the seek bar, and partly after the seek bar has reached the end. To me, that suggests a problem with the encoding (even if VLC is at fault too). – A.M. – 2013-08-15T21:26:10.873

Forgive the spin-off question about ffplay (which I had not tried until now, so thanks for the tip), but is there some reason it does not render white as white? It shows a light grey instead. – A.M. – 2013-08-15T21:33:36.087

I presume the playback problems are due to the small file size and low frame rate. I've seen playback problems with these kinds of videos all the time. The fact that ffplay works fine makes me think it's a parsing error with other players (and note that QuickTime works as well, for example). I'm not sure how to fix this other than choosing a higher frame rate and/or video length. For example, 3 fps produces a playable file in VLC for me. – slhck – 2013-08-15T21:41:09.727

I've noticed this as well, now that you mention it. ffplay shows the white frames as grey, while other players show them as white. Seems though that the "white" isn't read as white (histogram: http://i.imgur.com/tgrA7Y2.png)

– slhck – 2013-08-15T21:42:40.183

Success! Given your hint that low framerates are problematic, I looked around and found this: http://superuser.com/questions/601743/producing-stable-video-from-slow-images-with-ffmpeg The fix there (adding a separate, higher output framerate) worked for both of the problems I was seeing... It must be producing extra frames (or maybe not, if a keyframe can serve for a long time...?), which is a shame if it means extra storage space for the video, but it does solve this issue!

– A.M. – 2013-08-15T21:53:06.537

Adding "-r 3" right before the output filename in the command fixed the problem with WMP spending too much time on the first frame, but did not fix the problem with VLC playback. Adding "-r 10" right before the output filename in the command fixed the VLC playback problem (and was also good for WMP, as with "-r 3")! – A.M. – 2013-08-15T21:54:39.407

Great...accepting. :) I should ask this last question, though, since it is very related and could lead to an even tidier technique than the frame duplication work-around: Is there any chance a different choice of codec would mean less trouble with low framerates? I only ask because I just read somewhere that, for example, H.264 is only officially for something like 27 FPS and greater. Maybe there's another codec that would make VLC (etc.) play nice with 1 FPS (or even lower, which is what I am really after). – A.M. – 2013-08-15T22:16:29.900

There's no practical limit for frame rate in this codec. H.264 Level 1.1 specifies 7.5fps, for example, and that's the lowest fps you will find in all the levels. Internally frame rates are achieved by setting a certain time scale and the number of units for each tick, so this should work regardless of the framerate. Coding intra-frame only might give you better results, or using lossless encoders. But in essence this really just depends on the player. – slhck – 2013-08-16T05:48:29.683