Project File Export

Convert a gtrk v1 timeline structure into project files for multiple non-linear editors (NLE) in a single call: Premiere/FCP7 XML, Final Cut Pro X, OpenTimelineIO, JianYing draft, CapCut draft, and the Tonghe gtrk project file. Ideal for importing an algorithmically arranged video structure straight into an editor for further refinement.

ℹ️ Note: Unlike other endpoints, this one requires no file upload — the request body itself is the timeline structure. The asset paths in materials[].path are local references in the caller's editing environment; the server never reads the asset files, it only converts the structure. materials[].id is the platform-returned file ID (file_id) in cloud scenarios.

Create Task

Basic Information

ItemValue
Request MethodPOST
Request Path/task/video_project_struct
Content-Typeapplication/json
AuthenticationRaw API key in the Authorization header

Request Body

The body is a gtrk v1 timeline structure. All time fields are in seconds.

ParameterTypeRequiredDefaultDescription
versionstringYes-Contract version, fixed at "v1"
video_sizearrayYes-Canvas size [width, height] in pixels, e.g. [1920, 1080]
video_ratenumberYes-Overall frame rate (fps, integer), e.g. 60
durationnumberYes-Total output duration (seconds)
materialsarrayYes-Asset list; each entry has an id plus metadata (see below)
video_trackarrayYes-Video tracks (layered), see below
audio_trackarrayYes-Audio tracks (layered), see below
beat_trackarrayNo[]HTML particle overlay layers. This endpoint ignores beat_track; to render particles use html_animate_render
struct_metaobjectNo{}Contains nle_draft_dir (draft folder path), see below
project_formatsarrayNoallSubset of formats to produce; omit to produce all public formats. The legacy name output_formats is still accepted as an alias

materials[] entry

Each asset is identified by a single id — the platform file_id in cloud scenarios, or a local ID in purely local scenarios. Clips in video_track / audio_track / beat_track reference this id via their material field.

Each entry uses one of two reference forms, and both may be mixed within one request:

  • Local reference: the entry carries a non-empty path (absolute path recommended, always forward slashes /). The id may then be any local identifier — it only serves as the clip reference key and no platform file check is performed. The path is written into the generated project file as-is for your local editing software to load, so make sure it is valid in your environment;
  • Cloud reference: the entry has no path. The id must then be a platform file ID (file_id) of an existing file, otherwise 6004 (file not found) is returned.
FieldTypeRequiredDescription
idstringYesUnique asset identifier; any local ID when path is present, must be a platform file ID (file_id) when it is not; referenced by clips via material
pathstringNoLocal asset path (absolute + forward slashes recommended) for NLE project files / offline ffmpeg; never read by the server; when present, the entry is exempt from the platform file check
durationnumberNoTotal asset duration (seconds)
video_sizearrayNoOriginal asset size [width, height] (video assets)
video_ratenumberNoAsset frame rate (video assets)
audio_channelstringNoChannel layout, "stereo" or "mono" (audio assets)

💡 Tip: Fill in as much metadata per asset as you can, so that a client holding the gtrk can rebuild the project offline with ffmpeg without resolving IDs back through the cloud. A missing field does not break serialization — it is simply omitted.

Track object in video_track[] / audio_track[]

Both video and audio tracks are layered by track: track_index is an explicit integer z-order, and the track with the smallest track_index is the base track (main); the rest are overlays (larger track_index is closer to the front).

FieldTypeRequiredDescription
track_indexnumberYesExplicit layer; the smallest is the base track (main)
track_sizearrayNo(video track only) Original asset size [width, height] of this track, for scaling against the canvas video_size
mutedbooleanNo(video track only) Track-level default mute, can be overridden by a clip-level muted
volumenumberNo(audio track only) Track-level default volume, can be overridden by a clip-level volume
track_timelinearrayYesSequence of clip objects on the track. Array order does not matter (the server places clips by track_st)

Clip object in track_timeline[] (video / audio)

Every 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 to serve both "start + duration" and "start + end" consumers. The array order of track_timeline does not matter: every clip is placed absolutely on the timeline by its track_st (the server always positions clips by track_st), so out-of-order submissions produce the same output as time-ordered ones, and real gaps between clips are preserved as-is.

FieldTypeRequiredDescription
clip_idstringYesClip identifier; an empty string "" means a Gap (a gap omits material / clip_st / clip_ed)
materialstringYesReferences a materials[].id (omitted for gaps)
clip_stnumberYesSource in-point within the asset (seconds)
clip_ednumberYesSource out-point within the asset (seconds)
track_stnumberYesClip in-point on the timeline (seconds)
track_ednumberYesClip out-point on the timeline (seconds)
durationnumberYesClip duration (seconds)
mutedbooleanNo(video) Clip-level mute, overrides the track-level muted
volumenumberNo(audio) Clip-level volume, overrides the track-level volume

ℹ️ Two-layer mute / volume semantics: video uses muted, audio uses volume, each at both the track level and the clip level. Precedence: clip-level if present, otherwise track-level, otherwise the default (muted defaults to false, volume defaults to 1.0).

struct_meta object

FieldTypeRequiredDescription
nle_draft_dirstringNoAbsolute path to the JianYing / CapCut draft folder. The legacy name capcut_draft_path is still accepted as an alias

⚠️ What nle_draft_dir actually is: it is the absolute path of the draft folder where the JianYing / CapCut draft should land on disk. JianYing / CapCut recognize a draft by the pair of draft_content.json + draft_meta_info.json sitting in that folder. If you omit this path, the endpoint only produces draft_content.json (the content file); without draft_meta_info.json (the meta file) the editor may fail to open the draft. So to open the finished draft in JianYing / CapCut, always pass nle_draft_dir.

beat_track[] particle overlays

beat_track carries HTML animation particle overlay layers. This Project File Export endpoint ignores beat_track — NLE project files do not carry HTML particles. To actually render particles into the picture, use html_animate_render instead. The request body may still include beat_track to keep the gtrk structure complete, but it does not affect this endpoint's output.

project_formats values

There are 6 public output formats:

ValueOutputSaved as
xmlPremiere / FCP7 XML.xml
fcpxmlFinal Cut Pro X.xml
otioOpenTimelineIO.json
jianyingJianYing draft (produced as a pair automatically)draft_content.json + draft_meta_info.json
capcutCapCut draft (produced as a pair automatically)draft_content.json + draft_meta_info.json
gtrkTonghe project file (single-index JSON, for import into the Tonghe client).gtrk

ℹ️ Note: JianYing / CapCut drafts require both the content and meta files placed together in the draft folder to be recognized, so selecting jianying / capcut automatically produces both. files[].format in the response still identifies individual files (e.g. jianying_draft / jianying_meta). Compatibility: the legacy fine-grained values (jianying_draft, etc.) are still accepted with their original single-file semantics; new integrations should use the table above.

Request Example

The example below shows cutting multiple segments from one source: materials declares a single video source, video_track cuts several segments from the same asset using different clip_st / clip_ed and stitches them together, then layers an audio_track, and specifies project_formats.

curl -X POST https://api.ai-mcn.tv:10000/task/video_project_struct \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "version": "v1",
    "video_size": [1920, 1080],
    "video_rate": 60,
    "duration": 9.0,
    "materials": [
      {
        "id": "F100",
        "path": "C:/clips/source.mp4",
        "duration": 120.0,
        "video_size": [1920, 1080],
        "video_rate": 60,
        "audio_channel": "stereo"
      },
      {
        "id": "F200",
        "path": "C:/clips/bgm.mp3",
        "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": 10.0, "clip_ed": 13.0,
            "track_st": 0.0, "track_ed": 3.0, "duration": 3.0
          },
          {
            "clip_id": "c2", "material": "F100",
            "clip_st": 55.0, "clip_ed": 59.0,
            "track_st": 3.0, "track_ed": 7.0, "duration": 4.0,
            "muted": true
          },
          {
            "clip_id": "c3", "material": "F100",
            "clip_st": 88.0, "clip_ed": 90.0,
            "track_st": 7.0, "track_ed": 9.0, "duration": 2.0
          }
        ]
      }
    ],
    "audio_track": [
      {
        "track_index": 0,
        "volume": 0.8,
        "track_timeline": [
          {
            "clip_id": "a1", "material": "F200",
            "clip_st": 0.0, "clip_ed": 9.0,
            "track_st": 0.0, "track_ed": 9.0, "duration": 9.0
          }
        ]
      }
    ],
    "struct_meta": {
      "nle_draft_dir": "C:/Users/Me/AppData/Local/JianyingPro/User Data/Projects/com.lveditor.draft/20260626"
    },
    "project_formats": ["xml", "gtrk", "jianying"]
  }'

Success Example

{
  "code": 200,
  "msg": "success",
  "data": {
    "task_id": "537489015178247",
    "task_type": "video_project_struct",
    "status": "queued"
  }
}

Query Task Result

Basic Information

ItemValue
Request MethodGET
Request Path/task/video_project_struct/{task_id}
AuthenticationRaw API key in the Authorization header

Response Fields (output_result)

FieldTypeDescription
filesarrayList of successfully produced project files
files[].formatstringOutput format: xml / fcpxml / otio / gtrk / jianying_draft / jianying_meta / capcut_draft / capcut_meta
files[].file_idstringOutput file ID
files[].download_urlstringDownload path
files[].filenamestringSuggested file name (e.g. draft_content.json; the editor only recognizes it once placed in a draft folder)
errorsobjectFailed formats and reasons (non-empty on partial success)

ℹ️ Partial success: each format is generated independently; a failure in one format does not affect the others, and the task is still marked completed with the failures recorded under errors. The task is marked failed only when all formats fail.

Success Example

{
  "code": 200,
  "msg": "success",
  "data": {
    "task_id": "537489015178247",
    "status": "completed",
    "progress": 100,
    "output_result": {
      "files": [
        {"format": "xml", "file_id": "537489015178248", "download_url": "/download/a1/537489015178248.xml", "filename": "premiere.xml"},
        {"format": "gtrk", "file_id": "537489015178249", "download_url": "/download/a2/537489015178249.gtrk", "filename": "project.gtrk"},
        {"format": "jianying_draft", "file_id": "537489015178250", "download_url": "/download/a3/537489015178250.json", "filename": "draft_content.json"},
        {"format": "jianying_meta", "file_id": "537489015178251", "download_url": "/download/a4/537489015178251.json", "filename": "draft_meta_info.json"}
      ],
      "errors": {}
    },
    "create_time": "2026-06-01T08:00:00Z",
    "update_time": "2026-06-01T08:00:03Z"
  }
}

Error Codes

CodeHTTP StatusDescriptionResolution
6013400Missing required parameter (video_size/video_rate/duration/materials/video_track/audio_track)Provide the required parameters
6004400A cloud-referenced asset does not exist (an entry without path whose id matches no platform file)Verify the file_id, or add a path to switch the entry to a local reference
6016400Invalid parameter type or structure (e.g. a material not in the materials list, an illegal value in project_formats)Check the timeline structure and values
6502401Authentication failedCheck the Authorization header
6201402Quota insufficientBuy a quota pack or top up
6202402Balance insufficientTop up in the dashboard

Limitations

  • Structure-only conversion: the server does not read the files referenced by materials[].path; it only writes the paths into the project files. Make sure those paths are valid in your editing environment.
  • Particles are not rendered here: beat_track is ignored by this endpoint; render HTML particles via html_animate_render.
  • Per-call billing: billed once per request, regardless of how many formats are produced.
  • Draft version compatibility: the generated JianYing / CapCut drafts must be opened with a compatible client version (the draft schema evolves with the app). Place draft_content.json and draft_meta_info.json into the corresponding draft folder to open and keep editing.
  • Draft meta: jianying_meta / capcut_meta are produced only when struct_meta.nle_draft_dir is provided; without it only the content file is produced and the editor may fail to open the draft.