FFMPEG sensible defaults - ffmpeg

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");
?>

Related

ffmpeg: recommended bitrate vs resolution [duplicate]

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");
?>

FFmpeg ignores quantity parameter

this is how I use FFmpeg
ffmpeg -f dshow -i video="UScreenCapture" -vcodec libx264 -q 26 -f flv output.flv
the thing is, the quantity is always 28, ffmpeg ignores that. How to fix this? I need a "flash" codec anyway, to stream to twitch tv
The options -q (and the alias -qscale) are ignored by libx264. If you want to
control the quality,
use:
-crf
ffmpeg -i input -c:v libx264 -crf 22 output.flv
Or set the bitrate with -b:v
ffmpeg -i input -c:v libx264 -b:v 555k output.flv
According to the documentation, "the meaning of q is codec-dependent" and apparently libx264 ignores that option. Use -crf (and a -preset if you want) instead. The bigger the crf value, the lower the quality.
if you wish to generate CQP (constant QP stream), e.g for constant QP=20 i suggest using the following parameters:
'x264-params qp=20:ipratio=1.0:pbratio=1.0:qpstep=0'
Example:
ffmpeg -s 1920x1080 -i test.yuv -vcodec libx264 -x264-params qp=20:ipratio=1.0:pbratio=1.0:qpstep=0 -y test.h264
Notice that 'ipratio=1.0' makes x264 to encode P frame with same QP as I-frame and 'pbratio=1.0' makes x264 to encode B-frame with same QP as P-frame.
The -b options, -q, and -crf seem to do nothing for video qualtiy (at least for my install of ffmpeg version 9), so I am posting a result from another post that gets right to the point
If you want high quality, setting bitrate is a poor way to achieve that. There are many other settings with far bigger influence on quality than bitrate. I would leave the bitrate setting out entirely unless you are having to meet hardware requirements of some sort.
If you are trying to get higher quality, try something like
ffmpeg -i sourcefile.mov -target pal-dvd -qscale 2 -trellis 2 outputfile.mpg
output video size goes from 13Mb for a 2 min video to 130Mb, but it gets the job done.

FFmpeg frame rate when converting from GIF to MP4

I have a GIF image. I am trying to convert it to MP4.
ffmpeg -f image2 -r {delay_time_of_gif_between_each_frame}/1 -i temp/%05d.png -vcodec libx264 video.mp4
This MP4 is not running at the same speed when compared to the original GIF. How do I make it to run with the same speed?
It seems I am making mistakes with the -r property. I played with it but don't get anything useful. I even removed it. Still it isn't working.
If you already know the time of delay between subsequent frames, then you need to take the inverse of it to convert it to a frame rate. For example, if the time between each frame is 40ms (or 0.04s), then the inverse would be 1 divided by 0.04, thus 25 fps.
You can not simply divide the time between frames by 1, since division by 1 will give you the same result as before.
So, try either of these again:
ffmpeg -f image2 -r 1/0.04 -i temp/%05d.png -c:v libx264 out.mp4
ffmpeg -f image2 -r 25 -i temp/%05d.png -c:v libx264 out.mp4
Note that the default input frame rate for image2 is 25 anyway, but this was just for illustration.
Also, you can change the frame rate of the output video as well, by putting -r after the input file, which should make a difference.
ffmpeg -f images -i temp/%05d.png -c:v libx264 -r 25 out.mp4
Although this question is somewhat older:
Current versions of ffmpeg automatically determine the delays between the frames according to the information in the gif images, so no need to set the frame rate in the command.

ffmpeg setting for HD and normal quality

Hello i need to have two versions of the same file stored on my server, medium and HD quality, the thing is that don't really know ffmpeg that well so im just trying this is code at random, i'm using the code belo but I end up with a much larger file, however it works,it plays.
ffmpeg -i inputfile.wmv -vcodec libx264 -ar 44100 -b 200 -ab 56 -crf 22 -s 360x288 -vpre medium -f flv tmp.flv
Just need the two commands to create the 2 different files
You need to give more information about what bitrate, quality or target file size you are aiming for and the size and quality of your source material preferably including codecs used and relevant parameters.
You should read the manual or ffmpeg -h or both. There are several problems with your command line:
You are using constant rate factor, crf = 22, while still trying to limit the bitrate using -b 200.
Bitrate is specified in bits/s (unless you are using a very old ffmpeg), and 200 bps is not usable for anything, add k to get kilobits/s.
You have not specified an audio codec, but you have specified an audio bitrate, ffmpeg will try to guess the audio codec for you but I don't know what codec is the default for .flv-files.
I'm assuming that the command line you posted is supposed to be for the 'medium' quality file.
Some suggestions that you can try:
Try this first: specify audio codec, e.g. -acodec libmp3lame, or if the audio is already in a good format you can just copy it without modification using -acodec copy
Try a different rate factor, e.g. -crf 30, higher numbers mean uglier picture quality, but also smaller file size.
Try a different encoder preset, e.g. -vpre slow, in general, the slower presets enable features that require more CPU cycles when encoding but results in a better picture quality, see x264 --fullhelp or this page to see what each preset contains.
Do a 2-pass encode, link.
If you don't want to read all the documentation for ffmpeg and the codec parameters that you need I suggest you look at this cheat sheet, although the command line switches have changed over the different versions of ffmpeg so the examples might not work.
An example command line:
ffmpeg -i inputfile.wmv -vcodec libx264 -crf 25 -s 360x288 -vpre veryslow -acodec libmp3lame -ar 44100 -ab 56k -f flv tmp.flv
The parameter -s [size] is the size of the output video, in pixels, for the HD file you probably want something around 1280x720, if your material is 5:4 ratio (as 360x288 is) you'll want to try 1280x1024, 960x768 or 900x720. Don't set a size larger than the source material as that will simply upscale the video and you will (probably) end up with a larger file without any noticeable improvement in quality. The -ab parameter is the audio bitrate, you'll probably want to increase this parameter on the HD version as well.

FFmpeg bitrate issue

I'm dealing with a very big issue about bit rate , ffmpeg provide the -b option for the bit rate and for adjustment it provide -minrate and -maxrate, -bufsize but it don't work proper. If i'm giving 256kbps at -b option , when the trans-coding finishes , it provide the 380kbps. How can we achieve the constant bit rate using ffmpeg. If their is +-10Kb it's adjustable. but the video bit rate always exceed by 50-100 kbps.
I'm using following command
ffmpeg -i "demo.avs" -vcodec libx264 -s 320x240 -aspect 4:3 -r 15 -b 256kb \
-minrate 200kb -maxrate 280kb -bufsize 256kb -acodec libmp3lame -ac 2 \
-ar 22050 -ab 64kb -y "output.mp4"
When trans-coding is done, the Media Info show overall bit rate 440kb (it should be 320kb).
Is their something wrong in the command. Or i have to use some other parameter? Plz provide your suggestion its very important.
Those options don't do what you think they do. From the FFmpeg FAQ:
3.18 FFmpeg does not adhere to the -maxrate setting, some frames are bigger than
maxrate/fps.
Read the MPEG spec about video buffer verifier.
3.19 I want CBR, but no matter what I do frame sizes differ.
You do not understand what CBR is, please read the MPEG spec. Read
about video buffer verifier and constant bitrate. The one sentence
summary is that there is a buffer and the input rate is constant, the
output can vary as needed.
Let me highlight a sentance for you:
The one sentence summary is that there is a buffer and the input rate is constant, the output can vary as needed.
That means, in essence that the -maxrate and other settings don't control the output stream rate like you thought they did.

Resources