# mp4ff: reading and rewriting fragmented MP4 files in Go

> mp4ff is a Go library and a set of command line tools for parsing and writing MP4 files, focused on the fragmented form used by MPEG-DASH, HLS and MSS, with codec-specific support from AVC and HEVC through AV1, VVC, Opus, AC-4 and MPEG-H. It also ships encrypt, decrypt, defragment and crop tools, and a codec coverage table that is unusually complete.

**Eyevinn/mp4ff** — Library and tools for working with MP4 files containing video, audio, subtitles, or metadata. The focus is on fragmented files. Includes mp4ff-info, mp4ff-encrypt, mp4ff-decrypt and other tools.

- Repository: https://github.com/Eyevinn/mp4ff
- Website: https://dev.to/video/mp4ff-beyond-mp4-boxes-2bee
- Stars: 663 · Forks: 129
- Language: Go
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/eyevinn-mp4ff

## The library is about the file format, not the codecs

mp4ff is described as a library and a set of tools for working with MP4 files containing video, audio, subtitles or metadata, with the focus on fragmented files.

The README draws the boundary explicitly. The repo is focused on the file format, but goes beyond the base file format and supports codec-specific boxes. So the library parses and writes the ISO base media file format structure, and it also knows about the configuration boxes that carry the codec setup, such as avcC for AVC, hvcC for HEVC and dOps for Opus, plus the boxes that carry timing and colour information.

That distinction is the one to hold on to when judging the tool. mp4ff is not a transcoder and does not decode video. It moves around the containers, boxes and samples, and understands enough about each codec to read and write its configuration box correctly. That is exactly what a packaging, packaging tool or streaming pipeline needs, and it is exactly what a general media suite is bad at.

The scope covers a lot of ground on the codec side. Video entries for AVC, HEVC, AV1, AVS3, VP8 and VP9, VVC, Motion JPEG and encrypted video. Audio entries for AAC, AC-3, E-AC-3, AC-4, Opus, IAMF, MPEG-H 3D Audio and encrypted audio. Subtitles for WebVTT in both the sample form and the experimental paint model, TTML in the same two forms, and a generic subtitle type. Each row names the sample entry, the configuration box and the other boxes involved, which makes the table a useful checklist of what a given codec path in your pipeline will actually round-trip.

The library is written in Go, the module is github.com/Eyevinn/mp4ff, and the go.mod requires Go 1.24 with a single dependency, go-test/deep, which is a test helper.

## Nine tools, and info is the one you will use first

The command line tools live in the cmd directory, and the Makefile lists the set the build produces: mp4ff-crop, mp4ff-decrypt, mp4ff-defragment, mp4ff-encrypt, mp4ff-info, mp4ff-mvhevc, mp4ff-nallister, mp4ff-pslister and mp4ff-subslister.

mp4ff-info prints a tree of the box hierarchy of an MP4 file with information about the boxes, and with the -brands flag it checks the ftyp and styp brands against the content. That last part is the operationally interesting one, because a mismatch between the declared brand and the actual payload is the kind of thing that plays fine in one player and fails in another.

mp4ff-pslister extracts and displays SPS and PPS for AVC or HEVC in an MP4 file or in a bytestream, Annex B, file, with partial information printed for HEVC. That is the tool you want when a stream plays but looks wrong, since it tells you whether the parameter sets are actually in the file.

mp4ff-nallister lists NALUs and picture types for video in a progressive or fragmented file. mp4ff-subslister lists details of wvtt, wvtc, stpp or stpc subtitle samples, which is WebVTT or TTML inside ISOBMFF.

Then the four tools that change files. mp4ff-crop crops a progressive MP4 file to a specified duration, and the emphasis on progressive is deliberate. mp4ff-encrypt and mp4ff-decrypt handle fragmented files using the cenc or cbcs Common Encryption schemes, so the same scheme name covers both. mp4ff-defragment converts a fragmented MP4 file into a progressive one, which is the operation you need when a segment set has to become a single file.

mp4ff-mvhevc is the specialist one, inspecting MV-HEVC, Multi-View HEVC, files and muxing HEVC, in Annex B or MP4 form, into an MV-HEVC MP4.

## Installing from Go, Homebrew or a distribution package

All the tools are built for macOS, Linux and Windows, on both amd64 and arm64, for every release, and there are three installation routes.

Homebrew is the shortest, and the formula installs the whole set:

```bash
    brew install mp4ff
```

Installing from Go means installing the tools individually, repeating the command for each one you want, or running go install . from the tool's directory under cmd:

```bash
    go install github.com/Eyevinn/mp4ff/cmd/mp4ff-info@latest
    go install github.com/Eyevinn/mp4ff/cmd/mp4ff-encrypt@latest
```

The version reporting is worth knowing about, because it is the sort of detail that ends up in a bug report. The tools report the version that Go embeds when it builds them from a git checkout or with go install. A build from a source archive without git reports (devel) unless the version is set at link time:

```bash
    go build -ldflags "-X github.com/Eyevinn/mp4ff/internal.commitVersion=vX.Y.Z" ./cmd/mp4ff-info
```

The Makefile does this for you, and its comment explains why the flag exists. Building ./cmd/<tool> as a package makes Go embed the version from git, and the -X flags are there for builds from a source archive without git, where packagers replace the git commands. The build line sets both a commitVersion and a commitDate.

For Linux distributions, each release attaches .deb, .rpm and .apk packages with all the tools in a single mp4ff package, plus plain .tar.gz archives:

```bash
    sudo apt install ./mp4ff_<version>_linux_amd64.deb              # Debian/Ubuntu
    sudo rpm -i mp4ff_<version>_linux_amd64.rpm                     # Fedora/RHEL
    sudo apk add --allow-untrusted mp4ff_<version>_linux_amd64.apk  # Alpine
```

For any other distribution, the guidance is to download the .tar.gz archive and copy the binaries into a directory on your PATH.

## Running it in the cloud through the Open Source Cloud CLI

There is a third way to use the tools that is specific to this project, and it is a job runner rather than a local install.

The tools can be run as a job in the Eyevinn Open Source Cloud, and the README gives a worked example using mp4ff-crop with that project's CLI. The example exports an access token, then creates a job:

```bash
% export OSC_ACCESS_TOKEN=<your-personal-access-token>
% npx -y @osaas/cli@latest create eyevinn-mp4ff test \
  -o awsAccessKeyId=<s3-access-key-id> \
  -o awsSecretAccessKey=<s3-secret-key> \
  -o s3EndpointUrl=https://eyevinnlab-birme.minio-minio.auto.prod.osaas.io \
  -o cmdLineArgs="mp4ff-crop s3://input/VINN.mp4 s3://output/VINN-crop2.mp4"
```

The shape is worth reading carefully. The job is created against the eyevinn-mp4ff image, the outputs are S3 style credentials and an endpoint URL pointing at a MinIO server, and the actual work is expressed as a command line argument string. The file VINN.mp4 on the input bucket of that MinIO server is processed and the output uploaded to the output bucket on the same server.

This is a container that runs the tools against object storage, and it is a different deployment model from the local binaries. For a team that already has a bucket based media pipeline, it removes the need to install anything on the workers. The Dockerfile.osc file in the repository root is the image definition for that path.

The generic pattern underneath is simple enough to copy into your own runner: the tool takes a file path as an ordinary argument, so anything that can run a process and hand it a URL, including the s3:// scheme, works.

## The examples, and where the library stops

The examples directory is the closest thing to a tutorial, and the names describe the operations rather than the API.

initcreator creates typical init segments, an ftyp plus moov, for different video cases. segmenter and resegmenter cover splitting and re-splitting. add-sidx adds a segment index. combine-segs combines segments. multitrack builds a file with several tracks. ivf-to-mp4 converts an IVF file, the container used for VP8 and VP9 test streams, into MP4. stream-encrypt covers the Common Encryption path, which pairs with the encrypt and decrypt tools.

The Makefile builds the example binaries separately into examples-out, and the example targets listed in the build rule are add-sidx, combine-segs, initcreator, multitrack, resegmenter and segmenter.

The limitation of the project is the mirror image of its strength. Because it is a container library, the pixel content is out of scope. It does not decode frames, it does not transcode, and it does not do loudness normalisation or quality analysis. If your problem is a bad encode rather than a malformed container, these tools will describe the container accurately and not help with the encode.

There is also a fragmentation bias to keep in mind. The library is focused on fragmented files as used for streaming in MPEG-DASH, MSS and HLS fMP4, but it can also decode and encode all the boxes needed for progressive MP4 files. The word focused means the fragmented path is the tested one, and the progressive path is supported, and the crop tool explicitly only handles progressive files.

## Conclusion

Adopt mp4ff if you build or operate a streaming pipeline and need to inspect, segment, encrypt or defragment CMAF style MP4 files without shelling out to a media suite, especially if you need the box level detail that a metadata tool hides. Do not adopt it if you need a general transcoder, since the project is about the file format rather than the codecs inside it. Before you commit, run mp4ff-info with -brands against one of your real streams to check the brands match your content, and confirm the Go version and toolchain your build pipeline uses matches the 1.24 the module requires.

## FAQ

### What is mp4ff?

mp4ff is a Go library and a set of command line tools for parsing and writing MP4 files containing video, audio, subtitles or metadata. It is focused on fragmented files as used for streaming in MPEG-DASH, MSS and HLS fMP4, and can also decode and encode all the boxes needed for progressive MP4 files.

### How do I install the mp4ff command line tools?

With Homebrew using brew install mp4ff, from Go with go install for each tool under cmd, or from the .deb, .rpm and .apk packages attached to each release. A tar.gz archive is also provided for other distributions, and the binaries can be copied onto your PATH.

### What does mp4ff-info do?

It prints a tree of the box hierarchy of an MP4 file with information about the boxes. With the -brands flag it checks the ftyp and styp brands against the content, which is useful for spotting a declared brand that does not match the payload.

### Can mp4ff encrypt fragmented MP4 files?

Yes. mp4ff-encrypt encrypts a fragmented file using the cenc or cbcs Common Encryption scheme, and mp4ff-decrypt reverses it. The stream-encrypt example in the examples directory shows the same path in code.

### Which codecs does mp4ff support?

The codec table covers video in AVC, HEVC, AV1, AVS3, VP8 and VP9, VVC, Motion JPEG and encrypted form, audio in AAC, AC-3, E-AC-3, AC-4, Opus, IAMF, MPEG-H 3D Audio and encrypted form, and subtitles in WebVTT, TTML, their experimental paint model variants and a generic type, each with its sample entry and configuration box listed.

## Sources

- [Eyevinn/mp4ff on GitHub](https://github.com/Eyevinn/mp4ff)
- [License: MIT](https://github.com/Eyevinn/mp4ff/blob/master/LICENSE)
- [Project website](https://dev.to/video/mp4ff-beyond-mp4-boxes-2bee)
- [README](https://github.com/Eyevinn/mp4ff/blob/master/README.md)
- [Releases](https://github.com/Eyevinn/mp4ff/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/eyevinn-mp4ff
