MP4BOX.JS ✦ CLOUDFLARE WORKERS ✦ STREAMING PARSE ✦ MOOV EARLY-STOP ✦ URL OR RAW BYTES ✦ 200MB CAP ✦ EDGE-FAST ✦MP4BOX.JS ✦ CLOUDFLARE WORKERS ✦ STREAMING PARSE ✦ MOOV EARLY-STOP ✦ URL OR RAW BYTES ✦ 200MB CAP ✦ EDGE-FAST ✦

MP4 metadata
as an HTTP API

Stream an MP4 — from a URL or raw bytes — into mp4box.js and get structured metadata back. Parsing stops as soon as the moov atom is found, so it stays fast and memory-efficient on the edge.

POST /api/parse
GET /api/parse?url=<video-url>

Request

Two input modes, one endpoint. The mode is selected by the Content-Type header.

QUICKEST GET with query param
GET /api/parse?url=https://example.com/video.mp4
MODE 1 Parse from URL
POST /api/parse
Content-Type: application/json

{ "url": "https://example.com/video.mp4" }
MODE 2 Parse from raw bytes
POST /api/parse
Content-Type: video/mp4

<raw MP4 bytes as the request body>

Response

Example for a 10s clip with one video, one audio and one text track.

{
  "success": true,
  "source": "url",
  "info": {
    "duration": 10.026667,
    "brands": ["mp42", "isom", "avc1"],
    "mime": "video/mp4; codecs=\"avc1.4d400c,mp4a.40.2\"",
    "isQuickTime": false,
    "overallBitrate": 621714.86,
    "timescale": 90000,
    "fragmented": false,
    "progressive": false,
    "tracks": [
      { "id": 1, "type": "video", "codec": "avc1.4d400c",
        "width": 320, "height": 240, "bitrate": 51472,
        "timescale": 90000, "nb_samples": 250, "language": "und" },
      { "id": 2, "type": "audio", "codec": "mp4a.40.2",
        "sampleRate": 44100, "channelCount": 1, "bitrate": 70303,
        "timescale": 48000, "nb_samples": 45, "language": "und" }
    ]
  }
}

Schema

successboolean— request succeeded
source"url" | "body"— which input mode was used
info.durationnumber— duration in seconds
info.brandsstring[]— major + compatible brands
info.mimestring— MIME type with codecs parameter
info.isQuickTimeboolean— QuickTime brand detected
info.overallBitratenumber— combined bitrate, bits/s
info.timescalenumber— movie timescale
info.fragmented / progressiveboolean— fMP4 / progressive download
info.tracks[]TrackInfo[]— per-track details
TrackInfo
id · type ("video" | "audio" | "subtitles" | "metadata" | "other") · codec · bitrate · timescale · nb_samples · language · name
video tracks: width, height
audio tracks: sampleRate, channelCount

Errors

400Missing or invalid url; non-http(s) scheme
413Input exceeded the 200MB stream cap
422Not an MP4, or moov atom not found
502Upstream URL unreachable or non-200
500Internal error

Client examples

# quick GET (URL mode only)
curl 'https://your-worker.workers.dev/api/parse?url=https://example.com/video.mp4'

# from a URL
curl -X POST https://your-worker.workers.dev/api/parse \
  -H 'Content-Type: application/json' \
  -d '{"url": "https://example.com/video.mp4"}'

# from raw bytes
curl -X POST https://your-worker.workers.dev/api/parse \
  -H 'Content-Type: video/mp4' \
  --data-binary @video.mp4
Live

Try it live

Request