
Security News
Bun 1.2.19 Adds Isolated Installs for Better Monorepo Support
Bun 1.2.19 introduces isolated installs for smoother monorepo workflows, along with performance boosts, new tooling, and key compatibility fixes.
MP4Box.js enables advanced MP4 parsing, segmentation, and sample extraction directly in the browser or in Node.js environments. Built for performance and flexibility, it's inspired by the MP4Box tool from the GPAC Project.
MP4Box.js makes it easy to work with MP4 files using JavaScript, offering:
You can use MP4Box.js to:
On this page, you'll find documentation on how to build MP4box.js, install, use it in a browser, or contribute.
You can install MP4Box.js via npm:
npm install mp4box@latest
Similar to MP4Box -info file.mp4
, MP4Box.js can provide general information about the file (duration, number and types of tracks ...). For that, create an MP4Box ISOFile object, set the onReady
callback and provide data in the form of ArrayBuffer objects. MP4Box.js supports progressive parsing. You can provide small buffers at a time, the callback will be called when the 'moov' box is parsed.
var MP4Box = require('mp4box'); // Or whatever import method you prefer.
var mp4boxfile = MP4Box.createFile();
mp4boxfile.onError = function(e) {};
mp4boxfile.onReady = function(info) {};
mp4boxfile.appendBuffer(data);
mp4boxfile.appendBuffer(data);
mp4boxfile.appendBuffer(data);
...
mp4boxfile.flush();
The onMoovStart
callback is called when the 'moov' box is starting to be parsed. Depending on the download speed, it may take a while to download the whole 'moov' box. The end of parsing is signaled by the onReady
callback.
mp4boxfile.onMoovStart = function () {
console.log('Starting to receive File Information');
};
The onReady
callback is called when the the 'moov' box has been parsed, i.e. when the metadata about the file is parsed.
mp4boxfile.onReady = function (info) {
console.log('Received File Information');
};
The info
argument is an object with the following structure.
{
"duration": 360002,
"timescale": 600,
"isFragmented": false,
"isProgressive": true,
"hasIOD": true,
"brands": ["isom"],
"created": "2014-04-15T18:24:40.000Z",
"modified": "2014-04-15T18:24:40.000Z",
"tracks": [
{
"id": 2,
"created": "2012-02-13T23:07:31.000Z",
"modified": "2014-04-16T12:22:56.000Z",
"movie_duration": 360000,
"layer": 0,
"alternate_group": 0,
"volume": 0,
"track_width": 320,
"track_height": 180,
"timescale": 25000,
"duration": 15000000,
"bitrate": 120000,
"codec": "avc1.42c00d",
"video": {
"width": 320,
"height": 180
},
"language": "und",
"nb_samples": 15000
},
{
"id": 3,
"created": "2012-09-12T11:14:57.000Z",
"modified": "2014-04-16T12:22:56.000Z",
"movie_duration": 360002,
"layer": 0,
"alternate_group": 0,
"volume": 1,
"track_width": 0,
"track_height": 0,
"timescale": 44100,
"duration": 26460160,
"bitrate": 60000,
"codec": "mp4a.40.2",
"audio": {
"sample_rate": 44100,
"channel_count": 1,
"sample_size": 16
},
"language": "und",
"nb_samples": 25840
}
]
}
Track information object:
Video-specific information object:
Audio-specific information object:
Indicates that an error has occurred during the processing. e
is a String.
mp4boxfile.onError = function (e) {
console.log('Received Error Message ' + e);
};
Provides an ArrayBuffer to parse from. The ArrayBuffer must have a fileStart
(Number) property indicating the 0-based position of first byte of the ArrayBuffer in the original file. Returns the offset (in the original file) that is expected to be the fileStart
value of the next buffer. This is particularly useful when the moov box is not at the beginning of the file.
var ab = getArrayBuffer(); // any of your own method that returns an ArrayBuffer
ab.fileStart = 0;
var nextBufferStart = mp4boxfile.appendBuffer(ab);
Indicates that sample processing can start (segmentation or extraction). Sample data already received will be processed and new buffer append operation will trigger sample processing as well.
Indicates that sample processing is stopped. Buffer append operations will not trigger calls to onSamples or onSegment.
Indicates that no more data will be received and that all remaining samples should be flushed in the segmentation or extraction process.
var mp4boxfile = MP4Box.createFile();
mp4boxfile.onReady = function(info) {
...
mp4boxfile.onSegment = function (id, user, buffer, sampleNumber, last) {}
mp4boxfile.setSegmentOptions(info.tracks[0].id, sb, options);
var initSegs = mp4boxfile.initializeSegmentation();
mp4boxfile.start();
...
};
Indicates that the track with the given track_id
should be segmented, with the given options. When segments are ready, the callback onSegment is called with the user
parameter. The options
argument is an object with the following properties:
mp4boxfile.setSegmentOptions(1, sb, { nbSamples: 1000 });
Indicates that the track with the given track_id
should not be segmented.
mp4boxfile.unsetSegmentOptions(1);
Callback called when a segment is ready, according to the options passed in setSegmentOptions. user
is the caller of the segmentation, for this track, and buffer
is an ArrayBuffer containing the Movie Fragments for this segment.
mp4boxfile.onSegment = function (id, user, buffer, sampleNumber, last) {
console.log(
'Received segment on track ' +
id +
' for object ' +
user +
' with a length of ' +
buffer.byteLength,
);
};
Indicates that the application is ready to receive segments. Returns an array of objects containing the following properties:
[
{
"id": 2,
"buffer": "[ArrayBuffer]",
"user": "[SourceBuffer]"
},
{
"id": 3,
"buffer": "[ArrayBuffer]",
"user": "[SourceBuffer]"
}
]
It is possible to extract the samples of a track, in a similar manner to the segmentation process.
var mp4boxfile = MP4Box.createFile();
mp4boxfile.onReady = function(info) {
...
/* create a texttrack */
var texttrack = v.addTextTrack("metadata", "Text track for extraction of track "+info.tracks[0].id);
mp4boxfile.onSamples = function (id, user, samples) {}
mp4boxfile.setExtractionOptions(info.tracks[0].id, texttrack, options);
mp4boxfile.start();
...
};
Indicates that the track with the given track_id
for which samples should be extracted, with the given options. When samples are ready, the callback onSamples is called with the user
parameter. The options
argument is an object with the following properties:
mp4boxfile.setExtractionOptions(1, texttrack, { nbSamples: 1000 });
Indicates that the samples for the track with the given track_id
should not be extracted.
mp4boxfile.unsetExtractionOptions(1);
Callback called when a set of samples is ready, according to the options passed in setExtractionOptions. user
is the caller of the segmentation, for this track, and samples
is an Array of samples.
mp4boxfile.onSamples = function (id, user, samples) {
console.log('Received ' + samples.length + ' samples on track ' + id + ' for object ' + user);
};
Each sample has the following structure:
{
"track_id": 4,
"description": "[Box]",
"is_rap": true,
"timescale": 1000,
"dts": 0,
"cts": 0,
"duration": 1000,
"size": 41,
"data": "[ArrayBuffer]"
}
Indicates that the next samples to process (for extraction or segmentation) start at the given time (Number, in seconds) or at the time of the previous Random Access Point (if useRap is true, default is false). Returns the offset in the file of the next bytes to be provided via appendBuffer .
mp4boxfile.seek(10, true);
Releases the memory allocated for sample data for the given track id, up to (but excluding) the given sample number.
mp4boxfile.releaseUsedSamples(1, 250);
MP4Box.js
implements many features (parsing of many types of boxes, writing of boxes, sample processing, on-the-fly fragmentation ...). All these features may not be needed in all applications. In order to allow for a flexible configuration of the features, and to reduce the size of the final library, MP4Box.js
is split in many files and uses the tsup to compile a set of selected features into a single file. Currently, MP4Box.js
comes in two flavors:
For every flavor, tsup builds ESM, CJS, and IIFE versions of the library, which can be used in different environments (browser, Node.js, etc.). The IIFE version is not distributed to npm, but utilized in the demos.
Run the following command to build the library:
npm run build
Nowadays, most projects use bundlers like Webpack, Rollup, or Vite to manage dependencies and build their applications. If you are using one of these tools, you can simply import MP4Box.js
in your JavaScript files:
import * as MP4Box from 'mp4box';
If you are not using a bundler, you can still use MP4Box.js
in the browser. The library is written in ES6 modules, so you can import it directly in your HTML file. However, you will need to build it first or use a pre-built version. Check the Build section above for instructions on how to build the library.
Example of a simple HTML file that uses MP4Box.js
:
<html>
<head>
<meta charset="utf-8" />
<title>MP4Box.js in the browser</title>
<script src="https://cdn.jsdelivr.net/npm/mp4box/dist/mp4box.all.js"></script>
<!-- Alternatively, you can use a local build -->
<!-- <script type="module" src="mp4box.all.js"></script> -->
</head>
<body>
<script type="module">
import * as MP4Box from './mp4box.all.js';
// Create a new MP4Box instance
const mp4box = MP4Box.createFile();
// Example usage: Add a file to the MP4Box instance
// Note: You would typically fetch or read a file here
// For demonstration, we will just log the instance
console.log(mp4box);
</script>
</body>
</html>
If your favorite box is not parsed by MP4Box, you can easily contribute. Check out the CONTRIBUTING.md file for more information on how to add support for new boxes or features.
To contribute to MP4Box.js, simply clone the repository, run npm install
and npm test
.
FAQs
JavaScript version of GPAC's MP4Box tool
The npm package mp4box receives a total of 62,420 weekly downloads. As such, mp4box popularity was classified as popular.
We found that mp4box demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Bun 1.2.19 introduces isolated installs for smoother monorepo workflows, along with performance boosts, new tooling, and key compatibility fixes.
Security News
Popular npm packages like eslint-config-prettier were compromised after a phishing attack stole a maintainer’s token, spreading malicious updates.
Security News
/Research
A phishing attack targeted developers using a typosquatted npm domain (npnjs.com) to steal credentials via fake login pages - watch out for similar scams.