Skip to main content

Pickers Stable

The editor never browses the user's files or shows a media library of its own. Whenever it needs something from outside, it sends your app a request, and your app returns the answer. That's how media can come from your photo picker, your own content or your backend, and how every picker can look like the rest of your app.

RequestWhenReturn
Add mediaAdding a clip to the main trackA source you added
Add overlayAdding a layer above the main trackA source you added
Add audioAdding music or soundAn audio source
Add stickerAdding a sticker, when you give no sticker packsAn image source
Choose filterPicking a look for a clipAn effect id from the effect catalog
Choose fontChanging a text's fontA font family
Choose colourAny colour control (the request says which)A colour
Edit textTyping a text's contentThe new text
Choose text stylePicking a text styleA style id from the text style catalog

Your handler can take as long as it needs: show a sheet, wait for the user, download a file. The editor waits for the answer. Then:

  • An answer applies it. Added media lands at the playhead, on the main track, as an overlay or on an audio track.
  • Cancel (the user backed out) leaves things as they were.
  • Nothing lets the SDK show its built-in picker for that request.

The built-in pickers are deliberately simple, for getting started:

PlatformBuilt in
iOS, Android, React NativeFonts, colours, text, text styles, filters. Media always needs your picker.
WebAll requests: a file chooser for media, the browser's colour input, and lists.
macOSNone: handle every request.

How each platform spells it:

PlatformHandlerCancelBuilt-in picker
iOSasync closure returning RequestResponse?.cancelnil
Androidsuspend function returning RequestResponse?RequestResponse.Cancelnull
React Native, webfunction returning an answer or a promisenullundefined

Example: your media library​

dock.onRequest = { request in
switch request.kind {
case .addMedia, .addOverlay:
guard let asset = await MediaLibrarySheet.present() else { return .cancel }
let media = try? editor.addMedia(id: asset.id, file: asset.localFile)
return media.map { .source(id: $0.source) } ?? .cancel
case .chooseFont:
guard let family = await BrandFontSheet.present() else { return .cancel }
return .text(value: family)
default:
return nil // built-in picker
}
}

Stickers​

Stickers come from your library, organised in packs, as in messaging apps. Give the editor your packs, and Sticker opens a browser of them: a row of pack tabs, each shown by an image (the pack's icon, or its first sticker), and a grid of stickers. A tap adds the sticker at the playhead, sized to a quarter of the video's shorter side.

Each sticker is a media id. The SDK fetches stickers through your media resolver, the same as other media: thumbnails for the ones on screen, then the file when one is picked. PNG, WebP, GIF and APNG all work, static or animated.

dock.stickerPacks = [
StickerPack(id: "emoji", name: "Emoji", stickers: ["st_101", "st_102", "st_103"]),
StickerPack(id: "hearts", name: "Hearts", stickers: ["st_201", "st_202"]),
]

Without packs, Sticker sends your app an add sticker request instead, answered like add media.