I would like ffmpeg to do the following:
read an input mp4 (-i movie.mp4)
skip the first 5 seconds (-ss 5)
find scene changes and display the frame numbers (-vf "select=gt(scene\, 0.4, showinfo))
output #1 - a gif file (output.gif)
output #2 - a contact sheet with all the thumbnails (-vf "select scale=320:-1, tile=12x200" thumbnails.png)
This will generate the thumbnails:
ffmpeg -hide_banner -i d:/Test/movie01.mp4 -ss 5 -vf "select=gt(scene\,0.4), showinfo, scale=320:-1, tile=12x200" -vsync 0 thumbnails%03d.png
this will generate the gif:
ffmpeg -hide_banner -i d:/Test/movie01.mp4 -ss 5 -vf "select='not(mod(n,60))',setpts='N/(30*TB)', scale=320:-1" -vsync 0 output.gif
I would like to do both at once with 2 more features:
set fps and resolution for the gif; I would like the gif to represent the whole movie in X seconds, at Y fps (I know the duration of the input movie so I can calculate how often a frame needs to be captured)
set the width only for the thumbnail picture (tile=12 for example) and let ffmpeg determine the appropriate height
I have tried to compose a command line from what I read on this page: https://trac.ffmpeg.org/wiki/Creating%20multiple%20outputs, using the split / map commands but I couldn't get it to work
Use
ffmpeg -ss 5 -i input.mp4
-vf "select='not(mod(n,60))',setpts=N/Y/TB',scale=320:-1" -r Y output.gif
-vf "select='gt(scene\,0.4)',showinfo,scale=320:-1,tile=12x200" -vsync 0 thumbnails%03d.png
tile requires both W and H to be set.
Related
I'm trying to create a timeline of images for a video using FFMPEG.wasm. The times I want to pass in is 1/10 its total duration.
I tried:
const duration = video.current.duration;
const fps = duration / 10;
//this is the command I used on the CLI for a 1 hour video.
ffmpeg -skip_frame nokey -i temp.mp4 -vf "scale=180:-1,fps=1/600" out%d.png
but the output is really slow when it comes to long videos due to FFMPEG having to go through the entire video.
Is there a command that's like:
ffmpeg -ss "600, 1200, 1800 ... 6000" -i temp.mp4 -vf scale=180:-1 -frames:v 1 out%d.png
where it only outputs an image only at those specific times without having to loop the FFMPEG command 10 times?
I am trying to extract desired frames from video when someone in video start to speak and extract 5 frames per second when speaking. I get the framelist I want like 0, 6,12,18 and 200,206, 212....
I try to create scripts to do it automatically using below command per frame,but it's pretty slow, is there quick to get the desired frames from list with frame num as image name?
ffmpeg -i 1.mp4 -vf select='eq(n,0)' -vsync 0 -an -y -q:v 16 0.png
ffmpeg -i 1.mp4 -vf select='eq(n,6)' -vsync 0 -an -y -q:v 16 6.png
....
I use the following command for extracting the representative frame out of every 10 frames from the video.
ffmpeg -i input.avi -r 10 -vf thumbnail=10 -vsync 0 ./Output/%06d.png
If i get the 4th frame selected from 10-20th frames, i want to know the 2nd frame selected was 24th in the original one.
Right now the output is continuous 1,2,3.. n.png
Use
ffmpeg -i input.avi -vf thumbnail=10 -vsync 0 -frame_pts 1 ./Output/%06d.png
You'll need ffmpeg 4.0 or later.
I want to generate an image from a video, but first i want to scale it to a certain width/height then crop it to a set square size, the problem is that my new version ffmpeg doesnt seem to work with scaling first.
ffmpeg version 2.8.6-1ubuntu2
fails:
ffmpeg -y -i input.mp4 -an -ss 5 -s 150x150 -vf scale=-1:150,crop=150:150 -vframes 1 output-small.jpg
Invalid too big or non positive size for width '150' or height '150'
works:
ffmpeg -y -i input.mp4 -an -ss 5 -s 150x150 -vf crop=150:150,scale=-1:150 -vframes 1 output-small.jpg
However i cannot settle for the second command because i am generating images that could be larger then the original size (i'm creating a few different sizes for each image), therefore scale MUST come first. Anybody have any idea what changed or what i am doing wrong here?
This may be happening because your video is portrait, and so the scaled image has width smaller than 150px. Hence the crop fails.
Also, you should skip the -s option, otherwise you're triggering two scaler executions.
Try
ffmpeg -y -i input.mp4 -ss 5 -vf scale='if(gt(iw,ih),-1,150)':'if(gt(iw,ih),150,-1)',crop=150:150 -vframes 1 output-small.jpg
I have an mp4 that I want to overlay on top of a jpeg. The command I'm using is:
Ffmpeg -y -i background.jpg -i video.mp4 -filter_complex "overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2" -codec:a copy output.mp4
But for some reason, the output is 0 second long but the thumbnail does show the first frame of the video centred on the image properly.
I have tried using -t 4 to set the output's length to 4 seconds but that does not work.
I am doing this on windows.
You need to loop the image. Since it loops indefinitely you then must use the shortest option in overlay so it ends when video.mp4 ends.
ffmpeg -loop 1 -i background.jpg -i video.mp4 -filter_complex \
"overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2:shortest=1" \
-codec:a copy -movflags +faststart output.mp4
See overlay documentation for more info.
Well you should loop the image until the video duration. So to do the you need to add -loop 1 before the input image. Then the image will have a infinite duration. So to control it specify -shortest before the output file which will trim all the streams to the shortest duration among them. Else you can use -t to trim the image duration to the video length. This will do what you want.
Hope this helps!