DeepShrink
Fit any video or audio under a size limit — one command, local, no watermarks.
deepshrink compresses a video or audio file to a target size in a single command.
Need a clip under Discord's 8 MB limit, an email's 25 MB cap, or a Telegram / WhatsApp
size? Point DeepShrink at the file — it does the bitrate math, runs a two-pass encode,
and lands under the limit. Locally, without uploading to anyone's server, and
without watermarks.
A thin, fast Rust layer over ffmpeg.
Status: released and actively developed (v0.3). Handles video and audio, with target-size and VMAF-quality modes, H.264/H.265/AV1, batch processing, and a "never bigger" guard for already-compact files. Install via Homebrew or crates.io. See the changelog.
If DeepShrink is useful to you, please ⭐ star the repo — it genuinely helps. See Support to chip in.
Why
Everyone hits upload limits — Discord (8 / 25 / 50 MB), email (~25 MB), Telegram, WhatsApp, bug trackers, CI artifacts. The usual options are web converters (upload your file to a stranger's server, watermarks, queues), HandBrake (powerful, but hitting exactly N MB is manual trial and error), or hand-written ffmpeg commands (recompute the bitrate every time). DeepShrink answers the one question directly: make it ≤ N MB, don't make me think.
Install
Homebrew (macOS / Linux) — pulls in ffmpeg for you:
From crates.io (expects ffmpeg on your PATH):
Or download a prebuilt binary from the releases page.
DeepShrink shells out to ffmpeg / ffprobe. The Homebrew formula installs ffmpeg
automatically; other methods expect it on your PATH (brew install ffmpeg, or your
platform's package manager).
Usage
Fit a video under Discord's 8 MB limit:
Target an explicit size, or shrink by a percentage:
Compress audio (podcast, voice memo, music):
Preview the plan without encoding, or batch a whole folder:
Target a perceptual quality instead of a size, or pick a more efficient codec:
Without a size target DeepShrink never makes a file bigger — an already-compact file is kept as-is. To re-encode anyway:
--vmaf searches the encoder's quality setting (CRF) for the smallest output that meets
your target VMAF, and reports the score it achieved. It needs an ffmpeg built with the
libvmaf filter; without it, DeepShrink skips the measurement and encodes at a sensible
default. When a size target is set, --vmaf reports the VMAF actually achieved.
--codec av1 uses SVT-AV1 (falling back to libaom-av1); it needs an ffmpeg built with one
of those encoders, and DeepShrink says so plainly if neither is present. --mono downmixes
the audio to one channel — useful for speech — and applies to a video's audio track as well
as to a pure-audio input.
Metadata — shooting date, location, camera — is carried over so Photos and Finder show
the same place and date as the original, and the result keeps the original's modification
time; pass --strip-metadata to drop it. An iPhone .MOV stays .mov in quality mode
(QuickTime is where Apple's apps read location); size targets and presets produce .mp4.
A video's audio track is never re-encoded above its own bitrate.
HDR (iPhone HLG, HDR10) is kept as shot in quality mode. A size target or platform preset is for sending, so there it becomes 8-bit SDR that every phone, browser and chat app plays.
The original file is never modified — DeepShrink writes a new *.shrink.* file unless
you pass --overwrite.
Platform presets
| Preset | Limit |
|---|---|
discord |
8 MB |
discord-nitro |
500 MB |
email |
20 MB |
telegram |
2 GB |
whatsapp |
16 MB |
Platform limits change over time — verify against the current service.
How it works
ffprobe reads the file's duration and streams. DeepShrink computes the video / audio
bitrate that fits the target (minus container overhead), then runs a two-pass encode
for video, or picks a codec bitrate for audio. If the result overshoots the target, it
corrects once. Run with --dry-run to see the plan first.
--fast (macOS on Apple Silicon only). Encodes video with Apple's hardware encoder:
3–5× faster and far less memory at the same visual quality, for a somewhat larger file.
On Windows, Linux and Intel Macs (and for AV1) it prints a note and encodes in software.
A target is a ceiling, not a quota. When the quality preset alone lands well under the target (predicted from short sample encodes), that's what you get — a 2-second clip for Discord doesn't become 8 MB just because it could.
Never bigger. Without a size target (quality mode) DeepShrink won't hand back a file
that isn't at least 5% smaller: re-encoding an already-compact file only loses quality. Video is
predicted from three short sample encodes first (an already-optimal clip is recognised in
seconds, not after a full encode); audio isn't re-encoded at or above its own bitrate; and
every result is checked at the end. Such files are kept as-is (already compact). Pass
--allow-larger to re-encode anyway.
Update checks
For Homebrew installs, DeepShrink prints a one-line hint when a newer version is
available. It does this without any network call of its own — it asks your local
Homebrew (brew outdated, at most once a day, in a detached background process that never
delays your command). Nothing about your files is ever uploaded. Disable it entirely with
DEEPSHRINK_NO_UPDATE_CHECK=1. (Other install methods rely on cargo install / the
installer as usual.)
Scope
DeepShrink handles video and audio (the ffmpeg engine). Images, PDF, and office files are a planned "universal compressor" path built on pluggable engines. GIFs are handled by a sibling tool, DeepGif.
Support
DeepShrink is free and open-source, built and maintained by one developer.
- ⭐ Star the repo — the cheapest way to help; it boosts visibility so more people find the tool.
- Chip in a tip via the Sponsor button at the top of the repo, or directly through the monobank jar. It supports a Ukrainian developer and keeps the project moving. Thank you 💙💛
Part of DeepLab
DeepShrink is part of DeepLab — a line of tools for developers and product teams.
License
Licensed under either of
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
- Apache License, Version 2.0 (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.