Skip to content

How to reduce a video’s size in Python without noticeably losing quality

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

CodecCRFSizeQualityEncode Speed
H.265 (libx265)26–28Best compressionVery goodSlow
H.264 (libx264)22–24MediumGoodFast
AV1 (libaom-av1)30–36SmallestExcellentVery 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.

See also  Using pipelines in Python/R to improve coding efficiency & readability

Here’s how to fix it:


Step 1: Install FFmpeg (if not already)

  1. Go to FFmpeg Download.
  2. Download the static build for Windows.
  3. Extract it somewhere, e.g., C:\ffmpeg.

Inside that folder, there should be a bin\ffmpeg.exe.


Step 2: Add FFmpeg to Windows PATH

  1. Press Win + S → type Environment VariablesEdit the system environment variables.
  2. Click Environment Variables → under “System variables”, select Path → Edit → Add: C:\ffmpeg\bin
  3. 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 _compressed if 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.exe path without modifying PATH.
See also  How to apply a function to a matrix in numpy efficiently

Leave a Reply

error: Content is protected !!