A high-performance, stateless non-linear video and media rendering engine built on the Bun runtime using NodeAV (native FFmpeg bindings) and @napi-rs/canvas (native Skia rendering). It parses timeline manifests to composite and export fully rendered video/audio files.
- FFmpeg installed on your host system.
bun install
bun start- API Server:
http://localhost:3005 - Swagger Docs:
http://localhost:3005/docs - Health Check:
http://localhost:3005/health
A pre-packaged environment containing Bun, FFmpeg, and native Skia canvas libraries:
docker compose up --build -d # Start service
docker compose down # Stop serviceYou can import and use the rendering core directly in your TypeScript/JavaScript application:
import { RenderService, Manifest } from "./src/index";
const renderService = new RenderService();
const manifest: Manifest = {
id: "simple-example",
settings: {
width: 640,
height: 360,
fps: 30,
format: "mp4",
quality: "high",
shouldIncludeAudio: false
},
tracks: {
main: {
id: "track-main",
name: "Main Track",
type: "video",
isMain: true,
muted: true,
hidden: false,
elements: [
{
id: "clip-1",
type: "video",
sourceUrl: "./test-assets/mov_bbb.mp4",
startTime: 0,
duration: 5.0,
trimStart: 0,
trimEnd: 0,
params: { width: 640, height: 360 }
}
]
},
audio: [],
overlay: []
}
};
const videoPath = await renderService.renderManifest(
manifest,
(progress) => console.log(`Progress: ${progress}%`),
"./test-outputs/output.mp4"
);
console.log(`Rendered: ${videoPath}`);All environment variables (PORT, CONCURRENT_RENDER_LIMIT, resource limits) are documented in env.md.
Detailed specifications, time-mapping logics, and node-rendering algorithms:
| Category | Reference Guide |
|---|---|
| Manifest | Architecture & Schema • Render Dataflow • Simulation Cases |
| Tracks | Track Schema Spec • Layering & Z-Index |
| Elements | Video • Image • Audio • Text • Sticker • Graphic • Effect • Transition |
| Rendering | Algorithms Guide • Visual System Plan • Core Functions |
| Config | Environment Variables |
Execute automated E2E render tests using mock assets:
# Run a specific transition test interactively
bun run test:transition
# Run a standard track/element test
bun run test gaps
bun run test element:video
# Run all test suites sequentially
bun run test:render && bun run test:gaps && bun run test:animations && bun run test:pipAll rendered video outputs are saved under ./test-outputs/.