Topic: Compressing a really big video

Posted under General

So this is the basic scenario of where every bit counts, so you need to do all everything to make them count.

Firstly, currently acceptable fileformat for videos is WebM and that can contain VP8, VP9, Vorbis and Opus codecs. You should always use VP9 for video and Opus for audio as this is newer format which is competing directly with HEVC/h265, so you will get more quality compared to same bitrate with AVC/h264+AAC MP4 or VP8+Vorbis WebM.
https://trac.ffmpeg.org/wiki/Encode/VP9

It's kinda good to have some level of grasp of how everything in the video relates to each other. Not only does resolution and framerate play big part, but also how complex the video overall is; high amount of movement and lots of small details will require more bitrate to keep the quality high and consistant. Meanwhile predictable movement and slow moving stuff is extremely easy to compress and needs less bitrate. This is partially why I recommend using constant quality mode (or CRF option) when converting material to e621, because at this point you don't need to fine tune the bitrate yourself, but the encoder will simply dial the bitrate for you and gives the video as many bits as it needs to maintain desired perceived quality.

So now we are in situation where we need the file to be 99.99MB all of a sudden, preferabely exact. In these cases you need constant bitrate, so that you can predict the output files filesize, however now you are giving away bits consistantly troughout the video, meaning parts with literally nothing get as much bitrate as the parts where there's formula cars going. How to fix this, is use constrained quality (or simply to tell the encoder that it has leeway). This way we can let bitrate fluxuate similar to constant quality, but there's still the target bitrate it tries to achieve. Nice!

So the video is ~311.70MB large and has 6047kbps overall bitrate.
6047(bitrate)/311,7006931304932(og filesize)*99,99(desired filesize)=1 939,808102213197(overall bitrate)
Video has audio in it so we have to give chunk of it to that. Source is 192kbps MP3, as we are using Opus, 128kbps should be transparent quality and maybe even slightly too high considering source being MP3, https://wiki.xiph.org/index.php?title=Opus_Recommended_Settings&mobileaction=toggle_view_desktop
1 939,808102213197(overall bitrate)-128(audio bitrate)=1 811,808102213197‬(video bitrate)
You can also calculate this from the runtime, but I prefer bitrate and filesize.

So we are left with ~1.8mbps for our video bitrate and our video is 1920x1080@24FPS and the video looks to be relatively easy to compress (relatively small movement and not huge amount of extreme detail, considering the models textures are already showing softening for being low res). For 60 FPS video this would be bit rough, but for 24FPS, this should be more than enough bitrate to work with.
https://developers.google.com/media/vp9/settings/vod

Lastly, the best thing to do is to use sloooooow settings. This is the difference between telling your worker to have the thing ready at 11 and letting them do it in peace until the day ends, they will have so much more time to correct mistakes, optimize things and even clean up after themselves. First one of these things is two pass, which you should always use with VP9 regardless as it relies heavily on it. This lets the encoder to look up trough the material once so they will know what to expect and act accordingly when actual work starts. Second one is deadline, default is the middleline good, but there are couple other options including realtime if you need those frames now and not at 11, best which is the work in peace and I think there's also placebo which makes the encoder take week with no perceivalbe quality boost or bitrate decrease compared to best.

So the code would look something like:

ffmpeg -y -i "[wow][bp]heroes-players.mp4" -pass 1 -deadline best -c:v libvpx-vp9 -pix_fmt yuv420p -minrate 500k -b:v 1811k -maxrate 2500k -b:a 128k -f webm NUL
ffmpeg -i "[wow][bp]heroes-players.mp4" -pass 2 -metadata title="[WoW][BP] Connection with the Champions, MrKipler" -metadata url="https://twitter.com/MrKipler1/status/1271579778303299584" -deadline best -c:v libvpx-vp9 -pix_fmt yuv420p -minrate 500k -b:v 1811k -maxrate 2500k -b:a 128k "[wow][bp]heroes-players.webm"

And about 5 hours later:
post #2298197
(ended up raising bitrate by 1kbps and lowering audio to 112kbps)
Yes, there is still slight difference to original because of the higher compression rate, but I see this as not being significant enough to cut the post into two or start downscaling (which arguabely would lower the quality more than the compression).

aobird said:
Lower the resolution?

Problem I personally have with downscaling is that many people will just use the default scaling alghorithm without giving it too much of a think, so it's most likely bilinear or similar, additionally they might downscale from e.g. 1080p to 720p (2/3) instead of integer 1080p to 540p (1/2), so that the downscaling will result into the video looking almost as bad if not worse, so downscaling should be resorted if the bitrate gets so low that it's literal porridge othervice. This is a bit of a nitpicking as usually 1080p->720p will still look fine, but if we go back to every bit counting, then I feel like I have point here.
Lanczos is usually much better alternative to scaling stuff (-vf scale=-1:540:flags=lanczos) and with modern machines the difference it takes almost no difference in time.

Downscaling is also one of the reasons why furaffinity copies of stuff are usually worse from twitter copies, even if twitter stuff is usually more compressed.

Usually it's better idea to cut the content instead of scaling it, just that what works is case-by-case because if it's continuous video or a single image instead of comic, then cutting and cropping obviously doesn't work. As this video has a lot of seperated scenes, it could work as cut into two or more parts if it didn't fit into single post.

Updated

mairo said:
Yes, there is still slight difference to original because of the higher compression rate, but I see this as not being significant enough to cut the post into two or start downscaling (which arguabely would lower the quality more than the compression).

Your conversion is more than good enough 👍 And thank you very much for all of the information!

I'll revive this topic since I have a linked question: is there a practical way to covert a 40-minute, 3GB video? I'm assuming the answer is "just downscale", but I might as well see if there are any other options. Borrowing Mairo's calculation from above, the bitrate needed to smush this video under 100MB is so low it's unwatchable.

strikerman said:
I'll revive this topic since I have a linked question: is there a practical way to covert a 40-minute, 3GB video? I'm assuming the answer is "just downscale", but I might as well see if there are any other options. Borrowing Mairo's calculation from above, the bitrate needed to smush this video under 100MB is so low it's unwatchable.

I'm getting 5.3GB. Also please input the original file into post sources.
This is also one reason why I have been bothering about getting AV1 support as that would increase visual quality even further with these kind of uploads.

The video is also extremely high quality, high bitrate and 60 FPS, so downscaling and using extremely low bitrate would be unwatchable still in comparison to source.
You basically need to find 2, preferabeli 3 cutoff points in the animation and just upload in multiple parts. -ss <timestamp> for starting time and -t <timestamp> for duration before ending.

I can also give it a shot if you want.

I have also started to drop minrate/maxrate as it seems like with many materials this results the encoder visually compressing scenes it shouldn't.

  • 1