Lossless ISOBMFF (MP4/MOV/M4A/HEIF) box surgery in pure Elixir.
Parse any ISO Base Media file into a tree of ISOMedia.Box structs (every box,
including unknown/vendor boxes, preserved byte-for-byte), edit it, and re-serialize.
The invariant throughout is serialize(parse(file)) == file.
This module is the top-level entry point:
- Read/write —
read/2(withlazy: truefor files larger than RAM),write/2,parse/2,serialize/1. - Arrange —
faststart/1,fix_chunk_offsets/1. - Sample-level —
track_ids/1,samples/2(progressive or fragmented),extract_track/2,trim/3,concat/1. - Fragmented MP4 —
fragment/2(progressive → fMP4) anddefragment/1(fMP4 → progressive), inverses of each other.
trim, extract_track, concat, fragment, and defragment outputs can be chained
in memory (no disk round-trip); faststart/1/fix_chunk_offsets/1 require an original
parsed mdat and raise on a synthesized one.
iex> {:ok, boxes} = ISOMedia.parse(<<8::32, "free">>)
iex> ISOMedia.serialize(boxes)
<<8::32, "free">>
Summary
Functions
Losslessly concatenate compatible clips end-to-end. See ISOMedia.Concat.concat/1.
Defragment a fragmented MP4 tree into a progressive one. See ISOMedia.Defragment.defragment/1.
Extract a single track into a new box tree (then write/2 or serialize/1).
Move moov before mdat (faststart) and fix chunk offsets. See ISOMedia.Offsets.faststart/1.
Recompute stco/co64 chunk offsets for the current box arrangement. See ISOMedia.Offsets.fix_chunk_offsets/1.
Repack a progressive tree into a multiplexed fragmented MP4. See ISOMedia.Fragment.fragment/2.
Parse a binary into {:ok, [%ISOMedia.Box{}]}. See ISOMedia.Parser.parse/2.
Read a file and parse it. Pass lazy: true to keep large leaf payloads
(≥ :lazy_threshold, default 1 MB) as ISOMedia.FileSlice references instead of
loading them, so files larger than memory can be processed.
Decode a track's sample tables into [%ISOMedia.Sample{}] (progressive or fragmented).
Serialize a box or list of boxes back to a binary.
Split a fragmented tree into a CMAF init segment + media segments. See ISOMedia.Segment.split/1.
List the track_ids present in the movie.
Losslessly trim every track to the time range [start_sec, end_sec).
Serialize boxes and write them to path, streaming any FileSlice payloads
disk→disk (memory-safe for large files). Raises if path is one of the tree's
FileSlice sources (you cannot stream-overwrite the file you are reading).
Write a fragmented tree's init + media segment files into dir. See ISOMedia.Segment.write_segments/3.
Types
@type tree() :: [ISOMedia.Box.t()]
Functions
Losslessly concatenate compatible clips end-to-end. See ISOMedia.Concat.concat/1.
Defragment a fragmented MP4 tree into a progressive one. See ISOMedia.Defragment.defragment/1.
@spec extract_track(tree(), pos_integer()) :: tree()
Extract a single track into a new box tree (then write/2 or serialize/1).
Move moov before mdat (faststart) and fix chunk offsets. See ISOMedia.Offsets.faststart/1.
Recompute stco/co64 chunk offsets for the current box arrangement. See ISOMedia.Offsets.fix_chunk_offsets/1.
Repack a progressive tree into a multiplexed fragmented MP4. See ISOMedia.Fragment.fragment/2.
Parse a binary into {:ok, [%ISOMedia.Box{}]}. See ISOMedia.Parser.parse/2.
Read a file and parse it. Pass lazy: true to keep large leaf payloads
(≥ :lazy_threshold, default 1 MB) as ISOMedia.FileSlice references instead of
loading them, so files larger than memory can be processed.
@spec samples(tree(), pos_integer()) :: [ISOMedia.Sample.t()]
Decode a track's sample tables into [%ISOMedia.Sample{}] (progressive or fragmented).
Serialize a box or list of boxes back to a binary.
Split a fragmented tree into a CMAF init segment + media segments. See ISOMedia.Segment.split/1.
@spec track_ids(tree()) :: [pos_integer()]
List the track_ids present in the movie.
Losslessly trim every track to the time range [start_sec, end_sec).
@spec write(Path.t(), tree()) :: :ok | {:error, File.posix()}
Serialize boxes and write them to path, streaming any FileSlice payloads
disk→disk (memory-safe for large files). Raises if path is one of the tree's
FileSlice sources (you cannot stream-overwrite the file you are reading).
Write a fragmented tree's init + media segment files into dir. See ISOMedia.Segment.write_segments/3.