Skip to content

x-eight/headless-video-composer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Headless Video Composer 🎬

A server-side video composition engine for Node.js — compose videos programmatically using JSON configurations with full support for images, video overlays, text, and audio tracks.

FeaturesHow It WorksQuick StartConfigurationAPI ReferenceLicense


Features

  • 🖼️ Image Layers — Place background images or overlays with precise positioning, scaling, and rotation.
  • 🎥 Video Overlays — Embed video clips with trimming, timeline control, and alpha compositing.
  • ✏️ Dynamic Text — Add text layers via Fabric.js with full styling support (fonts, colors, positioning).
  • 🔊 Audio Sync — Mix multiple audio tracks with trim and timeline alignment for professional output.
  • ⏱️ Timeline System — Each clip has independent display (when it appears) and trim (source segment) controls in milliseconds.
  • 🖥️ Fully Headless — Runs entirely on the server with no browser, GPU, or display required.
  • 📦 Single MP4 Output — Produces ready-to-use H.264 + AAC MP4 files via WebCodecs.

How It Works

JSON Config → Fabric.js Canvas (per frame) → WebCodecs Encoder → MP4 Output
  1. Parse — A VideoConfig JSON defines canvas size, FPS, duration, and an array of clips.
  2. Compose — For each frame, clips are layered onto a Fabric.js StaticCanvas based on z-index and timeline visibility.
  3. Encode — Each composed frame is fed to a WebCodecs encoder (via Mediabunny) and muxed into an MP4 container.
  4. Audio — Audio tracks are decoded, trimmed, time-shifted, and muxed in sync with video.

Tech Stack

Technology Role
Mediabunny WebCodecs-based video/audio encoding & muxing
Fabric.js Server-side canvas composition (fabric/node)
TypeScript Type-safe configuration and rendering logic
Node.js Runtime environment (headless)

Quick Start

Prerequisites

  • Node.js ≥ 18
  • pnpm (recommended) or npm

Installation

git clone https://github.com/nickaroot/headless-video-composer.git
cd headless-video-composer
pnpm install

Add Your Assets

Place your media files in src/files/:

src/files/
├── background.png    # Background image
├── clip.mp4          # Video overlay
└── music.mp3         # Audio track

Run

pnpm dev

The output file (output.mp4) will be generated in the project root.

Configuration

The video composition is defined by a VideoConfig object with two main sections:

Settings

settings: {
    width: 720,        // Canvas width in pixels
    height: 1280,      // Canvas height in pixels
    fps: 30,           // Frames per second
    bgColor: '#000000', // Background fill color
    duration: 5000     // Total duration in milliseconds
}

Clips

Each clip in the clips array represents a layer in the composition:

{
    id: 'bg-image',           // Unique identifier
    type: 'Image',            // 'Image' | 'Video' | 'Text' | 'Audio'
    src: 'background.png',    // Source file (resolved from src/files/)
    left: 400,                // X position (pixels)
    top: 400,                 // Y position (pixels)
    width: 720,               // Display width
    height: 1280,             // Display height
    angle: 0,                 // Rotation in degrees
    zIndex: 1,                // Layer order (higher = on top)
    opacity: 1,               // 0.0 to 1.0
    flip: null,               // Flip transform
    display: { from: 0, to: 5000 },   // Timeline visibility (ms)
    trim: { from: 2000, to: 5000 }    // Source trim range (ms) — Video/Audio only
}

Clip Types

Type Description Required Fields
Image Static image layer src
Video Video overlay with optional trim src, optionally trim
Text Text rendered via Fabric.js text
Audio Audio track (no visual) src, optionally trim

API Reference

renderVideo(config: VideoConfig): Promise<void>

The main entry point. Accepts a VideoConfig object and renders the composition to an MP4 file.

import { renderVideo } from './core/renderer';

await renderVideo({
    settings: { width: 1920, height: 1080, fps: 30, bgColor: '#000', duration: 10000 },
    outputFile: 'my-video.mp4',
    clips: [ /* ... */ ]
});

Project Structure

src/
├── index.ts           # Entry point & sample configuration
├── core/
│   └── renderer.ts    # Main rendering loop (Fabric.js + WebCodecs)
├── types/
│   └── video.ts       # TypeScript interfaces (Clip, VideoConfig, Settings)
├── utils/
│   └── polyfills.ts   # WebCodecs polyfills for Node.js
└── files/             # Media assets directory (git-ignored)
    ├── background.png
    ├── clip.mp4
    └── music.mp3

License

This project is licensed under the MIT License — see the LICENSE file for details.

About

High-performance server-side video rendering engine using Mediabunny and Fabric.js for Node.js.

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors