MP4Box.js
MP4Box.js is a robust JavaScript library designed for comprehensive processing of MP4 files, including parsing, segmentation, and sample extraction. It enables advanced functionalities directly within web browsers or Node.js environments, making it a critical tool for working with the Media Source Extensions (MSE) API for adaptive streaming. The current stable version is 2.3.0, with a history of frequent minor and patch releases, indicating active development and maintenance. Key differentiators include its progressive parsing capabilities, cross-platform support, and its direct inspiration from the well-established GPAC MP4Box tool, providing a powerful and familiar API for developers handling MP4 media.
Common errors
-
ReferenceError: require is not defined
cause Attempting to use `require('mp4box')` in an ECMAScript Module (ESM) context (e.g., in a `.mjs` file or a Node.js project with `"type": "module"` in package.json).fixChange your import statement to `import MP4Box from 'mp4box';`. -
TypeError: MP4Box.createFile is not a function
cause Incorrectly importing the `MP4Box` object using named imports (e.g., `import { MP4Box } from 'mp4box';`) when it is exported as a default.fixUse the correct default import: `import MP4Box from 'mp4box';`. -
Cannot read properties of undefined (reading 'fileStart') or similar parsing errors after appendBuffer
cause The `ArrayBuffer` passed to `appendBuffer` is missing the `fileStart` property, which indicates the byte offset of the buffer's data within the original file.fixBefore calling `mp4boxfile.appendBuffer(buffer);`, ensure you set `buffer.fileStart = currentByteOffset;` where `currentByteOffset` is the starting position of that buffer's data in the complete file.
Warnings
- breaking Version 2.0.0 introduced significant internal changes, including the replacement of `MP4BoxStream` with `DataStream`. This impacts custom implementations that might have directly interacted with the stream abstraction.
- gotcha The library's examples and default export behavior (especially with `require('mp4box')`) can be confusing for modern JavaScript projects. While it provides CommonJS compatibility, the preferred and most robust way to use `mp4box.js` in current Node.js and browser environments is via ESM `import` statements.
- gotcha When appending data using `mp4boxfile.appendBuffer(buffer)`, it is crucial to set the `fileStart` property on the `ArrayBuffer` or `TypedArray` you provide. This property, indicating the byte offset of the buffer within the original file, is essential for `MP4Box.js` to correctly parse box offsets and structure.
Install
-
npm install mp4box -
yarn add mp4box -
pnpm add mp4box
Imports
- MP4Box (default export)
import { MP4Box } from 'mp4box';import MP4Box from 'mp4box';
- createFile
import { createFile } from 'mp4box';const mp4boxfile = MP4Box.createFile();
- TypeScript Types (MP4File, MP4Info)
import type { MP4File, MP4Info, MP4Track } from 'mp4box';
Quickstart
import MP4Box from 'mp4box';
const mp4boxfile = MP4Box.createFile();
mp4boxfile.onError = function(e) {
console.error('MP4Box error:', e);
};
mp4boxfile.onMoovStart = function () {
console.log('Starting to receive File Information (moov box)');
};
mp4boxfile.onReady = function(info) {
console.log('Received File Information:', info);
// Example: Log track details
info.tracks.forEach(track => {
console.log(`Track ID: ${track.id}, Type: ${track.movie_type}, Codec: ${track.codec}, Duration: ${track.duration/track.timescale}s`);
});
};
// Simulate appending data (e.g., from a fetched MP4 file)
async function loadMp4Data() {
// In a real scenario, 'url' would be the path to your MP4 file
const url = 'https://raw.githubusercontent.com/gpac/mp4box.js/master/test/initial-media/mp4/frag_raw.mp4';
const response = await fetch(url);
const reader = response.body.getReader();
let offset = 0;
while (true) {
const { done, value } = await reader.read();
if (done) {
mp4boxfile.flush(); // Signal end of file
break;
}
const buffer = value.buffer; // value is a Uint8Array, get its underlying ArrayBuffer
buffer.fileStart = offset; // Important for MP4Box to track byte ranges
mp4boxfile.appendBuffer(buffer);
offset += buffer.byteLength;
}
}
loadMp4Data();