the output movie is too fast how to control it - image

i have 60 images 000001.jpeg to 000060.jpeg now this is my command:
"-f image2 -i E:\\REC\\Temp\\%06d.jpeg -r 12 E:\\REC\\Video\\" + label1.Text + ".wmv"
The output is about 3 second but i expect to get only one minute, so how to set duration for each frame to be one image = one second so 60 image = one minute?

Default frame rate for inputs is 25, so in your example ffmpeg is dropping frames to go from 25 to 12 fps (the console output will confirm this).
You can declare just an input frame rate and the output will inherit this same frame rate:
ffmpeg -framerate 1 -i %06d.jpeg output.wmv
Or both an input and an output frame rate:
ffmpeg -framerate 1 -i %06d.jpeg -r 25 output.wmv
This second example is recommended if Windows Media Player has issues with 1 fps content. You will have to experiment to see which example works best for you.
See the image2 demuxer documentation for more information.

Related

FFmpeg: create a video from a list of images, where each images stay N frames

I need to create a video from a list of images, in such a way that the final video should be 24fps, but each image should stay during 3 frames before showing the next image (and I don't want to change the fps, I really need 3 identical frames).
For now I'm using:
ffmpeg -framerate 24 -pattern_type glob -i "build/*.jpg" "$#"
but each image stays only one frame.
You need to combine the input and output frame rates to achieve this:
ffmpeg -framerate 8 -pattern_type glob -i "build/*.jpg" -r 24 "$#"
The input -framerate 8 sets to show each image for 1/8=0.125 seconds, and output -r 24 sets the output framerate to be 24 fps and use each input frame for 24/8=3 output frames.

How to extract the very first frame of a second in a video using ffmpeg?

I am trying to extract the first frame of a second from a video. I have tried different ways to achieve this, but I failed. Here the commands I tried.
ffmpeg -i input.ts -s 400x222 -q:v 3 -start_number 0 -vf fps=1 %d.jpg
Later, I am trying to extract the frames again using the below command of that particular second. Here I'm extracting the frames of 210th second.
ffmpeg -ss 210 -i input.ts -s 300x250 -t 1 -start_number 0 images.%d.jpg
I want to extract only the starting frame of the second. Let's say from 0.001 of that particular second.
When I compare the frame of 210 second extracted by my first command with the first frame extracted by second command are completely different.
For the later use, to prevent the conflicts I want to extract only the very first frame of the original input video. I tried using the command which was told by stackoverflow experts in the past here. But when I run it. It is only extracting the starting frame(only 1 frame).
How can I extract the very starting frame of the video per every second?
try this command :
ffmpeg -i input.mp4 -vf "select=between(mod(n\, 25)\, 0\, 0), setpts=N/24/TB" output-%04d.png
you have to pass your video framerate or fps in between(mod(n\, 25)\, 0\, 0) my video fps is 25 so i pass 25
if your fps 60 then you have to pass 60 in between(mod(n\, 60)\, 0\, 0)
also if you want 1st 5 frames of every second then use between(mod(n\, 25)\, 0\, 4) it will give your 1st 5 frames of every second.

ffmpeg output images filename with time position

I am using ffmpeg to get some jpg from my video at a specific rate (one screenshot every 5 seconds) with this command :
ffmpeg -i source -f image2 -r 1/5 %d.jpg
This works and give me sequential filenames :
1.jpg
2.jpg
3.jpg
4.jpg
What if I need to know at which time those screenshots have been taken ? Something like a timestamp :
00:00:00.0000.jpg
00:00:05.0000.jpg
00:00:10.0000.jpg
00:00:15.0000.jpg
or the number of seconds :
0.jpg
5.jpg
10.jpg
15.jpg
I tried again with the new -frame_pts option :
ffmpeg -i source -f image2 -r 1/5 -frame_pts 1 %d.jpg
I got similar sequential filenames, but now they are starting from zero :
0.jpg
1.jpg
2.jpg
3.jpg
Use
ffmpeg -i source -vf fps=1,select='not(mod(t,5))' -vsync 0 -frame_pts 1 z%d.jpg
frame_pts will assign a serial number to the image name, where the number represents the frame position as per the output timebase. So the calculated time position is frame # x timebase. The timebase is the reciprocal of the output framerate e.g. for a 12 fps stream, timebase is 1/12. So output file image212 represents a time of 212 x 1/12 = 17.67s
To represent seconds, you need to generate a 1 fps stream and then pick every 5th frame, to get a frame from every 5th second. The vsync 0 is added to prevent ffmpeg from duplicating frames to generate a constant frame rate stream.
This may not be the best solution but it does the job
for (i = 0; i < $duration; $i += 0.5) { //where $duration is video duration
`ffmpeg -y -i video.mp4 -ss $i -vframes 1 $i.jpg`
}
Of course this would be very slow since it spawns ffmpeg for every frame but as I said may help you to get the job done.

FFMPEG, Extract first frame and hold for 5 seconds

I'm trying to overlay a 15 second video transition on the beginning of an image sequence (png sequence with an alpha to reveal the image below), which I can do fine with the overlay filter. But I want to hold the first frame of the image sequence for 5 seconds before playing the animation. I've tried trim/select but I can't seem to get it be a duration of 5 seconds, I also can't seem to concat it back with the other video to do the transition. So my questions are:
How do I get the first frame and hold it for 5 seconds, the method below works but doesn't seem like the cleanest option?
-framerate 30 -t 60.0 -i input1.%04d.jpg -framerate 30 -t 15.0 -i transition1_%03d.png -filter_complex "color=c=red:d=5:s=480x270:r=30[bg]; [bg][1:v]overlay[transhold]; [0:v][transhold]overlay=repeatlast=0[out]"
How can I concat that with the original before I overlay it on the main video, I can do it with two overlays with the start of the actual transition offset by the length of the hold using the command below, but it seems a bit clunky.
-framerate 30 -t 60.0 -i input1.%04d.jpg -framerate 30 -t 15.0 -i transition1_%03d.png -filter_complex "color=c=red:d=5:s=480x270:r=30[bg]; [1:v]split[trans][transhold]; [trans]setpts=PTS+5/TB[trans];[transhold]select=eq(n\0)[transhold];[bg][transhold]overlay[transhold]; [0:v][transhold]overlay=repeatlast=0[tmp1]; [tmp1][trans]overlay[out]"
This is all part of a larger command where I'm compiling four HD images into a 4k feed each with it's own transition so the cleaner I can be the better really. I'd also like to be able to vary the duration of the hold for the different HD inputs. If I need to I could bring in the first image as a different input but I would still need to concat them. I thought there must be a way to do this with filters...
This was answered in another post:
https://video.stackexchange.com/questions/23551/ffmpeg-extract-first-frame-and-hold-for-5-seconds
-framerate 30 -t 60.0 -i input1.%04d.jpg
-framerate 30 -t 15.0 -i transition1_%03d.png
-filter_complex
"[1]loop=149:1:0[trans];
[0][trans]overlay=eof_action=pass" out.mp4
The first frames of the second input is repeated 149 times, so that there are 150 instances (30 fps x 5s). The 0 at the end of loop is the starting index of the frame(s) to loop. The middle 1 is the number of frames to loop starting at the index in the 3rd argument.

Create a slideshow with 5 images using ffmpeg with an output rate of 3 fps

I tried everything, so this is my last chance.
I need to make a slideshow using ffmpeg of the following files:
image-1.jpg
image-2.jpg
image-3.jpg
image-4.jpg
image-5.jpg
The input rate will be 1 fps (these are images so it's normal), but I would like the output rate to be 3 fps. Each image must last 1 minute for example.
My aim is to have the smallest output file size for this slideshow. I can use any codec I want.
I tried this:
ffmpeg -f image2 -r 1/30 -i image-%d.jpeg video.mpg
But ffmpeg says:
MPEG1/2 does not support 5/1 fps

Resources