Docs
Cetus renders a plain HTML composition into video by seeking browser state for every frame and piping captured PNG frames into bundled ffmpeg.
Install
curl -fsSL https://cetus.cenvero.org/install | sh
Cetus ships as one binary per platform. After install it does not need Node.js, npm, system Chrome, or system ffmpeg.
Commands
cetus render cetus.html -o out.mp4
cetus render cetus.html -o out.webm
cetus preview cetus.html
cetus update check
cetus update apply
cetus version
cetus.html is the recommended default filename. Cetus accepts any HTML file path.
| Flag | Use |
|---|---|
-o, --output | Required output path. |
--fps | Frames per second. Defaults to the HTML value or 30. |
--width, --height | Override composition dimensions. |
--format | mp4 or webm. Defaults from output extension. |
--no-gpu | Disable GPU acceleration for CI, Docker, or headless Linux servers. |
Output Controls
The HTML composition should normally be the source of truth for render settings. Use CLI flags only when you intentionally want to override the HTML defaults for one render.
FPS
Set the frame rate in HTML with data-fps. Override it at render time with --fps only when you want a different output than the composition declares.
<div id="root"
data-composition-id="intro"
data-width="1920"
data-height="1080"
data-duration="10"
data-fps="30"></div>
cetus render cetus.html -o out.mp4 --fps 60
| FPS | Best For | Tradeoff |
|---|---|---|
24 | Cinematic motion and lighter renders. | Less smooth for UI motion. |
30 | Default web, product, launch, and social videos. | Balanced render time and smoothness. |
60 | Very smooth UI motion and fast transitions. | Twice as many frames as 30 fps. |
90+ | Special high-motion or high-refresh use cases. | Large frame counts and longer render times. |
Total captured frames are calculated as duration * fps. A 10 second video at 30 fps renders 300 frames. The same video at 60 fps renders 600 frames. Cetus accepts positive FPS values, so 90, 120, and 144 fps are possible when the extra render cost is acceptable.
Size
Use data-width and data-height in HTML for the composition canvas. Use --width and --height only for one-off override renders.
cetus render cetus.html -o landscape.mp4 --width 1920 --height 1080
cetus render cetus.html -o vertical.mp4 --width 1080 --height 1920
cetus render cetus.html -o square.mp4 --width 1080 --height 1080
Format
Cetus infers the format from the output extension unless --format is provided.
cetus render cetus.html -o out.mp4
cetus render cetus.html -o out.webm
cetus render cetus.html -o out.video --format mp4
Timeout and GPU
--timeout sets the maximum render time in seconds. GPU stays enabled by default for WebGL, Three.js, and shader animations. Use --no-gpu on CI, Docker, or headless Linux servers where GPU drivers are not available.
cetus render cetus.html -o out.mp4 --timeout 600
cetus render cetus.html -o out.mp4 --no-gpu
Composition HTML
The root element declares the canvas, duration, and identity of the video.
<div id="root"
data-composition-id="intro"
data-width="1920"
data-height="1080"
data-duration="5"
data-fps="30">
<h1 class="clip"
data-start="0.5"
data-duration="4"
data-track-index="0">
Hello World
</h1>
</div>
| Attribute | Required | Description |
|---|---|---|
data-composition-id | Yes | Unique composition ID. |
data-width | Yes | Output width in pixels. |
data-height | Yes | Output height in pixels. |
data-duration | Yes | Total duration in seconds. |
data-fps | No | Default frame rate. |
Clips
Any element with class="clip" appears only during its configured time range.
<video class="clip"
data-start="0"
data-duration="10"
data-track-index="1"
data-volume="0.4"
src="bg.mp4"
muted playsinline></video>
data-startis the clip start time in seconds.data-durationis how long the clip stays active.data-track-indexmaps to z-index layering.data-volumecontrols audio/video volume from 0.0 to 1.0.
Animation
CSS animations, WebGL, Three.js, GSAP, video, audio, and normal browser APIs can run inside a composition. GSAP timelines should be paused and registered on window.__timelines.
<script>
window.__timelines = window.__timelines || [];
const tl = gsap.timeline({ paused: true });
tl.from("#title", { opacity: 0, y: 40, duration: 0.8 });
window.__timelines.push(tl);
</script>
Rendering Model
For each frame, Cetus calculates time = frame / fps, writes that time to document.__cetusTime, seeks timelines, seeks media elements, updates clip visibility, then captures one deterministic browser frame through Chrome DevTools.
cetus.html
-> parse data attributes
-> launch embedded headless browser
-> seek frame state
-> capture PNG frame
-> pipe frames to embedded ffmpeg
-> write MP4 or WebM
Preview
The preview command serves the composition locally and injects a tiny live-reload client at runtime. It does not modify your source HTML.
cetus preview cetus.html
cetus preview cetus.html --port 8080
cetus preview cetus.html --no-open
Updates
For direct binary installs, Cetus can check the release manifest and apply the latest stable release.
cetus update check
cetus update apply
The updater downloads the archive for your platform, verifies its SHA-256 from the manifest, extracts the cetus binary, and replaces the current executable.
If Cetus is managed by Homebrew, self-update is disabled and Cetus prints the Homebrew command instead.
brew update && brew upgrade cenvero-cetus