Fixing the WebM "Missing Duration" Problem with a Lightweight, Zero-Dependency Library
/ 3 min read
Table of Contents
Introduction
Have you ever implemented audio or video recording features using the browser’s standard MediaRecorder API? While it is a powerful and convenient API, developers often run into a frustrating issue: the generated WebM files frequently lack the Duration metadata property, or report it as Infinity.
This “missing duration” issue causes several downstream problems:
- Server-side validation fails: Checks like “Max duration: 1 minute” become impossible.
- Media players struggle: Total time is not displayed.
- UI glitches: Seek bars fail to function correctly.
To solve this problem and accurately calculate the playback duration directly from WebM binaries, I built a new library called webm-meta-lite.
Repository: https://github.com/ainoya/webm-meta-lite
The Problem with Existing Solutions
When I first faced this issue, I researched existing solutions, but they felt like using a sledgehammer to crack a nut.
1. Using FFmpeg
FFmpeg is the industry standard for media processing. However, installing a massive binary on a server or container just to read a single timestamp is overkill. It significantly bloats Docker image sizes and adds unnecessary complexity to the deployment pipeline.
2. Existing JavaScript Libraries
There are Node.js libraries for WebM, but many are bundled with heavy recording or transcoding features. I only needed a lightweight parser, not a full media suite.
The Solution: webm-meta-lite
webm-meta-lite focuses on parsing the WebM binary structure to calculate the exact duration efficiently.
- Zero Dependencies: No external runtime dependencies to worry about.
- Pure TypeScript: No native binaries required. It runs seamlessly in both browsers and Node.js.
- Read-Only / Safe: It scans the binary to extract information without mutating or rewriting files.
Usage
The API is straightforward. You pass a WebM Blob (or a compatible Reader), and it returns the parsed metadata.
If you are using Node.js (v19.8+), utilizing fs.openAsBlob is the cleanest approach.
import { parseWebm } from 'webm-meta-lite';import { openAsBlob } from 'node:fs';
async function main() { // 1. Open the file as a Blob (Node.js v19.8+) const blob = await openAsBlob('./input.webm');
// 2. Parse Metadata // Even if the header lacks duration, the library scans the data to calculate it. const metadata = await parseWebm(blob);
// 3. Use the result // Note: The unit is milliseconds console.log(`Duration: ${metadata.durationMilliSeconds} ms`);
// Example: Server-side validation if (metadata.durationMilliSeconds > 60 * 1000) { throw new Error('Uploads must be under 1 minute.'); }}
main();For browsers, you can pass the File object directly. For older Node.js versions, the library also provides a createBufferReader helper.
How It Works: The 3-Stage Fallback Strategy
The core strength of this library lies in its algorithm. If the metadata is not found in the header, it calculates the duration from the actual data. Inspired by robust implementations in FFmpeg and webminspector, webm-meta-lite uses a 3-stage fallback strategy to ensure accuracy while maintaining performance.
Step 1: Header Scan
The library reads the first 64KB of the file. If the Duration is present in the Info segment, it returns immediately. This is the fastest path.
Step 2: Cues Scan
If the header is missing the duration, it looks for the Cues (index) element. If found, it uses the timestamp of the last Cue point to determine the length.
Step 3: Tail Scan (The “Safety Net”)
If neither of the above works—common with streamed recordings—the library performs a Tail Scan. It reads only the last 2MB of the file and scans the byte-level structure of the Cluster elements. By finding the timestamp of the very last audio/video block, it calculates the precise total duration.
Summary
MediaRecorderoften produces WebM files with missing orInfinityduration.- FFmpeg is frequently too heavy for simple duration checks.
webm-meta-liteprovides a lightweight, zero-dependency, and fast way to calculate duration.- It implements a robust 3-stage fallback algorithm inspired by FFmpeg.
If you need to validate user-uploaded audio/video on the backend or display accurate times in your UI, give it a try!