Section 06
Project Timeline & publishing
Where the Director auto-generates an edit, the Project Timeline is the hands-on layer: you pick the clips and arrange them yourself. Then Publish sends the result out of Studio as a shareable link or an NLE-ready file.
The timeline editor is the same multi-track editor the Director uses — only the driver differs (you vs. the agent team). Manual edits sit on top of a Director run's seeded timeline; either path produces a versioned, exportable assembly.
The Project Timeline
Each project has one working timeline. You build it by adding clips from the two places you discover them:
- Search results — click the + on any clip card.
- Segmentation — click the + on any segment row (visual / spoken / structure / transcript) or on a custom profile's segments.
As you add clips, a dock appears at the bottom of the Search and asset views showing the running assembly (count, duration, a thumbnail filmstrip). From the dock you can remove a clip, clear the timeline, or jump to the full editor with Open Timeline.
The editor
Open the Timeline module to get the full multi-track editor:
- A composition-backed preview up top — plays the real assembly via an
AVMutableCompositionbuilt from your tracks. What you see here is what gets exported / published. - The canvas below, where you can:
- Drag a clip to reorder.
- Drag a clip edge to trim in / out.
- Split at the playhead (toolbar button).
- Delete to remove a clip (history-preserving — it lives in the previous version).
- Zoom in / out (
Cmd -,Cmd 0,Cmd =); Fit snaps the timeline back to "full width in the viewport" after you've zoomed (and re-enables auto-fit on subsequent edits). Transport uses space and the arrow keys. - The video track carries the visual layer.
- The program audio lane is derived from the video track — per-clip lanes so you can see cut boundaries — and is what the preview / export mixes from by default.
- Optional music and voiceover lanes layer on top, with per-lane volume + ducking controls (Milestone 2).
Versioning
Every edit creates a new immutable version:
- A Director run creates an initial seeded version.
- Every manual gesture (reorder, trim, split, delete) commits a new version with provenance (author = "you" / "Director" / "agent") and a diff summary ("trim clip 4 by 0.8s", "split clip 7 at 12.34s").
- The version switcher (⌄ next to the version label) lists every version with timestamp + author + summary. Click to switch (preview that version), or use Restore to make it the head and branch from there.
- Duplicate creates a parallel branch so you can A/B two cuts without losing either.
Each version is a full snapshot of the timeline aggregate (Timeline struct serialized as JSON), not a diff. Switching versions is a JSON decode — fast, and there's no version-graph traversal to reason about.
Transitions
Adjacent clips can have an explicit transition. The model supports four kinds:
- Cut (default) — instantaneous.
- Dissolve — opacity ramp over a configurable duration.
- Dip to black — fade to black, then back up.
- Dip to white — fade to white, then back up.
Transitions OVERLAP the clips on either side rather than inserting extra time. This is the single most important invariant of the timeline — the same effectiveTransitionDurations() calculation is used by the preview builder, the FFmpeg export, and the FCPXML / EDL exporters, so what you see in preview is what every output produces.
M1 caveat: today the FFmpeg export and the FCPXML / EDL writers flatten transitions to cuts; cross-dissolves and dip transitions are visible in the preview only. Transition rendering at export is on the Milestone 2 roadmap.
Variations Studio
The docked Variations panel (right side of the editor) is a clip-swap auditioning tool. Pick any clip on the timeline → the panel shows ranked alternatives drawn from this run's unused candidate pool (the segments the Assistant Editor surfaced for the picked clip's phase but the Sequence Editor didn't choose). Drag an alternative onto the target slot to swap; each swap creates a new version, so you can A/B freely.
Useful for the Showrunner's territory — "this opener is fine but maybe there's a better one" — without re-running the whole Director.
Audio lanes
Three logical lanes:
- Program — derived from the video track. Per-clip, so cut boundaries are visible.
- Music — independent track for an underscore. You add a music clip from your library (any asset, picked into the music lane); volume + fade-in/out controls per clip.
- Voiceover — independent track for narration. ElevenLabs-backed audio description renders here when the audio-description feature is used (Milestone 2 + roadmap §Q).
Each lane has its own mix bus. The preview's AVAudioMix and the export's FFmpeg amix filter both read from the same lane structure.
Clearing / starting over
Clear (in the editor header or the dock) empties the timeline so you can start fresh. It's history-preserving — the previous cut is still restorable from the version switcher.
Publishing
Open the project's Publish module. It's organized by destination:
- TwelveLabs Cloud — Live. Renders your edit to MP4 and uploads it; you get a public link that opens in any browser without sign-in.
- YouTube / Instagram / Facebook — Coming soon. Shown as previews of the roadmap; not yet functional.
Under TwelveLabs Cloud you'll see your publishable work:
- Your Project Timeline (when it has clips), and
- Every ready Director run with its own card.
Each item is a card with a thumbnail, a status (Ready / Publishing / Published / Failed), and actions.
Publish to Cloud
- Click Publish… on the item.
- Fill in title / description / tags and accept the terms.
- Studio renders the assembly to MP4 (in the background, visible in the Job Monitor). No file-picker step — the render is automatic.
- The MP4 uploads to the TwelveLabs Cloud media bucket via a presigned PUT URL minted by the cloud API. A 1280×720 poster JPG is uploaded alongside for social-card previews (Open Graph / Twitter).
- When the upload completes, Studio calls
POST /v1/projects/{id}/complete; the card flips to Published. Use Open page to view it, or Copy URL to share.
Re-publishing — cache behavior
The render path is content-addressable: Studio hashes the accepted-clip set (asset id + segment in/out per clip) and uses that hash as the render cache key.
- Unchanged clip set → cache hit, no re-render. The previous render is reused. Re-publishing is near-instant.
- Any change to the accepted clips or their in/out times → cache miss, re-render. (Cosmetic-only edits to transitions, music, or VO lanes don't currently bust the cache — they'd compose at preview but not at render in M1.)
- Transition / audio-lane changes do not yet affect the cached MP4 — those aren't rendered in the shipped pipeline (Milestone 2).
This means there's no penalty to publishing early and iterating — the URL stays stable, and only real changes cost a re-render.
Export to a file / NLE
The Export action (or the item's overflow menu) writes a local file instead of publishing:
- FCPXML — for Final Cut Pro. The exporter writes per-clip elements as Final Cut clips; in Milestone 1 transitions are flattened to cuts (cross-dissolves come in Milestone 2).
- EDL (CMX 3600) — for DaVinci Resolve and Premiere. EDLs don't support multi-track audio or transitions cleanly, so the export flattens to a single video + program-audio track.
- Open in Final Cut Pro — writes the FCPXML and hands it to Final Cut Pro by document open, falling back to the default
.fcpxmlhandler if Final Cut isn't installed. - MP4 — a rendered, self-contained file (same render path as Publish, just written to disk).
Exports run as jobs (visible in the Job Monitor), using the same export framework for both Director runs and the Project Timeline.
Director vs. Timeline: publishing a Director run shares the auto-generated cut; publishing the Project Timeline shares the cut you assembled. Both land at a public TwelveLabs Cloud URL the same way, and both are exportable to FCPXML / EDL / MP4.
Render pipeline (under the hood)
The renderer is FFmpeg-backed. For each accepted clip Studio re-encodes a 1080p30 / yuv420p / AAC-48k canvas part with libx264 -preset veryfast -crf 20, then runs a final concat-demuxer pass to stitch the parts into the output MP4. Per-clip re-encode (rather than stream-copy) ensures consistent framerate, color, and audio across mixed source material.
For typical 60s content this renders in roughly half wall-clock duration on Apple Silicon — a 60s cut renders in around 30 seconds.
Render outputs are cached on disk; re-publishing an unchanged timeline reuses the previous render.
Once-published, what's next?
A published edit lives on the TwelveLabs Cloud — the web app at twelvelabs-studio.vercel.app shows it on your profile (signed-in only) and via direct /p/{id} links. From Studio's Publish card you can:
- Open page — view the published edit in a browser.
- Copy URL — share the link anywhere.
- Re-publish — push the latest timeline state to the same URL.
- Unpublish — remove the public link (not yet implemented; roadmap).