HTML Animation Render (Layered)
Render a composition spec into a finished video (mp4): a single video base track running through the whole piece (e.g. a talking-head A-roll) plus any number of custom HTML animation particles (overlaid transparently, without covering the subject) are composited in one render. The visual vocabulary is not predefined or enumerated — you author the particles freely, as long as they follow the seekable HTML-animation format. Materials are referenced by composition.assets.file_id.
Which endpoint?
- This endpoint · Layered: you have one long base track running through the whole piece (talking head / B-roll) with transparent particles overlaid on top, not covering the subject → use this.
- HTML Animation Render (Simple): particles are full-screen opaque cut-ins / short clips / pure HTML animation (no long base track running through) → use the simple endpoint, lighter and faster.
- Both endpoints take the exact same input spec; pick by your scene.
Difference from Timeline Render: timeline render is a single-video-track hard cut; this endpoint composites a video base track + multiple custom HTML animation particles, and the visuals are entirely defined by your particles.
Particle Format (Important)
Each custom HTML particle must be a self-contained, seekable HTML animation:
- Its root element must be wrapped in a
<template>:<template><div data-composition-id=...>…</div></template>, otherwise the particle cannot be parsed and the whole render fails; - It must declare its own
data-composition-id/data-width/data-height; - Its animation must be registered on a frame-seekable timeline (recommended: GSAP
gsap.timeline({paused:true})registered onwindow.__timelines). - ⚠️ A particle using only plain CSS
animation-delaywithout a registered timeline cannot be rendered frame-by-frame and will freeze at the animation's end state. Author particles in a seekable format.
Create Task
Basics
| Item | Value |
|---|---|
| Method | POST |
| Path | /task/html_animate_render |
| Content-Type | application/json |
| Auth | Authorization header (API Key directly) |
| Billing | By output duration (minutes) |
Request Body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
composition | object | Yes | — | Composition spec, see below |
render | object | No | {} | fps (defaults to composition.fps or 30) / quality (draft/standard/high, default high) |
composition object
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
video_size | object | Yes | — | {"width":w,"height":h} |
fps | number | No | 30 | Output frame rate |
duration | number | No | auto | Output duration (s); derived from max track/particle end if omitted |
assets | object | Yes | — | Material refs, must contain file_id: {asset_name: platform_file_id} (base tracks and any file_id-referenced particles) |
tracks | array | Yes | — | Base tracks (video/audio), at least 1 |
beats | array | No | [] | Custom HTML animation particle overlays |
tracks[] base-track object
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | video or audio |
asset | string | Yes | Asset name (key in assets.file_id) |
track_index | number | Yes | Layer (higher = front; no overlap within a layer) |
start | number | Yes | Start time on the output timeline (s) |
duration | number | No | Duration (s); optional for video/audio |
muted | boolean | No | Video only, default true |
volume | number | No | Audio only, default 1.0 |
beats[] particle object
| Field | Type | Required | Description |
|---|---|---|---|
id | string | No | Unique identifier |
start | number | Yes | Enter time (s) |
duration | number | Yes | On-screen duration (s) |
track_index | number | Yes | Overlay layer (z-order) |
opaque | boolean | No | Whether the particle is full-screen opaque (covers the base). For layered scenes usually false (transparent overlay that doesn't cover the subject); set true for a full-screen opaque cut-in |
html | string | one of | Inline: the particle HTML source directly in the field (self-contained, one call) |
html_asset | string | one of | Reference: the particle HTML is uploaded; put its key in assets.file_id |
Each particle must provide either
html(inline) orhtml_asset(file_id reference).
Request Example
curl -X POST https://api.ai-mcn.tv:10000/task/html_animate_render \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"composition": {
"video_size": {"width": 1920, "height": 1080},
"fps": 30,
"duration": 8.5,
"assets": {"file_id": {"base": "78246108192718854", "base_audio": "78246108192718855"}},
"tracks": [
{"type": "video", "asset": "base", "track_index": 0, "start": 0, "duration": 8.5, "muted": true},
{"type": "audio", "asset": "base_audio", "track_index": 5, "start": 0, "duration": 8.5, "volume": 1.0}
],
"beats": [
{"id": "b1", "start": 3.0, "duration": 4.6, "track_index": 10, "opaque": true,
"html": "<template><div data-composition-id=\"p1\" data-width=\"1920\" data-height=\"1080\">...particle HTML with a GSAP timeline registration...</div></template>"}
]
},
"render": {"fps": 30, "quality": "high"}
}'
Success Response
{"code": 200, "msg": "success", "data": {"task_id": "537489015178500", "task_type": "html_animate_render", "status": "queued"}}
Query Task Result
| Item | Value |
|---|---|
| Method | GET |
| Path | /task/html_animate_render/{task_id} |
| Auth | Authorization header |
Response (output_result)
| Field | Type | Description |
|---|---|---|
file_id | string | Output file ID |
download_url | string | Download path |
duration | number | Output duration (s) |
video_size | object | {"width":w,"height":h} |
Error Codes
| Code | HTTP | Description | Fix |
|---|---|---|---|
6013 | 400 | Missing composition | Provide required params |
6016 | 400 | Invalid spec (particle missing html/html_asset, too many clips, duration ≤ 0, render out of range) | Fix per response |
6004 | 404 | A file in assets.file_id does not exist | Check file ID / upload |
6014 | 400 | Base-track material type mismatch | Check material type |
6502 | 401 | Auth failed | Check Authorization header |
6201 / 6202 | 402 | Quota / balance insufficient | Top up |
Limits
- Particles must be seekable: each particle must be wrapped in a
<template>, declaredata-composition-id, and register a frame-seekable timeline (see "Particle Format"); plain-CSS particles without registration will freeze. - Clip cap: base tracks + particles ≤ 200.
- Billed by output duration (minutes); frame-by-frame rendering, so render time scales with duration/complexity — poll every 5–10 s.
- Best for: a long base track running through the piece + transparent particle overlays (subject on camera + graphics that don't cover them); for full-screen opaque cut-ins / short clips / pure HTML animation, use the lighter HTML Animation Render (Simple).
- Complementary to timeline render: use Timeline Render for single-track hard cuts; use this for a video base + custom animation particles.