Keeping Neil happy

The story of the first-ever remotely-induced heart-attack

Fig 1.- How to kill Neil, and make it look like an accident

Image compression

Given the importance of keeping our repository small and manageable, I decided to automate image compression a little, so it becomes a secondary concern instead of an obsession

Here you can see the original version of the script. For the most up-to-date version, checkout my git repo

This simple interface (IntelliJ IDEA) allows me to launch the script in 1 click, while I edit my markdown files.

The script, in action, skipping files that are already compressed (to avoid losing quality on every run):

As well as when compressing files that it has never encountered before:

"C:\Program Files\nodejs\node.exe" "C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js" run pack --scripts-prepend-node-path=auto

> fablab-documentation@1.0.0 pack
> node dist/app.js

docs\assignments\week03\circular-build.jpg - compressing
docs\assignments\week03\doing-rectangular-pattern-on-constrained-design-results-in-unconstrained.jpg - compressing
docs\assignments\week03\initial-idea.jpg - compressing
docs\assignments\week03\inkscape-error-living-hinge.jpg - compressing
docs\assignments\week03\in_to_mm_problem.jpg - compressing
docs\assignments\week03\in_to_mm_problem2.jpg - compressing
skipping assets directory: docs\assignments\week03\assets
docs\assignments\week03\in_to_mm_problem3.jpg - compressing
docs\assignments\week03\in_to_mm_solution.jpg - compressing
docs\assignments\week03\the-tyranny-of-floating-point-precision.jpg - compressing

Process finished with exit code 0

Video compression

Compressing videos and images to save space

An important part of our weekly tasks include keeping our repositories under control, and not committing files that are uncompressed or unnecessarily large.

So far, we’ve only touched on 2D, and we’ve already generated lots of files, some of them x00s of MB large. In the picture below you can see the original painting video (which was originally 15 minutes long) as well as the post-processed versions.

  1. The original file was a real-time recording of part of my screen while I painted the drawing.
  2. The second file is the same file, but played faster (x30) for a nice visual effect. The size reduction is noticeable, but it’s still too large.
  3. The third file is a web-optimised version of the file from step 2. We did the compression using handbrake.

Speeding up videos using ffmpeg

After a quick search I found that there’s an easy way to speed up videos using ffmpeg

ffmpeg -i input.mov -vf "setpts=(PTS-STARTPTS)/30" -crf 18 output.mov

Video compression using Handbrake

Handbrake comes with an out-of-the-box encoding profile that seems to hit a sweet spot: small enough size, with good enough quality.

I also wanted to learn about video encoding and wanted to read a bit about Constant Quality vs Average Bit Rate as well as other optimal settings for handbrake depending on our use case.

The articles above seem to indicate that ABR might outperform constant quality in some cases, so I wanted to give this a try and see if I could shave off some valuable bits off of my videos.

These are the 2 settings I compared.

Settings Comparison

Gmail Medium (out of the box with handbrake)
Property Value
Video CodecH.264 (x264)
Framerate30 Peak
Constant Quality 23 RF
Encoder Level 3.1
Advanced Optionsvbv-bufsize=5000:vbv-maxrate=500:aq-mode=2:aq-strength=0.8:direct=auto:analyse=all:deblock=3,2
Fablab Standard (custom made encoding preset)
Property Value
Video Codec H.264 (x264)
FPS Same as source
Framerate Variable
Quality Avg Bitrate: 700kbps
2-pass encoding yes
turbo first pass no
Encoder Preset slow
Fast Decode no
Encoder Level 3.1
Advanced Optionsvbv-bufsize=5000:vbv-maxrate=500:aq-mode=2:aq-strength=0.8:direct=auto:analyse=all:deblock=3,2

Fablab Standard (custom made encoding preset)

After multiple rounds of testing (the pic below is just the past iteration), I concluded that “handbrake defaults are good enough” (which is a fancy way of saying “AV engineers, much smarted than I am, have already done a much better optimization job than I could ever do with trial and error experiment for an hour”).

As you can see, while the custom preset (which I called “fablabstandard” and uses variable bitrate) got smaller size than an equally-sized video (the handbrake one called “gmail-medium”), it had some tiny visual artifacts from time to time, that bothered me. For a 10% larger size, I was happy with the tradeoff, especially because I coudn’t test if my custom preset might have had other drawbacks that I could not predict/foresee.

So all videos included in this repo, if they go through handbrake, they will use one of these 2 compression settings, depending on if variable bitrate provides a good enough edge or not, and no further optimizations will be done ( read: law of diminishing returns)

Why not use H.265 Video format?

Which video format should I use when compressing? “265” or “264”? (formally known HEVC/H.265 and MPEG-4/H.264 respectively)

While the H.265 format compresses a lot better than 264, is generally avoided because of lack of widespread support on browsers.

As I am writing this, 264 supports 98.31% of all global internet users, while 265 only supports 19.65%

The decision was easy: Accessibility and supports has more weight than just raw file size with numbers like these.

40x worse performance (40x more users who cannot access H.265 vs. users who cannot access H.264)

Automating compression

Since I imagine I will be using the “speed up” config for ffmpeg over and over, I created a small script in Windows that will allow me to drag&drop a file into it, and will speed up the file by a factor manually (defaults to x5 speed).

@echo off
echo Compressing %1

set "SpeedFactor="
set /p SpeedFactor=Speed SpeedFactor[5]:
if "%SpeedFactor%"=="" SET "SpeedFactor=5"

echo compressing at %SpeedFactor%
ffmpeg -i "%1" -vf "setpts=(PTS-STARTPTS)/%SpeedFactor%" -crf 18 "%~dp1fast_%~n1%~x1"
pause

I will have to re-do it again when I get my fixed laptop back, since I intend to use linux whenever possible.

Useful resources to build this script:


In future iterations

  1. incorporate Video compression using ffmpeg
  2. make this a standalone script so other FabAcademy students can incorporate it into their normal workflow.
  3. maybe explore binding the script as a pre-commit git-hook to make sure it compresses all images before each commit. Since the filenames are not changed (but the original is backed up with a different name, that gets .gitignored), it won’t break any img tags.