This article explains how to reduce the filesize of videos and some popular video codecs.
This is a simple comparison of my own experiments and methods on how to reduce filesizes.
To install the tools mentioned here:
To simply compress a video you can use, for example, ffmpeg -i "input.mp4" -crf 35 output.mp4. crf means "constant rate factor" and the higher you set it the more compressed the videos get. The higher the "crf" the lower the quality and the lower the filesize. Every video codec has its own interpretation of the crf value and there is no fixed number that works for every codec.
Another example to compress further: You can change the codecs to more modern ones. Simply add -vcodec h265 -acodec aac inside the ffmpeg command to change the codecs of video/audio to h264/aac respectively. (This would make the command look like ffmpeg -i "input.mp4" -crf 25 -vcodec h265 -acodec aac output.mp4)
If the framerate of the video is 60 you could lower it to 30 to save space. Simply add -r 30 inside the ffmpeg command to limit the framerate to 30.
Some videos have an extremely high resolution (e.g. 4K) and you can save a LOT of space if you limit the resolution to a lower one. Simply add -vf "scale=1280:-1" to set the resolution of the output video to HD.
(The "-1" in the height means "auto set height to match aspect ratio of input video with 1280 width".)
With all the settings combined the command would look like:
ffmpeg -i "input.mp4" -crf 25 -vcodec h265 -acodec aac -r 30 -vf "scale=1280:-1" output.mp4This once lowered the filesize of a 4K 30min video from 3.2GB down to 800MB.
user@debian:~/Videos$ ls -ahl -rwxrwxrwx 1 user user 341M Jan 22 16:41 'divinity2_20220122_16.mp4' user@debian:~/Videos$ ffmpeg -i "divinity2_20220122_16.mp4" -crf 25 _divinity2_20220122_16.mp4 user@debian:~/Videos$ ls -ahl _divinity2_20220122_16.mp4 -rwxrwxrwx 1 user user 54M Feb 3 10:31 _divinity2_20220122_16.mp4
| Bitrate(kbit/s) | Size | Type | Command |
|---|---|---|---|
| 5400 | 38.7M | 60FPS/FHD | /source file/ |
| 6700 | 49.1M | 60FPS/FHD | -acodec aac -vcodec h264 |
| 6100 | 44.9M | 30FPS/FHD | -acodec aac -vcodec h264 -r 30 |
| 3500 | 26.8M | 60FPS/HD | -acodec aac -vcodec h264 -vf "scale=1280:-1" |
| 3200 | 23.9M | 30FPS/HD | -acodec aac -vcodec h264 -vf "scale=1280:-1" -r 30 |
| Bitrate(kbit/s) | Size | Type | Command |
|---|---|---|---|
| 5100 | 38.4M | 60FPS/FHD | /source file/ |
| 1100 | 8.99M | 60FPS/FHD | -acodec aac -vcodec h264 |
| 1000 | 8.51M | 30FPS/FHD | -acodec aac -vcodec h264 -r 30 |
| 464 | 4.41M | 30FPS/HD | -acodec aac -vcodec h264 -vf "scale=1280:-1" -r 30 |
There exist many different video codecs. The popular ones are:
AV1 is a codec but to actually encode something to the format you need an encoder.
To list all AV1 encoders in ffmpeg:
$ ffmpeg -hide_banner -encoders | grep -i av1 V....D libaom-av1 libaom AV1 (codec av1) V....D librav1e librav1e AV1 (codec av1) V..... libsvtav1 SVT-AV1(Scalable Video Technology for AV1) encoder (codec av1) V....D av1_d3d12va D3D12VA av1 encoder (codec av1) V....D av1_nvenc NVIDIA NVENC av1 encoder (codec av1) V..... av1_qsv AV1 (Intel Quick Sync Video acceleration) (codec av1) V....D av1_amf AMD AMF AV1 encoder (codec av1) V....D av1_mf AV1 via MediaFoundation (codec av1) V....D av1_vaapi AV1 (VAAPI) (codec av1) V....D av1_vulkan AV1 (Vulkan) (codec av1) A....D wmav1 Windows Media Audio 1
VMAF (Video Multi-Method Assessment Fusion) is a library to objectively compare video quality between 2 videos.
It can be used to compare different video codecs with each other in regards to "filesize-to-quality" ratio.
ffmpeg supports vmaf out-of-the-box and will be used for the comparisons below.
An example usage of libvmaf:
ffmpeg -i distorted.mpg -i reference.mpg -lavfi libvmaf=log_path=output.xml -f null -
| flags | encode time | quality | filesize | size diff |
| /input/ | 0s | 100 | 1857361 | 100 |
| -vcodec libx264 | 13.862826518s | 78.518588 | 4747648 | 255 |
| -vcodec libsvtav1 | 12.417688337s | 78.363506 | 3050787 | 164 |
| -vcodec libx265 | 23.296691749s | 77.475143 | 2048236 | 110 |
| -vcodec libx264 -r 30 | 13.153794256s | 43.473222 | 4724905 | 254 |
| -vcodec libsvtav1 -r 30 | 12.251826181s | 43.584006 | 3037270 | 163 |
| -vcodec libx265 -r 30 | 21.872826926s | 43.707735 | 2054583 | 110 |
| -vcodec libx264 -crf 63 | 6.53311335s | 48.744032 | 248565 | 13 |
| -vcodec libx265 -crf 51 | 15.964289776s | 52.211390 | 215415 | 11 |
| -vcodec libsvtav1 -crf 63 | 11.452395578s | 63.788422 | 299710 | 16 |
| -vcodec libsvtav1 -preset 5 | 35.679031488s | 78.556270 | 2703378 | 145 |
| -vcodec libsvtav1 -preset 5 -crf 36 | 36.787216761s | 78.407436 | 2541498 | 136 |
| -vcodec libsvtav1 -preset 5 -crf 42 | 37.60140495s | 77.241037 | 1823098 | 98 |
| -vcodec libsvtav1 -vf atadenoise | 12.967361453s | 78.353880 | 3013724 | 162 |
| -vcodec libsvtav1 -vf hqdn3d | 13.033108112s | 78.142130 | 2921178 | 157 |
| -vcodec libx265 -vf atadenoise | 22.369891418s | 77.380541 | 2027430 | 109 |
| -vcodec libx265 -vf hqdn3d | 22.797749604s | 77.067950 | 1980212 | 106 |
| -vcodec libx264 -vf atadenoise | 13.60036988s | 78.385264 | 4744122 | 255 |
| -vcodec libx264 -vf hqdn3d | 14.249355655s | 78.083106 | 4613542 | 248 |
| flags | encode time | quality | filesize | size diff |
| /input/ | 0s | 100 | 83341348 | 100 |
| -vcodec libx264 | 2m18.452027487s | 71.341284 | 38335885 | 45 |
| -vcodec libsvtav1 | 1m46.818796498s | 72.159243 | 21008677 | 25 |
| -vcodec libx265 | 3m57.057959191s | 69.695734 | 12802516 | 15 |
| -vcodec libx264 -r 30 | 1m33.472165025s | 21.358468 | 32223708 | 38 |
| -vcodec libsvtav1 -r 30 | 59.474596951s | 21.643223 | 14512709 | 17 |
| -vcodec libx265 -r 30 | 2m45.375872608s | 21.406521 | 11419915 | 13 |
| -vcodec libx264 -crf 63 | 1m38.852187208s | 30.893665 | 3282285 | 3 |
| -vcodec libx265 -crf 51 | 2m59.600133385s | 31.012789 | 1794172 | 2 |
| -vcodec libsvtav1 -crf 63 | 1m43.538152334s | 59.393447 | 2537095 | 3 |
| -vcodec libsvtav1 -preset 4 | 6m23.049201576s | 72.359325 | 18292625 | 21 |
| -vcodec libsvtav1 -preset 5 | 4m58.157046422s | 72.328905 | 18542865 | 22 |
| -vcodec libsvtav1 -preset 6 | 3m39.611192232s | 72.301776 | 19113434 | 22 |
| -vcodec libsvtav1 -preset 7 | 2m23.515272883s | 72.118201 | 19805159 | 23 |
| -vcodec libsvtav1 -preset 8 | 1m48.395351859s | 72.159243 | 21008677 | 25 |
| -vcodec libsvtav1 -preset 9 | 1m1.818236216s | 72.074842 | 19603755 | 23 |
| -vcodec libsvtav1 -preset 10 | 45.382436567s | 70.212467 | 19221825 | 23 |
| -vcodec libsvtav1 -preset 11 | 41.889777764s | 69.551712 | 19315259 | 23 |
| -vcodec libsvtav1 -preset 12 | 45.195070846s | 69.551712 | 19315259 | 23 |
| -vcodec libsvtav1 -preset 13 | 41.919028717s | 69.551712 | 19315259 | 23 |
| -vcodec libsvtav1 -preset 5 -crf 36 | 4m46.768056974s | 72.223550 | 17403336 | 20 |
| -vcodec libsvtav1 -preset 5 -crf 42 | 4m56.988644991s | 71.566286 | 12491676 | 14 |
| -vcodec libsvtav1 -vf atadenoise | 1m53.404954076s | 72.156731 | 20891422 | 25 |
| -vcodec libsvtav1 -vf hqdn3d | 1m56.136302554s | 70.699122 | 20422932 | 24 |
| -vcodec libx265 -vf atadenoise | 4m4.45587605s | 69.435055 | 12288608 | 14 |
| -vcodec libx265 -vf hqdn3d | 4m6.005874417s | 68.100506 | 12205620 | 14 |
| -vcodec libx264 -vf atadenoise | 2m34.889483814s | 71.189477 | 37158446 | 44 |
| -vcodec libx264 -vf hqdn3d | 2m40.552963929s | 69.669793 | 35678596 | 42 |
| flags | encode time | quality | filesize | size diff |
| /input/ | 0s | 100 | 236968602 | 100 |
| -an -vcodec libx264 | 6m15.345760508s | 87.344353 | 148361131 | 76 |
| -an -vcodec libsvtav1 | 7m11.761984244s | 87.357077 | 97750864 | 50 |
| -an -vcodec libx265 | 9m55.586736357s | 85.889857 | 55217120 | 28 |
| -an -vcodec libx264 -tune animation | 6m44.460372372s | 87.548421 | 126011469 | 64 |
| -an -vcodec libx264 -crf 63 | 3m16.445515058s | 47.179454 | 8121671 | 4 |
| -an -vcodec libx264 -crf 63 -tune animation | 3m38.845457439s | 48.235334 | 7601532 | 3 |
| -an -vcodec libx265 -crf 51 | 8m8.995447947s | 49.520054 | 5808345 | 2 |
| -an -vcodec libsvtav1 -crf 63 | 7m4.740727534s | 75.700035 | 11125311 | 5 |
| -an -vcodec libsvtav1 -preset 5 | 18m18.19655016s | 87.517643 | 90526942 | 46 |
| -an -vcodec libsvtav1 -preset 5 -crf 36 | 17m50.142429102s | 87.420989 | 84466200 | 43 |
| -an -vcodec libsvtav1 -preset 5 -crf 42 | 18m46.927339274s | 86.791675 | 58767027 | 30 |
| -an -vcodec libsvtav1 -vf atadenoise | 8m6.070107256s | 87.309794 | 97049203 | 49 |
| -an -vcodec libsvtav1 -vf hqdn3d | 7m40.545940213s | 86.305366 | 88252006 | 45 |
| -an -vcodec libx265 -vf atadenoise | 11m4.700751616s | 85.732573 | 53663748 | 27 |
| -an -vcodec libx265 -vf hqdn3d | 10m57.35642272s | 84.699570 | 50932164 | 26 |
| -an -vcodec libx264 -vf atadenoise | 6m43.135803649s | 87.204040 | 139474882 | 71 |
| -an -vcodec libx264 -vf hqdn3d | 6m31.558524192s | 86.074931 | 120349381 | 61 |
| -an -vcodec libsvtav1 -preset 4 | 22m5.078420825s | 87.544898 | 87859793 | 45 |
| -an -vcodec libsvtav1 -preset 6 | 12m29.970540259s | 87.358997 | 87809573 | 45 |
| -an -vcodec libsvtav1 -svtav1-params keyint=10s:aq-mode=2:tune=0:enable-overlays=1:scd=1:scm=1 | 7m39.638659687s | 87.380198 | 95323139 | 48 |
AV1 was consistently fast in encoding, low in filesize and high in quality compared to the original.
x265 has a very high compression, reaching the smallest filesizes in every comparison but also having a lower quality compared to the other codecs.
Denoising with atadenoise or hqdn3d helps with lowering filesize but also reduces quality.
I, personally, would recommend:
Modern GPUs support the option to encode and decode video streams directly on the GPU.
This is way faster than using the CPU, but also very limited in regards to compression.
Ffmpeg supports "libx265" for HEVC encoding via CPU and, for nvidia, the "hevc_nvenc" codec for GPU encoding.
Comparing these 2 is difficult, because hevc_nvenc does not support the crf flag.
The input file is 1.8MB in size, with libx265 it goes down to 1.1MB (-0.7MB) but with hevc_nvenc it goes up to 2.8MB (+1MB).
It is expected to have a lower filesize with the HEVC codec becaues it is more optimized for lower filesizes. GPU encoding prioritizes speed over filesize.
(This has been written and tested years ago, with ffmpeg v7. It is kept for historical purposes)
I am not an expert with video codecs.
I simply tested a 1 minute long clip with different encodings and input parameters. The table below shows my findings in "time taken for encoding" and "resulting filesize".
The input file is a 1 minute long clip from the "YuruCamp" movie (to be precise its from the 2nd to the 3rd minute of the movie).
The input video is h264 1920x1080 23.98fps and the audio is aac 128kb/s 48000Hz stereo.
The video has a few scenes with barely any movement and near the end firework explosions, which should make it a good clip to compare multiple codecs.
Compared codecs:
| Flags | Size(MB) | Time | notes |
|---|---|---|---|
| /none/ | 22MB | 24.510s | h264 |
| -movflags +faststart | 22MB | 24.217s | 1:1 same as above |
| -fps_mode vfr | 22MB | 25.006s | no difference to above |
| -tune stillimage | 27MB | 26.464s | only good for slideshows |
| -tune animation | 18.7MB | 27.419s | good for anime |
| -tune animation -preset slow | 17.5MB | 41.268s | not worth the time |
| -vcodec libx265 | 7.8MB | 44.043s | bad compatibility |
| -vcodec libx264 -crf 51 | 2MB | 13.513s | very bad pixelation |
| -vcodec libvpx | 5.1MB | 44.044s | =vp8, .webm, fluctuating quality |
| -vcodec libvpx-vp9 | 13MB | 172.476s | vp9, .mp4 |
| -vcodec librav1e | 9.9MB | 1161.541s | very slow |
| -vcodec librav1e -speed 10 | 13MB | 432.934 | still slow |
| -vcodec libaom-av1 | ??? | ~17min | not worth it |
| -vcodec libsvtav1 | 9.9MB | 19.499s | very good compared to h265 |
| -vcodec libsvtav1 -crf 40 | 7.4MB | 18.623s | default=35 |
| -vcodec libsvtav1 -crf 63 | 1.9MB | 14.580s | still watchable |