// video infrastructure for people who ship
Upload once.
Stream everywhere.
TRANSCODMAX turns any source video into an adaptive HLS ladder — 360p / 720p / 1080p renditions behind a single master.m3u8 — ready for any player, on any connection. Dashboard or REST API. Your call.
3-rung
360p → 1080p ladder
2 GB
max source size
6s
segments, keyframe-aligned
H.264
main profile · veryfast · AAC
60/min
API rate limit per token
$ pipeline_status
workers idle · ready for inputNo jobs have hit this deployment yet. The first upload gets probed, encoded into up to 3 renditions and published behind a master playlist — live counters for ingested jobs, delivered ladders and processed footage appear here as soon as the pipeline runs.
Be job #1 »// the pipeline
Three stages. No hand-waving.
01
Ingest
Push a source through the dashboard or POST /api/v1/jobs. Uploads are validated by sniffed mimetype — not file extension — and capped at 2048 MB. Sources land on a private disk, immutable from the moment they arrive.
→ 202 Accepted
{ "id": 42, "status": "queued" }
02
Transcode
A supervised worker probes the source with ffprobe, then runs an x264 encode per rendition — veryfast preset, main profile, keyframes forced onto segment boundaries so players switch bitrates cleanly. Progress streams to the job record from 0 to 100. Sources are never upscaled: a 720p master gets a 720p ceiling.
status processing
progress ██████████░░░░░░ 63%
03
Deliver
One master.m3u8 advertises every variant with BANDWIDTH and RESOLUTION; each rendition ships its own VOD playlist and 6-second .ts segments. Serve from local storage in dev, or point the output disk at S3/R2 behind a CDN — output is write-once, so long cache TTLs are free.
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=3220801,
RESOLUTION=1280x720
720p/index.m3u8
// the ladder
Every job, the same contract.
Current encode targets, straight from the platform config. Renditions taller than the source are skipped — the ladder adapts down, never fakes up.
| Rendition | Video | Audio | Codec | Container |
|---|---|---|---|---|
| 360p | 800kbps · 360p | AAC 96kbps stereo | H.264 main / veryfast | HLS VOD · 6s .ts |
| 720p | 2800kbps · 720p | AAC 128kbps stereo | H.264 main / veryfast | HLS VOD · 6s .ts |
| 1080p | 5000kbps · 1080p | AAC 192kbps stereo | H.264 main / veryfast | HLS VOD · 6s .ts |
// playback
Standard HLS. Plays on everything.
Output is plain HLS v3 — MPEG-TS segments and VOD playlists. No SDK, no proprietary manifest, no player lock-in. Hand the master URL to whatever you already ship with.
Safari / iOS / tvOS
Native. Point <video src> at master.m3u8 and AVPlayer handles bitrate switching itself.
hls.js / video.js / Plyr
Chrome, Firefox, Edge via Media Source Extensions. Our own job pages use hls.js — nothing special about the manifest.
ExoPlayer / Media3
Android's default player consumes the master playlist directly; adaptive track selection works out of the box.
Smart TVs & set-tops
H.264 main profile + AAC is the lowest common denominator on purpose — Roku, Tizen, webOS and Chromecast all decode it in hardware.
$ embed_minimal
<video id="v" controls playsinline></video>
<script src="https://cdn.jsdelivr.net/npm/hls.js@1"></script>
<script>
const v = document.getElementById('v');
const src = '.../transcodes/42/master.m3u8';
if (Hls.isSupported()) {
const h = new Hls(); h.loadSource(src); h.attachMedia(v);
} else {
v.src = src; // Safari: native HLS
}
</script>
$ what_you_get
transcodes/42/
├── master.m3u8
├── 360p/
│ ├── index.m3u8
│ └── segment_000.ts … segment_NNN.ts
├── 720p/
│ ├── index.m3u8
│ └── segment_000.ts … segment_NNN.ts
├── 1080p/
│ ├── index.m3u8
│ └── segment_000.ts … segment_NNN.ts
Every file is immutable once written. Put a CDN in front with a year-long TTL — a completed job never changes, so there's nothing to invalidate.
// built for
Anywhere a video needs to become a stream.
▶
Course & LMS platforms
Lecture uploads arrive as 4 GB screen recordings. Hand them to the API on upload, store the playlist URL on the lesson, and students on hotel wifi still get the 360p rung instead of a spinner.
▩
UGC & community apps
Phone footage comes in every codec, rotation and resolution. ffprobe normalises it; the ladder never upscales, so a vertical 720p clip stays honest. Poll GET /jobs/{id} and flip the post to "ready" at 100%.
▤
Internal video & archives
Town-halls, trainings, product demos. Keep the ProRes master on the private source disk, serve the ladder from object storage, and stop emailing 2 GB .mov files around.
// spec sheet
The numbers, as configured on this deployment.
// the api
Three endpoints. Bearer token. Done.
POST /api/v1/jobs
Multipart upload (video=@file). Returns 202 with the queued job.
GET /api/v1/jobs
Paginated list of your jobs, newest first. Strictly scoped to your account.
GET /api/v1/jobs/{id}
Poll a single job for status, progress and the playlist URL.
401 unknown token · 403 account_pending / not your job · 422 not a video or over 2048 MB
$ sample_session
$ curl -H "Authorization: Bearer sk_live_..." \
-F "video=@launch-teaser.mov" \
https://transcodmax.on-forge.com/api/v1/jobs
HTTP/1.1 202 Accepted
{
"data": {
"id": 42,
"status": "queued",
"progress": 0,
"original": "launch-teaser.mov",
"playlist_url": null,
"error": null
}
}
$ curl -H "Authorization: Bearer sk_live_..." \
https://transcodmax.on-forge.com/api/v1/jobs/42
HTTP/1.1 200 OK
{
"data": {
"id": 42,
"status": "completed",
"progress": 100,
"playlist_url": ".../transcodes/42/master.m3u8"
}
}
// getting access
Operator-approved onboarding.
Register, and your account starts in pending state — you can log in and explore, but transcoding stays locked until an operator activates the account. Approval issues your sk_live_ API token and unlocks uploads instantly.
Waiting on activation? Write to support@trancodmax.com.
Create an account »What formats can I upload?
Anything with a real video mimetype — mp4, mov, mkv, webm, avi, mpeg and friends. Content is sniffed server-side; renaming a .zip to .mp4 gets you a 422.
Do you upscale low-res sources?
Never. Renditions taller than your source are dropped from the ladder. A 480p source produces a single honest 360p rung, not a blurry fake 1080p.
Where does my output live?
On the platform's output disk — local storage in development, S3/R2 behind a CDN in production. Playlists and segments are write-once and never mutated.
What happens when an encode fails?
The job is marked failed and the raw ffmpeg stderr is captured on the record — visible on the job page and in the API — so you can see exactly what the encoder choked on.