A REST API that parses MP3 files and returns the frame count. Built with Bun and Elysia, focusing on MPEG Version 1 Layer 3 files.
Elysia was chosen as the HTTP framework for several reasons:
- Bun-native: Built specifically for the Bun runtime, leveraging its performance advantages
- Type-safe: End-to-end type safety with built-in validation using TypeBox
- Minimal overhead: Lightweight with excellent performance benchmarks
- Developer experience: Clean, expressive API with excellent TypeScript support
- Built-in validation: Schema validation for request bodies without additional dependencies
The MP3 parser implements frame-by-frame parsing according to the MPEG Audio Layer III specification.
-
Skip ID3v2 Metadata: Detect and skip ID3v2 tags by checking for the "ID3" magic bytes at the file start. The tag size is encoded as a syncsafe integer (4 bytes, 7 bits each).
-
Frame Sync Detection: Scan for the frame sync pattern - byte
0xFFfollowed by a byte with bits111xxxxx(mask0xE0). -
Header Parsing: Each frame has a 4-byte header containing:
- MPEG version (2 bits) - only Version 1 (
0b11) is supported - Layer (2 bits) - only Layer 3 (
0b01) is supported - Bitrate index (4 bits) - maps to bitrates 32-320 kbps
- Sample rate index (2 bits) - maps to 32000, 44100, or 48000 Hz
- Padding bit (1 bit) - adds 1 byte to frame if set
- Channel mode (2 bits) - mono or stereo
- MPEG version (2 bits) - only Version 1 (
-
Frame Size Calculation:
frameSize = floor((144 * bitrate * 1000) / sampleRate) + padding -
VBR Header Detection: Skip Xing/Info headers in the first frame (these are metadata, not audio).
-
Frame Counting: Iterate through all valid frames, accumulating the count.
- MPEG1 Layer 3 Only: By design, the parser only counts MPEG Version 1 Layer 3 frames. Other versions/layers are skipped.
- Graceful Handling: Invalid frames are skipped rather than throwing errors, allowing partial parsing of corrupted files.
- Memory Efficient: The parser works with
Uint8Arrayfor direct byte manipulation without unnecessary copying.
- Bun runtime (v1.0+)
bun installbun run devServer runs at http://localhost:3000
Upload an MP3 file to get the frame count.
Request:
curl -X POST -F "file=@your-file.mp3" http://localhost:3000/file-uploadSuccess Response (200):
{
"frameCount": 8424
}Error Responses:
- 400: Invalid file or no file provided
- 500: Server error
bun testbun run lint # Check for issues
bun run format # Auto-format code
bun run check # Lint + format checkCompare results with mediainfo:
mediainfo --fullscan sample_file.mp3 | grep "Frame count"