An MP3 is not a container. It is an optional ID3v2 tag, a run of self-describing MPEG audio frames, and an optional ID3v1 trailer. Regions below expand; the MPEG frame header is drawn as a register map. Hover any field to light its exact bits and read the decode; click a field with a + to open its lookup table. Color marks kind (see the key). Example: FF FB 90 C0, a real MPEG-1 Layer III frame at 128 kbps, 44100 Hz, mono.
Top to bottom, what a reader walks. Only the frames are required.
Prepended metadata. A 10-byte header, then frames, until padding. The tag size is synchsafe (7 bits per byte) so the length can never contain a false 0xFF sync. Frame sizes differ by version: v2.3 is a plain big-endian uint32, v2.4 is synchsafe. When the unsync flag is set the writer stuffed a 0x00 after every 0xFF; strip those before reading frame sizes.
Each frame opens with the 4-byte header drawn below; it carries everything needed to compute the frame length and step to the next sync.
VBR cannot be sized from one bitrate, so the encoder writes a header into the first frame after the side-info block. "Xing" is true VBR, "Info" is CBR by LAME. Offset from frame start: 36 (MPEG-1 stereo), 21 (MPEG-1 mono or MPEG-2 stereo), 13 (MPEG-2 mono). Add 2 when the frame is CRC-protected: the 2 CRC bytes sit between the header and the side info.
The Fraunhofer encoder's VBR header. Unlike Xing/Info it sits at a fixed offset, frame start + 36, independent of version, channel mode, and side-info size. All fields big-endian; a frame carries at most one of Xing/Info/VBRI.
The original tag: a fixed 128-byte block at the very end. Superseded by ID3v2, but many files carry both.