Skip to main content

How to Extract Frames from Video

Sep 12, 2026 • 8 min read

Three ways to do it — pick the one that fits your workflow. All free, no watermarks, no account needed.

⚡ Quickest: Online Tool (This Site)

  1. Open Video Frame Extractor
  2. Drop your video (MP4, MOV, WebM — up to 2 GB)
  3. Choose FPS (1–60) and format (JPG/WebP/PNG)
  4. Click Extract → Download ZIP

Runs entirely in your browser via WebCodecs. No upload, no server, works offline after first load.

Method 1: Free Online Tool (Recommended)

Step-by-Step

1 Open the Extractor

Go to videotoimagesequence.online/video-frame-extractor. Works in Chrome, Firefox, Edge, Safari.

2 Load Your Video

  • Drag & drop, or click "Choose File"
  • Supported: MP4 (H.264), MOV (H.264), WebM (VP8/VP9)
  • Max: ~2 GB (browser memory limit)
  • HEVC/ProRes? Transcode to H.264 first (see codec guide)

3 Configure Extraction

FPS Presets: 1, 5, 10, 12, 15, 24, 25, 30, 60
Custom FPS: Slider 1–60
Format: JPG (small), WebP (smaller), PNG (lossless)
Quality: JPG 10–100, WebP 10–100

Tip: See FPS decision guide for task-specific recommendations.

4 Extract & Download

  • Click "Extract Frames" — progress bar shows frames processed
  • Frames zip automatically when complete
  • Download ZIP → unzip → frames named frame_000001.jpg

Advanced Features

⏱ Exact Timestamp Extractor

Need frames at specific times? Use Exact Timestamp Extractor — enter timestamps (e.g., 00:01:30.500) and get precise frames.

🎞 Image Sequence Export

For VFX/Blender/After Effects: Video to Image Sequence tool exports numbered sequences with padding (frame_0001, frame_0002...).

🤖 AI Dataset Export

For ML training: Video Frames for AI Datasets — preset FPS by task, auto-train/val/test split structure.

Method 2: FFmpeg (Command Line / Automation)

Best for: batch processing, CI/CD pipelines, servers, large videos, automation.

Basic Extraction

# Extract all frames (matches video FPS) ffmpeg -i input.mp4 frames/frame_%06d.jpg # Extract at specific FPS (e.g., 5 FPS) ffmpeg -i input.mp4 -vf fps=5 frames/frame_%06d.jpg # Extract with custom quality (1=best, 31=worst for JPG) ffmpeg -i input.mp4 -vf fps=5 -q:v 2 frames/frame_%06d.jpg

Format Options

# JPG (default) ffmpeg -i input.mp4 -vf fps=5 -q:v 2 frames/frame_%06d.jpg # PNG (lossless) ffmpeg -i input.mp4 -vf fps=5 frames/frame_%06d.png # WebP (modern, smaller) ffmpeg -i input.mp4 -vf fps=5 -c:v libwebp -quality 90 frames/frame_%06d.webp # BMP / TIFF (rare, lossless) ffmpeg -i input.mp4 -vf fps=5 frames/frame_%06d.bmp

Time Range Extraction

# Start at 1:30, extract 30 seconds at 10 FPS ffmpeg -ss 00:01:30 -t 30 -i input.mp4 -vf fps=10 frames/frame_%06d.jpg # Extract single frame at exact timestamp ffmpeg -ss 00:02:15.500 -i input.mp4 -vframes 1 frame_exact.jpg

Batch Process Multiple Videos

# Windows (PowerShell)
Get-ChildItem *.mp4 | ForEach-Object {'{'}
  $name = $_.BaseName
  ffmpeg -i $_.Name -vf fps=5 "$name/frame_%06d.jpg"
{'}'}

# Linux/macOS (Bash)
for f in *.mp4; do
  name="${f%.*}"
  mkdir -p "$name"
  ffmpeg -i "$f" -vf fps=5 "$name/frame_%06d.jpg"
done

Method 3: Python (OpenCV / MoviePy)

Best for: ML pipelines, data loading, custom preprocessing, integration with training code.

OpenCV (Fast, No Dependencies Beyond opencv-python)

import cv2
import os

def extract_frames_opencv(video_path, output_dir, fps=5, format='jpg', quality=90):
    os.makedirs(output_dir, exist_ok=True)
    cap = cv2.VideoCapture(video_path)
    video_fps = cap.get(cv2.CAP_PROP_FPS)
    frame_interval = int(video_fps / fps)
    
    count = 0
    saved = 0
    while True:
        ret, frame = cap.read()
        if not ret:
            break
        if count % frame_interval == 0:
            name = f"frame_{saved:06d}.{format}"
            if format == 'jpg':
                cv2.imwrite(os.path.join(output_dir, name), frame, [cv2.IMWRITE_JPEG_QUALITY, quality])
            elif format == 'png':
                cv2.imwrite(os.path.join(output_dir, name), frame)
            elif format == 'webp':
                cv2.imwrite(os.path.join(output_dir, name), frame, [cv2.IMWRITE_WEBP_QUALITY, quality])
            saved += 1
        count += 1
    cap.release()
    print(f"Extracted {saved} frames to {output_dir}")

# Usage
extract_frames_opencv('video.mp4', 'frames/', fps=5, format='jpg', quality=90)

MoviePy (Higher Level, Handles More Codecs)

from moviepy.editor import VideoFileClip
import os

def extract_frames_moviepy(video_path, output_dir, fps=5, format='jpg'):
    os.makedirs(output_dir, exist_ok=True)
    clip = VideoFileClip(video_path)
    duration = clip.duration
    
    # Sample at regular intervals
    times = [i / fps for i in range(int(duration * fps) + 1)]
    
    for i, t in enumerate(times):
        if t > duration:
            break
        frame = clip.get_frame(t)
        name = f"frame_{i:06d}.{format}"
        from PIL import Image
        Image.fromarray(frame).save(os.path.join(output_dir, name), quality=90 if format == 'jpg' else None)
    
    clip.close()
    print(f"Extracted {len(times)} frames to {output_dir}")

# Usage
extract_frames_moviepy('video.mp4', 'frames/', fps=5, format='jpg')

Comparison: Which Method to Use?

CriteriaOnline ToolFFmpegPython
SetupZeroInstall oncepip install
Max Video Size~2 GBUnlimitedRAM dependent
Batch/AutomationManualExcellentExcellent
Codecs SupportedH.264, VP8/9AllMost (via FFmpeg)
PrivacyLocal onlyLocal onlyLocal only
Preview/SeekVisualCLI onlyProgrammatic
Best ForOne-offs, quick jobsBatch, servers, CIML pipelines, custom logic

Troubleshooting

❌ "File too large" / Browser crashes

Video exceeds browser memory. Fix: Split video (ffmpeg -i input.mp4 -c copy -segment_time 300 -f segment part_%03d.mp4) or use FFmpeg/Python.

❌ "Codec not supported" (HEVC/ProRes)

Browser can't decode. Fix: Transcode first: ffmpeg -i input.mov -c:v libx264 -crf 18 -preset fast output.mp4

❌ Output frames are black/green/corrupted

Variable frame rate or seek issue. Fix: Force CFR: ffmpeg -i input.mp4 -vsync cfr -c:v libx264 fixed.mp4 then extract.

❌ Wrong number of frames extracted

FPS math mismatch. Fix: Check source FPS: ffprobe -v error -select_streams v -show_entries stream=r_frame_rate -of csv=p=0 input.mp4

❌ ZIP download fails / incomplete

Too many frames for browser ZIP. Fix: Lower FPS, use WebP, or extract in chunks with FFmpeg.

Quick Reference Card

Start Extracting Free →