BetterEdits app iconBetterEditsBeta
Manual
Markdown

Command line

Every command of BetterEdits cli with its options, grouped, with one example each.

Running commands

The command line is the app's own binary. Run it from the workspace folder.

/Applications/BetterEdits.app/Contents/MacOS/BetterEdits cli <command> [value…] [--option value…]
  • Commands talk to the running app over a Unix socket at ~/Library/Application Support/BetterEdits/cli.sock. If the app is not running the command launches it in the background and waits up to 20 seconds.
  • Positional values fill a command's required options in order, then its listed positionals: clip-split v1:1 2 is clip-split --clip v1:1 --at 2.
  • A bare --flag means true. --key=value works too. Numbers and true/false are typed; everything else is text.
  • Relative paths resolve from the folder you run in.
  • help lists every command; help <command> or <command> --help prints its options.
  • A failing command prints why and exits 1. Exit 2 means the app could not be reached.
  • Every command is an undo step in the app. With a workspace open but no video, editing commands are refused until project-open or project-new.

BETTEREDITS_NO_CLI=1 in the app's environment keeps the socket closed.

Refs and times

WhatHow to write it
Tracksv1, v2 (video, top first), a1 (audio), t1 (text), s1 (subtitles); a track's name; or its 8-character id
Clipsv1:2 is the second clip on v1 in time order; or the clip's 8-character id from timeline
Subtitle barss1:3 or the bar id
AssetsThe file's display name (its filename without extension), its id, or its path
TimesSeconds (4.5), 1:02.5, end, playhead

Positional refs change after edits. Ids last while the app runs and follow moves made in the app, but they are not in the project files: after an edit on disk they follow positions, and reopening a project mints new ones. Re-read timeline after any edit.

Read

CommandOptionsDoes
statusThe open project: name, path, files, duration, playhead, selection, tracks with clip counts; problem when the files on disk were refused
timeline--trackEvery track with every clip (ref, id, start, end, source in and out, text and position) or every subtitle bar
mediaThe media files the project uses, with copied: true for files copied into media/
probe--path (required)A file on disk: kind, duration, size, frame rate, sound, HDR
favoritesThe text favorites and caption styles with font, size and colors
guideThe editing guide as text
check[project]Lint a project's files through the app: every problem and warning at once; for the open project it adds what the app refused
lint[project], --jsonThe same without the app: reads project.json, timeline.json and styles.json, checks every clip against its file's real length, and warns about unused media or looks, text past the end or outside the safe area, very short or long bars, empty tracks and standing placeholders. Exit 1 on errors
sync--timeoutAfter writing a file: wait until the app has taken it in or refused it, and say which
levels--path (required), --every, --silence, --min_silenceA file's loudness over time (RMS in dBFS per step) and its silences, from the sound alone
help[command]The command list, or one command's options
be probe ~/Footage/talk.mov
be timeline --track v1

be stands for the full command above. There is no be on your Mac.

Workspace and projects

CommandOptionsDoes
workspace[path], --aboutShow the workspace, or set one up at a path and switch to it; --about says what gets made there and sets the canvas new videos start with
media-folders--add, --remove, --consolidate, --forceList the media folders, add one, or remove one. Removing a folder videos still use needs --consolidate (copy the files into the videos first) or --force
projectsThe projects in the workspace, newest first
project-new[name], --brief, --canvas, --structure, --forceStart a project in its own folder, with a brief, a canvas (9:16, 16:9, 1:1, 4:5) and a built-in structure. Without a workspace, an unsaved Untitled project; --force discards unsaved changes
project-open--project (required), --forceOpen a project by name, or a project folder, project.json or .be path
project-save[path], --forceSave now (the app saves by itself anyway); while the files on disk stand refused, --force replaces them with the app's copy. With a path, write a .be copy there
ratio[to]Show or change the canvas: 9:16, 16:9, 1:1 or 4:5
be project-new "Hook v2"
be media-folders --remove ~/Footage/June --consolidate

Tracks

CommandOptionsDoes
track-add--kind (required: video, audio, text), --name, --magnetic, --topAdd a track. Video goes right above the audio tracks, or on top with --top; audio at the bottom; text on top
track-set--track (required), --name, --magnetic, --locked, --hidden, --opacity (video, 0 to 1), --muted, --solo, --volume (0 to 1.5), --ducks (audio)Change a track
track-remove--track (required)Delete a track and everything on it
be track-set v1 --locked

Clips

CommandOptionsDoes
media-import--paths (required, several bare values work)Register files with the project without placing them; files outside the video and its libraries are copied into the video
media-relinkasset, pathPoint an asset (a missing one, say) at another file; every clip of it follows, cut to the file's length if shorter
clip-add--track (required), --asset, --path, --at, --in, --out, --durationPut a piece of a file on a video or audio track. Defaults: the whole file (photos 3 s), appended at the end of the track
placeholder-add--name (required), --track, --duration (default 3), --atAdd a named stand-in: a black plate on video, silence on audio
clip-replace--clip (required), --asset, --path, --with, --fillSwap what is behind a clip or placeholder, keeping its spot and length. --with moves another clip in; --fill puts a placeholder over the rest when the source is shorter
clip-slip--clip (required), [to], --bySlide which part of the file the clip plays. --to is the new source in point; --by shifts it
clip-split--clip, --at (both required)Cut a clip in two at a timeline time
clip-trim--clip (required), --start, --end, --in, --outMove a clip's edges. start and end are timeline times; in and out are source times
clip-move--clip, --to (both required), --trackMove a clip to a time, optionally onto another track of the same kind
clip-remove--clip (required)Delete a clip
clip-set--clip (required), --volume (0 to 1.5), --scale, --offsetX, --offsetY, --cropLeft, --cropRight, --cropTop, --cropBottom (0 to 0.45), --nameAdjust level, picture scale, offset, crop, or a placeholder's name
clip-duplicate--clip (required)Copy a clip, or a subtitle bar, right after itself
be clip-add v1 --path ~/Footage/talk.mov --in 12.4 --out 18.9
be clip-split v1:1 2
be clip-replace v1:2 --with v1:5 --fill

Text

CommandOptionsDoes
text-add--text (required), --at (default playhead), --duration (default 3), --track, --favorite, --font, --size (8 to 240), --color (#RRGGBB), --uppercase, --x, --y (0 to 1)Put text on screen for a stretch of time, wearing a favorite with overrides
text-set--clip (required), --text, --duration, --favorite, --font, --size, --color, --uppercase, --x, --yChange a text's words, look or position
be text-add "Stop doing this" --at 0 --duration 2.5 --favorite Strong --y 0.3

Captions

CommandOptionsDoes
transcript--trackThe words spoken on a track with start and end times, from its clips' analysed footage; names the files that have not been analysed. Adds nothing to the project
captions-generate[source], --replaceMake a subtitles track with bars from the transcript of a track's analysed footage, or refill one with --replace s1 (every bar replaced). The bars are linked to nothing and do not follow later cuts
captions--trackThe bars of a subtitles track
caption-edit--bar (required), --action (set, merge, split, remove), --text, --start, --endFix one bar
captions-style--track, --style, --position (top, center, bottom), --offset (bottom only, 0.02 to 0.5)Give a subtitles track a caption style and a position
be caption-edit s1:3 --text "Stop doing this"
be captions-style --style "Bold" --position bottom --offset 0.2

Analysis

Claude cannot watch video. analyze reads a file once through the BetterEdits analysis service and writes <file>.analyzemedia next to it: every spoken word with its timing, speakers, on-screen text, scenes and cuts, silences, music. transcript and captions-generate read it, and so does Claude, whole. Analysis is part of Pro (a 7-day free trial, then $19 a month with $22 of credit every month; video costs 20¢ a minute, speech 6¢). The Mac signs in once through login; the credential lives in the app's own settings, never in a workspace. Claude Code runs all of this for you; see Claude Code.

CommandOptionsDoes
analyzefiles (one or more paths), --type (video/footage, video/edit, audio/speech, audio/music; default by kind), --forceUpload each file, wait, write <file>.analyzemedia next to it, and report the words found, the charge and the balance left. A file that already has one is skipped unless --force. Signed out it fails with "Not signed in"; without Pro with the link to start it; without enough credit with the amount needed and the buy link
loginSigns this Mac in: opens the dashboard in the browser, waits for the approval, keeps the credential in the app's settings
logoutSigns this Mac out
accountWho is signed in, the plan (Pro, trial, free), the credit as dollars and minutes of video, and the dashboard links
be login
be analyze ~/Footage/talk.mov
be account

Look

CommandOptionsDoes
revealwhat (a clip ref, asset or path)Show a file in the Sources sidebar, folders opened, tile lit, as Show in Sources does
preview[path], --offShow a media file in the main player, as a click on it in the Sources sidebar does; --off brings the timeline back
frame--at (required), --width (default 360, max 1080), --outThe picture at a time, with text and captions drawn on, as a PNG
contact-sheet--out, --path, --clips, --every, --times (list), --start, --end, --columns (default 4), --width (default 240)One PNG of many frames, each labelled. Default: 12 frames over the piece; --clips one frame per clip with its ref; --path a source file's frames, to look before cutting

Without --out, PNGs go to cache/frames/ in the workspace, named after the command and the time. The command prints the path.

be contact-sheet --clips
be contact-sheet --path ~/Footage/talk.mov --every 2
be levels ~/Footage/talk.mov
be frame 3.2 --out cache/frames/hook.png

Drive the app

CommandOptionsDoes
seek--at (required), --playMove the playhead, optionally start playing
select--target (required)Select a clip or bar, or none to clear
app-showBring the window to the front
undoUndo the last change, yours or the user's
redoRedo the last undone change
export[path], --preview, --height, --start, --endRender an MP4 with text and captions burned in. Default path: projects/<Name>/exports/<Name>-<date>.mp4. --preview is a quick 540p standard-range file; otherwise the footage's own size, HDR kept. --height is the short side, as the export sheet counts (1080, 1440, 2160)
be select v1:2
be export --preview

Templates

CommandOptionsDoes
template--outThe open project as a template: the first video and audio tracks' clips as named segments, every text with its look
template-import--file (required), [name], --hereStart a project from a template file, or add it to the open project with --here
be template --out hook.json
be template-import hook.json "Hook v3"