compress

Intelligently reduce video file size using CRF-based compression while maintaining visual quality.

Overview

The compress command uses FFmpeg's Constant Rate Factor (CRF) encoding to reduce video file sizes by 30-70% while preserving visual quality. Unlike fixed bitrate encoding, CRF dynamically allocates more bits to complex scenes and fewer to simple ones, resulting in better quality-to-size ratios.

Key Features:

  • 🎯 Quality presets (low, medium, high, extreme)
  • 📉 Typical file size reduction: 40-60%
  • 🎬 Multiple codec support with optimal settings
  • ⚡ Hardware acceleration for faster encoding
  • 🔄 Automatic optimization for different platforms
  • 📦 Batch compression for entire folders

Common Use Cases:

  • Reducing storage requirements for video archives
  • Preparing videos for web/mobile delivery
  • Email attachments and file sharing
  • Social media uploads within size limits
  • Cloud storage optimization
Info

How CRF Works: CRF (Constant Rate Factor) maintains consistent perceived quality throughout the video. Complex scenes get more bits, simple scenes get fewer. This produces better visual quality than fixed bitrate at smaller file sizes.

Warning

Compression is Lossy: Each compression reduces quality slightly. Never compress already-compressed videos multiple times. Always work from original/high-quality sources.

Usage

Terminal
$ mediaproc video compress <input> [options]

Options

OptionAliasTypeDefaultDescription
--output-ostringAutoOutput file or directory path
--quality-qstringmediumQuality preset: low, medium, high, extreme
--codec-cstringh264Video codec: h264, h265, vp9, av1
--crfnumberAutoCustom CRF value (0-51, lower=better quality)
--presetstringmediumEncoding: ultrafast, fast, medium, slow, veryslow
--bitrate-bstringTarget bitrate (e.g., 2M, 5M)
--min-bitratestringMinimum bitrate (e.g., 1M)
--max-bitratestringMaximum bitrate (e.g., 8M)
--audio-bitratestring128kAudio bitrate (default: 128k)
--audio-codecstringaacAudio codec: aac, mp3, opus
--formatstringmp4Output format: mp4, mkv, webm
--optimize-forstringOptimize for: web, streaming, archive, mobile
--resizestringAlso resize during compression (e.g., 720p, 1080p)
--threadsnumberautoNumber of threads for encoding
--hw-accelbooleanfalseEnable hardware acceleration (GPU)
--strip-metadatabooleanfalseRemove all metadata from output
--two-passbooleanfalseUse two-pass encoding for better quality
--dry-runbooleanfalsePreview without executing
--verbose-vbooleanfalseShow detailed FFmpeg output

Flag Details

--quality - Compression Quality Preset

Quick presets that balance quality, file size, and encoding time.

Preset Comparison:

PresetCRFFile Size ReductionVisual QualityEncoding TimeBest For
low2860-70%AcceptableFastStorage optimization, previews
medium2340-50%HighModerateWeb delivery, general use ← default
high2030-40%Near-losslessSlowProfessional distribution
extreme1820-30%Visually losslessVery slowArchival, masters

Selection Guide:

  • Email/sharing: low (smallest files)
  • YouTube/social media: medium (good balance)
  • Client delivery: high (professional quality)
  • Archive/backup: extreme (preserve maximum quality)

Learn More:


--crf - Custom CRF Value

Override quality presets with a specific CRF (Constant Rate Factor) value.

Range: 0-51

  • 0: Lossless (huge files, rarely used)
  • 15-18: Near-lossless, archival quality
  • 19-23: High quality, imperceptible loss ← recommended range
  • 24-28: Good quality, visible in detailed scenes
  • 29-35: Moderate quality, noticeable compression
  • 36-51: Low quality, significant artifacts

Rule of Thumb:

  • Each +6 CRF ≈ halves file size
  • Each -6 CRF ≈ doubles file size
Tip

Sweet Spot: CRF 20-23 provides excellent quality-to-size ratio for most content. Go lower (18-19) only for critical professional work.


--codec - Video Encoder

CodecCompatibilitySpeedCompressionFile SizeBest For
h264✅ UniversalFastGoodBaselineMaximum compatibility
h265Modern (2016+)SlowExcellent40-50% smaller4K video, storage savings
vp9Web browsersVery slowExcellent40-50% smallerWebM, YouTube
av1Latest (2020+)Extremely slowBest50-60% smallerFuture-proofing

Recommendations:

  • General use: h264 (fast, compatible)
  • 4K/storage: h265 (best compression/speed balance)
  • Web only: vp9 or av1 (if time permits)

Learn More:


--preset - Encoding Speed/Efficiency

Controls encoding time vs file size efficiency (not quality).

Presets: ultrafastsuperfastveryfastfasterfastmediumslowslowerveryslow

PresetSpeedFile SizeQuality at Same CRF
ultrafast10x faster+25% largerSlightly lower
fast2x faster+10% largerMinimal difference
mediumBaselineBaselineBaseline ← default
slow1.5x slower-8% smallerSlightly better
veryslow3x slower-15% smallerBetter

When to Use:

  • Quick compression: fast or faster
  • Balanced: medium (default)
  • Maximum compression: slow or veryslow
  • Time critical: ultrafast (live/streaming)

--bitrate / --min-bitrate / --max-bitrate

Specify target, minimum, and maximum bitrates. Switches from CRF to bitrate-based encoding.

Format: Number + unit (M = Mbps, k = kbps)

  • Examples: 5M (5 Mbps), 2500k (2.5 Mbps)

Constrained Bitrate Example:

mediaproc video compress video.mp4 -b 5M --min-bitrate 3M --max-bitrate 8M

This keeps bitrate between 3-8 Mbps, targeting 5 Mbps average.

When to Use Bitrate:

  • Streaming with bandwidth limits
  • Platform-specific requirements
  • Predictable file sizes needed
Info

CRF vs Bitrate: CRF produces better quality distribution. Use bitrate only when file size predictability is required.


--audio-bitrate - Audio Quality

Set audio compression level (default: 128k).

Recommended Values:

  • 96k - Acceptable for speech, lowest size
  • 128k - Good for general content ← default
  • 192k - High quality, music videos
  • 256k - Excellent, professional audio
  • 320k - Highest quality MP3 equivalent

File Size Impact: Audio typically 5-10% of total file size at default settings.


--audio-codec - Audio Encoder

CodecQualityCompatibilityBest For
aacExcellentUniversalMP4 videos, general use ← default
mp3GoodUniversalBroader compatibility needs
opusBestModern browsersWebM, lowest bitrate for quality

--optimize-for - Platform Optimization

Apply codec and encoding settings optimized for specific platforms.

Available Options:

web - Web streaming

  • H.264 High Profile
  • Optimized for progressive download
  • FastStart enabled (playback while downloading)

streaming - Live/VOD streaming

  • Lower latency settings
  • Balanced quality/bandwidth
  • Suitable for adaptive bitrate

mobile - Mobile devices

  • H.264 Baseline/Main Profile
  • Lower resolution/bitrate consideration
  • Battery-efficient decoding

archive - Long-term storage

  • Maximum quality preservation
  • Metadata retention
  • Future-proof codec selection

--resize - Compress + Resize

Simultaneously compress and resize video (more efficient than separate operations).

Format: Resolution preset or dimensions

  • Presets: 360p, 480p, 720p, 1080p, 1440p, 2160p
  • Custom: 1280x720, 1920x1080

Example:

mediaproc video compress 4k-video.mp4 -q medium --resize 1080p

This downscales from 4K to 1080p while compressing, resulting in much smaller file than 4K compression alone.


--hw-accel - Hardware Acceleration

Enable GPU-accelerated encoding (5-10x faster).

Supported Hardware:

  • NVIDIA GPUs (NVENC)
  • Intel processors (Quick Sync)
  • AMD GPUs (VCE/AMF)
  • Apple Silicon (VideoToolbox)

Trade-offs:

  • ✅ Much faster encoding
  • ⚠️ Slightly lower quality than CPU
  • ⚠️ May have limited codec options

Learn More:


--strip-metadata - Remove Metadata

Removes all metadata (date, location, camera info, copyright) from output.

Use When:

  • Privacy concerns
  • Reducing file size (minimal impact, ~1-5KB)
  • Publishing to public platforms

Preserved: Video/audio streams (not removed) Removed: EXIF, GPS, creation date, software info, copyright, comments


--two-pass - Two-Pass Encoding

Encodes video twice for optimal quality distribution at target bitrate.

How It Works:

  1. First pass: Analyzes complexity, collects statistics
  2. Second pass: Encodes using statistics for optimal bit allocation

When to Use:

  • Target bitrate specified (--bitrate)
  • Maximum quality at specific file size
  • Consistent quality critical

Cost: 2x encoding time (processes video twice)

Learn More:

Low Quality (CRF 28)

  • Use case: Storage optimization, low-bandwidth streaming
  • File size: ~60-70% smaller than source
  • Quality: Acceptable for non-critical content
  • Encoding speed: Fast

Medium Quality (CRF 23)

  • Use case: General distribution, web delivery
  • File size: ~40-50% smaller than source
  • Quality: High quality, minimal artifacts
  • Encoding speed: Moderate (default)

High Quality (CRF 20)

  • Use case: Professional delivery, high-quality streaming
  • File size: ~30-40% smaller than source
  • Quality: Near-lossless quality
  • Encoding speed: Slow

Extreme Quality (CRF 18)

  • Use case: Archival, master copies, cinema-grade
  • File size: ~20-30% smaller than source
  • Quality: Visually lossless
  • Encoding speed: Very slow

Codec Comparison

H.264 (libx264)

  • Compatibility: Universal (all devices)
  • Encoding speed: Fast
  • Compression: Good
  • Best for: General use, broad compatibility

H.265 (libx265)

  • Compatibility: Modern devices (2016+)
  • Encoding speed: Slow (2-3x longer than H.264)
  • Compression: Excellent (50% better than H.264)
  • Best for: 4K video, storage savings

VP9 (libvpx-vp9)

  • Compatibility: Web browsers, YouTube
  • Encoding speed: Very slow
  • Compression: Excellent (similar to H.265)
  • Best for: WebM format, open-source projects

Examples

Basic Compression

Terminal
$ mediaproc video compress video.mp4
Input file: video.mp4
Duration: 00:05:30 • Resolution: 1920x1080
Original size: 450.5 MB
Compressing with CRF 23 (H.264)...
✓ Compression complete
Output file: video_compressed.mp4
New size: 225.3 MB • Saved: 225.2 MB (50.0%)

Specify Output Location

Terminal
$ mediaproc video compress input.mp4 -o output/compressed.mp4
✓ Saved to output/compressed.mp4
Terminal
$ mediaproc video compress input.mp4 -o output/
✓ Saved to output/input_compressed.mp4

Quality Presets

Terminal
$ mediaproc video compress large-video.mp4 -q low
✓ Compressed with CRF 28 • 600 MB → 180 MB (70% reduction)
Terminal
$ mediaproc video compress important-video.mp4 -q high
✓ Compressed with CRF 18 • 450 MB → 315 MB (30% reduction)
Terminal
$ mediaproc video compress video.mp4 -q medium
✓ Compressed with CRF 23 • 450 MB → 225 MB (50% reduction)

Custom CRF Value

Ultra-high quality
$ mediaproc video compress source.mp4 --crf 15
✓ Compressed with CRF 15 (near-lossless)
Balanced quality
$ mediaproc video compress video.mp4 --crf 20
✓ Compressed with CRF 20
Higher compression
$ mediaproc video compress video.mp4 --crf 30
✓ Compressed with CRF 30 (smaller file)

Different Codecs

Terminal
$ mediaproc video compress 4k-video.mp4 -c h265 -q medium
✓ Compressed with H.265 • 1.2 GB → 600 MB (50% smaller than H.264)
Terminal
$ mediaproc video compress video.mp4 -c vp9 -q high
✓ Compressed with VP9 codec
Terminal
$ mediaproc video compress video.mp4 -c h264 -q medium
✓ Compressed with H.264 (maximum compatibility)

Audio Bitrate Control

# Lower audio bitrate for smaller file
mediaproc video compress video.mp4 --audio-bitrate 96k

# High-quality audio
mediaproc video compress music-video.mp4 --audio-bitrate 256k

# Standard quality (default)
mediaproc video compress video.mp4 --audio-bitrate 128k

Dry Run Preview

# Preview settings without processing
mediaproc video compress video.mp4 -q high --dry-run

Output:

[DRY RUN] Would execute: ffmpeg -i video.mp4 -c:v libx264 -crf 18 -c:a aac -b:a 128k video_compressed.mp4 Input: video.mp4 (450.5 MB) Expected quality: High (CRF 18) Codec: H.264

Verbose Output

# See detailed FFmpeg processing
mediaproc video compress video.mp4 -v

Output shows frame-by-frame encoding progress:

frame= 1234 fps=45 q=23.0 size= 12345kB time=00:00:41.13 bitrate=2458.3kbits/s speed=1.5x

Batch Compression

# Compress all MP4 files in directory
for file in *.mp4; do
  mediaproc video compress "$file" -q medium -o compressed/
done

# Compress with different qualities
for file in *.mp4; do
  mediaproc video compress "$file" -q high -o high-quality/
  mediaproc video compress "$file" -q low -o web-optimized/
done

Use Cases

Web Video Optimization

Reduce file size for faster streaming and lower bandwidth:

# Step 1: Compress with medium quality
mediaproc video compress large-video.mp4 -q medium

# Step 2: Further optimize with custom CRF
mediaproc video compress large-video_compressed.mp4 --crf 25 -o web-ready.mp4

Email Attachments

Most email services limit attachment size (10-25 MB):

# Aggressive compression for email
mediaproc video compress video.mp4 -q low --audio-bitrate 64k

# Check output size first with dry-run
mediaproc video compress video.mp4 -q low --dry-run

Storage Space Recovery

Free up disk space by compressing archived videos:

# H.265 provides best compression
mediaproc video compress archive/*.mp4 -c h265 -q medium

# Batch process with size reporting
for file in archive/*.mp4; do
  mediaproc video compress "$file" -c h265 -o compressed/ -v
done

Social Media Uploads

Optimize for Instagram, TikTok, Facebook:

# Instagram stories (small file size)
mediaproc video compress story.mp4 -q low -o story-optimized.mp4

# YouTube upload (high quality)
mediaproc video compress youtube-video.mp4 -q high -c h264

# TikTok (balance quality and size)
mediaproc video compress tiktok.mp4 -q medium --audio-bitrate 128k

4K Video Compression

Reduce massive 4K file sizes:

# H.265 codec recommended for 4K
mediaproc video compress 4k-video.mp4 -c h265 -q high

# More aggressive for streaming
mediaproc video compress 4k-video.mp4 -c h265 -q medium --crf 24

Screen Recordings

Compress screen captures efficiently:

# Screen recordings have low complexity, compress well
mediaproc video compress screen-recording.mp4 -q low

# Tutorial videos with voice
mediaproc video compress tutorial.mp4 -q medium --audio-bitrate 96k

Technical Details

CRF Encoding

Constant Rate Factor (CRF) is a quality-based encoding mode:

  • How it works: Allocates bits based on scene complexity
  • Range: 0 (lossless) to 51 (worst quality)
  • Sweet spot: 18-28 for most content
  • File size: Variable, depends on video complexity

Codec Selection

When to use H.264:

  • Maximum compatibility needed
  • Fast encoding required
  • Target: older devices, TVs, mobile

When to use H.265:

  • 4K or high-resolution video
  • Storage space is priority
  • Modern devices only (2016+)
  • Willing to wait 2-3x encoding time

When to use VP9:

  • Web delivery (HTML5 video)
  • Open-source requirement
  • YouTube optimization
  • WebM container format

Audio Processing

Audio is re-encoded with AAC codec by default:

  • Default bitrate: 128 kbps (good quality)
  • Range: 64k (acceptable) to 256k (excellent)
  • Codec: AAC (universal compatibility)
  • Channels: Preserved from source (stereo/5.1)

Output Format

Output format is automatically determined:

  • H.264: .mp4 container
  • H.265: .mp4 container (HEVC)
  • VP9: .webm container

Performance Considerations

Encoding Speed

Approximate encoding speeds (relative to H.264):

  • H.264: 1x (baseline)
  • H.265: 2-3x slower
  • VP9: 3-5x slower
  • AV1: 10-20x slower (not included)

Hardware Acceleration

FFmpeg can use hardware encoders:

# CPU encoding (default, best quality)
mediaproc video compress video.mp4 -c h264

# For GPU acceleration, use FFmpeg directly:
ffmpeg -hwaccel cuda -i input.mp4 -c:v h264_nvenc output.mp4

Disk Usage

Temporary files are not created. Processing is done in single pass.

Error Handling

Common Errors

FFmpeg not found:

Error: FFmpeg is not installed or not in PATH Install: brew install ffmpeg (macOS) or apt install ffmpeg (Ubuntu)

Invalid CRF value:

Error: CRF must be between 0 and 51 Provided: 55

Insufficient disk space:

Error: Not enough disk space Required: ~200 MB Available: 50 MB

Unsupported codec:

Error: Codec 'h265' not available in your FFmpeg build Available codecs: h264, vp9 Check with: ffmpeg -codecs

Best Practices

  1. Test with samples: Use --dry-run before batch processing
  2. Keep originals: Never overwrite source files
  3. Choose appropriate quality: Medium is good for most use cases
  4. Consider target platform: H.264 for compatibility, H.265 for size
  5. Monitor output size: Check compression ratio makes sense
  6. Use verbose mode: Debug encoding issues with -v
  7. Batch processing: Process multiple files in loops
  8. Verify output: Always check compressed video plays correctly

Troubleshooting

Compression Not Effective

If file size doesn't reduce significantly:

  • Video may already be compressed
  • Try lower CRF value: --crf 28 or --crf 30
  • Switch to H.265: -c h265
  • Check source codec: might already be efficient

Quality Too Low

If compressed video looks bad:

  • Increase quality: -q high
  • Lower CRF value: --crf 20
  • Check source quality (garbage in, garbage out)
  • Use H.265 for better quality at same size

Encoding Too Slow

If processing takes too long:

  • Use H.264 instead of H.265/VP9
  • Reduce quality: -q low
  • Process smaller files first
  • Consider hardware acceleration with FFmpeg directly

Output File Too Large

If compressed file is still too big:

  • Lower CRF: --crf 28 or --crf 30
  • Reduce audio bitrate: --audio-bitrate 64k
  • Consider resizing first: mediaproc video resize input.mp4 --scale 720p
  • Use H.265 codec: -c h265

Advanced Examples

Compare Quality Presets

# Create all three quality versions
mediaproc video compress video.mp4 -q low -o video-low.mp4
mediaproc video compress video.mp4 -q medium -o video-medium.mp4
mediaproc video compress video.mp4 -q high -o video-high.mp4

# Compare file sizes
ls -lh video*.mp4

Archive Compression Pipeline

#!/bin/bash
# Compress all videos in archive directory with H.265

for file in archive/*.mp4; do
  filename=$(basename "$file" .mp4)
  echo "Processing: $filename"

  mediaproc video compress "$file" \
    -c h265 \
    -q medium \
    -o "compressed/$filename.mp4"

  echo "Original: $(du -h "$file" | cut -f1)"
  echo "Compressed: $(du -h "compressed/$filename.mp4" | cut -f1)"
  echo "---"
done

Quality Testing Script

#!/bin/bash
# Test different CRF values to find optimal quality

input="test-video.mp4"

for crf in 18 20 23 25 28; do
  output="test-crf-$crf.mp4"
  mediaproc video compress "$input" --crf $crf -o "$output"
  size=$(du -h "$output" | cut -f1)
  echo "CRF $crf: $size"
done
  • transcode - Convert between formats and codecs
  • resize - Change video resolution before compressing
  • trim - Remove unwanted sections to reduce size
  • extract-audio - Extract audio for separate compression

See Also

Found an issue? Help us improve this page.

Edit on GitHub →