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 🙏

© 2026 – Pkg Stats / Ryan Hefner

fmp4-mp4-remuxer

v0.1.5

Published

Browser/Node-friendly fMP4 fragments to MP4 remuxer (video track)

Readme

fmp4-mp4-remuxer

npm version License

TypeScript library and CLI to remux fragmented MP4 (fMP4) inputs into a single playable MP4.

This tool reconstructs timeline metadata, preserves decode and composition order, and produces a clean progressive container:

ftyp + moov + mdat

from fragmented sources such as:

  • Self-contained fMP4 recordings
  • DASH or CMAF init plus .m4s segments
  • WebRTC or browser capture fragments

Features

  • Pure TypeScript implementation with no FFmpeg dependency
  • Supports both self-contained fragmented MP4 files and init plus fragment workflows
  • Correct DTS and PTS normalization across fragments
  • Preserves B-frame composition offsets
  • Outputs standards-compliant progressive MP4 playable in common players
  • Lightweight CLI and library API
  • Zero runtime dependencies

Install

npm install fmp4-mp4-remuxer

Quick example

# Create 1 second fMP4 fragments with FFmpeg
ffmpeg -i input.mp4 -c copy -f segment \
  -segment_time 1 -movflags +frag_keyframe+empty_moov \
  out%03d.mp4

# Merge them using the CLI
npx fmp4-mp4-remuxer --dir ./ --out merged.mp4

When to use this

Use this library when:

  • FFmpeg concat fails on fragmented MP4
  • You downloaded DASH or CMAF segments and need a single MP4
  • You recorded browser or WebRTC video producing multiple fragments
  • You need timeline accurate remuxing in Node.js or browser-based tooling

Library usage

import { flattenFmp4ToMp4WithOptions } from "fmp4-mp4-remuxer";

const { buffer, idrTimestamps } = await flattenFmp4ToMp4WithOptions(
  [initSegment, ...fragments],
  { normalizeAcrossFiles: true }
);

// buffer is an ArrayBuffer containing the final MP4

CLI usage

Basic

npx fmp4-mp4-remuxer --out out.mp4

By default, the CLI reads all .mp4 or .m4s files from:

./fmp4-files

sorted naturally by filename.


Merge self-contained fragmented MP4 files

npx fmp4-mp4-remuxer a.mp4 b.mp4 c.mp4 --out merged.mp4

Merge DASH init plus fragments

npx fmp4-mp4-remuxer \
  --init init.mp4 \
  chunk001.m4s chunk002.m4s \
  --out merged.mp4

Use a custom directory

npx fmp4-mp4-remuxer \
  --dir ./fragments \
  --out merged.mp4 \
  --normalize-across-files

CLI options

| Option | Description | | --- | --- | | --dir <dir> | Directory containing fragmented MP4 inputs | | --init <path> | Optional init segment for DASH-style inputs | | --out <path> | Output MP4 path. Default is ./out.mp4 | | --normalize-across-files | Normalize timestamps across inputs. Enabled by default | | --no-normalize-across-files | Disable cross-file normalization | | --allow-trun-data-offset-fallback | Enable fallback parsing when trun.data_offset is missing | | -h, --help | Show help |


API surface

Functions

  • flattenFmp4ToMp4(buffers)
  • flattenFmp4ToMp4WithOptions(buffers, options)

Classes

  • Fmp4Flattener

Options map to FlattenOptions.


How it works

  • Parse MP4 boxes such as moov, moof, and mdat
  • Extract samples and timing metadata
  • Normalize DTS and PTS across fragments
  • Rebuild sample tables and durations
  • Emit a clean progressive MP4

All steps are implemented in TypeScript without FFmpeg.


Compatibility

The generated MP4 output is intended to play correctly in:

  • Modern web browsers
  • VLC and common desktop media players
  • Standard MP4 processing pipelines

Playback correctness depends on valid fragmented MP4 input structure.


Limitations

  • Currently targets the video track only
  • Output MP4 is built fully in memory, so large inputs require significant RAM
  • Requires structurally valid fragmented MP4 inputs

Some malformed streams may require:

  • --allow-trun-data-offset-fallback

Development

npm install
npm run build
npm run typecheck

License

This project is licensed under the MIT License.
See the LICENSE file for details.


Purpose

Fragmented MP4 stitching in pure JavaScript is poorly documented, rarely implemented correctly, and often dependent on FFmpeg.

This project provides a small, correct, dependency-free remuxer usable in Node.js tooling and future browser or WebAssembly workflows.