I'm trying to create video from image but it's fit to video size (hd). How to keep aspect ratio of my image BUT get 1280 x 720 video?
Here is current result (image is 3264 x 2448 px, video 1280 x 720 px):
Here is my current command:
ffmpeg -loop 1 -i IMAGE_PATH -t 3 -s hd720 -c:v mpeg4 -pix_fmt yuv420p -preset ultrafast RESULT_PATH
Should I divide my task to two operations (generate image with black stripes then generate video)? Could you help to modify command to get desired result?
It is better to use aspect though you specify the s in the command.
-aspect 3264/2448
And also try pad to get the black bars around the output video without stretching the video to fit the screen size. This question is about that.
Hope this will help you!
Related
I have a generic process whose purpose is to take a video at any aspect ratio and generate a PNG from one of its frames. This frame should:
Be as large as possible, but no larger than 720x405 (16:9)
Maintain the aspect ratio of the video
Have no letterboxing
ffmpeg -y -nostats -ss 10 -i ./video.mp4 -max_muxing_queue_size 6400 -an -frames:v 1 -r 24/1 -vf "scale=w=720:h=405:force_original_aspect_ratio=decrease" -f image2 ./frame.png
When I give this command a video with a sample_aspect_ratio (SAR) of 4:3 and a display_aspect_ratio (DAR) of 16:9, I end up with a 540x405 (4:3) PNG where the image is horizontally compressed. Presumably force_original_aspect_ratio is looking at sample_aspect_ratio rather than display_aspect_ratio.
How do I ensure that the generated image maintains the same aspect ratio as the video (as displayed to the user)?
Insert a scale filter to convert frames to square pixels.
-vf "scale=iw*sar:ih,setsar=1,scale=w=720:h=405:force_original_aspect_ratio=decrease"
I've been trying to get this to work on and off for the past month and am very frustrated, so I'm hoping someone on here could help me. What I'm trying to do is very simple but I struggle with ffmpeg. I basically just want to take a folder of pictures, each of which have different sizes and some may be horizontal or vertical orientation, and put them into a video slideshow where they show for maybe 5-10 seconds each. No matter what I try, it always winds up stretching out the pictures to be out of the ratio and they just look funny. I noticed Windows 10 Photo program does this perfectly, but I want a programmatic approach and I don't think it has a commandline feature. Can someone help me tweak this ffmpeg commandline to work the way I need it to? Desired video output would be 1920x1080 in this case. Thanks!
ffmpeg -r 1/5 -start_number 0 -i "C:\Source_Directory_Pictures\Image_%d.jpg" -c:v libx264 -vf "pad=ceil(iw/2)*2:ceil(ih/2)*2" "F:\Destination_Output\Test_Output.mp4"
Use a combination of scale and pad to generate proportionally resized images centered onto a 1080p frame.
Use
ffmpeg -framerate 1/5 -start_number 0 -reinit_filter 0 -i "C:\Source_Directory_Pictures\Image_%d.jpg" -vf "scale=1920:1080:force_original_aspect_ratio=decrease:eval=frame,pad=1920:1080:-1:-1:eval=frame" -r 25 -c:v libx264 "F:\Destination_Output\Test_Output.mp4"
for example, this command line:
ffmpeg -i rtsp://184.72.239.149/vod/mp4:BigBuckBunny_175k.mov -vf "scale=w=416:h=234:force_original_aspect_ratio=decrease" -an -f rawvideo -pix_fmt yuv420p -r 15 -
works fine except if the source video was 360x240, output will be 351x234. which kinda sucks as yuv420p video with odd sizes is difficult to handle due to the way colour data is stored.
is there a way i could force ffmpeg to give nearest possible even values?
If you're resizing use just one of the dimensions with an absolute value, example:
Change:
-vf "scale=w=416:h=234:force_original_aspect_ratio=decrease"
To:
-vf "scale=w=416:h=-2"
Should scale to a width of 416 and scale the height appropriately so the aspect ratio keeps the same.
-2 = scale using mod 2
-4 = scale using mod 4 etc....
you can achieve that by using force_divisible_by=2 in your filter like this :
-vf scale=w=852:h=480:force_original_aspect_ratio=decrease:force_divisible_by=2
i know the question is old but hope this help someone.
To get a 200x100 thumbnail from a video, I do ffmpeg -ss 100 -i /tmp/video.mp4 -frames:v 1 -s 200x100 image.jpg. But if the source video isn't in the same aspect ratio as 200x100, the thumbnail gets distorted (either stretched or squished, horizontally or vertically) and it looks bad.
Is there a way that ffmpeg can figure out for example that a 500x200 video is 100px too wide, and remove 50px from the right and 50px from the left, making the video 400x200? And because 400x200 is the same aspect ratio as 200x100, the thumbnail would have no distortion.
I know there are other tools that can do this to the thumbnails generated by ffmpeg, but I'd prefer doing it within ffmpeg and not having to process the thumbnails again.
You can use the force_original_aspect_ratio option in the scale filter.
ffmpeg -ss 100 -i /tmp/video.mp4 -frames:v 1 -q:v 2 -vf "scale=200:100:force_original_aspect_ratio=increase,crop=200:100" image.jpg
If your thumbnail size is 200x100 fixed, then run
ffmpeg -ss 100 -i /tmp/video.mp4 -vf "scale='if(gt(dar,200/100),100*dar,200)':'if(gt(dar,200/100),100,200/dar)',setsar=1,crop=200:100" -frames:v 1 image.jpg
The scale filter checks the aspect ratio of the source and scale so that one dimension fits the 200x100 canvas and the other overshoots, unless it's a perfect match. Then the crop filter crops it to 200x100 from the center thus taking care of the out of bounds region.
I already have found out how to scale the thumbnail to stay within specified bounding dimensions while maintaining aspect ratio. For example, to get the frame shown at 6 seconds into the input.mp4 video file, and scale it to fit into 96x60 (16:10 aspect ratio):
ffmpeg -y -i input.mp4 -ss 6 -vframes 1 -vf scale="'if(gt(a,16/10),96,-1)':'if(gt(a,16/10),-1,60)'" output.png
This is fine, it works.
Next, I would like to do the same, but if the video's aspect ratio is not exactly 16:10, then I would like to force the output image to have an aspect ratio of 16:10 by taking the above transformation, and filling or padding the space with white. That is, I want the output to be as if I took, say, a 96x48 image, and laid it over a 96x60 white background, resulting in white bars above and below the 96x48 image.
Ideally, I do not want to resort to using another tool or library, such as ImageMagick. It would be best if ffmpeg could do this on its own.
Here's what I went with. For the -vf argument:
-vf "scale='if(gt(a,16/10),96,-1)':'if(gt(a,16/10),-1,60)', pad=w=96:h=60:x=(ow-iw)/2:y=(oh-ih)/2:color=white"
This applies two filters in sequence, separated by a comma.
target_H = 2436
target_W = 1124
ffmpeg -i 1.mp4 -ss 1 -vframes 1 -vf "scale=min(iw*2436/ih\,1124):min(2436\,ih*1124/iw),pad=1124:2436:(1124-iw)/2:(2436-ih)/2:green" output.png