VidStudio SDK reference
    Preparing search index...

    Interface EditorBackend

    The one door between the editor UI (or a test, or a coding agent) and the project. Times are seconds. Every method that changes the project is async, runs on the backend's serial queue, is undoable unless stated, and ends by emitting an event. Reads that hit the store are async; reads of engine state are sync.

    The design lives in design-docs/video-editor/agent-interface/backend.md.

    interface EditorBackend {
        projectId: string;
        activateKeyframing(
            clipTransformId: string,
            param: string,
            clipLocalSec: number,
        ): Promise<void>;
        addClipFromAsset(
            trackId: string,
            assetId: string,
            options: PlaceOptions,
        ): Promise<string>;
        addColorLayer(color: string, atTimeSec: number): Promise<string>;
        addEffect(
            clipId: string,
            transformId: string,
            options?: AddEffectOptions,
        ): Promise<string>;
        addTextTrack(): Promise<string>;
        addTextTrackWithClips(
            captions: CaptionClipSpec[],
            style: TextProperties,
        ): Promise<string>;
        addTrackFromAsset(
            assetId: string,
            type: "video" | "audio",
            options?: PlaceOptions,
        ): Promise<string>;
        adoptLegacyOpacity(clipId: string): Promise<boolean>;
        cancelExport(): void;
        canRedo(): boolean;
        canUndo(): boolean;
        copyClip(clipId: string): Promise<void>;
        deactivateKeyframing(clipTransformId: string, param: string): Promise<void>;
        deleteClip(clipId: string): Promise<void>;
        deleteClips(clipIds: string[]): Promise<void>;
        deleteKeyframe(keyframeId: string): Promise<void>;
        discardExportFile(opfsPath: string): Promise<void>;
        dispose(): Promise<void>;
        duplicateClip(clipId: string): Promise<string>;
        easeAllKeyframes(clipId: string): Promise<number>;
        easeKeyframeLane(clipTransformId: string, param: string): Promise<number>;
        exportProject(
            settings: ExportSettings,
            range?: { endSec: number; startSec: number },
        ): Promise<ExportResult>;
        findClipAt(trackId: string, timeSec: number): Promise<Clip | undefined>;
        getActiveTextClipModels(): Clip[];
        getCanvasSize(): { height: number; width: number } | null;
        getClip(clipId: string): Promise<Clip | undefined>;
        getClipBaseRect(clipId: string): Rect | null;
        getClipEffects(clipId: string): Promise<ClipEffectView[]>;
        getClipGeometryKeyframeInfo(
            clipId: string,
            clipLocalSec: number,
            types: readonly GeomType[],
        ): GeometryKeyframeInfo;
        getCurrentTime(): number;
        getDuration(): number;
        getEffectCatalog(): Promise<Transform[]>;
        getLicenceState(): Promise<LicenceState>;
        getLoadingAudioCount(): number;
        getMediaAssets(): Promise<MediaAsset[]>;
        getPlayerState(): PlayerState;
        getProject(): Promise<Project>;
        getProxyProgress(): Record<string, number>;
        getResolvedTransformsAt(clipId: string): ResolvedTransform[];
        getTimeline(): Promise<TimelineView>;
        getTransitions(): Promise<Transition[]>;
        hasClipboard(): boolean;
        importAsset(file: File, probe: MediaProbe): Promise<MediaAsset>;
        importAudio(file: File, options?: PlaceOptions): Promise<string>;
        importFromUrl(
            url: string,
            options?: { type?: "video" | "audio" },
        ): Promise<MediaAsset>;
        importImage(file: File, options?: PlaceOptions): Promise<string>;
        importVideo(file: File, options?: PlaceOptions): Promise<string>;
        isHeadless(): boolean;
        linkClips(videoClipId: string, audioClipId: string): Promise<void>;
        loadDocument(
            document: ProjectDocument,
            resolve: MediaResolver,
        ): Promise<void>;
        moveClip(clipId: string, newStartSec: number): Promise<void>;
        moveKeyframe(keyframeId: string, newClipLocalSec: number): Promise<void>;
        nextFrame(): Promise<void>;
        open(): Promise<void>;
        pasteClip(trackId: string, atTimeSec: number): Promise<string | null>;
        pause(): void;
        placeClips(placements: ClipPlacement[]): Promise<void>;
        play(): void;
        previewClipGeometry(clipId: string, geometry: GeometryValues): void;
        previousFrame(): Promise<void>;
        readAssetFile(assetId: string): Promise<File>;
        readAssetPreviewFile(assetId: string): Promise<File>;
        readExportFile(opfsPath: string): Promise<File>;
        redo(): Promise<void>;
        removeEffect(clipTransformId: string): Promise<void>;
        removeTrack(trackId: string): Promise<void>;
        removeTransition(transitionId: string): Promise<void>;
        renameProject(name: string): Promise<void>;
        renameTrack(trackId: string, label: string | null): Promise<void>;
        renderFrameAt(timelineSec: number): Promise<ImageBitmap>;
        reorderEffects(
            clipId: string,
            orderedClipTransformIds: string[],
        ): Promise<void>;
        reorderTracks(frontToBack: string[]): Promise<void>;
        restyleTextClips(
            clipIds: string[],
            changes: Partial<TextProperties>,
        ): Promise<number>;
        saveDocument(): Promise<
            { document: ProjectDocument; media: MediaManifest },
        >;
        seek(timeSec: number): Promise<void>;
        setCanvasSize(
            size: { height: number; width: number } | null,
        ): Promise<void>;
        setClipGeometry(
            clipId: string,
            geometry: GeometryValues,
            changed: Iterable<GeomType>,
            options?: SetClipGeometryOptions,
        ): Promise<void>;
        setEffectParams(
            clipTransformId: string,
            params: Record<string, unknown>,
            options?: SetEffectParamsOptions,
        ): Promise<void>;
        setEffectWindow(
            clipTransformId: string,
            window: { end_offset: number; start_offset: number },
        ): Promise<void>;
        setFrameRate(fps: number): Promise<void>;
        setKeyframe(
            clipTransformId: string,
            param: string,
            clipLocalSec: number,
            value: number,
            easing?: string,
        ): Promise<string>;
        setKeyframeEasing(keyframeId: string, easing: string): Promise<void>;
        setLoopPlayback(on: boolean): Promise<void>;
        setPlaybackRate(rate: number): void;
        setSelectedTextClipId(clipId: string | null): void;
        setTrackHidden(trackId: string, hidden: boolean): Promise<void>;
        setTrackStartTime(trackId: string, startSec: number): Promise<void>;
        setTrackVolume(trackId: string, volume: number): Promise<void>;
        setTransition(
            outgoingClipId: string,
            incomingClipId: string,
            type: TransitionType,
            durationSec: number,
        ): Promise<void>;
        setWorkArea(range: WorkArea | null): Promise<void>;
        snapshot(): Promise<ProjectSnapshot>;
        splitClipAt(clipId: string, timelineSec: number): Promise<string | null>;
        subscribe(listener: (event: EditorEvent) => void): Unsubscribe;
        transcribeClipToTextTrack(
            clipId: string,
            opts: {
                onProgress?: (p: TranscriptionProgress) => void;
                signal?: AbortSignal;
            },
        ): Promise<number>;
        trimClip(clipId: string, window: ClipWindow): Promise<void>;
        undo(): Promise<void>;
        unlinkClip(clipId: string): Promise<void>;
        updateClip(clipId: string, patch: ClipPatch, label?: string): Promise<void>;
    }

    Implemented by

    Index
    projectId: string
    • Switches animation on for one param: its stored keyframes come back, or a first one is made at clipLocalSec from the current value (invalid-argument outside the clip).

      Parameters

      • clipTransformId: string
      • param: string
      • clipLocalSec: number

      Returns Promise<void>

    • Adds a clip of a stored asset to an existing video or audio track; type-mismatch for a track of another kind. Not undoable.

      Parameters

      Returns Promise<string>

    • Adds an image track holding a canvas-sized flat colour (any CSS colour) starting at atTimeSec. Not undoable.

      Parameters

      • color: string
      • atTimeSec: number

      Returns Promise<string>

    • Adds an effect from the catalog (transform-not-found otherwise). Recipes (zoom presets) open their window at atClipLocalSec (default 0); other effects ignore it.

      Parameters

      Returns Promise<string>

    • Adds a text track with one "Text" clip of five seconds at the playhead; change it with updateClip and trimClip. Not undoable.

      Returns Promise<string>

    • Adds a text track with one clip per caption, all in style. Not undoable.

      Parameters

      Returns Promise<string>

    • A new video or audio track playing an asset that is already in the project (the source monitor's "Add to Timeline"). Lands after everything else unless startSec says where.

      Parameters

      • assetId: string
      • type: "video" | "audio"
      • Optionaloptions: PlaceOptions

      Returns Promise<string>

    • Old projects kept opacity on the clip row. Moves it into an Opacity row of the Transform group so the rows are the single owner; the picture does not change. Returns false when there was nothing to move. Not undoable.

      Parameters

      • clipId: string

      Returns Promise<boolean>

    • Asks the running export to stop, so exportProject rejects with export-cancelled. Nothing happens when none runs.

      Returns void

    • Whether redo() has a step to replay.

      Returns boolean

    • Whether undo() has a step to take back.

      Returns boolean

    • Copies the clip with its effects and keyframes to the backend's clipboard. Not undoable.

      Parameters

      • clipId: string

      Returns Promise<void>

    • Switches animation off for one param; its keyframes stay stored so activateKeyframing can bring them back.

      Parameters

      • clipTransformId: string
      • param: string

      Returns Promise<void>

    • The same as deleteClips([clipId]).

      Parameters

      • clipId: string

      Returns Promise<void>

    • Deletes every named clip and the linked partner of each, in one undo step. An unknown id is clip-not-found and nothing is deleted. An empty list changes nothing.

      Parameters

      • clipIds: string[]

      Returns Promise<void>

    • Deletes the keyframe; keyframe-not-found when there is none.

      Parameters

      • keyframeId: string

      Returns Promise<void>

    • Drop a finished export's MP4 and the project's export folder from browser storage. Call it once the user is done with the result, otherwise every export the user downloads sits in storage for ever. Never rejects, and never before the browser has finished streaming a download from the file.

      Parameters

      • opfsPath: string

      Returns Promise<void>

    • Cancels queued work, drops every listener and destroys the player. Safe to call twice.

      Returns Promise<void>

    • Pastes a copy of the clip right after it on its own track; clip-overlap when the next clip is in the way.

      Parameters

      • clipId: string

      Returns Promise<string>

    • Eases every keyframe lane of every effect on the clip. Returns how many changed.

      Parameters

      • clipId: string

      Returns Promise<number>

    • Eases one lane: the keyframes of one param on one effect. Returns how many changed.

      Parameters

      • clipTransformId: string
      • param: string

      Returns Promise<number>

    • Encodes the timeline, or range, to an MP4 in file storage, reporting export-progress; nothing-to-export when empty, missing-media when a placed file never arrived, export-cancelled after cancelExport(), engine-required headless.

      Parameters

      • settings: ExportSettings
      • Optionalrange: { endSec: number; startSec: number }

      Returns Promise<ExportResult>

    • The clip on the track playing at timeSec (start inclusive, end exclusive), or undefined.

      Parameters

      • trackId: string
      • timeSec: number

      Returns Promise<Clip | undefined>

    • The text clips showing at the playhead.

      Returns Clip[]

    • The size the preview draws at, or null before the renderer has one.

      Returns { height: number; width: number } | null

    • The clip row, or undefined when there is no such clip.

      Parameters

      • clipId: string

      Returns Promise<Clip | undefined>

    • The rectangle the clip's picture fills on the canvas before its effects, or null when its frame is not loaded.

      Parameters

      • clipId: string

      Returns Rect | null

    • Every effect on the clip with its definition and keyframes; throws when a definition is missing.

      Parameters

      • clipId: string

      Returns Promise<ClipEffectView[]>

    • Whether any of types animates on the clip, and whether a keyframe sits at clipLocalSec.

      Parameters

      • clipId: string
      • clipLocalSec: number
      • types: readonly GeomType[]

      Returns GeometryKeyframeInfo

    • The playhead in seconds; 0 before open().

      Returns number

    • The timeline length in seconds; 0 before open().

      Returns number

    • Every effect definition a clip can take, seeded by open().

      Returns Promise<Transform[]>

    • The outcome of the licence check open() runs once; resolves when it has run. "invalid" and "localhost" draw a watermark on the preview, renderFrameAt and exports.

      Returns Promise<LicenceState>

    • Audio tracks being added whose sound is still decoding (a long file takes a while). audio-loading reports changes.

      Returns number

    • Every media file stored in the project, placed on the timeline or not.

      Returns Promise<MediaAsset[]>

    • The state the player last reported; "idle" before open().

      Returns PlayerState

    • The project row. Throws a plain Error when the store has no project with this id.

      Returns Promise<Project>

    • Videos whose proxy is being made, by asset id, each 0 to 1. Proxies are made in the background after an import and on open; proxy-progress reports changes.

      Returns Record<string, number>

    • The clip's effects resolved at the playhead, for the canvas overlay.

      Parameters

      • clipId: string

      Returns ResolvedTransform[]

    • The timeline as the panel draws it: tracks, layers, audio, transitions and the duration.

      Returns Promise<TimelineView>

    • Every transition between two clips of this project.

      Returns Promise<Transition[]>

    • Whether copyClip has put a clip on the clipboard.

      Returns boolean

    • Stores a media file in the project without placing it on the timeline (the source monitor's Import). probe is what the caller already learned about the file; it fills the asset row. Not undoable. Works headless.

      Parameters

      Returns Promise<MediaAsset>

    • Stores the file and adds an audio track playing it; audio-loading reports the decode. import-failed when it does not decode. Not undoable.

      Parameters

      Returns Promise<string>

    • Fetches a web address into file storage as a stream (never whole into memory), probes it and adds it like importAsset. type: "audio" keeps only a video's sound. Cross-origin addresses must allow this page (Access-Control-Allow-Origin). A failed download is import-failed. Not undoable. Works headless.

      Parameters

      • url: string
      • Optionaloptions: { type?: "video" | "audio" }

      Returns Promise<MediaAsset>

    • Stores the picture and adds an image track showing it; import-failed when it does not decode. Not undoable.

      Parameters

      Returns Promise<string>

    • Stores the file and adds a video track playing it, after everything else unless startSec says where; import-failed when it does not decode. Not undoable.

      Parameters

      Returns Promise<string>

    • True when constructed without a preview canvas. Engine methods throw in this mode.

      Returns boolean

    • Marks a video clip and the audio clip that is its sound as linked. From then on the two move, delete and split together. Refuses clips that are not one video and one audio (type-mismatch) and a clip that is linked already (invalid-argument).

      Parameters

      • videoClipId: string
      • audioClipId: string

      Returns Promise<void>

    • Replaces this project's content with document. resolve gives each asset's file or a web address; either is written to file storage as a stream. An asset it fails on loads with missing: true: its clips show a flat placeholder and export refuses (missing-media). Any other failure leaves the project as it was. Clears undo and redo.

      Parameters

      Returns Promise<void>

    • The same as placeClips with one clip kept on its own track.

      Parameters

      • clipId: string
      • newStartSec: number

      Returns Promise<void>

    • Moves the keyframe, taking the place of one already at the new time; invalid-argument for a time outside the clip.

      Parameters

      • keyframeId: string
      • newClipLocalSec: number

      Returns Promise<void>

    • Steps the playhead one frame forward at the project frame rate.

      Returns Promise<void>

    • Runs the licence check, seeds effect definitions, renumbers an old project's track orders once (see stacking-migration.ts) and loads the project into the player (if a preview is attached). Missing proxies are made in the background afterwards.

      Returns Promise<void>

    • Pastes the clipboard clip at atTimeSec; null when the clipboard is empty, type-mismatch for a track of another kind, clip-overlap when it would overlap.

      Parameters

      • trackId: string
      • atTimeSec: number

      Returns Promise<string | null>

    • Pauses the preview.

      Returns void

    • Puts every clip at its placement in one undo step, or refuses and changes nothing: a track of another kind (type-mismatch), a start before zero (invalid-argument), a clip overlapping another on its new track (clip-overlap). Judged on the final layout, so clips moving together may swap places. A transition whose two clips no longer touch on one track is removed in the same step. A linked clip brings its partner: a partner that is not named is placed on its own track shifted by the same seconds, and a pair named with two different shifts is refused (invalid-argument).

      Parameters

      Returns Promise<void>

    • Starts the preview and emits preview-played.

      Returns void

    • Engine-only, not persisted: shows a drag in progress. Cleared by the next persisted change.

      Parameters

      Returns void

    • Steps the playhead one frame back at the project frame rate.

      Returns Promise<void>

    • The media file behind an asset (for waveforms and transcription). Works headless.

      Parameters

      • assetId: string

      Returns Promise<File>

    • The asset's proxy when it has one, else the original: lighter to preview. Works headless.

      Parameters

      • assetId: string

      Returns Promise<File>

    • The finished MP4 an export left behind (ExportResult.opfsPath), for the download button.

      Parameters

      • opfsPath: string

      Returns Promise<File>

    • Replays the latest undone step; does nothing when there is none.

      Returns Promise<void>

    • Removes the effect and its keyframes; effect-not-found when there is none.

      Parameters

      • clipTransformId: string

      Returns Promise<void>

    • Removes the track and its clips. The partner of a linked clip on it is unlinked, since its clip is gone.

      Parameters

      • trackId: string

      Returns Promise<void>

    • Removes the transition; transition-not-found when there is none.

      Parameters

      • transitionId: string

      Returns Promise<void>

    • Sets the project name as given; nothing is checked.

      Parameters

      • name: string

      Returns Promise<void>

    • null or an empty string clears the name back to the default. Trimmed, at most 60 characters.

      Parameters

      • trackId: string
      • label: string | null

      Returns Promise<void>

    • Composes one frame at the preview size: a slow cold path for tests and thumbnails, not scrubbing. invalid-argument before 0; engine-required headless.

      Parameters

      • timelineSec: number

      Returns Promise<ImageBitmap>

    • orderedClipTransformIds must name every effect on the clip exactly once.

      Parameters

      • clipId: string
      • orderedClipTransformIds: string[]

      Returns Promise<void>

    • frontToBack must name every visual track of the project exactly once, front first, which is the order the timeline shows. Writes new orders so the picture matches. Refuses audio tracks (type-mismatch) and incomplete or repeated lists (invalid-argument). No undo step and no event when nothing changes.

      Parameters

      • frontToBack: string[]

      Returns Promise<void>

    • Writes only the touched style properties onto each text clip, leaving the rest of every clip's style alone. One undo step. Returns how many clips changed.

      Parameters

      Returns Promise<number>

    • The project as plain JSON, plus one manifest entry per stored media file. An entry's read() hands back a handle to the stored file, never its bytes.

      Returns Promise<{ document: ProjectDocument; media: MediaManifest }>

    • Moves the playhead to timeSec.

      Parameters

      • timeSec: number

      Returns Promise<void>

    • Fixes the output size in pixels; null lets the canvas follow the first video again.

      Parameters

      • size: { height: number; width: number } | null

      Returns Promise<void>

    • Persists the Transform group rows for changed. A type that is animated gets a keyframe at atClipLocalSec; one that is not gets a static value (mode "auto"). "keyframe" always keyframes, "static" always freezes.

      Parameters

      Returns Promise<void>

    • Merges params over the effect's stored params (a key set to undefined is removed). With record: false the write is a live preview: no undo step; the next recorded write on the same effect undoes back to the params from before the first preview.

      Parameters

      Returns Promise<void>

    • Sets the clip-local span the effect applies over; invalid-argument when it starts before 0 or ends before it starts.

      Parameters

      • clipTransformId: string
      • window: { end_offset: number; start_offset: number }

      Returns Promise<void>

    • Sets the frame rate used for frame stepping and export; nothing is checked.

      Parameters

      • fps: number

      Returns Promise<void>

    • Adds a keyframe, or changes the one already at that time, and returns its id; invalid-argument for a non-finite value, an unknown easing or a time outside the clip.

      Parameters

      • clipTransformId: string
      • param: string
      • clipLocalSec: number
      • value: number
      • Optionaleasing: string

      Returns Promise<string>

    • Sets the keyframe's easing; invalid-argument for an unknown easing name.

      Parameters

      • keyframeId: string
      • easing: string

      Returns Promise<void>

    • Switches looping over the work area on or off.

      Parameters

      • on: boolean

      Returns Promise<void>

    • Sets the preview speed, 1 being normal.

      Parameters

      • rate: number

      Returns void

    • Which text clip the preview outlines as selected; null for none.

      Parameters

      • clipId: string | null

      Returns void

    • Visual tracks only (type-mismatch for audio, which keeps its mute). A hidden track is not drawn.

      Parameters

      • trackId: string
      • hidden: boolean

      Returns Promise<void>

    • Shifts the whole track so it starts at startSec; a text track moves its first clip. Not undoable.

      Parameters

      • trackId: string
      • startSec: number

      Returns Promise<void>

    • Sets the track's volume; type-mismatch for anything but an audio track. Not undoable.

      Parameters

      • trackId: string
      • volume: number

      Returns Promise<void>

    • Sets or replaces the transition between two clips that meet on one track, trimming a clip to make footage when needed; invalid-argument when they do not meet, have no media or the duration does not fit.

      Parameters

      • outgoingClipId: string
      • incomingClipId: string
      • type: TransitionType
      • durationSec: number

      Returns Promise<void>

    • Sets the range to play and export. A first range switches looping on; null clears the range and the loop.

      Parameters

      Returns Promise<void>

    • The project with ids replaced by stable labels and numbers rounded, for comparing in tests.

      Returns Promise<ProjectSnapshot>

    • Cuts the clip in two at timelineSec and returns the new second half. A linked clip whose partner is also cut by that time is split with it, and the two new halves are linked to each other. One undo step. invalid-split when the cut is too near an edge.

      Parameters

      • clipId: string
      • timelineSec: number

      Returns Promise<string | null>

    • Hears every event the backend emits; returns the function that unsubscribes.

      Parameters

      Returns Unsubscribe

    • Transcribes the clip's sound on the device and adds a text track of captions, returning how many (none: no track). invalid-argument for a clip without media; engine-required headless.

      Parameters

      Returns Promise<number>

    • Trims this one clip only; a linked partner is left alone so sound and picture can be cut apart.

      Parameters

      Returns Promise<void>

    • Takes back the latest undo step and refreshes everything; does nothing when there is none.

      Returns Promise<void>

    • Breaks the link the clip is in. Refuses a clip that is not linked (invalid-argument).

      Parameters

      • clipId: string

      Returns Promise<void>

    • Writes the given clip fields as one undo step named label; nothing but the clip's existence is checked.

      Parameters

      • clipId: string
      • patch: ClipPatch
      • Optionallabel: string

      Returns Promise<void>