Timeline Render
Renders a gtrk v1 timeline structure directly into a final video (a single mp4). It shares the same gtrk v1 contract with Project File Export: from the same timeline you can export editor projects for refinement, or render the final video in the cloud.
ℹ️ Note: Unlike project export, rendering must actually read the media, so each
materials[].idmust be a platform file ID (file_id) already uploaded to the platform;materials[].path(local path) is ignored by this endpoint. Every material referenced by a clip must be uploaded first.
Create Task
Basics
| Item | Value |
|---|---|
| Method | POST |
| Path | /task/video_timeline_render |
| Content-Type | application/json |
| Auth | Authorization header (raw API Key) |
| Billing | by input duration (total output duration, minutes) |
Request Body
The body is a gtrk v1 timeline structure. All time fields are in seconds.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
version | string | Yes | — | Contract version, fixed to "v1" |
video_size | array | Yes | — | Output canvas size [width, height] in pixels, e.g. [1920, 1080] |
video_rate | number | Yes | — | Output frame rate (fps, integer), e.g. 30 |
duration | number | No | auto | Total output duration (seconds); inferred from the timeline tail when omitted |
materials | array | Yes | — | Material list; each id is a platform file ID, see below |
video_track | array | Yes | — | Video track list. This endpoint renders only 1 video track, see below and "Limitations" |
audio_track | array | Yes | — | Audio track list (layered), 0–N tracks; multiple tracks are mixed, empty array [] = silent |
beat_track | array | No | [] | HTML particle overlay layer. This endpoint ignores beat_track; to render particles use html_animate_render |
struct_meta | object | No | {} | Draft-output and other metadata; ignored by this endpoint. You can pass the same timeline used for project export as-is |
materials[] entry
Each material is identified by a single id — in this endpoint id is the platform file ID (file_id), and the material must be uploaded first. Clips reference this id via the material field.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Material identifier, i.e. the platform file ID (file_id), referenced by clips via material |
path | string | No | Local material path; ignored by this endpoint (used only by project export / offline ffmpeg) |
duration | number | No | Material total duration (seconds) |
video_size | array | No | Material native size [width, height] (video materials) |
video_rate | number | No | Material frame rate (video materials) |
audio_channel | string | No | Channel layout, "stereo" or "mono" (audio materials) |
💡 Tip: Materials referenced by the video track must be video files; materials referenced by audio tracks may be audio or video files.
materials[].path/duration/video_size/video_rate/audio_channelare only reference metadata at render time — you can pass the same timeline used for project export as-is.
video_track[] object
track_index is an explicit z-layer integer, and the lowest track_index is the base track (main). This endpoint renders only the main base track — any extra overlay video tracks are ignored (see "Limitations").
| Field | Type | Required | Description |
|---|---|---|---|
track_index | number | Yes | Explicit layer; the lowest is the base track (main), i.e. the one actually rendered |
track_size | array | No | Native size [width, height] of this track's material, used to scale/fit to the canvas video_size |
muted | boolean | No | Track-level default mute, overridable by clip-level muted |
track_timeline | array | Yes | Sequence of clips on the track, each a clip object |
audio_track[] object
Audio tracks may be multiple and are mixed automatically. volume has two-level semantics (track and clip).
| Field | Type | Required | Description |
|---|---|---|---|
track_index | number | Yes | Explicit layer (distinguishes multiple audio tracks) |
volume | number | No | Track-level default volume, overridable by clip-level volume; defaults to 1.0 |
track_timeline | array | Yes | Sequence of clips on the track, each a clip object |
track_timeline[] clip object (video / audio)
Each non-gap clip carries both the source-trim timecodes (clip_st/clip_ed) and the on-track timecodes (track_st/track_ed/duration); the two sets are kept redundantly. This endpoint takes the segment clip_st–clip_ed from the source material and places it at track_st on the output.
| Field | Type | Required | Description |
|---|---|---|---|
clip_id | string | Yes | Clip identifier; empty string "" means a gap (black frames on video, silence on audio); a gap omits material / clip_st / clip_ed |
material | string | Yes | References materials[].id (omitted for gaps) |
clip_st | number | Yes | Trim-in inside the source material (seconds) |
clip_ed | number | Yes | Trim-out inside the source material (seconds) |
track_st | number | Yes | In-point on the output timeline (seconds); clips on the same track must not overlap |
track_ed | number | Yes | Out-point on the output timeline (seconds) |
duration | number | Yes | Clip duration (seconds), must be > 0 |
muted | boolean | No | (video) clip-level mute, overrides track-level muted |
volume | number | No | (audio) clip-level volume, overrides track-level volume |
ℹ️ Two-level mute / volume semantics: video uses
muted, audio usesvolume, each with a track level and a clip level. Priority: clip level if present, otherwise track level, otherwise the default (muteddefaults tofalse,volumeto1.0).
Request Example
The example below shows multiple clips from one source plus one audio track: materials declares one video source (F100) and one background track (F200); video_track cuts several segments from the same video source using different clip_st/clip_ed (with a black-frame gap in between); audio_track lays down one BGM.
curl -X POST https://api.ai-mcn.tv:10000/task/video_timeline_render \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"version": "v1",
"video_size": [1280, 720],
"video_rate": 30,
"duration": 22.47,
"materials": [
{
"id": "F100",
"duration": 120.0,
"video_size": [1920, 1080],
"video_rate": 30,
"audio_channel": "stereo"
},
{
"id": "F200",
"duration": 180.0,
"audio_channel": "stereo"
}
],
"video_track": [
{
"track_index": 0,
"track_size": [1920, 1080],
"muted": false,
"track_timeline": [
{
"clip_id": "c1", "material": "F100",
"clip_st": 18.50, "clip_ed": 28.05,
"track_st": 0.0, "track_ed": 9.55, "duration": 9.55
},
{
"clip_id": "",
"track_st": 9.55, "track_ed": 10.55, "duration": 1.0
},
{
"clip_id": "c2", "material": "F100",
"clip_st": 33.70, "clip_ed": 45.62,
"track_st": 10.55, "track_ed": 22.47, "duration": 11.92
}
]
}
],
"audio_track": [
{
"track_index": 0,
"volume": 0.8,
"track_timeline": [
{
"clip_id": "a1", "material": "F200",
"clip_st": 0.0, "clip_ed": 22.47,
"track_st": 0.0, "track_ed": 22.47, "duration": 22.47
}
]
}
]
}'
Success Response Example
{
"code": 200,
"msg": "success",
"data": {
"task_id": "537489015178400",
"task_type": "video_timeline_render",
"status": "queued"
}
}
Query Task Result
Basics
| Item | Value |
|---|---|
| Method | GET |
| Path | /task/video_timeline_render/{task_id} |
| Auth | Authorization header (raw API Key) |
Response (output_result)
The output is a single mp4 video.
| Name | Type | Description |
|---|---|---|
file_id | string | Output video file ID |
download_url | string | Download path |
duration | number | Output duration (seconds), equals total timeline duration |
video_size | array | Output resolution [width, height] |
Success Response Example
{
"code": 200,
"msg": "success",
"data": {
"task_id": "537489015178400",
"status": "completed",
"progress": 100,
"output_result": {
"file_id": "537489015178401",
"download_url": "/download/c1/537489015178401.mp4",
"duration": 22.47,
"video_size": [1280, 720]
},
"create_time": "2026-06-11T08:00:00Z",
"update_time": "2026-06-11T08:00:25Z"
}
}
Error Codes
| Code | HTTP Status | Description | Solution |
|---|---|---|---|
6013 | 400 | Required parameter missing (version / video_size / video_rate / materials / video_track / audio_track) | Provide required parameters |
6016 | 400 | Invalid structure (material not in the materials list, clip count over limit, duration ≤ 0, overlapping clips, etc.; details in response) | Fix the timeline as indicated |
6004 | 404 | A file in materials[].id does not exist | Check the file IDs and upload status |
6014 | 400 | Material type mismatch (e.g. non-video file on the video track) | Check material types |
6502 | 401 | Authentication failed | Check the Authorization header |
6201 | 402 | Insufficient quota | Purchase a quota package or top up |
6202 | 402 | Insufficient balance | Top up via dashboard |
Limitations
- Single video track: this capability renders only 1 video track — the main base track (lowest
track_index); any extra overlay video tracks are ignored. For multi-track compositing / picture-in-picture / particle animation, use Project File Export (export a project to your editor for refinement) or html_animate_render (particle compositing into a final video). Audio tracks may be multiple and are mixed automatically. - Particles ignored:
beat_trackis ignored by this endpoint; the body may carry it to keep the gtrk structure intact, but it does not affect the output. For HTML particles use html_animate_render. - Clip count limit: total clips across all tracks ≤ 500.
- Always re-encoded: cut points rarely fall on keyframes, so output is re-encoded (h264 + aac); rendering time scales with output duration — poll every 5–10 seconds.
- Automatic media normalization: materials with different resolutions / frame rates are scaled, letterboxed to
video_sizeand frame-rate normalized; heterogeneous materials can be mixed freely. - Billed by input duration: charged by total timeline duration (= output duration, minutes), independent of source material length.
- Complements project export: the same gtrk v1 timeline (with
materials[].idas platform file IDs) can be sent to both endpoints — refine in your editor, or render in the cloud.