Export: start, then poll
Use these three tools to write the timeline to a file from an agent, follow the job and stop it. export doesn’t wait for the file. It checks the request, puts a job on the Export Queue and returns at once, and the agent then asks how the job is going until it ends.
- Menu
- File ▸ Export…Window ▸ Export Queue
- Keys
- ⌘E
- Where
- The export sheet's Add to Queue, and each row's Cancel in the Export Queue
- Agent tools
exportexport_statuscancel_export
Write a file
Section titled “Write a file”-
Call
exportwith a preset and a path. It returns straight away.{ "preset": "h264", "path": "/Volumes/Edits/cut", "size": "1080p" }{ "export_id": 3, "path": "/Volumes/Edits/cut.mp4", "status": "running" } -
Call
export_statuswith thatexport_id, pause, and call it again untilstatusisdone,failedorcancelled. -
Read the
doneresult. It says what the file holds, including the loudness it measured and any warnings.
To stop the job, call cancel_export. The job shows in Window ▸ Export Queue like any other, but the window doesn’t open by itself.
Export
Section titled “Export”export does what File ▸ Export… does with Add to Queue, and it writes the file the same way, so an agent’s file and a person’s match. It takes the export sheet’s controls in the sheet’s own terms, apart from the frame rate, which it doesn’t take, and Quality, which it sets as exact rates.
| Argument | Type | Required | What it does |
|---|---|---|---|
preset |
string | Yes | The encoding: a container and a codec. See Presets. |
path |
string | Yes | Where to write, such as ~/Movies/cut.mp4. See Path handling. |
size |
string or [width, height] |
No | The output size. See Size. |
range |
string | No | project for the whole timeline, or in_out for the in/out range. See Range. |
video_bitrate |
integer | No | Target video rate in bits per second. See Exact bitrates. |
audio_bitrate |
integer | No | Target AAC or Opus rate in bits per second. See Exact bitrates. |
loudness_lufs |
number | No | Normalise the whole mix to this loudness, −70 to 0. See The loudness report. |
peak_dbtp |
number | No | The master limiter’s ceiling, −20 to 0. See Peak dBTP. |
audio_bits |
integer | No | 16 or 24, for WAV and AIFF. See Audio bits. |
stems |
string | No | tracks or names, to write stems beside an audio mix. See Stems. |
burn_in_timecode |
boolean | No | Draw the project timecode over the picture, on top of everything. Off by default. See Burn in timecode. |
dynamic_range |
string | No | hlg, pq or sdr, in an HLG project. See Dynamic range. |
encoder_speed |
string | No | faster, balanced or smaller, for AV1. See Encoder speed. |
project |
string | No | The path of the open project to export, as get_project reports it. Without it, the frontmost project. |
It returns {export_id, path, status}. path is the file that will be written, with ~ expanded and the extension corrected. status is running if the job started at once, or queued if it’s waiting.
Jobs in the queue run one at a time, behind anything already there. A job writes the project as it stood when export was called, so later edits don’t reach it. Calling export pauses playback in that project’s window.
export takes no scope. With a nest open it still writes the project’s timeline, not the nest’s.
Export status
Section titled “Export status”export_status reports how a job is going, as its row in the Export Queue does, and it never waits. Pass the export_id, which is an integer of 1 or more.
Every result carries export_id, status, path and elapsed, the seconds since export was called, or from then to the finish once the job has ended. The rest depends on the status.
status |
Also carries |
|---|---|
queued |
waiting while an AV1 or VP9 job is held for memory. estimated_seconds on av1, av1_webm, vp9_webm and vp9_alpha_webm. |
running |
progress, from 0 to 1. phase while the job has one: “Preparing…” until the file’s writer exists, while renders, masks and measurements are still being made, and “Measuring loudness…” during the first pass over the mix. estimated_seconds on the same four presets. |
done |
What the file holds, in the next table. |
failed |
reason, the queue row’s sentence. |
cancelled |
reason, the queue row’s sentence. |
estimated_seconds is the export sheet’s estimate of the whole export in whole seconds, and it’s only an estimate.
waiting is a sentence such as “Waiting for memory: AV1 and VP9 exports running now hold about 2.1 GB of the 8.0 GB this Mac allows them, and this one needs about 7.0 GB.” AV1 and VP9 exports may hold a quarter of this Mac’s memory between them, though a job with no other running always starts. While one is held, a later job in the queue may run first.
A done result adds these keys.
| Key | What it holds |
|---|---|
ok |
true. |
bytes |
The file’s size. |
preset, container, codec |
What was written. |
width, height |
The file’s size in pixels. These are reported on audio presets too, where they mean nothing. |
fps |
The rate as [num, den], such as [30, 1]. |
start, duration |
The part of the timeline written, in ticks. |
burn_in_timecode |
Whether the argument was on. |
dynamic_range |
The picture written: hlg, pq or sdr. Only for a video preset in an HLG project. |
encoder_speed |
The speed used. Only on av1 and av1_webm. |
audio_bits |
The depth written. Only on audio_wav and audio_aiff. |
stems |
[{name, tracks, path}], one per file beside the mix. Only when stems was asked for. |
loudness |
What the mix measured. See The loudness report. |
graphic_warnings |
[{name, frame, message}], each distinct warning a graphic gave while the file was drawn. Collecting stops after 64 distinct reports, so a noisy graphic’s list can be cut short. frame is the graphic’s own frame, or null. Absent when there were none. |
cursor_warnings |
[{media, path, message}], each media whose cursor file couldn’t be drawn. Its clips were written without a cursor. Absent when there were none. |
Cancel export
Section titled “Cancel export”cancel_export stops a job, as the row’s Cancel does, and returns what export_status would. Pass the export_id.
| The job is | What happens |
|---|---|
| Queued | It’s cancelled before it starts. The result reads cancelled, with the reason “Cancelled before it started.” |
| Running | It stops and its partly written file is removed. The result may still read running until writing has stopped, and export_status then reads cancelled, with the reason “Cancelled.” |
| Finished | It’s left alone, and its file stays. The result is the finished job’s. |
Export id and its lifetime
Section titled “Export id and its lifetime”An export_id is known until Frame Job quits. Removing a finished row from the Export Queue, or choosing Clear Finished, doesn’t lose it, so an agent can still read how that job ended.
An id belongs to the launch, not to a project, so export_status and cancel_export don’t need project. Only ids that export returned are known. A job a person queued from the sheet has no id an agent can follow. Any other number returns the error “No export this launch has export_id 7 — ids come from export and last until Frame Job quits.”
Refusals and failures
Section titled “Refusals and failures”A problem Frame Job can see from the request comes back from export itself as an error, and nothing is queued.
| The request | What stops it |
|---|---|
| An empty timeline | “There is nothing on the timeline to export.” |
| A folder that doesn’t exist | “There is no folder at … to write into.” Frame Job never creates the folder. |
| An unknown preset | The error lists all the presets. |
An unknown size, or one it can’t read |
The error lists the sizes. See Size. |
range of in_out with no range set |
“This project has no in/out range — set one with set_range {start, end}, or export with range "project".” |
| A number out of range, or a word it doesn’t know | The error names the argument and the value. |
| An option the preset doesn’t have | See Audio bits, Stems, Dynamic range and Encoder speed. |
| A graphic clip in the range with no module, or a module that doesn’t compile | “The export was not started: the graphic “…” does not compile — …. Fix the module and export again.” A clip with no module reads “has no module in graphics/” in place of “does not compile — …”. It names each graphic and its first error, and it covers graphics inside nests. An audio-only preset draws no graphics, so it isn’t stopped by one. |
More than 600 frames on gif or apng |
“An animated GIF is limited to 600 frames and this range is …. Shorten the range.” There’s no frame-rate argument. See The 600-frame limit. |
| A size of another shape on a transparent preset | “An export that keeps transparency has to have the canvas’s own shape…”. See Transparent presets. |
Anything that goes wrong after that comes back from export_status as failed, with the sentence in reason. Check for it even when export answered cleanly.
| What went wrong | The reason |
|---|---|
| A stem’s file would be one of the project’s media | “The stem “…” would replace media this project uses; export under another name.” |
| A graphic fails while it’s drawn | “The export was stopped at frame … of the graphic “…”: …. No file was written.” |
| A retimed clip’s sound, an isolated voice or a voice effect couldn’t be rendered | The sentence names the clip and the reason. |
| A Remove Background clip’s masks couldn’t be made | “Clip …’s person masks could not be made: ….” A picture set to Foreground says foreground masks. |
| A clip’s gate, leveller or de-esser needs a loudness that hasn’t been measured | “Clip …’s loudness or speech has not been measured yet…”. Wait for the clip’s analysis, then export again. |
| This Mac has no encoder for the preset | “This Mac cannot export with the “…” preset.” |
A graphic’s warnings are different: they don’t stop the export, and they arrive as graphic_warnings in the done result.
Presets
Section titled “Presets”There are 15 presets, one per encoding. A preset says nothing about size. These are the rows of the sheet’s Format control, described in Choose a format. A wrong id’s error lists them all.
| Preset | In the sheet | File | Picture | Sound |
|---|---|---|---|---|
h264 |
H.264 (MP4) | .mp4 |
8-bit. The sheet’s first row. | AAC |
hevc |
HEVC (MP4) | .mp4 |
8-bit | AAC |
hevc_alpha |
HEVC with Alpha (MOV) | .mov |
8-bit with transparency. Safari’s transparent movie. | AAC |
hevc_10bit |
HEVC 10-bit (MP4) | .mp4 |
10-bit | AAC |
av1 |
AV1 (MP4) | .mp4 |
10-bit | AAC |
av1_webm |
AV1 (WebM) | .webm |
10-bit | Opus |
vp9_webm |
VP9 (WebM) | .webm |
8-bit (Profile 0) for an SDR picture, 10-bit (Profile 2) for HLG and PQ. One speed. | Opus |
vp9_alpha_webm |
VP9 with Alpha (WebM) | .webm |
Always 8-bit, with transparency. The transparent movie Chrome and Firefox play. | Opus |
prores_422 |
ProRes 422 (MOV) | .mov |
10-bit. An editing master. | 16-bit LPCM |
prores_4444 |
ProRes 4444 (MOV) | .mov |
12-bit with transparency. A master. | 16-bit LPCM |
audio_m4a |
Audio only (M4A) | .m4a |
None | AAC |
audio_wav |
Audio only (WAV) | .wav |
None | 48 kHz LPCM, 16 or 24 bits |
audio_aiff |
Audio only (AIFF) | .aiff |
None | 48 kHz LPCM, 16 or 24 bits |
gif |
Animated GIF | .gif |
256 colours. Fits inside 480 × 270 unless size says otherwise. |
None |
apng |
Animated PNG | .png |
Lossless, with transparency. Fits inside 960 × 540 unless size says otherwise. |
None |
Macs before M3 can’t play av1 and av1_webm back.
Frame rate
Section titled “Frame rate”There’s no frame-rate argument, so the sheet’s frame rate control has no agent equivalent. An export runs at the project’s rate, gif at 12.5 fps and apng at 25 fps. The done result’s fps says which, with 12.5 fps as [25, 2].
Path handling
Section titled “Path handling”The folder must exist. A ~ at the start is expanded, and an existing file at the path is replaced. It’s removed as writing starts, so a job that fails or is cancelled from then on leaves neither file. Anything earlier, such as a refused call or a cancel while the job is measuring loudness, leaves it as it was.
The file always ends in the preset’s extension.
path |
preset |
Writes | Why |
|---|---|---|---|
cut.mp4 |
h264 |
cut.mp4 |
The extension is already right. |
cut |
h264 |
cut.mp4 |
With no extension, it’s added. |
cut.mov |
h264 |
cut.mp4 |
A different media extension is replaced. |
Talk v1.2 |
h264 |
Talk v1.2.mp4 |
Any other suffix stays part of the name. |
cut.webm |
h264 |
cut.mp4 |
So is .webm. |
cut.mp4 |
av1_webm |
cut.webm |
The same the other way round. |
The extensions it replaces are .mov, .mp4, .m4v, .m4a, .mp3, .wav, .aif, .aiff, .caf, .framejob, .srt, .vtt, .png, .jpg, .jpeg, .heic, .gif and .webm. The returned path is always the file that gets written.
size is the sheet’s Size control. See Export size for what the sizes mean to a person.
size |
In the sheet | What it writes |
|---|---|---|
document |
Document size | The project’s own size. The default on every movie preset. |
2160p |
4K | A short edge of 2160 pixels. |
1440p |
1440p | A short edge of 1440 pixels. |
1080p |
1080p | A short edge of 1080 pixels. |
720p |
720p | A short edge of 720 pixels. |
preset |
GIF default, APNG default | The format’s cap. gif and apng only, where it’s the default. |
[width, height] |
Custom… | Exactly this size, from 16 to 8192 pixels on each edge. |
The number is always the short edge, and the long edge follows the project’s shape, rounded to an even number. A vertical project’s 1080p is 1080 × 1920. Every size means the same on every project, so a 1920 × 1080 project’s 1080p is its own size, and a size larger than the project scales it up.
A movie is written at exactly the size asked for. If the shape differs from the project’s by more than a pixel, the picture is letterboxed. Within a pixel, it fills the frame instead.
- Even edges. Every preset but
prores_4444,gifandapngneeds even dimensions, so an odd width or height is written one pixel smaller. That coversdocumenton a project with an odd edge. Thedoneresult’swidthandheightare the file’s. - GIF and APNG. A size is a box the picture is fitted inside, keeping its shape and never scaling up. A vertical 1080 × 1920 project’s GIF default comes out at 152 × 270.
- Audio presets. A size has no effect, and
presetisn’t one of their sizes. - Transparent movies. A
[width, height]of another shape is an error. See Transparent presets.
An unknown size returns an error with the list, for example “No export size is called “480p” for h264. The sizes are: document, 2160p, 1440p, 1080p, 720p — or pass [width, height].” A custom size outside 16 to 8192 pixels is an error too. It isn’t clamped.
range is the sheet’s Range control. project, the default, writes the whole timeline. in_out writes the range set with set_range, and export returns an error when there’s no range. See Export a range.
The range is snapped to the export’s frame grid and kept inside the project. A range that comes to nothing is an error too.
burn_in_timecode shows project time even in a range export, so a file written from 00:00:10:00 begins at 00:00 with a burn-in that reads 00:00:10:00.
Exact bitrates
Section titled “Exact bitrates”The sheet offers quality tiers. An agent sets the rates directly, in bits per second, so 8 Mbps is 8000000. Each must be a whole number from 1 to 4,294,967,295.
video_bitrate is the target video rate. Without it, Frame Job works out a rate from the frame size and frame rate. ProRes, GIF and APNG ignore it, because ProRes is fixed by its profile and the other two have no bitrate.
On the AV1 and VP9 presets it works differently:
av1andav1_webm. It’s a soft cap. The encoder works at a constant quality matched to HEVC at that rate, and the file usually comes in well under it. Very detailed footage can go up to about 1.25 times over. Without it, the quality is matched to HEVC at 0.07 bits per pixel per frame.vp9_webm. It’s a soft cap too, matched to HEVC, or HEVC 10-bit in an HDR export. Up to about 1.15 times over was measured.vp9_alpha_webm. It’s the same soft cap on the picture’s stream alone. The transparency’s stream comes on top, at a constant quality.
audio_bitrate is the AAC or Opus rate, 192 kbps when absent. Opus takes the nearest rate its encoder offers. ProRes, WAV and AIFF ignore it, because they write LPCM.
The loudness report
Section titled “The loudness report”Every export with sound measures its own mix and reports it as loudness in the done result, normalised or not. GIF and APNG have no sound, and a timeline with no sound has nothing to measure, so loudness is absent from both.
loudness_lufs normalises the whole mix to an integrated loudness, from −70 to 0. The sheet’s Loudness rows are −14 for streaming, −16 for podcasts and −23 for EBU R 128 broadcast, and an agent can ask for any value, such as −14.5. The export measures itself first, then applies one gain to everything, through the master limiter. The file lands on the target with its loudest peaks limited, rather than the whole mix held down. GIF and APNG ignore it.
| Key | What it holds |
|---|---|
summary |
The same line the queue row and the progress sheet show, such as “Peak −1.0 dBTP · −16.0 LUFS”, with “ · peaks limited by 8.6 dB” when the limiter took 0.05 dB or more. |
integrated_lufs |
The file’s integrated loudness. Absent when it has none, and summary then says “loudness not measurable”. |
true_peak_dbtp |
The file’s true peak. null when it’s silent. |
sample_peak_dbfs |
The file’s sample peak, never above the true peak. null when it’s silent. |
gain_db |
The gain applied to reach the target. |
ceiling_dbtp |
The master limiter’s ceiling. |
limited_db |
How far the limiter turned the loudest peak down. |
capped_by_gain |
true when the +40 dB limit on the gain decided it, so the file may be short of the target. |
target_lufs |
The loudness_lufs asked for. Absent when none was. |
A programme shorter than one 400 ms measuring block, or one too quiet to pass the standard’s gate, has a peak and no integrated loudness. Digital silence reads “Silent” in summary.
Peak dBTP
Section titled “Peak dBTP”Every export with sound goes through a master limiter, so the file’s true peak stays at or under a ceiling. peak_dbtp sets that ceiling, from −20 to 0. It’s −1 when absent, which is the sheet’s fixed value. 0 is the loosest, and there’s no way to turn the limiter off.
You can pass it with or without loudness_lufs. limited_db in the report says how far the limiter turned the loudest peak down.
Audio bits
Section titled “Audio bits”audio_bits is the sheet’s Bit depth control: 16, the default, or 24. It’s rounded once from the mix and never dithered, and the done result repeats it.
It works on audio_wav and audio_aiff only. On any other preset export returns the error “h264 has no bit depth; audio_bits applies to audio_wav and audio_aiff”, naming the preset. ProRes keeps 16-bit sound. Any other number is an error, whatever the preset.
stems also writes stems beside the mix, on audio_m4a, audio_wav and audio_aiff. It’s the sheet’s Stems control.
stems |
What it writes |
|---|---|
tracks |
One file per heard track. |
names |
One file per track name. Heard tracks whose names match, ignoring case, share a file, and an unnamed track gets its own. |
A track is heard when it has sound in it and isn’t muted or silenced by another track’s solo. Each stem is named <file> - <track name>.<ext>, beside the mix, so mix.wav and a track called Voice give mix - Voice.wav. An unnamed track is Track N, and Stem file names has the other cases.
A stem holds its tracks’ sound before the master, with no loudness gain and no limiter, so the stems add up to the mix wherever the master changed nothing. Any file already at a stem’s name is replaced.
The done result lists each one as stems [{name, tracks, path}]. tracks holds the ids of the timeline tracks in that stem.
- On any other preset
exportreturns the error “h264 has no stems; stems applies to audio_m4a, audio_wav and audio_aiff”, naming the preset. - With no track heard, the error is “stems: no track is heard, so there is no stem to write”.
- If a stem’s file would be one of the project’s media, the job fails before any stem is written, and
export_statusgives the reason. - A failed or cancelled job leaves neither the mix nor any stem it wrote. A file it hadn’t yet replaced stays.
Dynamic range
Section titled “Dynamic range”dynamic_range chooses the picture an HLG project writes. It’s the sheet’s Dynamic Range control.
dynamic_range |
What it writes |
|---|---|
hlg |
BT.2100 HLG, with no Dolby Vision. The default on the presets that carry HDR. |
pq |
HDR10: BT.2100 PQ at 1,000 cd/m², with a P3-D65 mastering display of 0.005–1,000 cd/m², MaxCLL 1,000 and MaxFALL 0. |
sdr |
The project’s SDR version. |
The presets that carry HDR are hevc_10bit, av1, av1_webm, vp9_webm, prores_422 and prores_4444. Every other video preset in an HLG project writes the SDR version, vp9_alpha_webm included, and audio presets ignore the argument.
hlgorpqon another video preset returns the error “h264 is 8-bit and writes the SDR version; export dynamic_range “pq” as hevc_10bit, av1, av1_webm, vp9_webm, prores_422 or prores_4444”.hlgorpqin an SDR project returns the error “dynamic_range “pq” needs an HLG project; set_canvas output “hlg” first”.sdrin an SDR project changes nothing.
Once a job is done, dynamic_range in the result names the picture that was written. An SDR project’s result has no such key.
Encoder speed
Section titled “Encoder speed”encoder_speed trades export time for file size on av1 and av1_webm. It’s the sheet’s Speed control, and the done result names the one used.
encoder_speed |
SVT-AV1 preset | What it does |
|---|---|---|
faster |
8 | The quickest. |
balanced |
6 | The default. |
smaller |
4 | The smallest file for the picture, and the slowest. |
On every other preset export returns the error “h264 has no encoder speed; encoder_speed applies to av1 and av1_webm”, naming the preset. That includes vp9_webm and vp9_alpha_webm, which have one speed.
Transparent presets
Section titled “Transparent presets”Four presets keep a transparent canvas transparent: prores_4444, hevc_alpha, vp9_alpha_webm and apng. See Transparent exports. A GIF can show a fully transparent pixel, but it has no alpha channel, so nothing partial survives.
On the three movie presets, a [width, height] of a different shape from the canvas can’t be written, because the padding would destroy the alpha channel. export returns an error that names both sizes, and nothing is queued. The shape is judged after an odd edge is evened, and within a pixel the picture fills the frame, so a size in the canvas’s own proportions always works, at any scale. Every named size already has the canvas’s shape.
apng fits its picture inside the size instead, so this doesn’t apply to it.