A smart Bash script that compresses videos to a user-defined target size using ffmpeg, designed for Termux and lightweight environments.
💬 Discord Note: Discord currently allows 20MB uploads for free users. The script defaults to 20MB for safety (targeting ~95% to account for container overhead) but lets you choose another target size interactively at runtime.
Perfect for:
- Discord uploads (20MB free limit — 20MB default)
- Quick file sharing
- Mobile encoding via Termux
- Low-resource Linux systems
- 🎯 User-selectable target output size (default 20MB)
- 🔁 2-pass encoding for accurate size targeting
- 🛡️ 95% safety margin calculation to account for container metadata overhead
- 📊 Real-time progress bar (built with pure Bash to prevent subshell errors)
- 🛠️ Robust
N/Aduration handling and metadata fallbacks - 🧠 Automatic bitrate calculation with minimum bitrate floors
- 🔊 Smart audio/video bitrate allocation (with mute support)
- 📐 Auto resolution detection
- 📉 Auto downscale to 720p if width > 1280px
- ⚡ Uses all available CPU cores (
nprocwith fallback) - 📱 Fully optimized for Termux & minimal systems
- 🧹 Automatic temporary file and isolated pass-log cleanup
You need:
bashffmpegffprobecoreutils(forwc,stat, ornproc, usually preinstalled)
Install in Termux:
pkg update
pkg install ffmpeg coreutils
chmod +x compress20mb.sh
./compress20mb.sh input.mp4 output.mp4
When running, you will be prompted:
Enter target size in MB (default 20 MB):
- Press Enter to keep 20MB
- Type
8,10, or any other number to change target size
Example:
./compress20mb.sh video.mp4 compressed.mp4
- Prompts for target size (default 20MB) and optional audio removal.
- Reads video duration using
ffprobe(falling back to video stream duration if container metadata is missing/N/A). - Calculates total available bits with a 5% safety margin for container overhead.
- Reserves 64 kbps for audio (or 0 kbps if muted).
- Assigns remaining bitrate to video (ensuring a minimum floor of 64 kbps).
- Downscales to 720p if width > 1280px.
- Performs isolated 2-pass encoding:
- Pass 1: analysis pass outputting to isolated process log files.
- Pass 2: final encode with real-time Termux-compatible progress tracking.
- If file exceeds target (verified via exact byte checks):
- Reduces video bitrate by 5%
- Re-encodes automatically
- Cleans up temporary files and pass logs.
Target size (MB) × 8192 × 0.95 = total available kilobits
Total kilobits ÷ duration (seconds) = total bitrate (kbps)
Video bitrate = total bitrate − audio bitrate
══════════════════════════════════════
Duration: 214s
Target: 20MB (Targeting ~95% safety ceiling)
Video Bitrate: 727k
Audio Bitrate: 64k
Threads: 8
Scaling: 720p
Codec: libx264 (2-pass)
══════════════════════════════════════
Progress: [########################## ] 54% (115s/214s)
Done: output.mp4 (18.84MB)
- Output size will never exceed target
- Very long videos will have lower quality (bitrate constrained)
- Very short videos may look very high quality
- Uses all logical CPU cores detected via
nproc - Designed for reliability, Termux compatibility, and failure protection over raw speed
You can change the default prompt value or modify audio/preset options:
# Default prompt value
DEFAULT_TARGET_MB=20
# Change audio bitrate (kbps)
AUDIO_BITRATE=64
# Change x264 preset
-preset fast
2-pass encoding:
- Improves bitrate distribution across variable-complexity scenes
- Ensures accurate file size target matching
- Produces better quality at low bitrates
- Guarantees ≤ TARGET_MB output
This version prioritizes accuracy, reliability, and full Termux compatibility while remaining lightweight.
MIT License — free to use and modify.