Skip to content

Repository files navigation

shrinkit

tests

shrinkit compresses macOS screen recordings and speeds them up. Drop a .mov into a folder, or right-click it in Finder, and a much smaller .mp4 comes back. A QuickTime capture that started at a few hundred megabytes usually ends up in single digits.

A raw screen capture is almost always too big to attach to a pull request, a Jira ticket or a Slack message, and too slow to sit through. Playing it back at 2x and re-encoding it at a fixed quality deals with both at once.

The encoding is ffmpeg. A launchd agent watches the folder for you, so the whole thing runs without an app to open. Every part of it is configurable, and it can also cut a stretch out of the middle, to shorten a recording or redact something in it.

Demo

2026-07-30.13.34.12-2x.mp4

Requirements

  • macOS
  • ffmpeg. The installer offers to fetch it with Homebrew if you do not have it.

Install

git clone https://github.com/noxend/shrinkit.git
cd shrinkit
./install.sh

The installer copies the script to ~/.local/bin/shrinkit, creates the working folders under ~/Movies/shrinkit, registers a launchd agent that watches input/, and puts a shrinkit shortcut on your Desktop. Run it again any time to update; it never overwrites your settings.

For a different working folder:

SHRINKIT_DIR="$HOME/Movies/clips" ./install.sh

~/Desktop, ~/Documents and ~/Downloads are guarded by macOS privacy protection, and a background job is refused there until you grant it Full Disk Access by hand. If you install into one of them the script prints the steps. Anywhere else, ~/Movies included, needs nothing.

Use

  1. Open the shrinkit shortcut on your Desktop and drop a recording into input/. QuickTime .mov, .mp4 and .m4v all work.
  2. Give it a few seconds.
  3. Collect the result from output/, converted to .mp4 and named clip.mp4.

The original goes to a hidden .processed/ folder, so the working folder holds only settings.conf, presets/, input/ and output/.

Right-click a video

Most of the right-click menu is the list of your presets. Every file in presets/ gets an entry named after it, so out of the box you get shrinkit: 2x, the everyday one, shrinkit: sharp, sharper than the default for something like a PR, and shrinkit: tiny, as small as it gets. The result is named after the preset that ran, clip-2x.mp4, clip-sharp.mp4 or clip-tiny.mp4, and lands beside the original, which stays where it is. You can select several files to do them together.

Add a preset and it becomes a new entry; the installer rebuilds the menu from presets/ every time it runs. One entry isn't a preset: shrinkit: mark cuts, for marking a stretch to remove before shrinking (see below).

One-off changes on the command line

Every setting doubles as a flag, so one file can be handled differently without editing anything:

shrinkit --speed 4 --crf 32 recording.mov
shrinkit --no-remove-audio recording.mov

A true/false setting takes no value: --remove-audio turns it on and --no-remove-audio turns it off. Name no files and the flags apply to whatever is sitting in input/. Flags beat the config file.

One flag is not a setting: --cut takes a range to remove from the recording, and needs the file named. See below.

Cutting a stretch out of the middle

From the command line, name the ranges with --cut, once each:

shrinkit --cut 0:32-0:35 --cut 2:30-end recording.mov

That is the whole feature for a one-off. The rest of this section is the other way in, a file you edit next to the recording, which is what the right-click menu uses and what survives being closed and come back to.

Right-click a recording and choose shrinkit: mark cuts. It opens the recording, so you can find the moment, and a <recording>.cuts text file next to it (creating one the first time) where you mark what to remove, one range per line:

# clip.mov.cuts
0-0:20
0:32-0:35
1:10-1:12.5
2:30-end

Save it, then process the recording as usual: drop it into input/ or right-click it and pick a preset. Each range is removed entirely, not just skipped past on playback, since the frames are never written to the output at all. Good for cutting a secret out of a recording, a password typed into a form, a private chat glanced at mid-recording, and works just as well for plain shortening.

end reaches the real length of the clip without you having to know it, so trimming the end is the same .cuts line as everything else, not a separate mechanism: 2:30-end cuts from 2:30 on. 0 is already the start, so trimming the beginning needs nothing special: 0-0:20 cuts the first 20 seconds.

Times are M:SS, M:SS.f, or plain seconds, in the file and in --cut alike. # starts a comment, a range under a tenth of a second is too short to reliably land on a real frame, a range starting at or past the clip's real length cuts nothing and is skipped rather than silently doing nothing while claiming success, and a line that does not parse is skipped rather than stopping the run. All of these are logged, so check the log if a cut you expected does not show up in the result. If you edit the file in TextEdit rather than through the menu entry, save it as plain text (Format > Make Plain Text) with Smart Dashes off (Edit > Substitutions), or it will not parse as written.

--cut replaces the sidecar for that run rather than adding to it, the same way every other flag beats the config file, and says so in the log when there was one to ignore. Unlike the other flags it needs the recording named on the same command line: a timestamp only means something in one particular file, so applying one to whatever happens to be sitting in input/ is never what you meant. Name several files and the same ranges apply to all of them, sidecars included, so that is worth a second look before you do it.

Cutting needs a steady frame rate to land exactly where it is told to, so a recording gets resampled to fps (30 if fps = 0) before anything is removed, even when fps = 0 would otherwise mean "keep the original" for the rest of the recording.

Dropping a recording into input/ files the .cuts sidecar away with the original once processing is done. Right-clicking a file directly leaves both in place, the same way it leaves the recording itself in place. Once you have the result, check it and clean up the source yourself.

Presets

A preset is a file of the same settings in presets/, read on top of settings.conf. Whatever it leaves out stays as the config has it, so a preset only spells out what it changes. The finished file is named after the preset that made it, which is how you can tell two copies apart.

shrinkit --preset tiny recording.mov

Copy a preset file to make your own, then give it a menu entry without reinstalling:

shrinkit preset install tiny     # adds "shrinkit: tiny" to the right-click menu
shrinkit preset remove tiny      # takes the entry out, keeps the file

Flags beat a preset, and a preset beats the config file.

Settings

From the command line:

shrinkit config              # what is in effect right now
shrinkit config crf 32       # change one
shrinkit config edit         # open it in $EDITOR

Or edit ~/Movies/shrinkit/settings.conf yourself. It is one key = value per line, and a line starting with # is a comment. Changes take effect on the next recording. A value you get wrong goes back to its default and the log says so, and a line that makes no sense is skipped, so a typo here will never leave a recording unprocessed.

Setting What it does Default
speed Speed multiplier. 2 is twice as fast, 1 leaves it alone 2
fps Cap the frame rate, up to 240; 0 keeps the original 30
crf Quality against size, the main knob. Lower is sharper and bigger, higher is smaller (18 high, 23 good, 28 small, 32 tiny) 28
codec h264 plays everywhere, hevc is about 30% smaller and less compatible h264
remove_audio true drops the sound, false keeps it and speeds it up to match true
max_height Downscale tall videos to this height; 0 keeps the original 0
keep_original true files the original in .processed/, false deletes it true
keep_days Delete originals from .processed/ once this many days old, up to 3650; 0 keeps them forever 0
notify Post a macOS banner when a file is done true
notify_sound Glass, Ping, Pop, Hero and the rest, or none Glass
notify_start Also post a quiet banner when a file starts true
copy_to_clipboard Put the finished file on the clipboard, ready to paste false

Logs go to a hidden .logs/ folder. The watched folder is fixed when you install, because launchd wants an absolute path; to move it, run the installer again with SHRINKIT_DIR. To have results land somewhere else, a synced folder for instance, replace output/ with a symlink to it.

System Settings > Login Items will list shrinkit from an unidentified developer. That is your own script rather than a signed application, so there is nothing to sign.

Update and uninstall

./update.sh      # pull and reinstall; settings and recordings are untouched
./uninstall.sh   # remove the agent, the script and the menu entries

Uninstalling leaves your recordings and settings where they are.

License

MIT

About

Shrink and speed up macOS screen recordings with ffmpeg. Drop a .mov into a folder or right-click it, and a much smaller .mp4 comes back, small enough to attach to a pull request or paste into Slack.

Topics

Resources

Stars

23 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages