skip to content
ainoya.dev
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

  • MediaRecorder often produces WebM files with missing or Infinity duration.
  • FFmpeg is frequently too heavy for simple duration checks.
  • webm-meta-lite provides 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!