Extract Frames from Video Using API: Developer Guide 2026
Photo by Denise Jans on Unsplash
Tutorial16 min read

Extract Frames from Video Using API: Developer Guide 2026

Complete guide to extracting images and frames from videos using a simple API. Learn frame extraction techniques, thumbnail generation, and best practices.

By Eranol Team
#extract images#frame extraction#video frames#thumbnail generation#api tutorial

Extracting frames from videos is essential for creating thumbnails, analyzing content, and generating image sequences. This comprehensive guide shows you how to extract images from videos using a simple API, with support for various formats and extraction patterns.

Why Extract Images from Video?

Common Use Cases

Use CaseDescriptionOutput
ThumbnailsVideo preview imagesSingle frame (JPG)
StoryboardsVisual content overviewMultiple frames
AnalysisContent detectionFrame sequence
AnimationCreate image sequencesAll frames
PreviewsHover previewsKey frames

Benefits

  • Better UX: Show video content before playback
  • SEO: Image search optimization
  • Analytics: Visual content analysis
  • Archival: Preserve key moments
  • Editing: Extract specific frames for editing

API Integration Guide

Step 1: Extract Single Frame

javascript
const extractFrame = async (videoUrl, timestamp) => { try { const response = await fetch('https://eranol.com/api/v1/extract/images', { method: 'POST', headers: { 'x-api-key': process.env.ERANOL_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ input_url: videoUrl, timestamp: timestamp, format: 'jpg' }) }); if (!response.ok) { throw new Error(`API Error: ${response.statusText}`); } const result = await response.json(); return result; } catch (error) { console.error('Frame extraction failed:', error); throw error; } }; // Extract frame at 5 seconds const job = await extractFrame('https://example.com/video.mp4', 5);

Step 2: Extract Multiple Frames

javascript
const extractMultipleFrames = async (videoUrl, timestamps) => { const response = await fetch('https://eranol.com/api/v1/extract/images', { method: 'POST', headers: { 'x-api-key': process.env.ERANOL_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ input_url: videoUrl, timestamps: timestamps, format: 'jpg', quality: 'high' }) }); return await response.json(); }; // Extract frames at specific times const job = await extractMultipleFrames(videoUrl, [1, 5, 10, 15, 20]);

Step 3: Extract at Intervals

javascript
const extractAtIntervals = async (videoUrl, interval = 1) => { const response = await fetch('https://eranol.com/api/v1/extract/images', { method: 'POST', headers: { 'x-api-key': process.env.ERANOL_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ input_url: videoUrl, interval: interval, // Extract every N seconds format: 'jpg' }) }); return await response.json(); }; // Extract frame every 2 seconds const job = await extractAtIntervals(videoUrl, 2);

Step 4: Extract All Frames

javascript
const extractAllFrames = async (videoUrl, fps = null) => { const response = await fetch('https://eranol.com/api/v1/extract/images', { method: 'POST', headers: { 'x-api-key': process.env.ERANOL_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ input_url: videoUrl, extract_all: true, fps: fps, // Optional: limit frame rate format: 'jpg' }) }); return await response.json(); }; // Extract all frames at 10 FPS const job = await extractAllFrames(videoUrl, 10);

Extraction Patterns

1. Thumbnail Generation

javascript
const generateThumbnail = async (videoUrl, options = {}) => { const response = await fetch('https://eranol.com/api/v1/extract/images', { method: 'POST', headers: { 'x-api-key': process.env.ERANOL_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ input_url: videoUrl, timestamp: options.timestamp || 'auto', // Auto-detect best frame width: options.width || 1280, height: options.height || 720, format: 'jpg', quality: 'high' }) }); return await response.json(); }; // Generate thumbnail with auto-detection const thumbnail = await generateThumbnail(videoUrl);

2. Storyboard Creation

javascript
const createStoryboard = async (videoUrl, frameCount = 9) => { const response = await fetch('https://eranol.com/api/v1/extract/images', { method: 'POST', headers: { 'x-api-key': process.env.ERANOL_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ input_url: videoUrl, frame_count: frameCount, distribute: 'evenly', // Distribute evenly across video width: 320, height: 180, format: 'jpg', create_grid: true, // Combine into single image grid_columns: 3 }) }); return await response.json(); }; // Create 3x3 storyboard const storyboard = await createStoryboard(videoUrl, 9);

3. Hover Preview Frames

javascript
const generateHoverPreviews = async (videoUrl, previewCount = 10) => { const response = await fetch('https://eranol.com/api/v1/extract/images', { method: 'POST', headers: { 'x-api-key': process.env.ERANOL_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ input_url: videoUrl, frame_count: previewCount, distribute: 'evenly', width: 640, height: 360, format: 'jpg', quality: 'medium' }) }); return await response.json(); }; // Generate 10 preview frames const previews = await generateHoverPreviews(videoUrl, 10);

Format and Quality Options

Image Format Comparison

FormatQualityFile SizeUse Case
JPGGoodSmallThumbnails, web
PNGExcellentLargeTransparency needed
WebPExcellentSmallModern browsers

Quality Settings

javascript
const qualityPresets = { thumbnail: { width: 320, height: 180, format: 'jpg', quality: 'medium' }, preview: { width: 640, height: 360, format: 'jpg', quality: 'high' }, fullsize: { width: 1920, height: 1080, format: 'jpg', quality: 'high' }, transparent: { width: 1280, height: 720, format: 'png', quality: 'high' } }; const extractWithPreset = async (videoUrl, preset, timestamp) => { const settings = qualityPresets[preset]; const response = await fetch('https://eranol.com/api/v1/extract/images', { method: 'POST', headers: { 'x-api-key': process.env.ERANOL_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ input_url: videoUrl, timestamp: timestamp, ...settings }) }); return await response.json(); }; // Extract preview-quality frame const preview = await extractWithPreset(videoUrl, 'preview', 10);

Best Practices

1. Smart Thumbnail Selection

javascript
const generateSmartThumbnail = async (videoUrl) => { const response = await fetch('https://eranol.com/api/v1/extract/images', { method: 'POST', headers: { 'x-api-key': process.env.ERANOL_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ input_url: videoUrl, timestamp: 'auto', // AI-powered best frame detection avoid_black_frames: true, avoid_blurry_frames: true, width: 1280, height: 720 }) }); return await response.json(); };

2. Batch Frame Extraction

javascript
const batchExtractFrames = async (videos) => { const jobs = await Promise.all( videos.map(video => extractFrame(video.url, video.timestamp)) ); const results = await Promise.all( jobs.map(job => waitForCompletion(job.job_id)) ); return results; }; // Extract thumbnails from multiple videos const videos = [ { url: 'https://example.com/video1.mp4', timestamp: 5 }, { url: 'https://example.com/video2.mp4', timestamp: 10 }, { url: 'https://example.com/video3.mp4', timestamp: 3 } ]; const thumbnails = await batchExtractFrames(videos);

3. Optimize for Web

javascript
const extractWebOptimized = async (videoUrl, timestamp) => { const response = await fetch('https://eranol.com/api/v1/extract/images', { method: 'POST', headers: { 'x-api-key': process.env.ERANOL_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ input_url: videoUrl, timestamp: timestamp, format: 'webp', width: 1280, height: 720, quality: 'medium', optimize: true }) }); return await response.json(); };

Real-World Implementation

javascript
class FrameExtractor { constructor(apiKey) { this.apiKey = apiKey; this.baseUrl = 'https://eranol.com/api/v1'; } async extractFrame(videoUrl, timestamp, options = {}) { const defaultOptions = { format: 'jpg', width: 1280, height: 720, quality: 'high' }; const finalOptions = { ...defaultOptions, ...options }; const response = await fetch(`${this.baseUrl}/extract/images`, { method: 'POST', headers: { 'x-api-key': this.apiKey, 'Content-Type': 'application/json' }, body: JSON.stringify({ input_url: videoUrl, timestamp: timestamp, ...finalOptions }) }); if (!response.ok) { throw new Error(`API Error: ${response.statusText}`); } const job = await response.json(); return await this.waitForCompletion(job.job_id); } async extractMultiple(videoUrl, timestamps, options = {}) { const frames = await Promise.all( timestamps.map(ts => this.extractFrame(videoUrl, ts, options)) ); return frames; } async waitForCompletion(jobId) { const maxAttempts = 60; for (let i = 0; i < maxAttempts; i++) { const response = await fetch(`${this.baseUrl}/status/${jobId}`, { headers: { 'x-api-key': this.apiKey } }); const status = await response.json(); if (status.state === 'completed') { return status.output_url; } else if (status.state === 'failed') { throw new Error(`Extraction failed: ${status.error}`); } await this.sleep(3000); } throw new Error('Extraction timeout'); } sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } } // Usage const extractor = new FrameExtractor(process.env.ERANOL_API_KEY); // Extract single frame const thumbnail = await extractor.extractFrame('https://example.com/video.mp4', 5); // Extract multiple frames const frames = await extractor.extractMultiple('https://example.com/video.mp4', [1, 5, 10, 15]); console.log('Frames extracted:', frames);

Cost Optimization

Extraction Cost

TypeCostUse Case
Single frame$0.02Thumbnails
10 frames$0.05Storyboards
100 frames$0.20Analysis
All frames (30fps, 1min)$1.00Animation

Troubleshooting

Issue 1: Black Frames

Solution:

javascript
const job = await extractFrame(videoUrl, timestamp, { avoid_black_frames: true, fallback_offset: 1 // Try 1 second later if black });

Issue 2: Blurry Frames

Solution:

javascript
const job = await extractFrame(videoUrl, 'auto', { avoid_blurry_frames: true, quality_threshold: 0.8 });

Conclusion

Extracting frames from videos using an API is simple and powerful:

Flexible extraction - Single frames or sequences ✅ Smart detection - Auto-select best frames ✅ Multiple formats - JPG, PNG, WebP ✅ Batch processing - Extract from multiple videos ✅ Cost-effective - Pay per extraction

Ready to extract frames? Try Eranol's Frame Extraction API with $1 free credit.


Related Articles:

Ready to try FFmpeg API?

Get $1 free credit and start processing videos today.

Get Started Free →