Building an HLS video pipeline with FFmpeg and BullMQ
Introduction
When building a video platform, one of the first challenges is converting uploaded video files into adaptive bitrate HLS streams. This tutorial walks through building a production-ready encoding pipeline using FFmpeg and BullMQ.
Architecture overview
The pipeline consists of three main components:
1. Upload handler — accepts video files and stores them temporarily
2. Job queue — BullMQ manages encoding jobs with retry logic
3. Encoding worker — FFmpeg processes videos into multi-quality HLS
Upload → Queue Job → FFmpeg Worker → HLS Output → CDN
Setting up the queue
BullMQ provides a robust job queue built on Redis. It handles retries, concurrency, and job prioritization out of the box.
import { Queue, Worker } from 'bullmq';const encodingQueue = new Queue('video-encoding', {
connection: { host: 'localhost', port: 6379 },
defaultJobOptions: {
attempts: 3,
backoff: { type: 'exponential', delay: 5000 },
},
});
FFmpeg encoding profiles
We encode each video into three quality levels for adaptive streaming. Each profile targets a specific bandwidth range.
const profiles = [
{ name: '360p', width: 640, height: 360, bitrate: '800k' },
{ name: '720p', width: 1280, height: 720, bitrate: '2500k' },
{ name: '1080p', width: 1920, height: 1080, bitrate: '5000k' },
];
The encoding worker
The worker picks up jobs from the queue and runs FFmpeg to produce HLS segments. Each quality level gets its own playlist, and a master playlist references all of them.
This approach ensures that players can switch between quality levels seamlessly based on the viewer's bandwidth — which is the whole point of adaptive bitrate streaming.
Error handling and retries
Video encoding can fail for many reasons: corrupt input files, out-of-memory errors, or FFmpeg crashes. BullMQ's retry mechanism handles transient failures automatically, while permanent failures are logged and flagged for review.
Conclusion
Building a reliable encoding pipeline is one of the most critical parts of any video platform. With FFmpeg for encoding and BullMQ for job management, you get a production-ready system that handles failures gracefully and scales horizontally.