Skip to main content

Editing from code Preview

Everything the editor's controls do is also available from code: build your own controls, apply templates, or automate edits. Each call is one undo step, and the views update right away. Calls fail with an error on invalid input, e.g. an unknown clip or a clip that would overlap another.

These APIs are in preview. On the web, typed editing calls aren't available yet.

Clips​

_ = try editor.apply(edit: .move(clip: clip, track: track, startUs: 3_000_000))
_ = try editor.apply(edit: .trimStart(clip: clip, startUs: 1_000_000))
_ = try editor.apply(edit: .trimEnd(clip: clip, endUs: 6_000_000))
let right = try editor.apply(edit: .split(clip: clip, atUs: 4_000_000))
_ = try editor.apply(edit: .setSpeed(clip: clip, speed: 2))
let copy = try editor.apply(edit: .duplicate(clip: clip))
_ = try editor.apply(edit: .delete(clip: clip, ripple: true))
  • Trim times are timeline times. The SDK tells you how far each end can go (trimLimits / trimRange), e.g. for your own trim handles.
  • split returns the new right-hand clip; duplicate places the copy right after.
  • Deleting with ripple closes the gap.

Properties​

Every editable value of a clip is a property: position, scale, rotation, opacity, volume, crop, masks, text style, each effect's controls and more. Ask the SDK for a clip's properties instead of hard-coding them: each comes with its path, a label, its group (e.g. Transform), its type, range, unit, default and whether it can be keyframed. That's everything needed to build a panel.

for p in try editor.properties(clip: clip) { print(p.path, p.label) }
try editor.setProperty(clip: clip, path: "rotation", value: .number(value: 15), atUs: nil)
let scale = try editor.property(clip: clip, path: "scale", atUs: 0)
try editor.resetProperty(clip: clip, path: "rotation")

Values are numbers, booleans, colours or text (for text, fonts and choices). Reading a value takes a time because keyframed values change over time.

Keyframes​

Animatable properties change over time through keyframes. Keyframe times are relative to the clip's start.

_ = try editor.setKeyframe(clip: clip, path: "scale", atUs: 0, value: 1)
let k = try editor.setKeyframe(clip: clip, path: "scale", atUs: 2_000_000, value: 1.3)
_ = try editor.apply(edit: .setKeyframeEasing(clip: clip, path: "scale", keyframe: k, easing: .easeOut))

Once a property has keyframes, setting it at a time changes the keyframe there.

Effects, transitions and animations​

The SDK has catalogs of its built-in effects, transitions and animations. Offer them from the catalog rather than hard-coding ids, which can change between releases.

Each catalog effect has an id, a label, a kind (effect, transition or audio), whether it's a ready-made bundle with a few controls, and a picker category such as look.

let catalog = editor.effectCatalog()
let look = catalog.first { $0.kind == "effect" && $0.bundle }!
let fx = try editor.addEffect(clip: clip, kind: look.id)

let transition = catalog.first { $0.kind == "transition" }!
_ = try editor.apply(edit: .setTransition(clip: clip, kind: transition.id, durationUs: 500_000))

let zoomIn = editor.animationPresets().first { $0.kind == .in }!
_ = try editor.apply(edit: .setAnimation(clip: clip, kind: .in, preset: zoomIn.id))
  • An effect's controls appear among the clip's properties.
  • A transition goes from a clip into the next one; set none to remove it.
  • Clips have In, Out and Loop animations; setting none removes one.
  • An effect clip on an effects track changes everything below it while it plays.

Grouping edits​

Wrap several calls in a session to make them one undo step, e.g. for a panel with Done and Cancel. Cancelling reverts everything since the session began.

editor.beginSession()
do {
try editor.setProperty(clip: clip, path: "x", value: .number(value: 0), atUs: nil)
try editor.setProperty(clip: clip, path: "y", value: .number(value: 0), atUs: nil)
editor.commitSession()
} catch {
editor.cancelSession()
}

Linked clips​

Link clips that belong together:

Link
MediaA video and its audio from the same file: moving, trimming, speed changes and splits stay in sync; deleting one deletes both.
AttachedThe first clip is the anchor; the others move and are deleted with it, e.g. a title on a shot. Their trims stay independent.
SetA group with no rules of its own, e.g. one caption set.

Undo and changes​

undo() and redo() step through the history, and canUndo() / canRedo() tell you whether there's anything to step to. A change listener tells you after every change, whether from your code, the user's gestures, undo, or a selection change. Use it to update your own buttons and to save.