2

Zictovid

An engine that generates vertical 3D videos where every bounce lands exactly on the beat. Sub-band DSP analysis, inverse solver, Blender rendering at 1080×1920 and 60 fps, 735 tests. Next.js frontend, NestJS API, self-hosted GPU worker.

Zictovid - Videos locked to the beat

Zictovid generates vertical 3D music videos in which every impact of a bouncing ball lands exactly on a beat of the track. You drop in a song, the engine analyses the signal, derives a trajectory, builds the scene and renders the video.

The inverse solver

The core of the product is not Blender, it is the inverse solver. Most tools simulate a ball and hope it lands on the beat. Zictovid does the opposite: it starts from the beat timestamps and analytically derives the level geometry from them.

That has two consequences. Synchronization is exact by construction rather than approximate, and rendering becomes deterministic — therefore unit-testable, without ever launching Blender.

The full pipeline chains four stages:

  • DSP analysis of the track, producing the beat map (beatmap.json)
  • Inverse solver, deriving the level geometry from it (level.json)
  • Blender, driven through bpy, building the scene and rendering a silent video
  • ffmpeg muxing, re-attaching the audio track and delivering final.mp4

Analysis relies on peak detection across frequency sub-bands, with no source separation, followed by six corrective passes. Beat intensity drives bounce height, and the format is natively vertical: 1080×1920 at 60 fps, ready for TikTok, Reels and Shorts.

Testing discipline

This is the part I am happiest with: 735 green tests, with golden files compared down to the ULP and a ratcheting anti-regression baseline across the measurement benches. On an engine that manipulates signal and floating-point geometry, this is what makes refactoring possible without breaking sync.

The stack

  • Engine: Python — DSP, solver, scene generation through bpy, EEVEE rendering, ffmpeg muxing
  • Frontend: Next.js deployed on Vercel
  • API: NestJS — Google authentication, quotas, Stripe, render queue
  • Data: PostgreSQL, orchestrated with Docker Compose
  • Hosting: render worker self-hosted on one of my own machines, exposed through a Cloudflare Tunnel — 3D rendering demands a GPU, so it cannot live in a standard cloud container

Pricing derived from real cost

The three tiers — free Discovery, Creator at €24/month, Studio at €59/month — are not a marketing guess. Rendering was measured: roughly 45 minutes of GPU time per 60 seconds of video on an RTX 3070 Ti. At that cost an unlimited plan is untenable, and the real economic lever is maximum duration per video rather than the number of videos.

Those values live in a single source of truth, read by both the pricing page and the quota and Stripe billing engine. The file explicitly separates what commits — prices in cents, quotas, Stripe identifiers — from what is displayed and translated per language. Two price lists that drift apart means a customer billed for something they never got.


Available at zictovid.com.