Skip to content
TubePress — free, self-hosted & actively maintained
Media & transcoding

Transcoding

How TubePress converts uploads into web-ready renditions with distributed FFmpeg workers.

Transcoding turns a single uploaded file into several web-friendly MP4 renditions, so viewers get a quality menu, fast-starting playback and a consistent codec regardless of what was uploaded. It also bakes in optional extras — watermarks and intro/outro clips — and builds the scrub-preview sprites the player uses.

Everything here is configured under /admin/settings?tab=transcode, split across the Formats, Queue, Servers, Watermark, Intros and Timeline sub-tabs. Transcoding can run on the CMS server itself or be distributed to dedicated workers.

Why transcode

A raw upload may be any resolution, codec or container. Transcoding standardises it into MP4/H.264 renditions with +faststart so playback begins before the file is fully downloaded, and it produces several sizes (for example 720p and 480p) so the player can offer a quality selector and serve smaller files to smaller screens. The same pass is where watermarks and pre/post-roll clips are applied, since they have to be encoded into each rendition.

The transcoding pipeline

When a video is ready to process, TubePress enqueues one job per output into the transcode_jobs table and works through them:

  1. Queue. A job is created for the full-resolution source rung and for each active format below the source height, plus a timeline job if previews are enabled.
  2. Pick up. A worker — this server or a remote one — claims the next pending job, starting with the source rung.
  3. Download. A remote worker pulls the source over HTTP (a direct, key-authenticated URL that bypasses signed media links).
  4. Transcode. FFmpeg encodes the rendition, applying trim, watermark and intros as configured, reporting percentage progress as it goes.
  5. Upload & callback. The result is uploaded back in chunks and a callback marks the job complete.

The video's status tracks this: it sits at processing while jobs run, flips to published as soon as the source rung finishes, and only becomes error if the source rung can never be produced. Lower renditions continue filling in after publish.

Embed videos are never transcoded. Only uploaded or URL-based files enter the pipeline; a video with an embed code is served straight from its source.

Renditions & formats

Output formats are fully editable on the Formats tab and stored in the video_formats table. Each format has a name, a file postfix (for example _720p.mp4), a target resolution, raw FFmpeg options, a keep aspect ratio flag and an active toggle. The built-in defaults are:

FormatResolution
720p1280 × 720
480p854 × 480
360p640 × 360

Two rules keep quality sane. TubePress never upscales: any format at or above the source height is skipped. And the original top quality is always kept — if a watermark or trim is in play it is re-encoded into a full-resolution source rendition (shown with a star in the queue), otherwise the source file is served as-is. A Trim start option (0–300 seconds) can drop the first seconds of every video; like the watermark, it is applied to every format including the source.

The job queue

The Queue tab (/admin/settings?tab=transcode&sub=queue) groups jobs by video and lets you filter by All / Pending / Processing / Completed / Failed. Each video shows a badge per rung — the starred source rung, then each resolution, then TIMELINE — coloured by job status:

pending
Queued, waiting for a free worker.
processing
Active, with a live stage (downloading, transcoding or uploading) and a percentage.
completed
Rendition produced and stored.
failed
Out of retries for now; auto-recovery still applies (below).

A per-video console (the terminal icon) streams the live job list, the worker handling each rung, elapsed time and any error message. A Retry failed jobs button re-queues everything that is currently failed in one click.

Remote transcode servers

Transcoding is CPU-heavy, so you can move it off the web server. On the Servers tab, This Server sets how many FFmpeg jobs run locally at once (1–4, or 0 to use remote workers only) and lets you override the FFmpeg path. Below it you register remote workers; jobs auto-distribute to the least-loaded one, and each carries a max concurrent jobs limit (a good rule is one job per two CPU cores).

  1. Add the server. Click Add Server, give it a name and a URL such as http://YOUR-IP:8090, and save. An API key and the start command are shown immediately.
  2. Install FFmpeg + PHP. On the worker box run sudo apt install ffmpeg php-cli php-curl.
  3. Deploy the worker. Download transcode-worker.php (from /api/transcode-worker-download or a temporary wget link), upload it, and open the port with sudo ufw allow 8090/tcp.
  4. Start it. Run the worker with your key:
php transcode-worker.php --port=8090 --key=YOUR_API_KEY
  1. Verify. Click Check; a healthy worker reports Online with its detected encoder and live CPU/GPU usage.

GPU acceleration (NVIDIA, AMD, Intel or Apple) is detected and used automatically. The worker pulls the source, transcodes, reports progress and uploads results in chunks back to the CMS — the chunked upload is what keeps each request under Cloudflare's 100 MB limit. For unattended hosts the setup guide includes a systemd unit so the worker restarts on boot.

Protect the worker in production. The worker speaks plain HTTP on its port. Put Nginx with HTTPS in front of it, and restrict the port to your CMS server.

Monitoring & retries

The system is built so a video is never silently abandoned. A failed encode is retried automatically with an increasing back-off — from about half a minute up to a few hours — because most failures are transient (a slow or flaky CDN). Beyond that, an hourly recovery task re-queues any job still marked failed, so it keeps trying until the rendition lands. No manual click is required, though the Retry failed jobs button is there if you want to force it.

If the source rung itself permanently fails, its dependent sub-format jobs are cancelled (they cannot proceed without a source) and the video is marked error; recovery will still attempt to bring it back. When the source rung finally completes, the video auto-publishes.

Requirements

FFmpeg must be available wherever transcoding runs:

  • Local processing: install FFmpeg on the CMS server (sudo apt install ffmpeg). The Transcode page shows the detected version once present.
  • Remote processing: each worker needs FFmpeg plus php-cli and php-curl, at least 2 CPU cores and 2 GB RAM, and an open worker port.
No FFmpeg, no transcoding. If FFmpeg is missing locally and no remote server is online, the transcoding toggle cannot be enabled — install FFmpeg or add a worker first.

Next steps

Still stuck?

Open a ticket from your dashboard and our team will help you out.

Try the live demo → Download TubePress →