npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@opensubtitles/video-metadata-extractor

v1.8.1

Published

A comprehensive NPM package for video metadata extraction and subtitle processing using FFmpeg WASM. Supports metadata extraction, individual subtitle extraction, batch subtitle extraction with ZIP downloads, and memory-safe processing of files of any siz

Readme

@opensubtitles/video-metadata-extractor

A comprehensive NPM package for video metadata extraction and subtitle processing using FFmpeg WASM. Supports metadata extraction, individual subtitle extraction, batch subtitle extraction with ZIP downloads, and memory-safe processing of files of any size using chunked streaming.

Features

  • 🎥 Comprehensive Metadata Extraction: Extract detailed video information including duration, resolution, bitrate, codecs, and stream details
  • 📄 Individual Subtitle Extraction: Extract single subtitle tracks with quick or full processing modes
  • 📦 Batch Subtitle Extraction: Extract all subtitle tracks at once as a downloadable ZIP file
  • 🧠 Memory-Safe Processing: Handle files of any size using 500MB chunked streaming (tested up to 10GB, theoretically unlimited)
  • Smart File Processing: Automatic format detection with optimized processing strategies
  • 🌐 Browser-Native: No server required, all processing happens in the browser using FFmpeg WASM
  • 📱 TypeScript Support: Full type safety with comprehensive interfaces
  • 🎯 Multiple Formats: Support for SRT, ASS, VTT subtitle formats
  • 🗂️ Smart Filename Generation: Automatic filename generation with language codes and duplicate handling

Installation

npm install @opensubtitles/video-metadata-extractor

Quick Start

import { VideoMetadataExtractor } from '@opensubtitles/video-metadata-extractor';

// Initialize the extractor
const extractor = new VideoMetadataExtractor({
  debug: true,
  onProgress: (progress) => console.log(`Progress: ${progress.progress}% - ${progress.text}`),
  onError: (error) => console.error('Error:', error.message)
});

// Initialize FFmpeg (required before any operations)
await extractor.initialize();

// Extract metadata
const metadata = await extractor.extractMetadata(file);
console.log('Video duration:', metadata.format?.duration);
console.log('Subtitle tracks:', metadata.streams?.filter(s => s.codec_type === 'subtitle').length);

// Extract a single subtitle track (quick mode)
const subtitle = await extractor.extractSubtitle(file, 2, { 
  format: 'srt', 
  quick: true 
});
console.log('Subtitle preview:', subtitle.preview);
extractor.downloadFile(subtitle.data, subtitle.filename);

// Extract all subtitles as ZIP
const batch = await extractor.extractAllSubtitles(file);
console.log(`Extracted ${batch.successfulExtractions}/${batch.totalStreams} subtitle tracks`);
extractor.downloadZip(batch.zipBlob, batch.zipFilename);

// Clean up when done
await extractor.terminate();

API Reference

VideoMetadataExtractor

The main class for video processing operations.

Constructor Options

interface VideoMetadataExtractorOptions {
  /** Custom FFmpeg core URL */
  ffmpegCoreURL?: string;
  /** Custom FFmpeg WASM URL */
  ffmpegWasmURL?: string;
  /** Progress callback */
  onProgress?: (progress: ProgressState) => void;
  /** Error callback */
  onError?: (error: ErrorState) => void;
  /** Enable debug logging */
  debug?: boolean;
  /** Timeout for FFmpeg operations in milliseconds */
  timeout?: number;
  /** Chunk size for large file processing in bytes */
  chunkSize?: number;
}

Methods

initialize(): Promise<void>

Initialize FFmpeg WASM. Must be called before any processing operations.

extractMetadata(file: File): Promise<VideoMetadata>

Extract comprehensive metadata from a video file.

Parameters:

  • file: File - The video file to process

Returns: VideoMetadata object containing format info and stream details

extractSubtitle(file: File, streamIndex: number, options?: ExtractionOptions): Promise<SubtitleExtractionResult>

Extract a single subtitle track.

Parameters:

  • file: File - The video file
  • streamIndex: number - Index of the subtitle stream to extract
  • options?: ExtractionOptions - Extraction configuration

Options:

interface ExtractionOptions {
  /** Output format: 'srt' | 'ass' | 'vtt' | 'webvtt' */
  format?: string;
  /** Use quick extraction (faster but may be incomplete) */
  quick?: boolean;
  /** Timeout in milliseconds */
  timeout?: number;
  /** Custom filename */
  filename?: string;
}

Returns: SubtitleExtractionResult with subtitle data and metadata

extractAllSubtitles(file: File): Promise<BatchExtractionResult>

Extract all subtitle tracks and create a ZIP file.

Parameters:

  • file: File - The video file

Returns: BatchExtractionResult with all extracted subtitles and ZIP blob

downloadFile(data: Uint8Array, filename: string, progressCallback?: (progress: number) => void): void

Download a subtitle file (handles large files automatically).

downloadZip(zipBlob: Blob, filename: string): void

Download a ZIP file containing multiple subtitles.

isInitialized(): boolean

Check if FFmpeg is initialized and ready for use.

getSupportedFormats(): string[]

Get list of supported video file formats.

terminate(): Promise<void>

Clean up resources and terminate FFmpeg.

Data Types

VideoMetadata

Contains comprehensive video file information:

interface VideoMetadata {
  format?: {
    filename: string;
    format_name: string;
    duration: string;
    size: string;
    bit_rate: string;
    fps: string;
    movietimems: string;
    movieframes: string;
  };
  streams?: Array<{
    codec_type: string;
    codec_name: string;
    width?: number;
    height?: number;
    language?: string;
    forced?: boolean;
    default?: boolean;
    index?: number;
    // ... additional stream properties
  }>;
}

SubtitleExtractionResult

Result from individual subtitle extraction:

interface SubtitleExtractionResult {
  data: Uint8Array;
  filename: string;
  extension: string;
  size: number;
  preview: string;
}

BatchExtractionResult

Result from batch subtitle extraction:

interface BatchExtractionResult {
  extractedFiles: Array<{
    filename: string;
    data: Uint8Array;
    size: number;
    language?: string;
    forced?: boolean;
    streamIndex: number;
  }>;
  zipBlob: Blob;
  zipFilename: string;
  totalStreams: number;
  successfulExtractions: number;
}

Supported Formats

The library supports a wide range of video formats including:

Video Formats: MP4, AVI, MOV, MKV, WebM, FLV, WMV, MPG, MPEG, TS, M2TS, OGV, GIF, and many more

Subtitle Formats: SRT, ASS, VTT, WebVTT

Memory Management

The library uses advanced chunked processing to handle files of any size:

  • Chunked Reading: Files are processed in 500MB chunks to maintain consistent memory usage
  • Progressive Extraction: Large files use progressive chunk extraction for subtitle processing
  • Automatic Cleanup: Temporary files are automatically cleaned up after operations
  • Memory-Safe: Peak memory usage stays around 500MB regardless of file size

Browser Compatibility

Requires modern browsers with WebAssembly support:

  • Chrome 57+
  • Firefox 52+
  • Safari 11+
  • Edge 79+

React Integration

For React applications, you can also use the included React hook:

import { useVideoMetadata } from '@opensubtitles/video-metadata-extractor';

function VideoProcessor() {
  const {
    metadata,
    progress,
    error,
    isLoaded,
    handleFileSelect,
    extractSubtitle,
    extractAllSubtitles
  } = useVideoMetadata();

  const handleFile = (file: File) => {
    handleFileSelect(file);
  };

  // ... component logic
}

Examples

Basic Metadata Extraction

import { VideoMetadataExtractor } from '@opensubtitles/video-metadata-extractor';

const extractor = new VideoMetadataExtractor();
await extractor.initialize();

const file = document.querySelector('input[type="file"]').files[0];
const metadata = await extractor.extractMetadata(file);

console.log(`Duration: ${metadata.format?.duration} seconds`);
console.log(`Resolution: ${metadata.streams?.[0]?.width}x${metadata.streams?.[0]?.height}`);
console.log(`Subtitle tracks: ${metadata.streams?.filter(s => s.codec_type === 'subtitle').length}`);

Subtitle Extraction with Progress

const extractor = new VideoMetadataExtractor({
  onProgress: (progress) => {
    document.getElementById('progress').textContent = 
      `${progress.progress}% - ${progress.text}`;
  }
});

await extractor.initialize();

// Quick extraction for fast results
const quickSubtitle = await extractor.extractSubtitle(file, 2, { 
  format: 'srt', 
  quick: true 
});

// Full extraction for complete results
const fullSubtitle = await extractor.extractSubtitle(file, 2, { 
  format: 'srt', 
  quick: false 
});

Batch Processing

const extractor = new VideoMetadataExtractor({ debug: true });
await extractor.initialize();

// Extract all subtitles
const batch = await extractor.extractAllSubtitles(file);

console.log(`Successfully extracted ${batch.successfulExtractions} out of ${batch.totalStreams} subtitle tracks:`);

batch.extractedFiles.forEach(subtitle => {
  console.log(`- ${subtitle.filename} (${subtitle.language || 'unknown'}) - ${subtitle.size} bytes`);
});

// Download the ZIP file
extractor.downloadZip(batch.zipBlob, batch.zipFilename);

Error Handling

const extractor = new VideoMetadataExtractor({
  onError: (error) => {
    console.error('Extraction error:', error.message);
    // Handle error in UI
  }
});

try {
  await extractor.initialize();
  const metadata = await extractor.extractMetadata(file);
} catch (error) {
  console.error('Failed to process video:', error.message);
}

License

MIT

Contributing

This package is part of the OpenSubtitles ecosystem. Contributions are welcome!

Links