Building a Self-Hosted Video Processing Platform with Bun, FFmpeg, and Docker

FFMPG video procession image

Modern video applications need more than simple file uploads. They require automated transcoding, adaptive streaming, thumbnail generation, and a scalable processing pipeline.

To explore this space, I built a self-hosted video processing platform using Bun and FFmpeg that converts uploaded videos into production-ready HLS streams.

What the Project Does

The platform allows users to:

  • Upload video files
  • Automatically process videos in the background
  • Generate multiple video resolutions
  • Create adaptive HLS playlists
  • Generate thumbnails
  • Generate preview sprite images
  • Generate VTT files for video scrubbing previews
  • Track processing status

After processing, videos are delivered as adaptive bitrate streams that can be played efficiently across different devices and network conditions.

Tech Stack

Backend

  • Bun
  • TypeScript
  • SQLite

Video Processing

  • FFmpeg
  • FFprobe

Deployment

  • Docker
  • Docker Compose

Processing Pipeline

When a video is uploaded:

1. Video Analysis

FFprobe extracts metadata such as:

  • Duration
  • Resolution
  • Codec information
  • Frame rate

2. Thumbnail Generation

The system generates preview thumbnails from the source video.

3. Multi-Bitrate Transcoding

The video is converted into multiple resolutions:

  • 1080p
  • 720p
  • 480p

Each stream is encoded using H.264 and AAC.

4. HLS Packaging

FFmpeg creates:

  • .m3u8 playlists
  • .ts segments

A master playlist is generated for adaptive streaming.

Example:

1080/playlist.m3u8
720/playlist.m3u8
480/playlist.m3u8
master.m3u8

5. Preview Assets

Additional assets are generated:

  • Thumbnail sprites
  • WebVTT timeline previews

These improve the user experience when seeking through videos.

Why HLS?

HLS (HTTP Live Streaming) offers several advantages:

  • Adaptive bitrate streaming
  • Better playback on slow networks
  • Reduced buffering
  • Broad browser anddevice support
  • CDN-friendly architecture

Instead of serving a single large video file, the player dynamically switches between quality levels based on network conditions.

Why Bun?

The project uses Bun as the backend runtime because it provides:

  • Fast startup times
  • Excellent TypeScript support
  • Built-in package management
  • Native APIs for file handling
  • Simplified deployment

For media processing workloads, Bun offers a lightweight and efficient runtime environment.

Containerized Deployment

The entire platform runs inside Docker containers.

The container includes:

  • Bun runtime
  • FFmpeg
  • FFprobe
  • Application code

This makes deployment consistent across development and production environments.

Challenges Faced

Running Desktop-Specific Code in Containers

Initially, the application attempted to open the server URL automatically using:

xdg-open

This works on desktop Linux environments but fails inside Docker containers because no graphical environment exists.

The solution was to remove automatic browser launching and keep the application server-only.

Bun Build Targets

While creating production builds, Bun-specific imports required compiling with:

bun build --target=bun

Without the correct target, Bun APIs such as:

import { spawn } from "bun";
import { Database } from "bun:sqlite";

cannot be bundled correctly.

Current Features

✅ Video Upload

✅ FFmpeg Processing

✅ Multi-Resolution Transcoding

✅ HLS Streaming

✅ Thumbnail Generation

✅ Preview Sprite Generation

✅ WebVTT Timeline Previews

✅ SQLite Storage

✅ Docker Deployment

Conclusion

This project demonstrates how a lightweight stack consisting of Bun, FFmpeg, SQLite, and Docker can be used to build a complete video processing pipeline capable of generating adaptive HLS streams and video preview assets.

It provides a strong foundation for building video platforms, online learning systems, media libraries, or any application that requires efficient video delivery at scale.

Project link: github.com/joy095/ffmpeg-video-stream

Portfolio: joykarmakar.vercel.app

LinkedIn: linkedin.com/in/joy-karmakar-cooch-behar

ende