How can I reduce a video's size with ffmpeg?
Solution 1
Update 2020: This answer was written in 2009. Since 2013 a video format much better than H.264 is widely available, namely H.265 (better in that it compresses more for the same quality, or gives higher quality for the same size). To use it, replace the libx264 codec with libx265, and push the compression lever further by increasing the CRF value — add, say, 4 or 6, since a reasonable range for H.265 may be 24 to 30. Note that lower CRF values correspond to higher bitrates, and hence produce higher quality videos.
ffmpeg -i input.mp4 -vcodec libx265 -crf 28 output.mp4
To see this technique applied using the older H.264 format, see this answer, quoted below for convenience:
Calculate the bitrate you need by dividing your target size (in bits) by the video length (in seconds). For example for a target size of 1 GB (one gigabyte, which is 8 gigabits) and 10 000 seconds of video (2 h 46 min 40 s), use a bitrate of 800 000 bit/s (800 kbit/s):
ffmpeg -i input.mp4 -b 800k output.mp4
Additional options that might be worth considering is setting the Constant Rate Factor, which lowers the average bit rate, but retains better quality. Vary the CRF between around 18 and 24 — the lower, the higher the bitrate.
ffmpeg -i input.mp4 -vcodec libx264 -crf 20 output.mp4
Solution 2
You mentioned wanting to reduce filesize to fit more videos on a mobile device, which is my usecase as well. All the answers here are for reducing the compression quality but nobody has mentioned reducing video frame size. It's a lot quicker, up to multiple times faster depending on your source and the amount of the resolution decrease, as there are less pixels to be encoded. Also the file size can be reduced significantly.
The downside is you also lose a large amount of quality because less pixels mean less image details. But when converting for a small device this may be acceptable.
See the ffmpeg docs on scaling for more info.
To scale to half size:
ffmpeg -i input.mkv -vf "scale=trunc(iw/4)*2:trunc(ih/4)*2" -c:v libx265 -crf 28 half_the_frame_size.mkv
One third size:
ffmpeg -i input.mkv -vf "scale=trunc(iw/6)*2:trunc(ih/6)*2" -c:v libx265 -crf 28 a_third_the_frame_size.mkv
One quarter size:
ffmpeg -i input.mkv -vf "scale=trunc(iw/8)*2:trunc(ih/8)*2" -c:v libx265 -crf 28 a_fourth_the_frame_size.mkv
One fifth size:
ffmpeg -i input.mkv -vf "scale=trunc(iw/10)*2:trunc(ih/10)*2" -c:v libx265 -crf 28 a_fifth_the_frame_size.mkv
In these examples, the size is divided by twice the value and multiplied by two to ensure the pixel size is a multiple of two, which is required for some codecs including H265. Be aware that changing the resolution always requires reencoding, so all the ins and outs of the other answers apply here as well.
Solution 3
I tested most of the other proposed answers to this question. The test data conclusions are below. These are the proposed answers that I tested:
(BR) Modify the bitrate, using:
ffmpeg -i $infile -b $bitrate $newoutfile
(CR) Vary the Constant Rate Factor, using:
ffmpeg -i $infile -vcodec libx264 -crf 23 $outfile
(SZ) Change the video screen-size (for example to half its pixel size), using:
ffmpeg -i $infile -vf "scale=iw/2:ih/2" $outfile
(BL) Change the H.264 profile to "baseline", using:
ffmpeg -i $infile -profile:v baseline $outfile
(DF) Use the default ffmpeg processing, using:
ffmpeg -i $infile $outfile
DATA
- "size" - percent pixel size of the converted video in relation to the original.
- "bitrate" - bitrates of original and converted videos.
- "definition" - pixel size of videos.
- "convert" - time to convert the video in seconds.
I calculated the target bitrate for (BL)using the proposed method.
=== File A - How Node Is Helping To Propel Angular-Fnbixa7Ts6M.mkv ===
original BR CR SZ BL DF
-------- --- -- -- -- --
size 64152 kb 214% 76% 40% 83% 76%
bitrate 411 kb/s 883 313 165 342 313
definition 1920x1080 1920x1080 1920x1080 960x540 1920x1080 1920x1080
convert -- 648 509 225 427 510
=== File B - Using GraphQL with Angular _ By - Lee Costello-OGyFxqt5INw.mkv ===
original BR CR SZ BL DF
-------- --- -- -- -- --
size 410301 kb 33% 109% 28% 143% 109%
bitrate 2687 kb/s 880 2920 764 3843 2920
definition 3840x2160 3840x2160 3840x2160 1920x1080 3840x2160 3840x2160
convert -- 2307 3188 1116 2646 3278
CONCLUSIONS
The (SZ) method is definitely the quickest method. It was 2X to 4X faster. This can be very much an issue on high-def videos, since all of the other methods took longer to convert than the actual length of the video! For example, The (CR) method took 53 minutes to convert the 21 minute video.
The (SZ) method is definitely the best method if the definition of the video is larger than the definition of the screen that will be displaying it. For example, if your phone can only display a 1080p picture, sending it a 3840x2160 video is just wasteful. It would be best to half its size to 1080p.
Some of the proposed answers actually INCREASED the size of some videos. For example, the (BR) method more than doubled the size of the 1080p sample. It did however make the 2160p size one-third. For the high-def sample, the (CR), (BL) and (DF) methods all INCREASED the size of the video.
Correct (or best) Answer
It is always best to first lower the resolution to the maximum supported by your target display.
If you want to reduce file size further, it will depend on personal choices. You can either reduce information content or increase compression.
You can lower the resolution more if that is not something that concerns you.
If the video doesn't include fast action scenes, you may want to lower the frame rate.
If you have a powerful processor and space is the only issue, you can increase the compression rate.
Bit rate is a combination of multiple factors. So just telling ffmpeg to lower the bit rate may not give you the results you want.
Another way of lower information content is to lower the color depth. How to do this was not yet discussed.
Solution 4
Note that it seems that ffmpeg
already performs some optimization when ran without options, so before trying to use settings you don't understand or deciding to explicitly lose information, give a try to a default conversion :
ffmpeg -i input.mp4 output.mp4
In my case it reduced the bitrate of both the video and audio (you can check and compare the input and output file by running ffprobe
on them), transforming a 700 Mb video into a 60 Mb one of seemingly similar quality.
Solution 5
Unless you're looking for a specific bit rate, I'd recommend the -crf
option.
This is most commonly used for x264
encoding as described in this article.
In short: a constant rate factor (CRF) of 23 would make a DVD quality movie (~700MB - 1GB) and lower CRF values would be higher quality (larger files).
An example from the linked article:
ffmpeg -i input.mp4 -c:v libx265 -crf 28 output.mp4
Related videos on Youtube
xralf
Updated on September 18, 2022Comments
-
xralf almost 2 years
How can I use
ffmpeg
to reduce the size of a video by lowering the quality (as minimally as possible, naturally, because I need it to run on a mobile device that doesn't have much available space)?I forgot to mention that when the video can use subtitles (*.srt or *.sub), I'd like to convert them too to fit the parameters of the converted video file.
-
Kevin over 12 yearsI haven't used it but the
ffmpeg
man page shows a-fs
option to limit the output size, does something likeffmpeg -i in.avi -fs 100M out.avi
work? -
Peter.O over 12 yearsThe
.avi
is not the main issue..avi
is just a container. The main issue is which codecs you use.. Many (most?).avi
vids use older style codecs (eg XviD) which are fine, but are larger for the same quality when compared to the later generation of codecs .. You can typically get a tight encoding by using theH.264
video compression standard (eg. codecx264
) andaac
compression for audio.. The container and codecs you use is up to you and your phone... The.mp4
container is well accepted.. (but can your phone handle it: see this link -
xralf over 12 years@Kevin This wants more parameters for conversion.
-
Sridhar Sarnobat almost 6 yearsIf it's too overwhelming, there is a fallback option of using Quicktime which has export presets of
480p
etc. -
Tarik over 4 years@Kevin Best answer. Please, post as an official answer so that I can upvote.
-
Wolfpack'08 over 4 yearsThis answer appears on the top of search engines for the search term "reduce video resolution ffmpeg", and the accepted answer increases the size of videos.
-
cipricus over 4 years@Wolfpack'08 - I have seen size increased with the second command of accepted answer when the input video was already the result of the same command. So: A->B->C, B was between 4 and 5 times smaller than A; but C was a bit larger than B.
-
Wolfpack'08 over 4 years@cipricus thank you for explaining. I've seen the increases with both video formats. I'm using handbrake to reduce video size, right now, but I did find an article with beginner-level cookbook-style commands for reducing resolution and stuff; so, I hope I'll be off of the GUIs soon.
-
Garrett over 2 years@Kevin, using the
-fs
option seems to crop the video for me, rather than keeping it the same length, but reducing quality. -
mistige over 2 yearsIn addition to what Garrett mentions: -fs option will force the video to stay below the requested max-length. So, I would recommend against it. If your other settings are ok and reducing the output-video-size, you won't need the -fs option to crop. If using -fs anyway, beware of its danger and check your output, assuring it contains the end of the movie.
-
-
xralf about 12 yearsThe video of size 338 MB was reduced on size 130 MB. The quality rapidly lowered. Is there some explanation for this process? The original author doesn't explain his guidline.
-
xralf about 12 yearsAnother thing are the subtitles. I don't want them to embed, but I'd like the new srt or sub file to fit the new converted video.
-
Vicky Chijwani about 12 yearsYou could try a higher bit-rate, or maybe experiment with the Constant Rate Factor the original author talks about. Other than that, I'm sorry, but I don't have much knowledge of
ffmpeg
. I was able to answer only because I've wanted to compress videos withffmpeg
in the past and had come across that answer. -
xralf about 12 yearsThanks, your answer shifts the question closer to the solution. I will leave it open for some time yet.
-
abeboparebop almost 8 yearsI found that the former made the first few seconds blocky and pixelized (a la this question on SuperUser) but adding the
-crf
option without changing anything else resolved this issue. -
Martin Argerami over 7 yearsThe second command took a 101MB mp4 file I had, and created a 121MB output.mp4.
-
Patrick Roberts over 7 yearsSecond command, using
-crf 24
took a 255.3MB video I had and reduced it to 72.7MB without lowering the quality noticeably. Have an upvote! -
sinisterstuf about 6 yearsImpressively reduced a ~2G video to 14MB, still looks good, this was the first search result and it's exactly what I was looking for, thanks!
-
ZN13 about 6 yearsMight be good to note that you can now use
libx265
for even more size reduction. -
Hermann over 5 yearsThe answer is good, but I want to point out another detail: Some devices (e.g. old tablets, a raspberry pi 1) may not only feature low memory, but also low processing power. In such cases, you may want to limit the complexity of the decompression by restraining the profile via
-profile:v baseline
(as shown at superuser.com/questions/371460/…). Also-pix_fmt yuv420p
is good for compatibility and-movflags +faststart
allows an early start. -
Harshiv over 5 yearsSecond option is awesome, original file was 376MB mp4, crf of 20 reduced it to about 49MB without considerable artifacts, worth an upvote!
-
John Pankowicz over 5 years@Hermann The second solution also solved problems I had with videos on a laptop with plenty of memory but limited CPU power. My cheap IdeaPad 100S with an Intel Celeron N3050 1.6GHz CPU choked on most of my downloaded Youtube videos but using the 2nd solution solved it completely. If I come across one that dosn't play, I'll try your solution.
-
Fadwa about 5 yearsThis takes forever! Is this normal, the time it takes. I am trying to lower a 1G video.
-
Sam Hosseini about 5 yearsWent from 4Gb to 2Gb with this, thanks!!
-
André Levy about 5 yearsWorked for me. Reduced 625MB to 140 with
libx265 -crf 24
. And the initial video was already cut at low quality in iMovie. Interestingly, running it again over the resulting file reduced it further to 123MB. -
Nirali about 5 yearsIt works. but it takes too much time. Is there any improvement for less execution time
-
sodimel almost 5 years
-
pjtnt11 almost 5 yearsThis increased the size of my video from 10.8MB to 14MB
-
vhs over 4 yearsBy far the most simple answer so far. Used it on an 18s 4K video from Pixabay and the result was a 30% reduction in size without any noticeable reduction in quality.
-
Skippy le Grand Gourou over 4 years@pjtnt11 Good to know it's not always efficient, thanks for reporting.
-
Aleyam over 4 yearswhat if we mix 2 method for better result like starting by (SZ) then end with a (CR)?
-
John Pankowicz over 4 years@aleyam It depends entirely on which ones you are mixing and in what order. Starting with SZ and ending with CR makes sense. This is an example of what I mention in "Correct (or best) Answer". You are first lowering the resolution and then increasing compression. But different combos or different orders make no sense - for example doing SZ after CR. Also some methods would work against each other. For example, CR tries to dynamically vary the frame bitrate but BR tries to keep it constant.
-
JustCarty over 4 yearsWhile this might work, it is worth noting that it is not sustainable. In future, the FFMPEG defaults might change and produce different results. Perhaps, the defaults will make the changes better, but IMO it is risky since you are relying on the devs to optimise your file - are they creating smaller files, without worrying about quality, or are they trying to find a balance between the two?
-
Old account over 4 yearsAnother success story here with
ffmpeg -i output.mp4 -vcodec libx264 -crf 24 output_compressed.mp4
from 2.5 GB 1920x1080 20min video down to 287.9 MB, huge reduction, amazing! -
Maëlan over 4 yearsPlease note that the quoted answer included a dramatic miscalculation (mixing bytes and bits) which lead the “fixed bitrate” method to compress 8 times more than intended. This has been fixed.
-
Maëlan over 4 yearsThanks for having gathered this data. Unfortunately, this benchmark compares apples to oranges. (1) Method DF adds no info to the picture since it is identical to Method CR, i.e. re-encoding with
libx264
and CRF 23, i.e. ffmpeg’s default settings. (2) Method BL is not actually a compression method, and the output size varies (in either direction) because of other, uncontrolled factors. [Lowering the “profile” of H.264 to “baseline” means ensuring compatibility with some legacy hardware—which is largely unnecessary as of 2019 since H.264 has been around for more than 15 years.] -
Maëlan over 4 years(3) BR literally applies a constant bitrate, so the resulting bitrate is obviously what you asked for (approx.). If you ask for twice that of the input, then it should come as no surprise that the output is twice as large! [Also, note that encoding to a constant bitrate is discouraged, you should instead do a 2-pass average bitrate encoding, see other answers.] (4) CR provides an interesting data-point but remains limited to one arbitrary value for the CRF. With the same shortcoming that if you pick a target quality higher than that of the input, then you get a larger output.
-
Maëlan over 4 years(5) The running time of encoding is proportional to the (unknown) number of frames of the input video, hence it would be better expressed as a ratio (running time of encoding) / (length of video) or better yet, as frames encoded per second (because different videos have a different number of frames per second).
-
Maëlan over 4 yearsIt is wise words however that you should always start by shrinking your video to the resolution of the display you are targeting—a larger resolution is just a waste of everything. But it is independent from applying either BR or CR. Hence, a more relevant benchmark would compare BR with several target bitrates and CR with several CRFs, showing for each entry the three sides of the tradeoff: achieved bitrate, achieved quality (after encoding,
libx265
reports the “average QP”—the lower the better) and running time of encoding. And have another benchmark about shrinking. -
Maëlan over 4 yearsAs a final note, nowadays there is no strong reason not to prefer the better and more recent H.265 format (or even AV1, if you are patient enough) over H.264.
-
somenxavier over 4 yearsSecond command it's the best. And then convert mp4 to webm,
-
Matthias Braun over 4 years+1: This reduced a
.mov
file's to a fifth without reducing resolution or image quality:ffmpeg -i vid.mov -b 8507k out.mp4
. The.mov
file's format was MPEG-4 according tomediainfo
. It used h264 as the video codec, judging from the output offfmpeg -i vid.mov 2>&1
. -
Lluís about 4 yearsdon't use libx265 if you plan to use it on html5 video, see gist.github.com/Vestride/278e13915894821e1d6f#support
-
alexis about 4 yearsFor the first option my ffmpeg complains:
Please use -b:a or -b:v, -b is ambiguous
. BTW, Why not just decrease the original bitrate by a certain factor? get the bitrate withffmpeg -i inputfile
and then just use a lower number in the first option. May this avoid the issue of actually increasing the video size? -
Joeytje50 about 4 yearsReminder to everyone who upvotes this answer to also upvote the answer this one is quoted from. Gotta upvote the OP.
-
Gabriel Staples about 4 yearsHere is a very well-written and informative article about CRF (Constant Rate Factor) and what it means: slhck.info/video/2017/02/24/….
-
Arka Prava Basu about 4 yearsHi. After ` ffmpeg -i input.mp4 -vcodec libx265 -crf 28 output.mp4` ios devices cannot seem to play the video. AFAIK after ios11 HEVC is supported. Any idea on this?
-
KetZoomer over 3 yearsI was able to reduce file size from 10 megabits to 5 megabits. My video was 1080p, so I added -s hd720 and it reduced it from 10 megabits to 1 megabit.
-
Shimon S over 3 yearsAfter using libx265 can not open video nor in Chrome nor in QuickTime Player. libx264 yields 15% larger file, but it's more compatible.
-
Abinash Dash over 3 years
ffmpeg -i input.mp4 -vcodec libx264 -crf 24 output.mp4
and i got a video of size 80mb from 290 mb. No visible loss of quality(at least to my eyes). Thanks. -
vdegenne over 3 yearsif h.265 is better than 264 (and you said that in 2013) why now in 2021 h.264 is still widely used over h.265?
-
West over 3 yearsTried first method and cant use the file with ios. Instead I used
ffmpeg -i input.mp4 -vcodec libx264 -crf 28 output.mp4
and worded fine. On converting some 58Mb file, libx265 gave a 10MB while using libx264 gave 13Mb, so not much difference and less headaches -
Ellery Familia over 3 yearsThis answer is under-rated. It significantly reduced both the size and speed of the encoding. Thank you!
-
Miles Wolbe over 3 years@AkraPravaBasu: According to Comparing H.265 (HEVC) and H265 video file size, adding
-tag:v hvc1
allowed QuickTime (on a Mac) to play converted H265 files. -
Tianyi Shi about 3 yearsIt is also worth noting that libx265 is not the only H.265 encoder. By compiling ffmpeg with hardware acceleration options (which is available on recent Mac, Linux and Windows machines), faster encoders will be available (for example,
-vcodec hevc_qsv
on Linux/Windows). See: trac.ffmpeg.org/wiki/HWAccelIntro -
Mateen Ulhaq about 3 yearsThis answer should probably also mention that H.265 hardware decoding (or encoding!) may not be supported on all devices and that the encoding process is typically much slower than H.264.
-
user1133275 about 3 yearsHow is the data shared from pass 1 to pass 2?
-
Max Robbertze about 3 yearsOff the top of my head... i think it writes a tmp file derived from $1
-
Déjà vu almost 3 years...and reduces significantly the video quality, even with /2.
-
Alex Styl almost 3 yearsSomeone else already mentioned it that libx265 has limited support for browsers. see gist.github.com/Vestride/278e13915894821e1d6f#support
-
Heath Raftery over 2 yearsFor @arka-prava-basu and @shimon-s , adding
-tag:v hvc1
makes the result Quicktime compatible, with no change to file size! -
Bram over 2 yearsCaveat Emptor: If I upload the 265 video to reddit, it gets refused, but the 264 is accepted.
-
cregox over 2 yearscould you also recommend the best free video format? ideally something made with agpl, even if ffmpeg still haven't done it themselves.
-
cregox over 2 yearscould you also recommend the best free video format? ideally something made with agpl (even if ffmpeg still haven't done it themselves talk.ahoxus.org/notice/AHZ626fsOe14jNUcng#ffmpeg).
-
cregox over 2 yearscould you also recommend the best free video format? ideally something made with agpl (even if ffmpeg still haven't done it themselves talk.ahoxus.org/notice/AHZ626fsOe14jNUcng#ffmpeg).
-
cregox over 2 yearsvery curious to know: why libopus? disclaimer: i look for the best free video format... ideally something made with agpl (even if ffmpeg still haven't done it themselves talk.ahoxus.org/notice/AHZ626fsOe14jNUcng#ffmpeg).
-
cregox over 2 yearshow about a fixed size but keep the aspect ratio?
-
John Pankowicz over 2 years@cregox What's "best" depends on your application. Also, the video format (normally meaning "file format") is not what's most important. It's the type of video codec used. Different file formats can use the same codec, and visa-versa. I recommend you read: brid.tv/…
-
Azykos about 2 yearsIn my case, the command reduced video bitrate dramatically (without noticeable quality reduction) but increased audio bitrate a little (that is obviously not good). To keep original audio track run
ffmpeg -i input.mp4 -acodec copy output.mp4
-
Admin about 2 yearsWorks great ! got down to approx. 88 MB from 412 MB !
-
Admin about 2 yearsDon't forget
-preset veryslow
. The slower the preset it, the more the compression is and the lesser is the file size. For one of my small video,-preset placebo
created 2664250 Bytes file,-preset veryslow
create of 2473329 Bytes file-preset slower
created of 2589027 Bytes file,-preset slow
created 3370628 Bytes file,-preset medium
created 3410426 Bytes file,-preset ultrafast
created 10708290 Bytes file. Ultrafast takes smallest amount of time to render the video, but video is biggest. So I will choose slow/veryslow/medium. More info: trac.ffmpeg.org/wiki/Encode/H.264