Works with any backend npm install Zero dependencies

Inline video playback in the lightbox

The same lightbox that handles images + PDFs renders videos with native HTML5 <video> controls. playsInline, preload=metadata (no full download until play), and a clean pause + revoke on close so memory doesn't pile up across previews.

Try it: drop an .mp4 or .webm file. A " Play" button appears next to its filename (videos only). Click - the lightbox opens with native controls (play/pause/seek/volume/fullscreen).
Auto-detection

The lightbox auto-detects video from both the MIME type and the filename:

// All four work without specifying kind:
MultipleUpload.showLightbox(videoFile, 'My clip'); // File.type = video/*
MultipleUpload.showLightbox('/clips/demo.mp4', 'My clip'); // extension
MultipleUpload.showLightbox(blob, 'My clip', { kind: 'video' }); // explicit when MIME is generic
MultipleUpload.showLightbox(videoUrl, 'My clip'); // URL extension match
Supported formats
  • Universal: .mp4 (H.264 + AAC) plays everywhere.
  • Open codecs: .webm (VP8/VP9), .ogg / .ogv (Theora). Excellent in Chrome / Firefox / Edge; Safari 16+ added VP9.
  • Apple: .mov (QuickTime) plays in Safari; modern Chrome on macOS also handles it.
  • Newer: .m4v (effectively MP4) - universally supported.
Memory + bandwidth safety
  • preload="metadata": the browser fetches the first few KB to determine duration + first frame, NOT the entire video.
  • playsInline: prevents iOS from auto-launching full-screen player on tap.
  • Auto-pause on close: the close handler runs video.pause() + src='' + load() - frees the decoder + network connection.
  • Blob URL revoke: when the source was a File / Blob, the object URL is revoked on close.
Pair with thumbnails for a click-to-play grid

The uploader's built-in generateVideoThumbs generates a first-frame still for each video file. Combine it with the lightbox for a YouTube-style grid:

uploader.on('taskAdded', (task) => {
 if (!/^video\//.test(task.file.type)) return;
 task.on('thumbnailReady', (thumbUrl) => {
 const tile = renderVideoTile(task, thumbUrl);
 tile.addEventListener('click', () => {
 MultipleUpload.showLightbox(task.file, task.fileName);
 });
 });
});