To generate a video thumbnail in React, load the video in an HTML <video> element, seek to the time you want, wait until that frame is available, and copy it to a canvas with drawImage(). Export the canvas as an image Blob and display it with an object URL. The key details are waiting for the seek to finish and, for cross-origin video, getting permission from the video host to export the frame.
How the browser turns a video frame into a thumbnail
An HTML video element exposes its current decoded frame to a canvas. The basic sequence is: load metadata, choose a valid time, seek, wait for the new frame, draw it to a 2D canvas, then export the canvas. MDN documents video elements as canvas image sources and describes seeking before drawing: drawImage() and Using images.
Do not draw immediately after assigning video.currentTime. Seeking is asynchronous: the browser may not have decoded the requested frame yet. Also confirm the video has nonzero intrinsic dimensions (videoWidth and videoHeight) before sizing the canvas. A video frame is available for drawing when media readiness has advanced beyond metadata-only loading; MDN notes the current frame data is available after seeking when readyState is greater than 1.
A React component for a video URL or uploaded file
This component accepts a video URL and a time in seconds. It creates a temporary video element, captures one frame, and renders the resulting PNG. When src changes, the prior operation is cancelled and its object URL is released so an older, slower load cannot replace the new thumbnail.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →#1 Best Overall
- 【17.3" FHD IMMERSIVE DISPLAY】 This hp 17 inch laptop features a stunning 17.3-inch Full HD (1920 x 1080) Anti-Glare screen. The narrow-bezel design and high-definition resolution provide an expansive, crystal-clear viewing area, perfect for video editing, detailed spreadsheets and professional video conferencing.
- 【ULTRA RYZEN 5 PERFORMANCE】 Powered by the AMD Ryzen 5 7520U processor (4 Cores, 8 Threads, Up to 4.3GHz), this hp 17 laptop delivers high-efficiency multitasking that beats i7-1165G7 in multi-core benchmarks. Best laptop for video editing. Ideal for 2026 AI-enhanced office workflows, student productivity, and seamless streaming.
- 【ELITE MEMORY & STORAGE】 Configured with up to high-speed LPDDR5 RAM and PCIe NVMe M.2 SSD for rapid boot-ups and massive data access. This hp 17 ensures zero-lag performance even when running multiple browser tabs and memory-intensive professional applications simultaneously.
- 【WINDOWS 11 PRO & HARDWARE SUPPORT】 This hp 17.3 laptop runs on Windows 11 Pro, delivering enterprise-level security, while the integrated 720p privacy camera features a physical shutter for secure video conferencing. Stay connected with ultra-fast Wi-Fi 6 and Bluetooth 5.3, and power through your day with up to 9 hours of battery life. The laptop 17 with a full-size keyboard with a numeric keypad makes this hp 17” laptop a ready-to-deploy solution for business users requiring reliability, security, and sustained performance.
- 【CONNECTIVITY & CONTROL】 Equipped with Wi-Fi 6, Bluetooth, USB Type-C, and HDMI for ultimate peripheral support. As a complete video editing laptop solution includes mouse and tablet stand to protect your device and streamline your mobile workstation setup.
import { useEffect, useState } from "react";
function captureFrame(video, time, signal) {
return new Promise((resolve, reject) => {
const cleanup = () => {
video.removeEventListener("seeked", onSeeked);
video.removeEventListener("error", onError);
signal.removeEventListener("abort", onAbort);
};
const fail = (message) => {
cleanup();
reject(new Error(message));
};
const onAbort = () => fail("Capture cancelled");
const onError = () => fail("The video could not be loaded or decoded");
const onSeeked = () => {
if (signal.aborted) return onAbort();
if (video.readyState < 2 || !video.videoWidth || !video.videoHeight) {
return fail("The requested video frame is not ready");
}
const canvas = document.createElement("canvas");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
const context = canvas.getContext("2d");
if (!context) return fail("Could not create a 2D canvas context");
try {
context.drawImage(video, 0, 0, canvas.width, canvas.height);
canvas.toBlob((blob) => {
cleanup();
if (signal.aborted) return reject(new Error("Capture cancelled"));
if (!blob) return reject(new Error("The browser could not export the image"));
resolve(blob);
}, "image/png");
} catch (error) {
cleanup();
reject(error);
}
};
video.addEventListener("seeked", onSeeked);
video.addEventListener("error", onError);
signal.addEventListener("abort", onAbort, { once: true });
if (signal.aborted) return onAbort();
if (!Number.isFinite(time) || time < 0 || time >= video.duration) {
return fail(`Choose a time from 0 up to (but not including) ${video.duration} seconds`);
}
video.currentTime = time;
});
}
export function VideoThumbnail({ src, time = 1, crossOrigin }) {
const [imageUrl, setImageUrl] = useState("");
const [error, setError] = useState("");
useEffect(() => {
if (!src) {
setImageUrl("");
setError("Choose a video source");
return;
}
const controller = new AbortController();
let createdUrl = "";
setImageUrl("");
setError("");
const video = document.createElement("video");
video.preload = "auto";
video.muted = true;
video.playsInline = true;
// Set before src so the request uses the selected CORS mode.
if (crossOrigin) video.crossOrigin = crossOrigin;
const onMetadata = async () => {
try {
const blob = await captureFrame(video, time, controller.signal);
if (controller.signal.aborted) return;
createdUrl = URL.createObjectURL(blob);
setImageUrl(createdUrl);
} catch (err) {
if (!controller.signal.aborted) setError(err.message || "Thumbnail capture failed");
}
};
const onError = () => setError("The video could not be loaded. Check its URL, format, and access permissions.");
video.addEventListener("loadedmetadata", onMetadata, { once: true });
video.addEventListener("error", onError, { once: true });
video.src = src;
video.load();
return () => {
controller.abort();
video.removeEventListener("loadedmetadata", onMetadata);
video.removeEventListener("error", onError);
video.pause();
video.removeAttribute("src");
video.load();
if (createdUrl) URL.revokeObjectURL(createdUrl);
};
}, [src, time, crossOrigin]);
if (error) return <p role="alert">{error}</p>;
return imageUrl
? <img src={imageUrl} alt="Video thumbnail" />
: <p aria-live="polite">Generating thumbnail…</p>;
}
Use it with a same-origin URL like <VideoThumbnail src="/media/demo.mp4" time={2.5} />. For a file input, create a local object URL and pass it as src:
const fileUrl = URL.createObjectURL(file);
setVideoSrc(fileUrl);
Revoke that input URL when the selected file changes or the owning component unmounts: call URL.revokeObjectURL(fileUrl). The thumbnail component separately revokes the object URL it creates for the PNG.
Rank #2
- SUPERCHARGED BY M5 — The 14-inch MacBook Pro with M5 brings next-generation speed and powerful on-device AI to personal, professional, and creative tasks. Featuring all-day battery life and a breathtaking Liquid Retina XDR display with up to 1600 nits peak brightness, it’s pro in every way.*
- HAPPILY EVER FASTER — Along with its faster CPU and unified memory, M5 features a more powerful GPU with a Neural Accelerator built into each core, delivering faster AI performance. So you can blaze through demanding workloads at mind-bending speeds.
- BUILT FOR APPLE INTELLIGENCE — Apple Intelligence is the personal intelligence system that helps you write, express yourself, and get things done effortlessly. With groundbreaking privacy protections, it gives you peace of mind that no one else can access your data — not even Apple.*
- ALL-DAY BATTERY LIFE — MacBook Pro delivers the same exceptional performance whether it’s running on battery or plugged in.
- APPS FLY WITH APPLE SILICON — All your favorites, including Microsoft 365 and Adobe Creative Cloud, run lightning fast in macOS.*
Important implementation choices
- Capture time: The example requires
0 <= time < duration. A timestamp at or beyond the duration is invalid; use an earlier time if you want a frame near the end. - Output dimensions: The example uses intrinsic video dimensions for a full-resolution frame. To make a smaller thumbnail, calculate a scale factor from the intrinsic width and height, set proportionally smaller canvas dimensions, and draw into those dimensions. Avoid setting width and height to zero.
- Image format: The example exports PNG with
toBlob(). You can request another supported image type, such as JPEG or WebP, and pass a quality value where the format supports it. Check the returned Blob type if your app depends on a particular encoder. - React lifecycle: Each source or time change starts a distinct operation. The effect cleanup aborts the old work and releases generated URLs. If you add retries, timers, or more event listeners, clean those up in the same effect.
Using the component with a cross-origin video
For a same-origin video, the browser can generally export the captured canvas directly. For a video hosted on another origin, the video request must use a CORS mode and the server must authorize your page’s origin with an Access-Control-Allow-Origin response header. Setting crossOrigin in React is not enough if the host does not grant permission. Without approval, drawing may taint the canvas, and exporting pixels with toBlob() or toDataURL() can fail with a security error. See MDN’s guidance on cross-origin canvas sources and the crossorigin attribute.
For a CORS-enabled host, render with <VideoThumbnail src="https://media.example/video.mp4" crossOrigin="anonymous" time={4} />. The component assigns the property before setting src, which matters because the request mode must be chosen before loading begins. The server still needs to send an authorization header appropriate to your page. If the host does not provide that access, use a same-origin copy or ask the host to configure CORS; client-side code cannot bypass the browser’s restriction.
Rank #3
- BUILT FOR COLLEGE. AND BEYOND — MacBook Air with the M5 chip packs blazing speed and powerful AI capabilities into an incredibly portable design. And with up to 18 hours of battery life,* this thin and light powerhouse is ready to take on almost any major, just about anywhere.
- TEAR THROUGH TOUGH ASSIGNMENTS — With its faster CPU and unified memory, the M5 chip delivers even more performance and fluidity across apps, making multitasking and creative workflows smooth and responsive. A powerful Neural Engine and next-generation GPU with Neural Accelerators give you a powerful platform for AI.
- MAKE QUICK WORK OF YOUR TO-DO LIST — Apple Intelligence helps you write, express yourself, and get things done effortlessly — whether it’s for school or everyday life. With groundbreaking privacy protections, it gives you peace of mind that no one else can access your data — not even Apple.*
- UP TO 18 HOURS OF BATTERY LIFE — MacBook Air delivers incredible battery life with amazing performance, so you can power through a full day of classes without worrying about plugging in.
- A BRILLIANT 13.6-INCH DISPLAY* — The gorgeous Liquid Retina display on MacBook Air supports 1 billion colors, making photos and videos pop with rich contrast and sharp detail, and text appears supercrisp. So everything — from class presentations to movies to games — looks truly stunning.
When a frame callback is useful
For a single thumbnail, the seeked event is the simpler trigger. If you are analyzing many frames, building a moving preview, or need work synchronized with frames presented to the compositor, requestVideoFrameCallback() can be useful. Feature-detect it because MDN marks it Baseline 2024 but warns older devices or browsers may lack support: requestVideoFrameCallback(). It is not necessary to add this API to a one-frame capture.
Troubleshooting React video thumbnails
- The thumbnail is blank or from the wrong moment: Do not draw on the same line as the
currentTimeassignment. Wait forseeked, then verifyreadyState > 1and nonzerovideoWidth/videoHeight. - Canvas export throws a security error: The source is likely cross-origin without server authorization. Set
crossOrigin="anonymous"before the source loads and confirm the media server returns a suitableAccess-Control-Allow-Originheader. - No frame appears and dimensions are zero: Wait for
loadedmetadatabefore validating the duration or seeking. Check the browser network panel for a failed request and confirm the URL is accessible to the page. - The chosen timestamp fails: Compare it with
video.duration; it must be finite and less than the duration. Some media can have unknown duration while loading, another reason not to seek before metadata arrives. - The video loads but cannot be decoded: Browser support for media formats varies. Provide a format supported by the browsers you target, and test the actual source file rather than assuming every browser can decode it. MDN’s video element reference covers video sources and browser playback.
- Canvas context or image Blob is missing: Confirm the canvas dimensions are positive, the browser can provide a 2D context, and the export callback returns a Blob. Surface these errors in the UI rather than leaving a permanent loading state.
- An old thumbnail replaces a new one: Tie each capture to the source and timestamp as in the effect above. Abort or ignore prior work and revoke the old URL when dependencies change.
Performance and reliability considerations
Loading a video far enough to decode a frame costs more than displaying an existing poster image. If a thumbnail already exists on your server, using that image avoids fetching and decoding the video in the browser. For client-side generation, capture only when needed—such as after file selection or a user request—rather than rerunning on unrelated renders. Keep the canvas at the intended output size instead of exporting a huge frame when the interface needs only a small preview.
Rank #4
- 【Ryzen 5 6600H for Demanding Daily Performance】AMD Ryzen 5 6600H processor features 6 cores, 12 threads, and boost speeds up to 4.5GHz, delivering stronger performance for office multitasking, coding, content handling, and sustained daily workloads. Compared with many common thin-and-light Intel Ryzen 5 7430U, Core i3-1315U, Core i5-1334U, AMD Ryzen 5 7520U, and Ryzen 7 5825U configurations, it is a better fit for users who need more performance headroom.
- 【Radeon 660M Graphics】AMD Radeon 660M integrated graphics with RDNA 2 architecture supports everyday visual work, smooth media playback, light photo editing, and casual gaming needs like LoL or CS2 at 1080p settings. It is a balanced fit for students, remote workers, and entry-level creators who want capable graphics without the extra heat and power draw of a dedicated GPU.
- 【16GB RAM & 512GB SSD with Upgrade Room】16GB DDR5 memory and a 512GB PCIe SSD deliver smooth out-of-the-box performance for multitasking, large file handling, and daily storage needs. With dual SO-DIMM slots and an M.2 2280 design, the system still leaves room to upgrade up to 64GB RAM and up to 4TB SSD as your needs continue to grow.
- 【2 Year Warranty Support】Includes a 2-year manufacturer warranty and a 90-day hassle-free return window, with final assembly in the United States and after-sales replacement handled in the United States under this listing workflow. That added service clarity gives students, professionals, and home users more confidence when choosing a laptop for long-term daily use.
- 【53.58Wh Battery and 100W PD】A 53.58Wh smart battery paired with a separate 100W PD charger gives this laptop more flexibility for campus study, coffee shop work, and moving between rooms at home. The USB-C setup also supports convenient power and display connectivity, helping reduce the hassle of slow charging and frequent outlet hunting during a busy day.
The example loads metadata and seeks within the browser; it does not guarantee every remote video can be fetched, decoded, or exported. Network failures, unsupported codecs, access restrictions, and CORS policy can all prevent capture. Present a fallback state or allow the user to retry after correcting the source. For repeated captures from one video, keep the loaded video available and serialize seeks rather than creating many concurrent decoders.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
ScreenshotNeo takes website screenshots; it is not a replacement for extracting a frame from a video file or URL. Use the browser-and-canvas method above when your output must be a particular video frame. If you instead need an image of a webpage that contains a video player, ScreenshotNeo can capture that webpage with one API request. It removes cookie banners, popups, and chat widgets before the shot; bot checks, blank pages, and failed loads are never billed; it also provides an MCP server for AI agents using Claude, Cursor, or another MCP client. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000. Details and parameters are in the ScreenshotNeo documentation.
Free tools Windows power users keep installed
One-click scans. No signup required.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See ScreenshotNeo for the service, or sign up free for 1,000 screenshots a month with no card.
Best Value
- 🚀 RESPONSIVE INTEL CORE 3 100U PROCESSOR: Powered by the Intel Core 3 100U (6 cores, up to 4.7GHz) with integrated Intel UHD Graphics, this Dell laptop handles everyday productivity, browsing, and multitasking with smooth, dependable performance. Windows 11 Home keeps you ready to work, learn, and stay connected right out of the box, making this an ideal everyday computing companion for home or office use.
- ⚡ SMOOTH 8GB DDR5 MEMORY & FAST 256GB NVME SSD: 16GB DDR5 memory keeps multitasking fluid across everyday apps and browser tabs, while the 256GB M.2 PCIe NVMe SSD delivers fast boot times and ample storage for documents, photos, and files. An SD card slot adds convenient options for transferring media directly from cameras or other devices.
- 🎨 SMOOTH 15.6" FHD DISPLAY WITH 120HZ REFRESH RATE: Enjoy a 15.6-inch Full HD (1920x1080) IPS anti-glare display with 120Hz refresh rate, WVA viewing angles, and 250 nits brightness for fluid, comfortable everyday viewing. The 720p HD camera with integrated microphone and precision touchpad round out a well-equipped display and input experience for work, browsing, and video calls.
- 🔌 VERSATILE CONNECTIVITY FOR EVERYDAY NEEDS: Stay connected with Realtek Wi-Fi 6 (2x2, MU-MIMO) and Bluetooth wireless connectivity for fast, reliable performance. Ports include USB 3.2 Gen 1 Type-A, USB 2.0, USB 3.2 Gen 1 Type-C, HDMI 1.4, a universal audio jack, and an SD card slot, giving you flexible options for peripherals, displays, and storage expansion in any setting.
- 🛡️ DURABLE CARBON BLACK DESIGN FOR EVERYDAY USE: Finished in a sleek Carbon Black plastic chassis, this laptop weighs a manageable 4.19 lbs for everyday portability. Tuned dual speakers deliver clear audio for calls and media, while the non-backlit keyboard and precision touchpad provide comfortable, reliable input. Ideal for students, home users, and everyday professionals seeking dependable performance.
Frequently Asked Questions
Can React generate a thumbnail from a video file selected by the user?
Yes. Create an object URL from the selected File, pass it as the video source, and revoke that URL when the file changes or the component unmounts.
Can I capture a frame without playing the video?
Yes. Load metadata, set currentTime, wait for the seek and frame data, then draw to canvas; playback is not required.
Why does canvas.toBlob() fail for a video URL?
A cross-origin source without server CORS authorization can taint the canvas, preventing export. The video request mode and the media server’s response headers must both permit access.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

