Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ffmpeg images-to-video script anyone? [duplicate]

I'm wanting to take a bunch of images and make a video slideshow out of them. There'll be an app for that, right? Yup, quite a few it seems. The problem is I want the slides synced to a piece of music, and all the apps I've seen only allow you to show each slide for a multiple of a whole second. I want them to show for multiples of 1.714285714 seconds to fit with 140 bpm.

The tools I've seen generally seem to have ffmpeg under the hood, so presumably this kind of thing could be done with a script. But ffmpeg has sooo many options...I'm hoping someone will have something close.

I'll have up to about 100 slides, the ones that have to show for 3.428571428 secs or whatever I guess I can simply show twice.

like image 617
danja Avatar asked Sep 19 '11 08:09

danja


3 Answers

For very recent versions of ffmpeg (roughly from the end of year 2013)

The following will create a video slideshow (using video codec libx264 or webm) from all the png images in the current directory. The command accepts image names numbered and ordered in series (img001.jpg, img002.jpg, img003.jpg) as well as random bunch of images.

(each image will have a duration of 5 seconds)

ffmpeg -r 1/5 -pattern_type glob -i '*.png' -c:v libx264 out.mp4   # x264 video
ffmpeg -r 1/5 -pattern_type glob -i '*.png'              out.webm  # WebM video

For older versions of ffmpeg

This will create a video slideshow (using video codec libx264 or webm) from series of png images, named img001.png, img002.png, img003.png, …

(each image will have a duration of 5 seconds)

ffmpeg -f image2 -r 1/5 -i img%03d.png -vcodec libx264 out.mp4     # x264 video
ffmpeg -f image2 -r 1/5 -i img%03d.png                 out.webm    # WebM video

You may have to slightly modify the following commands if you have a very recent version of ffmpeg

This will create a slideshow in which each image has a duration of 15 seconds:

ffmpeg -f image2 -r 1/15 -i img%03d.png out.webm

If you want to create a video out of just one image, this will do (output video duration is set to 30 seconds):

ffmpeg -loop 1 -f image2 -i img.png -t 30 out.webm

If you don't have images numbered and ordered in series (img001.jpg, img002.jpg, img003.jpg) but rather random bunch of images, you might try this:

cat *.jpg | ffmpeg -f image2pipe -r 1 -vcodec mjpeg -i - out.webm

or for png images:

cat *.png | ffmpeg -f image2pipe -r 1 -vcodec png -i - out.webm

That will read all the jpg/png images in the current directory and write them, one by one, using the pipe, to the ffmpeg's input, which will produce the video out of it.

Important: All images in a series need to be of the same size (x and y dimensions) and format.

Explanation: By telling FFmpeg to set the input file's FPS option (frames per second) to some very low value, we made FFmpeg duplicate frames at the output and thus we achieved to display each image for some time on screen. You have seen, that you can set any fraction as framerate. 140 beats per minute would be -r 140/60.

Source: The FFmpeg wiki


For creating images from a video use

ffmpeg -i video.mp4 img%03d.png

This will create images named img001.png, img002.png, img003.png, …

like image 120
erik Avatar answered Nov 09 '22 08:11

erik


You can extract images from a video, or create a video from many images:

For extracting images from a video:

ffmpeg -i foo.avi -r 1 -s WxH -f image2 foo-%03d.jpeg

This will extract one video frame per second from the video and will output them in files named 'foo-001.jpeg', 'foo-002.jpeg', etc. Images will be rescaled to fit the new WxH values. If you want to extract just a limited number of frames, you can use the above command in combination with the -vframes or -t option, or in combination with -ss to start extracting from a certain point in time. For creating a video from many images:

ffmpeg -f image2 -i foo-%03d.jpeg -r 12 -s WxH foo.avi

The syntax foo-%03d.jpeg specifies to use a decimal number composed of three digits padded with zeroes to express the sequence number. It is the same syntax supported by the C printf function, but only formats accepting a normal integer are suitable.

This is an excerpt from the documentation, for more info check on the documentation page of ffmpeg.

like image 24
svrx Avatar answered Nov 09 '22 07:11

svrx


I wound up using this:

mencoder "mf://html/*.png" -ovc x264 -mf  fps=1.16666667  -o output.avi

and changing the sample rate afterwards in LiVES.

a load more details (and the end result video) at: http://hyperdata.org/hackit/ (mirror)

like image 3
danja Avatar answered Nov 09 '22 06:11

danja