# Video Selfie

The Video Selfie module records a short video of the user performing a guided series of actions, including capturing their ID and selfie, to confirm physical presence and run liveness and face match checks. It can also capture voice consent. It requires camera access. It requires microphone access when audio or voice consent is enabled. See [Add Required Permissions](https://developer.incode.com/docs/setup-ios#add-required-permissions).

For an overview of this module and how it works, see [Video Selfie](https://developer.incode.com/docs/video-selfie).

How you use this module depends on your integration pattern. When the app defines the steps in code, you add the module to an `IncdOnboardingFlowConfiguration` as shown below; when the flow is defined in Dashboard, you reference it and let the back end drive the steps. See [Integration Approaches](https://developer.incode.com/docs/ios-flow-configuration).

**Availability:** All variants.

Use this module when:

- You need a recorded, narrated verification session for regulatory purposes.
- You want identity capture and a liveness check combined into one guided flow.

## Add Video Selfie

1. Add a selfie step before Video Selfie: either an [ID Capture](https://developer.incode.com/docs/module-id-scan) that captures a selfie, or the [Selfie](https://developer.incode.com/docs/module-selfie) module. The face captured here is matched against that selfie, so omitting it causes the module to fail with `selfieNotMatched`.
2. Add the module with the `VideoSelfieConfiguration()` initializer. The initializer takes the four occlusion and quality checks: lenses, face mask, closed eyes, and head covering. All the optional configuration options are set afterward on the `config` object, through a mix of instance methods and properties.
   ```swift
   let config = VideoSelfieConfiguration(
       lensesCheck: true,
       faceMaskCheck: true,
       closedEyesCheck: true,
       headCoverCheck: true
   )

   config.selfieScan(enabled: true, performLivenessCheck: true, mode: .selfieMatch)
   config.idScan(enabled: true, validateId: true)
   config.voiceConsent(enabled: true, faceRecognition: true)
   config.randomQuestions(enabled: true, questionsCount: 3)
   config.handGesture(enabled: true)
   config.tutorials(enabled: true)
   config.maxVideoLength(120)
   config.videoCodecType = .hevc

   let flowConfig = IncdOnboardingFlowConfiguration()
   flowConfig.addVideoSelfie(videoSelfieConfiguration: config)
   ```

## Configuration Options

Configure the module through a `VideoSelfieConfiguration` instance (`config` in the example above).

| Option                                               | Type                                                                    | Description                                                                                                                                                                                                                 |
| ---------------------------------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `selfieScan(enabled:performLivenessCheck:mode:...)`  | `enabled: Bool`, `performLivenessCheck: Bool`, `mode: SelfieMode`       | Configures the selfie step, its liveness check, and the comparison `mode`. `SelfieMode.selfieMatch` (default) matches the new selfie against a previously captured selfie; `.faceMatch` matches it against the captured ID. |
| `idScan(enabled:validateId:...)`                     | `enabled: Bool`, `validateId: Bool?`                                    | Adds an ID capture step and controls ID validation and OCR/image comparison against the captured ID.                                                                                                                        |
| `voiceConsent(enabled:consent:faceRecognition:)`     | `enabled: Bool`, `consent: String?`, `faceRecognition: Bool`            | Records spoken voice consent, with an optional consent string for the user to read aloud. Enables face recognition.                                                                                                         |
| `randomQuestions(enabled:questionsCount:questions:)` | `enabled: Bool`, `questionsCount: Int?`, `questions: [String: String]?` | Prompts the user with liveness questions during recording.                                                                                                                                                                  |
| `handGesture(enabled:)`                              | `Bool`                                                                  | Adds a hand-gesture liveness step.                                                                                                                                                                                          |
| `tutorials(enabled:)`                                | `Bool`                                                                  | Shows or hides the tutorial screen before recording.                                                                                                                                                                        |
| `authorizationDialog(enabled:companyTitle:)`         | `enabled: Bool`, `companyTitle: String`                                 | Shows an authorization dialog with the given company title.                                                                                                                                                                 |
| `maxVideoLength(_:)`                                 | `Int`                                                                   | Sets the maximum recording length, in seconds.                                                                                                                                                                              |
| `showSelfieStepFirst(_:)`                            | `Bool`                                                                  | Presents the selfie step before the other steps.                                                                                                                                                                            |
| `setLogo(_:)`                                        | `UIImage?`                                                              | Sets a `UIImage` logo shown during recording.                                                                                                                                                                               |
| `cameraFacingConfig`                                 | `CameraFacingConfiguration`                                             | `CameraFacingConfiguration` controlling the camera facing per step (selfie, ID front/back, document, random questions, voice consent).                                                                                      |
| `videoCodecType`                                     | `VideoSelfieCodecType`                                                  | `VideoSelfieCodecType`: `.hevc` (default) or `.h264`.                                                                                                                                                                       |
| `disableAudio`                                       | `Bool`                                                                  | Records video without audio.                                                                                                                                                                                                |
| `minVideoLengthRequired`                             | `Bool`                                                                  | When `true`, enforces a minimum recording length of 31 seconds.                                                                                                                                                             |

`documentScan(enabled:)` is deprecated; use `idScan(enabled:...)` instead.

### Global Defaults

These same configuration options can be set as app-wide defaults on `IncdOnboardingManager` instead of per-instance on `VideoSelfieConfiguration`.

| `VideoSelfieConfiguration` Option   | `IncdOnboardingManager` Property | Global Default |
| ----------------------------------- | -------------------------------- | -------------- |
| Liveness check in `selfieScan(...)` | `videoSelfieLivenessCheck`       | N/A            |
| The `mode` in `selfieScan(...)`     | `videoSelfieSelfieMode`          | `.selfieMatch` |
| `randomQuestions(questionsCount:)`  | `videoSelfieQuestionsCount`      | `3`            |
| `maxVideoLength(_:)`                | `videoSelfieMaxVideoLength`      | `300`          |
| `disableAudio`                      | `videoSelfieDisableAudio`        | `false`        |
| `videoCodecType`                    | `videoSelfieCodecType`           | `.hevc`        |
| `tutorials(enabled:)`               | `showVideoSelfieTutorials`       | `true`         |

## Result

```swift
func onVideoSelfieCompleted(_ result: VideoSelfieResult)
```

`VideoSelfieResult` fields:

- `selfie: UIImage?`
- `idFront: UIImage?`
- `idBack: UIImage?`
- `passport: UIImage?`
- `document: UIImage?`
- `voiceConsentSelfie: UIImage?`
- `audioData: Data?`
- `videoData: Data?`: The screen recording delivered to your app. Relevant in [Capture-Only Mode](https://developer.incode.com/docs/ios-capture-only-sdk) too.
- `error: VideoSelfieError?`

## Errors

`VideoSelfieError` covers permission, matching, and recording failures. For example:

- `videoSelfieNotAuthorized`
- `screenRecordingPermissionsDenied`
- `recordingMicrophonePermissionsDenied`
- `voiceConsentMicrophonePermissionsDenied`
- `cameraPermissionsDenied`
- `selfieNotMatched`
- `idNotValid`
- `idTypeNotMatched`
- `idOCRNotValid`
- `idFaceNotMatched`
- `audioNotMatched`
- `videoUploadError`
- `spoofDetected`
- `maxVideoLengthReached`

<br />
