VEDL Language Reference
Write video edits as text. Learn VEDL with examples for cuts, photo layouts, transitions, animated props, captions, music, color grading and export.
VEDL is a text file that describes a video edit. Each line does one job: keep a part of a recording, show a photo, add a title, or mix in music. Save the file with a .vedl extension.
This guide describes the current development version. VEDL v2 is not yet released. Photo compositions, per-scene transitions and animated props require a build that includes those commands.
Start with a short edit
Save this as talk.vedl, next to a recording named talk.mp4:
source "talk.mp4"
cut 01:12 01:32 frame=fill
cut 04:03 04:18 frame=fill
transition xfade 0.5
text "A better way to begin" at 0 for 3 pos=top size=56
fade out 0.5
This keeps two parts of the recording and joins them with a half-second crossfade. The result is 34.5 seconds: 20 + 15 − 0.5. The title appears for the first three seconds.
Render a portrait video:
5am media edit render talk.vedl --aspect 9:16 --output talk-short.mp4
Examples below use placeholder filenames. Replace them with your own media. A photo-only script uses still or scene lines and needs no source line.
| What you want to do | Commands and examples |
|---|---|
| Choose footage and framing | Video editing: source, cut, delete, prepend, append, frame, focus |
| Arrange photos or add a moving character | Photo composition: still, presentation, scene, props |
| Change from one scene to the next | Transitions and beat timing: transition, join, saved frame schedules |
| Add words, logos or speaker names | Text and branding: text, captions, caption, card, brand, overlay, speaker |
| Show another clip over the main video | B-roll: insert |
| Add a soundtrack or balance volume | Music and loudness: music, normalize |
| Adjust color and finish the edit | Color grading and finishing: grade, grade hsl, fade, chapter |
| Make a video or an editable project | Rendering and export |
File format
- Write one command per line. Blank lines are ignored. Command names are case-insensitive; use the lowercase option values shown here.
- Put filenames and text in double quotes. Use
\"for a quote inside a string and\\for a backslash. Relative paths start from the.vedlfile's directory. - Start a comment with
#, either on its own line or after whitespace. A color such ascolor=#ffee00is not a comment. - Times accept seconds, minutes and seconds, or hours, minutes and seconds.
90,1:30and0:01:30mean the same time. Decimal seconds are allowed. - Durations are in seconds:
0.5,3and3s. Thescene,joinand prop commands use integer frame counts where specified. - Positions such as
focus=0.6,0.4are fractions:0,0is the top-left corner and1,1is the bottom-right. - Quote an option value that contains spaces:
font="Instrument Serif".
Two clocks: at vs atsrc
Use at for a time in the finished video. Use atsrc for a time in the original recording. Image overlays use the equivalent names from and fromsrc.
source "interview.mp4"
cut 01:00 01:20
text "Meet the founder" at 0 for 3
text "The first customer" atsrc 01:08 for 3
The first title appears when the output starts. The second appears eight seconds later, because source time 01:08 falls eight seconds into the kept footage.
Source times are adjusted for cuts and transition overlaps. If an anchor points into removed footage, the renderer moves it to a nearby kept moment and reports a warning. In photo-only scripts, use at: there is no source recording for atsrc to refer to.
Video editing
Keep or remove parts of a recording
Use source once to name the main recording. cut START END keeps a range, including its start and excluding its end. Write cuts in time order, without overlaps.
source "interview.mp4"
cut 00:10 00:25 # introduction
cut 01:00 01:20 # the answer
Or use delete START END to remove ranges and keep the rest:
source "interview.mp4"
delete 0 10
delete 00:25 01:00
Choose cut or delete for one script; do not mix them. Overlapping deletes are merged. With neither command, a source-only script keeps the whole recording. Kept ranges shorter than 50 milliseconds are dropped with a warning.
prepend "intro.mp4" and append "outro.mp4" add complete clips before or after the edit. Use at most one of each:
source "interview.mp4"
cut 10 30
prepend "intro.mp4"
append "outro.mp4"
Fit a video into the canvas
Add framing options to a cut:
| Option | Result |
|---|---|
frame=fill | Fill the canvas by cropping the source. |
frame=fit | Keep the whole source visible; add bars where needed. |
frame=split | Stack two crops of the same video, usually for two speakers. Requires a portrait canvas. |
frame=face | Ask Clip Maker to find a face. It saves a concrete crop; a manually rendered unresolved face falls back to centered fill. |
focus=X,Y | Center the crop on this point in the source. On its own, it implies frame=fill. |
focus2=X,Y | Choose the second crop in a video split. |
focus_end=X,Y | Move a fill crop from focus to this point over the cut. |
Keep a speaker in frame as they lean across the picture:
source "interview.mp4"
cut 10 18 frame=fill focus=0.65,0.45
cut 18 19 frame=fill focus=0.65,0.45 focus_end=0.45,0.45
cut 19 30 frame=fill focus=0.45,0.45
The middle cut moves the crop for one second. All three cuts touch, so they play continuously without a transition between them.
For two speakers:
source "interview.mp4"
cut 10 30 frame=split focus=0.25,0.5 focus2=0.75,0.5
focus controls the top panel; focus2 controls the bottom. Those two points are also the defaults when omitted. On a square or landscape canvas, video split falls back to fill with a warning. Photo layout=split is a different layout and works at those aspect ratios.
focus_end requires a starting focus and fill framing. A video cut cannot use focus with frame=fit or frame=face.
Photo composition
Show one photo with still
Use still "photo.jpg" for SECONDS. A still lasts 0.5–180 seconds and has no audio of its own. A document holds at most 64 timeline lines (still, scene, cut and clip together) and 256 commands in all.
still "street.jpg" for 3 frame=fill focus=0.5,0.4 motion=pan
still "cafe.jpg" for 3 frame=fill motion=zoom
still "sunset.jpg" for 4 frame=fill motion=zoomout
transition xfade 0.5
These three photos make a nine-second video after the two crossfade overlaps.
motion | Camera movement |
|---|---|
none | Hold the picture still; the default. |
zoom | Slowly move closer. |
zoomout | Slowly pull back. |
pan | Slowly move across the picture. |
Use frame=fit to keep the whole photo visible. Use frame=fill and an optional focus to control the crop.
Give photos an instant-print frame
presentation instant gives the stills a white paper border, a deeper bottom margin and a shadow:
presentation instant background="#e8e5dc" tilt=-5 animation=slide
still "friends.jpg" for 3 frame=fill motion=none
still "beach.jpg" for 3 frame=fill motion=zoom
transition xfade 0.4
| Setting | Meaning |
|---|---|
background=COLOR | Canvas color; default #e8e5dc. |
image="paper.jpg" | Optional background image, cropped to fill the canvas. Takes priority over the solid color. |
tilt=N | Clockwise print rotation, from −12 to +12 degrees; default 0. |
animation=none|slide|fade | Print entrance and exit; default none. |
The entrance and exit happen inside the photo's duration. They do not add time or replace a transition between scenes. Tilt and these entrance settings belong to the instant-print layout.
A plain still line under a presentation always renders as an instant print. presentation with any other layout (split, stack, gallery, contact, full) is only valid next to scene lines, where it supplies the shared background; next to a plain still it is rejected with an error that points at scene.layout.
Arrange several photos with scene
scene gives a photo layout a name, a frame count and a frame rate. At 30 fps, frames=90 means three seconds.
presentation split background="#f3ede3"
scene "details" frames=90 fps=30 layout=split photos="[{\"path\":\"detail.jpg\",\"frame\":\"fill\"},{\"path\":\"whole.jpg\",\"frame\":\"fill\"}]"
This shows two photos in vertically stacked panels. Change layout=split to layout=stack to arrange the same two photos as overlapping prints.
| Layout | Photos | Appearance |
|---|---|---|
full | 1 | A photo across the canvas; its frame setting controls cropping. |
instant | 1 | A white instant-print frame and shadow. |
gallery | 1 | A photo with its original shape, surrounded by a matte. |
stack | 2 or 3 | Overlapping, slightly rotated prints. |
split | 2 | Two vertically stacked photo panels. |
contact | 4 or 6 | A contact sheet with two columns. |
Each entry in photos has a path. Optional settings are frame:"fill" or "fit", motion:"none", "zoom", "zoomout" or "pan", and focus:{"x":0.5,"y":0.4}. Each photo can have its own crop and camera move. Omitted photo motion means no movement.
Keep the JSON array on the same command line. Quotes inside it need escaping, as shown above. Unknown fields and trailing JSON are rejected.
A scene ID must be unique, using 1–64 letters, digits, underscores or hyphens. Scene durations are 0.5 seconds to just under 180 seconds. fps is an integer from 1 to 120; every scene and join in the document must use the same value. An explicit render frame rate must match it.
Use presentation for shared background settings and scene layout=… for each composition. Multi-photo layouts need explicit scene photo slots. Photo scenes and ordinary video cut lines can appear together in timeline order.
Add a bird or character with props
A prop is a transparent image that moves inside a scene. For a character that also flaps or waves, provide a sprite atlas: one PNG containing equally sized square animation frames, arranged left to right, then top to bottom.
This example expects bird-atlas.png to have four columns and four rows, with 16 frames:
scene "garden" frames=90 fps=30 layout=gallery photos="[{\"path\":\"garden.jpg\",\"frame\":\"fill\"}]" props="[{\"id\":\"bird\",\"path\":\"bird-atlas.png\",\"action\":\"fly\",\"startFrame\":15,\"frames\":60,\"x\":0.5,\"y\":0.35,\"size\":0.24,\"layer\":\"front\",\"columns\":4,\"rows\":4,\"count\":16}]"
The bird flies across the three-second scene. Its action starts at frame 15 and lasts through frame 74: two seconds at 30 fps. The atlas supplies the wing movement.
| Prop setting | Meaning |
|---|---|
id, path | A unique ID within the scene and the atlas filename. Optional name is a display label, up to 80 characters. |
action | fly crosses the scene, peek rises into view, hop jumps and lands, wave stays in place while the atlas supplies the gesture, hold stays in place with no fade and may span the whole scene, fade stays in place with a fade envelope, and slide-left, slide-right, slide-up and slide-down travel through the position along one axis. |
startFrame, frames | Scene-local start and duration. Frame numbering starts at 0. |
x, y | Resting position or flight center, from 0 to 1 across the canvas. |
size | Sprite width as a fraction of canvas width: 0.05–0.6. |
layer | front draws above photos; behind draws above the backdrop but below photos. A full-frame photo hides a behind prop. |
flip | Optional true mirrors the sprite and reverses a fly path. |
columns, rows, count | Atlas grid and number of used cells. Each axis is 1–8; count is 1 through the number of cells, at most 64. |
beat | Optional true lets Reel Studio's beat-sync pass align this action. It does not analyze music when a saved file is rendered. |
A scene supports up to three props. Each action must fit inside it and last 2 frames to 4 seconds (hold may last the whole scene). The atlas must be no larger than 4096 pixels on either side, with square cells. A single-cell PNG also works for a cutout that only needs positional movement.
Props fade in and out during the first and last 20% of their action, with at least one frame for each fade. Two-frame actions skip the fades. Captions and titles stay above props. A scene transition moves the composed picture, including its props.
Reel Studio prepares atlases from a saved Storybook character or a design from its character & sticker studio. VEDL uses the resulting PNG and frame settings; it does not generate character art or run Storybook code during rendering.
Transitions and beat timing
Use one transition throughout
transition TYPE SECONDS sets the transition between separate shots:
source "demo.mp4"
cut 0 4
cut 10 14
cut 20 24
transition push 0.4
| Type | What happens |
|---|---|
cut | Switch immediately; no duration needed. |
xfade | Blend the outgoing and incoming pictures. |
fadeblack | Fade through black. |
wipe | Reveal the next picture across the canvas. |
push | Move both pictures across the canvas. |
snap-zoom | Zoom in, switch pictures near the middle, then settle. |
Omitting transition gives hard cuts. Use at most one global transition line. Durations are 0–10 seconds and are capped at 45% of the shortest shot. Transitions overlap their neighbors, so they shorten the total output.
Adjacent cuts of the same source that touch, such as cut 0 10 and cut 10 20, form one continuous shot. They never receive a transition between them.
Choose a transition for a particular scene
Use join after a named scene. It overrides the global transition at that boundary. Its timing is in frames, not seconds.
This example expands the second photo in a split layout into the next full-frame scene:
presentation split background="#f3ede3"
scene "pair" frames=90 fps=30 layout=split photos="[{\"path\":\"detail.jpg\",\"frame\":\"fill\",\"motion\":\"none\"},{\"path\":\"whole.jpg\",\"frame\":\"fill\",\"motion\":\"none\"}]"
scene "hero" frames=90 fps=30 layout=full photos="[{\"path\":\"whole.jpg\",\"frame\":\"fill\",\"motion\":\"none\"}]"
join after="pair" effect=panel-reveal frames=14 impact=13 fps=30 source=1
The output is 166 frames: 90 + 90 − 14. The next scene starts at output frame 76, and the reveal reaches full frame at frame 89. source=1 selects the second photo; slot indexes start at 0.
A join accepts the six transition types above, plus these composition effects:
| Effect | Requirement |
|---|---|
card-deal | The incoming scene is a Stack. Its last print slides into place. |
hero-expand | A photo in Gallery, Stack, Split or Contact Sheet expands into a following Full frame scene. |
panel-reveal | A photo in Split expands into a following Full frame scene. |
Hero Expand and Panel Reveal must use the same photo and focus in the outgoing slot and incoming scene. Set both to frame:"fill" and motion:"none". Use source=N to choose between repeated copies of a photo; otherwise the first matching slot is used. These three effects require join, not a global transition.
Deal a new print into a stack:
scene "opening" frames=60 fps=30 layout=full photos="[{\"path\":\"first.jpg\",\"frame\":\"fill\"}]"
scene "prints" frames=90 fps=30 layout=stack photos="[{\"path\":\"first.jpg\",\"frame\":\"fill\"},{\"path\":\"second.jpg\",\"frame\":\"fill\"}]"
join after="opening" effect=card-deal frames=12 impact=11 fps=30 direction=left
Join rules:
afternames an existing scene that has a following segment. Only one join may follow that scene.frames=0 impact=0is required foreffect=cut. Other effects use 1 through2*fpsframes, no more than 45% of either neighboring scene. A hand-written join outside that limit is rejected.impactis a frame within the transition: 0 throughframes-1. It marks the moment to align with a beat. It does not change the effect's animation.direction=left|right|up|downapplies to Push, Wipe and Card Deal. Omitted means left.
For a hard cut, use join after="opening" effect=cut frames=0 impact=0 fps=30 instead of the Card Deal line.
Sync to music and replay the result
Beat sync is a planning option in Reel Studio; it is not a VEDL command. The planner measures the music and writes concrete scene durations and join frames into the saved file.
For photo compositions, it keeps the selected effects and total output length. Cut lands on the first incoming frame. Xfade, Fade through black, Wipe and Snap Zoom use the middle frame, floor(frames/2). Push, Card Deal and the two expansion effects use the last transition frame, frames-1.
Props marked beat:true can move their impact to a nearby measured beat, at most half a second away, while keeping the action inside its scene. Hop uses its landing frame; the other actions use the midpoint. This also works in a single-scene reel. If the music has no reliable beat or the timing does not fit, the planner keeps the original timing.
A saved .vedl file replays those decisions without another analysis pass. Playing it again does not choose new beats or regenerate the atlas. Older one-photo still plans use mood-based cuts or dissolves; the per-scene join path preserves your chosen effects.
Text and branding
Titles, captions and cards serve different purposes. text is a simple title; caption is a line in the caption style; card is a designed callout, quote or list.
Renderer support: caption, card and speaker-name layers below are attached by Clip Maker and Reel Studio. The standalone media edit render command currently attaches simple text titles, but not those additional layers. See Rendering and export.
Simple titles with text
source "talk.mp4"
cut 0 12
text "A small change, a big difference" at 0 for 3 pos=top size=56 color=white
text "WORDS" at|atsrc TIME for SECONDS accepts pos, size and color. Defaults are pos=bottom size=48 color=white. Duration is greater than 0 and at most 60 seconds; size is 8–300.
Positions are top, bottom, center, top-left, top-right, bottom-left and bottom-right. Size is pixels on a 1080-pixel-wide canvas and scales with output width. Long titles wrap and may shrink to fit.
Use a typographic apostrophe (’) in text. A straight apostrophe (') is rejected. This restriction does not apply to caption or card text.
Caption style and written captions
captions sets one style for transcript captions and written caption lines. It does not create or load a transcript. Clip Maker supplies the transcript separately.
still "cafe.jpg" for 4 frame=fill
captions style=pop color=white accent=#ffee00 size=48 pos=bottom
caption "Coffee before the city wakes" at 0.5 for 3
The written line appears for three seconds starting half a second into the photo. No transcript is needed for a caption line.
| Setting | Choices |
|---|---|
style | clean, bold, minimal, karaoke, pop, none; default clean. The app calls pop Kinetic. |
color | Main text color. |
keywords="coffee,city" | Up to 16 keywords to highlight. |
accent | Highlight color; falls back to the brand accent, then the style default. |
pos | bottom, center or top; default bottom. |
size | 8–200 pixels on a 1080-wide canvas; omitted uses the style's size. |
font="Family" | Font family, such as Inter or Instrument Serif. |
case | keep or upper; default keep. |
Use at most one captions line. A written caption lasts 0.2–180 seconds and has at most 200 characters. A font is a family name: commas, braces and control characters are rejected. Its only timing options are at|atsrc TIME for SECONDS; set its appearance on captions. Animated styles create word timing for written lines.
Callouts, quotes, lists and title cards
source "talk.mp4"
cut 0 20
card callout "37%" at 2 for 3 sub="less time spent on setup"
card quote "Start with one small habit." at 7 for 4 speaker="Ali"
card list "Try this today" at 13 for 6 items="Pick one task|Set a timer|Review the result"
| Card type | Content |
|---|---|
callout | A large number or short phrase; sub supplies its label. |
quote | A pull quote over a blurred background; speaker supplies attribution. |
list | A heading and up to six items, separated by |. Items appear one by one. |
title | A heading with an optional sub line. |
All cards accept at|atsrc TIME for SECONDS, accent=COLOR and pos=center|top|bottom. Default position is center. Duration is 1–15 seconds. A list needs items; allow enough time for its 1.2-second item spacing.
Brand settings and image overlays
Use brand for a shared accent, font and full-duration logo. Use overlay for an image that appears at a particular time:
source "demo.mp4"
cut 0 15
brand name="Field Notes" accent=#e8b04a font="Inter" logo="logo.png" logo_pos=top-right logo_scale=0.14
overlay "badge.png" from 5 for 4 pos=bottom-left scale=0.18 opacity=0.9
Use one brand line, with at least one setting. The logo defaults to the top-right at 14% of canvas width. logo_scale must be greater than 0 and at most 0.5. The brand logo is drawn above ordinary image overlays.
overlay accepts from|fromsrc TIME, for SECONDS, pos, scale and opacity. Defaults are top-right, scale 0.2 and opacity 1. Omit for to continue to the end. Scale is a fraction of canvas width, greater than 0 through 1.5; opacity is greater than 0 through 1.
Inter and Instrument Serif ship with the shared clip renderer. Clip Maker can also use an uploaded brand font. A font family name alone does not embed a font in a .vedl file; the renderer needs access to it.
Speaker names
Match the labels in a diarized transcript:
source "interview.mp4"
cut 10 30 frame=split focus=0.25,0.5 focus2=0.75,0.5
captions style=clean
speaker "Speaker 1" name="Ali" side=left color=#e8b04a chip=intro
speaker "Speaker 2" name="Sara" side=right color=#82bdab chip=turns
intro introduces a speaker once for four seconds; turns shows their name for three seconds at the start of each turn; always keeps it visible while they speak; off hides it. Default is intro. A speaker without name has no visible name label. Speaker lines do not detect voices or create a transcript.
B-roll
insert shows another video or image while the main recording's audio keeps playing. The inserted video's audio is not used.
source "tutorial.mp4"
cut 0 20
insert "screen-recording.mp4" at 5 for 6 from=2 mode=pip pos=top-left scale=0.3 shape=rect
At output second 5, show six seconds of the screen recording, starting two seconds into that file.
| Mode | Result |
|---|---|
cutaway | The inserted picture fills the canvas. Default. |
pip | The inserted picture sits in a small window over the main video. |
swap | The inserted picture fills the canvas; the main video moves into the small window. |
Use at or atsrc for placement. for is 0.5–30 seconds; from defaults to 0. Window settings are pos, scale=0.15..0.5 and shape=rect|circle. Defaults are top-right, 0.35 and circle.
An insert covers the timeline for its duration; it does not extend the edit. Use prepend or append to add time before or after it.
Music and loudness
Add music under speech
source "interview.mp4"
cut 10 30
music "bed.mp3" style=podcast level=-22 duck=10
normalize target=-16 peak=-1.5
The renderer measures the recording and music, then mixes the bed below the voice. It lowers the music further while speech is present. A short track loops; a long track is trimmed to the output.
| Setting | Meaning |
|---|---|
start | Source position where the music begins. Defaults to 0; accepts seconds or a timestamp such as 0:13.5. |
style=podcast | Speech-focused mix; the default. |
style=documentary | Documentary mix preset. |
style=promo | Promotional mix preset. |
style=ambient | Ambient soundtrack preset. |
level | Music level relative to the voice, −40 through 0 dB. More negative is quieter. |
duck | Additional reduction while the voice is active, 0–30 dB. |
Use at most one music line. Start with a style and add level or duck only when you need to change the balance. These values are decibels, not volume percentages.
Choose where the music starts
Use start=TIME to pick the part of a track that fits your reel:
still "morning.jpg" for 5
still "evening.jpg" for 5
music "piano.mp3" start=0:13.5 style=ambient
Here the soundtrack starts at 13.5 seconds into the song as the first photo appears.
You can write 13.5, 0:13.5, or 00:00:13.5. The start defaults to zero,
must be non-negative and before the end of the track, and cannot exceed 86400 seconds.
When playback reaches the track's end, it loops from 0:00. Later loops use
the full track, and the soundtrack ends with the video.
In Reel Studio, seek with the audio player's scrubber and press Set start here. The marked time applies to the rough cut and your next render. Reset music start returns it to zero; choosing another track also resets it. If Sync to music is enabled, beat timing is recalculated for the selected starting point on render.
Give a photo reel a soundtrack
still "morning.jpg" for 3 frame=fill motion=pan
still "evening.jpg" for 3 frame=fill motion=zoomout
transition xfade 0.5
music "piano.mp3" style=ambient
fade out 0.8
Photos are silent, so the music becomes the main soundtrack. It is adjusted to the style's target loudness without voice ducking. The same behavior applies to a silent video recording.
Adding music does not turn on beat sync. Enable that planning option in Reel Studio; see Transitions and beat timing.
Set the output loudness
normalize sets the measured loudness target and peak limit. Use it with or without music:
source "talk.mp4"
cut 0 20
normalize target=-16 peak=-1.5
target is −36 through −8 LUFS; default −16. peak is −9 through 0 dBTP; default −1.5. LUFS describes overall loudness; dBTP limits the loudest peaks. Use at most one normalize line. Normalizing a silent recording cannot add sound and produces a warning.
Color grading and finishing
Adjust the whole picture
source "walk.mp4"
cut 0 15
grade exposure=0.3 contrast=1.08 saturation=1.12
This slightly brightens the picture and increases contrast and color intensity.
| Setting | Range | Unchanged value |
|---|---|---|
exposure | −3 to +3 stops | 0 |
brightness | −1 to +1 | 0 |
contrast | 0–3 | 1 |
saturation | 0–3 | 1 |
gamma | 0.1–3 | 1 |
A grade applies across the main timeline, including photo compositions. It is not a timed or per-scene setting. B-roll inserts and output text/image overlays are added after this grade.
Adjust one color range
source "garden.mp4"
cut 0 15
grade saturation=1.05
grade hsl greens hue=-5 sat=8 lum=4
grade hsl blues sat=-10
grade hsl changes a color band: reds, yellows, greens, cyans, blues or magentas. hue shifts the color by −180 to +180 degrees; sat and lum change saturation and lightness by −100 to +100. Zero leaves a setting unchanged. Each HSL line needs at least one nonzero adjustment.
HSL grading requires FFmpeg's huesaturation filter. A build without it skips these adjustments with a warning. Exposure uses a brightness approximation when FFmpeg lacks its exposure filter.
Fade the start or end
source "walk.mp4"
cut 0 15
fade in 0.5
fade out 1
fade affects video and audio at the output's edges. It does not add time. Use at most one fade-in and one fade-out. A fade through black between scenes belongs to transition or join instead.
Add chapter markers
source "lesson.mp4"
cut 0 30
chapter "The idea" at 0
chapter "The demonstration" at 12
card title "The demonstration" at 12 for 2
chapter "TITLE" at|atsrc TIME adds a navigation marker to the output container when rendered through the shared clip renderer. It does not draw text. The title card in this example supplies the on-screen heading.
Markers are sorted, kept at least half a second apart, and dropped when they fall past the end. Chapter display depends on the player. Standalone media edit render currently does not attach the chapter metadata.
Rendering and export
Render a video file
5am media edit render edit.vedl --aspect 9:16 --output reel.mp4
Choose --aspect 9:16, 1:1 or 16:9, or set --width and --height. Without a size override, the canvas follows the source or first photo. Photo scenes use their declared fps; other documents derive the frame rate from their source.
When framing is omitted, standalone edit render keeps the whole picture with bars as needed. Clip Maker and Reel Studio normally crop to fill. Write frame=fill explicitly, or "frame":"fill" in photo slots, when you want a script to keep the same crop across entry points.
Rendering needs local FFmpeg and the referenced files. Basic hand-written edits need no AI call or API key. Logged-out CLI renders may carry a watermark; signing in removes it.
Know which renderer you are using
| Feature | Current rendering support |
|---|---|
| Cuts, framing, stills, compositions, joins, props, B-roll, logos, titles, music and fades | Supported by standalone edit render and the shared clip renderer. V2 commands need a current development build. |
Independent video clip lines (with their overlays) | Supported by standalone edit render and the shared clip renderer; the web editor export keeps their overlays as metadata with a warning. |
| Transcript captions, written captions, cards and speaker names | Attached by Clip Maker/Reel Studio's shared renderer; need FFmpeg with libass. Standalone edit render does not currently attach these layers. |
| Chapter metadata | Written by the shared clip renderer; not currently attached by standalone edit render. |
| Text shaping and font fallback | Simple titles use libass when available. Without it, the fallback uses one font file, selected with --font if needed. |
A .vedl file stores editing instructions, not the media, transcript, fonts or generated sprite pixels. Keep those assets with the project to reproduce the result.
Export an editable project
5am media edit export edit.vedl --new-album "My reel assets" --project-name "My reel"
Export uploads the media and creates a Video Editor project. It requires login and either --album or --new-album.
Cuts, supported transitions, titles, image overlays, framing, B-roll, cards and compatible grading become editor items. Written captions can be exported from caption lines; transcript captions also need the transcript supplied by the exporting app. Clip Maker supplies it when publishing an editable project; standalone CLI export does not.
The general Video Editor does not yet reproduce photo-layout choreography, animated props or the newer composition effects. Their settings and asset URLs are preserved as metadata, with warnings. Gamma/HSL grading, speaker labels, chapter markers and the ducked music mix also have rendering limits in the editor. Fades produce a warning and are not preserved as an editable effect.
Keep the rendered MP4 when exact playback matters. An editable export can look different from the VEDL render.
Troubleshooting
| Problem | What to check |
|---|---|
| A photo has bars or a different crop | Set frame=fill explicitly, or use frame=fit when bars are intended. Check each composition slot separately. |
| A join is rejected | Check the scene ID, matching fps, impact range and 45% overlap limit. Reveal effects also need matching photos, focus, Fill framing and no camera motion. |
| A scene's JSON will not parse | Keep it on one line, escape its inner quotes, and remove trailing text or unknown fields. |
| A prop is missing | Check the atlas path, grid, transparent pixels, frame interval and layer. A behind prop is hidden by a full-frame photo. wave needs changing atlas cells to show a gesture. |
| Captions or cards are missing | Check the renderer support table, libass availability, transcript where needed, and that captions style=none is not selected. |
| A title with an apostrophe is rejected | Replace ' with ’ in text commands. |
| Media cannot be read | Check paths relative to the .vedl file and whether FFmpeg can decode each file. A still image reporting no intrinsic duration is normal; its scene supplies the duration. |
Where scripts come from
Clip Maker and 5am media clips save one document per clip. Reel Studio saves one per reel, using simple stills or named photo compositions. 5am media highlight saves the edit for its highlight reel. You can also generate a script from a transcript with 5am media edit generate, or write one by hand.