I would like to use ffmpeg on Ubuntu with the following command:
ffmpeg -i input_video -vf scale=w=320:h=-1 -y -vcodec libx264 -preset ultrafast -r 60 output_video
For the -r option the documentation says:
-r[:stream_specifier] fps (input/output,per-stream)
Set frame rate (Hz value, fraction or abbreviation).
As an input option, ignore any timestamps stored in the file and
instead generate timestamps assuming constant frame rate fps. This is
not the same as the -framerate option used for some input formats like
image2 or v4l2 (it used to be the same in older versions of FFmpeg).
If in doubt use -framerate instead of the input option -r.
As an output option, duplicate or drop input frames to achieve
constant output frame rate fps.
I would like to use the output option. How can I do this? What is the per-stream option doing (it is not written above)?
Second, is it correct that the -vf scale=w=320:h=-1 option scaled the video to width 320 and keeping the aspect ratio?
I would like to use the -r output option. How can I do this?
Your command is using it as an output option. The location of options is important as it determines what is applied to the input or the output:
ffmpeg [input options] -i input [output options] output
What is the per-stream option doing (it is not written above)?
"per-stream" means that this option can be declared several times to apply to different streams using stream specifiers. Since you have only one video stream in your output you can ignore this.
Second, is it correct that the -vf scale=w=320:h=-1 option scaled the video to width 320 and keeping the aspect ratio?
Yes, but when encoding with libx264 consider using -2 instead of -1. It does the same thing but makes sure the result is divisible by 2 which is required for this encoder (there are exceptions).
Related
If I want to change the video speed with ffmpeg,
what exactly is the difference changing the fps:
ffmpeg -y -r 10 -i video.mp4 video_new_fps.mp4
or using filter and setpts:
ffmpeg -i video.mp4 -filter:v "setpts=PTS*3" -an video_new_fps.mp4
It seems that with both options I can speed up or slow down the video.
So which one should be used in which case?
IMO, the latter is a universal safer approach. If the input video stream uses a constant framerate, then both should result in the identical output. If the input framerate is variable, -r input option will mess up the timing, I presume.
I have a folder containing 1701 image frames named "frame0000.jpg", "frame0001.jpg",..., "frame1700.jpg". When I try to convert them to a video using this command:
ffmpeg -r:1751/61 -b:2400k -i frame%3d.jpg video1.avi
It produces a video with a bitrate of 717kbs and 25 frames/second (so the FPS is also different than what I specified!); hence, it has a poor quality.
I read a lot about this issue such as:
FFMPEG ignores bitrate
But couldn't find the solution to my case.
Any help is appreciated.
Fixed command:
ffmpeg -framerate 1751/61 -i frame%3d.jpg -b:v 2400k video1.avi
Option placement is important
Syntax is:
ffmpeg [input options] -i input [output options] output
Use valid options
-r:1751/61 is incorrect. Use -framerate 1751/61. The image demuxer prefers -framerate, not -r.
-b:2400k is incorrect. Use -b:v 2400k
Refer to the log
It should have provided errors to help you determine the problem:
Invalid stream specifier: 1751/61
Option b (video bitrate (please use -b:v)) cannot be applied to input -- you are trying to apply an input option to an output file or vice versa. Move this option before the file it belongs to.
I want to create a gif image from a jpeg image list, everything works fine, but how can I slow the animation?
Here is my code:
<?php
exec('ffmpeg -f image2 -i thumb/%001d.jpg -vf scale=480x240 out.gif');
?>
To slow down an image sequence, lower its framerate
ffmpeg -f image2 -framerate 10 -i thumb/%001d.jpg -vf scale=480x240 out.gif
You want the -r flag to set the frame rate (in frames per second). From the official documentation:
-r[:stream_specifier] fps (input/output,per-stream)
Set frame rate (Hz value, fraction or abbreviation).
As an input option, ignore any timestamps stored in the file and instead generate timestamps assuming constant frame rate fps. This is not the same as the -framerate option used for some input formats like image2 or v4l2 (it used to be the same in older versions of FFmpeg). If in doubt use -framerate instead of the input option -r.
As an output option, duplicate or drop input frames to achieve constant output frame rate fps.
For example, setting to 30 fps:
ffmpeg -f image2 -i thumb/%001d.jpg -vf scale=480x240 -r 30 out.gif
Note: The -r argument must appear after the input file if you want it to apply to the output
I'm using ffmpeg to watermark videos with a PNG file using vfilters like so:
ffmpeg -i 26.wmv -vcodec libx264 -acodec copy -vf "movie=logo.png [watermark]; [in][watermark] overlay=10:10 [out]" 26_w.mkv
However, the input files are all of different quality/bitrates, and I want the output files to be of similar quality/bitrate to the input files. How would I achieve this?
Also, I know almost nothing about ffmpeg, so are there any options which would be sensible to set to give a good quality:filesize ratio?
Usually wanting the output to be the "same quality" as the input is an assumed thing that people will always want. Unfortunately, this is not possible when using a lossy encoder, and even lossless encoders may not provide the same quality due to colorspace conversion, chroma subsampling, and other issues. However, you can achieve visually lossless (or nearly so) outputs when using a lossy encoder; meaning that it may look as if the output is the same quality to your eyes, but technically it is not. Also, attempting to use the same bitrate and other parameters as the input will most likely not achieve what you want.
Example:
ffmpeg -i input -codec:v libx264 -preset medium -crf 24 -codec:a copy output.mkv
The two option for you to adjust are -crf and -preset. CRF (constant rate factor) is your quality level. A lower value is a higher quality. The preset is a collection of options that will give a particular encoding speed vs compression tradeoff. A slower preset will encode slower, but will achieve higher compression (compression is quality per filesize). The basic usage is:
Use the highest crf value that still gives you the quality you want.
Use the slowest preset you have patience for (see x264 --help for a preset list and ignore the placebo preset as it is a joke).
Use these settings for the rest of your videos.
Other notes:
You do not have to encode the whole video to test quality. You can use the -ss and -t options to select a random section to encode, such as -ss 30 -t 60 which will skip the first 30 seconds and create a 60 second output.
In this example the audio is stream copied instead of re-encoded.
Remember that every encoder is different, and what works for x264 will not apply to other encoders.
Add -pix_fmt yuv420p if the output does not play in dumb players like QuickTime.
Also see:
FFmpeg and x264 Encoding Guide
FFmpeg and AAC Encoding Guide
Here is a set of very good examples http://ffmpeg.org/ffmpeg.html#Examples
Here is a script i made for converting files to flv video and also adding a preview image
<?php
$filename = "./upload/".$_GET['name'].".".substr(strrchr($_FILES['Filedata']['name'], '.'), 1);
move_uploaded_file($_FILES['Filedata']['tmp_name'], $filename);
chmod($filename, 0777);
exec ("ffmpeg -i ".$filename." -ar 22050 -b 200 -r 12 -f flv -s 500x374 upload/".$_GET['name'].".flv");
exec ("ffmpeg -i ".$filename." -an -ss 00:00:03 -an -r 1 -s 300x200 -vframes 1 -y -pix_fmt rgb24 upload/".$_GET['name']."%d.jpg");
?>
I'm using ffmpeg to watermark videos with a PNG file using vfilters like so:
ffmpeg -i 26.wmv -vcodec libx264 -acodec copy -vf "movie=logo.png [watermark]; [in][watermark] overlay=10:10 [out]" 26_w.mkv
However, the input files are all of different quality/bitrates, and I want the output files to be of similar quality/bitrate to the input files. How would I achieve this?
Also, I know almost nothing about ffmpeg, so are there any options which would be sensible to set to give a good quality:filesize ratio?
Usually wanting the output to be the "same quality" as the input is an assumed thing that people will always want. Unfortunately, this is not possible when using a lossy encoder, and even lossless encoders may not provide the same quality due to colorspace conversion, chroma subsampling, and other issues. However, you can achieve visually lossless (or nearly so) outputs when using a lossy encoder; meaning that it may look as if the output is the same quality to your eyes, but technically it is not. Also, attempting to use the same bitrate and other parameters as the input will most likely not achieve what you want.
Example:
ffmpeg -i input -codec:v libx264 -preset medium -crf 24 -codec:a copy output.mkv
The two option for you to adjust are -crf and -preset. CRF (constant rate factor) is your quality level. A lower value is a higher quality. The preset is a collection of options that will give a particular encoding speed vs compression tradeoff. A slower preset will encode slower, but will achieve higher compression (compression is quality per filesize). The basic usage is:
Use the highest crf value that still gives you the quality you want.
Use the slowest preset you have patience for (see x264 --help for a preset list and ignore the placebo preset as it is a joke).
Use these settings for the rest of your videos.
Other notes:
You do not have to encode the whole video to test quality. You can use the -ss and -t options to select a random section to encode, such as -ss 30 -t 60 which will skip the first 30 seconds and create a 60 second output.
In this example the audio is stream copied instead of re-encoded.
Remember that every encoder is different, and what works for x264 will not apply to other encoders.
Add -pix_fmt yuv420p if the output does not play in dumb players like QuickTime.
Also see:
FFmpeg and x264 Encoding Guide
FFmpeg and AAC Encoding Guide
Here is a set of very good examples http://ffmpeg.org/ffmpeg.html#Examples
Here is a script i made for converting files to flv video and also adding a preview image
<?php
$filename = "./upload/".$_GET['name'].".".substr(strrchr($_FILES['Filedata']['name'], '.'), 1);
move_uploaded_file($_FILES['Filedata']['tmp_name'], $filename);
chmod($filename, 0777);
exec ("ffmpeg -i ".$filename." -ar 22050 -b 200 -r 12 -f flv -s 500x374 upload/".$_GET['name'].".flv");
exec ("ffmpeg -i ".$filename." -an -ss 00:00:03 -an -r 1 -s 300x200 -vframes 1 -y -pix_fmt rgb24 upload/".$_GET['name']."%d.jpg");
?>