Search
Loading...
Skip to content

Access Recordings

In this guide, you’ll learn how to access user videos generated by the IMGLY Camera when it’s used as a standalone video camera. This guide covers “Dual Camera”, “Record Reaction” and “Standard” camera modes.

What You’ll Learn#

  • How to read the onDismiss completion result and extract recorded clips.
  • How Dual Camera returns clips with layout frames, so you can recreate the layout.
  • How Reaction Mode returns the base video plus separate reaction clips.
  • How to persist temp files.

When to Use It#

  • After any camera session (Standard, Dual or Reaction) when you need to retrieve the captured media.
  • When you want to reproduce the previewed layout in your editing flow.
  • When you need to save recordings for later retrieval.

Reading Camera Results#

When the user dismisses the camera after recording, the video appears in a Swift standard Result enum with two cases:

  • Camera Result for success
  • Camera Error for failure

The Camera Result case has two cases as well:

  • recording used for single and dual mode recordings and contains an array of Recording structures.
  • reaction used for reaction mode recordings and contains a Recording structure wrapping the original video that was reacted to. It also contains an array of the users reactions as an array of Recording structures.

The Camera Error enum has three cases:

  • cancelled when the user canceled the camera view
  • permissionsMissing when the user has denied your app permission to use the camera hardware.
  • failedToLoadVideo (record reaction only) when the reaction video fails to load correctly.

A bare example of initializing an IMGLY Camera with an onDismiss closure is:

private let settings = EngineSettings(license: "<your license key">)
Camera(settings,
config: CameraConfiguration(), // Adjust if you set max duration, mode switching, UI tint, etc.
mode: .standard // .standard, .dualCamera(...), or .reaction(...)
) { result in
switch result {
case .success(let cameraResult):
switch cameraResult {
case .recording(let recordings): //[Recording]
// Standard / Dual: one or more clips.
case .reaction(let baseVideo, let reactions): //Recording, [Recording]
// Reaction: base video + separate reaction clips.
}
case .failure(let error):
// User canceled, permissions missing, or other camera error
}
}

The Recording structure has a duration property, which is a CMTime type and an array of Video types named videos.

The Video type contains a url which points to the video file. This originates in the app’s caches or temp directory. To persist the video long term, you need to add some kind of storage mechanism in your code. Video also has a rect property.

For a standard video, the rect property will be the full rect of the video preview window of the camera. For Dual and Reaction modes, the rect indicates which section of the screen the video comes from. The dimensions of the rect are the dimensions of the preview window. The video itself is recorded full screen.

Video Segments#

The results of the video capture return as an array or Recording types because the user can tap the record button on the camera to make multiple recording segments. The segments appear as arcs around the record button, as shown below.

Record button indicating four recording segments.

In Single/Reaction, recording.videos.count is typically 1; in Dual, it’s 2 (one Video per lens) for each Recording segment.

Debug window for dual camera recording with four video segments.

The preceding debug window screenshot shows the reactions for a dual camera recording where the user created four segments. Each segment contains a videos array with two entries, one for each camera.

Persist Temporary Files#

Video URLs are typically returned as temporary file URLs. If you want to use them later, copy or move them to an app-managed location like the app’s documents or library directory.

A minimal example of copying the video to the app’s documents directory and giving it a new filename follows:

func persistFile(from sourceURL: URL, fileName: String) throws -> URL {
// Get destination in the app's Documents directory
let docsURL = try FileManager.default.url(
for: .documentDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: true
)
let destinationURL = docsURL.appendingPathComponent(fileName)
// Remove if file already exists
if FileManager.default.fileExists(atPath: destinationURL.path) {
try FileManager.default.removeItem(at: destinationURL)
}
// Copy from tmp to Documents
try FileManager.default.copyItem(at: sourceURL, to: destinationURL)
//use .moveItem(at:, to:) if you prefer
return destinationURL
}

Next Steps#

Now that you are able to extract the video you can:

  • Add it to the user’s photo library.
  • Open a scene with the CE.SDK and insert the video.
  • Create local assets and add them to one of the prebuilt editor’s asset panel.

Troubleshooting#

❌ Error: URLs are invalid or empty

  • Use the URLs immediately after capture, copy/move them to a safe folder. Treat returned URLs as temporary.

❌ Error: User canceled

  • Handle .failure(.cancelled) silently or with some minimal UI cues. Don’t show an error or alert.

❌ Error: Videos Don’t appear in Photos.app

  • Saving to Photos.app isn’t automatic. Use PHPhotoLibrary from Apple’s Photos framework to save them.

❌ Error: Storage balloons during long sessions

  • Prefer moveItem(at:to:) over copyItem after capture and prune old temp files on app launch. For uploads, delete local files after you persist to a remote URL.