You can reduce a video’s size in Python without noticeably losing quality by using efficient codecs, lower bitrates, or slight resolution/frame rate adjustments — typically through FFmpeg, which can be called from Python.
Below are the recommended methods and Python examples.
✅ Best Methods to Reduce Video Size With Minimal Quality Loss
1. Re-encode with a more efficient codec (H.265 / HEVC or AV1)
- H.265 is ~40–50% smaller than H.264 at the same visual quality
- AV1 is even better, but encoding is slower
2. Use CRF (Constant Rate Factor)
CRF controls quality.
Lower = better quality.
Recommended:
- H.264: CRF 18–23
- H.265: CRF 20–28
3. Reduce bitrate or scale resolution slightly
Scaling from 1080p → 720p cuts size by ~50%.
🟦 Install FFmpeg
You need FFmpeg installed on your system:
Ubuntu/Debian
sudo apt install ffmpeg
Mac
brew install ffmpeg
Windows
Install from ffmpeg.org and add to PATH.
🟩 Option 1: Using Python + subprocess (recommended)
✔ Re-encode with H.265 (best size reduction)
import subprocess
input_video = "input.mp4"
output_video = "output_compressed.mp4"
cmd = [
"ffmpeg",
"-i", input_video,
"-vcodec", "libx265",
"-crf", "28",
"-preset", "medium",
"-acodec", "aac"
]
subprocess.run(cmd)
- libx265 = H.265 codec
- crf=28 → good compression, small size
- Lower CRF (e.g., 22) → better quality, larger file
- preset controls speed (slower = better compression)
🟩 Option 2: Compress video using H.264 (faster)
import subprocess
cmd = [
"ffmpeg",
"-i", "input.mp4",
"-vcodec", "libx264",
"-crf", "23",
"-preset", "medium",
"-acodec", "aac"
]
subprocess.run(cmd)
🟩 Option 3: Reduce Resolution (scaling)
import subprocess
cmd = [
"ffmpeg",
"-i", "input.mp4",
"-vf", "scale=1280:-1", # 720p
"-vcodec", "libx264",
"-crf", "20",
"-preset", "medium",
"output_720p.mp4"
]
subprocess.run(cmd)
🟩 Option 4: Reduce Bitrate
import subprocess
cmd = [
"ffmpeg",
"-i", "input.mp4",
"-b:v", "1500k", # target bitrate
"-b:a", "128k",
"output_bitrate.mp4"
]
subprocess.run(cmd)
⭐ Recommended Settings for Best Quality-to-Size Ratio
| Codec | CRF | Size | Quality | Encode Speed |
|---|---|---|---|---|
| H.265 (libx265) | 26–28 | Best compression | Very good | Slow |
| H.264 (libx264) | 22–24 | Medium | Good | Fast |
| AV1 (libaom-av1) | 30–36 | Smallest | Excellent | Very slow |
FFMPEG Error Handling
That error is very common on Windows: it means Python cannot find ffmpeg in your system PATH. subprocess.run is trying to run the ffmpeg command, but Windows doesn’t know where it is.
Here’s how to fix it:
Step 1: Install FFmpeg (if not already)
- Go to FFmpeg Download.
- Download the static build for Windows.
- Extract it somewhere, e.g.,
C:\ffmpeg.
Inside that folder, there should be a bin\ffmpeg.exe.
Step 2: Add FFmpeg to Windows PATH
- Press
Win + S→ typeEnvironment Variables→ Edit the system environment variables. - Click Environment Variables → under “System variables”, select Path → Edit → Add:
C:\ffmpeg\bin - Click OK and restart your terminal/IDE.
Step 3: Test FFmpeg
Open Command Prompt or Anaconda Prompt:
ffmpeg -version
You should see FFmpeg version info.
Step 4: Run Python script again
import subprocess
cmd = [
"ffmpeg",
"-i", "input.mp4",
"-vcodec", "libx264",
"-crf", "23",
"-preset", "medium",
"-acodec", "aac",
"output.mp4"
]
subprocess.run(cmd)
✅ It should work now.
Another alternative: update the script to provide the path to ffmpeg.exe
Here’s a ready-to-use Python function for Windows that compresses a video using FFmpeg. It works even if FFmpeg is not in your PATH — you just need to provide the path to ffmpeg.exe.
import subprocess
import os
def compress_video(input_path, output_path=None, ffmpeg_path=None, codec="libx264", crf=23, preset="medium"):
"""
Compress a video using FFmpeg.
Parameters:
- input_path: str, path to the input video
- output_path: str, path to save the compressed video (default: adds '_compressed' suffix)
- ffmpeg_path: str, full path to ffmpeg.exe (optional if FFmpeg is in PATH)
- codec: str, video codec ('libx264' or 'libx265')
- crf: int, quality factor (lower = better quality)
- preset: str, encoding speed preset ('ultrafast', 'superfast', 'fast', 'medium', 'slow', 'veryslow')
"""
if not os.path.isfile(input_path):
raise FileNotFoundError(f"Input file not found: {input_path}")
if output_path is None:
base, ext = os.path.splitext(input_path)
output_path = f"{base}_compressed{ext}"
ffmpeg_cmd = ffmpeg_path or "ffmpeg" # use full path if provided, else assume in PATH
cmd = [
ffmpeg_cmd,
"-i", input_path,
"-vcodec", codec,
"-crf", str(crf),
"-preset", preset,
"-acodec", "aac",
output_path
]
try:
subprocess.run(cmd, check=True)
print(f"Video compressed successfully!\nSaved as: {output_path}")
except subprocess.CalledProcessError as e:
print("Error compressing video:", e)
# -------------------------
# Example usage:
input_video = r"C:\Users\YourUser\Videos\example.mp4"
ffmpeg_exe = r"C:\ffmpeg\bin\ffmpeg.exe" # replace with your path to ffmpeg.exe
compress_video(input_video, ffmpeg_path=ffmpeg_exe, codec="libx265", crf=28)
✅ Features:
- Automatically adds
_compressedif no output filename is given. - Works with both H.264 (
libx264) and H.265 (libx265) codecs. - Allows specifying CRF and preset for quality vs speed.
- Safe for Windows — can use full
ffmpeg.exepath without modifying PATH.