face_liveness_verification

Production-focused Flutter package for face detection workflow integration, challenge-based face liveness checks, and FaceNet identity verification.

Best for onboarding, login protection, attendance, and KYC-like mobile verification flows.

face_liveness_verification banner

Table of Contents

  • Banner
  • Features
  • Use Cases
  • Getting Started
  • Architecture (Image + Diagram)
  • How It Works
  • Quick Start
  • Complete Developer Example
  • Enrollment and Verification Flows
  • UI Integration
  • Configuration Reference
  • Result Model and Failure Reasons
  • Performance and Tuning
  • Security and Privacy
  • API Map
  • SEO and Discoverability
  • Example App
  • Validation
  • License

Features

  • End-to-end pipeline: liveness + embedding + matching.
  • Action-based liveness flow: smile, blink, turn left/right, look up/down, neutral.
  • Configurable thresholds, timeouts, retries, and action order randomization.
  • FaceNet embedding extraction with TFLite.
  • Template enrollment and verification orchestration.
  • Template storage abstraction for custom secure persistence.
  • Built-in default UI plus custom UI builder option.
  • Unified result models with normalized failure reasons.

Use Cases

  • User onboarding with selfie liveness and identity binding.
  • Returning-user face verification for authentication.
  • Attendance/check-in with replay-resistance via challenge flow.
  • Step-up verification before sensitive actions.

Getting Started

1. Add dependency

dependencies:
  face_liveness_verification: ^1.0.1
flutter pub get

2. Import package

import 'package:face_liveness_verification/face_liveness_verification.dart';

3. Add permissions

Android, android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.CAMERA" />

iOS, ios/Runner/Info.plist:

<key>NSCameraUsageDescription</key>
<string>Camera is required for face liveness verification.</string>

4. SDK requirements

  • Dart SDK: ^3.13.0
  • Flutter: >=1.17.0

Platform Support

Platform Status
Android Supported
iOS Supported
Web Not officially supported
macOS / Windows / Linux Not officially supported

Architecture (Image + Diagram)

Face Liveness Verification Architecture

Add your generated image to this path so it renders in GitHub and pub.flutter-io.cn:

  • doc/mermaid-diagram.png

How It Works

  1. Your app sends per-frame faces, image size, and image bytes to the service.
  2. The package checks frame validity: single face, position, and face size range.
  3. Liveness state machine drives challenge actions until completion.
  4. After liveness passes, FaceNet creates an embedding from the best available face crop.
  5. Live embedding is compared with template embedding using selected metric.
  6. You receive one unified result object for UI updates and business decisions.

Quick Start

final service = FaceLivenessMatchService(
  livenessConfig: const FaceLivenessConfig(),
  matchingConfig: const FaceMatchingConfig(
    metric: FaceSimilarityMetric.euclidean,
    threshold: 1.0,
  ),
  templateStore: InMemoryFaceTemplateStore(),
);

await service.warmUp();

Complete Developer Example

import 'dart:typed_data';
import 'dart:ui';

import 'package:face_liveness_verification/face_liveness_verification.dart';
import 'package:google_mlkit_face_detection/google_mlkit_face_detection.dart';

class FaceVerificationEngine {
  FaceVerificationEngine()
      : _service = FaceLivenessMatchService(
          livenessConfig: const FaceLivenessConfig(
            actions: [
              FaceLivenessAction.smile,
              FaceLivenessAction.blink,
              FaceLivenessAction.turnLeft,
              FaceLivenessAction.turnRight,
            ],
            challengeTimeout: Duration(seconds: 12),
            totalSessionTimeout: Duration(seconds: 45),
            randomizeActionOrder: true,
          ),
          matchingConfig: const FaceMatchingConfig(
            metric: FaceSimilarityMetric.euclidean,
            threshold: 1.0,
          ),
          templateStore: InMemoryFaceTemplateStore(),
        );

  final FaceLivenessMatchService _service;

  Future<void> initialize() async {
    await _service.warmUp();
  }

  Future<FaceLivenessMatchResult> enroll({
    required String faceId,
    required List<Face> faces,
    required Size imageSize,
    required Uint8List imageBytes,
  }) {
    return _service.enrollAndPersist(
      faceId: faceId,
      faces: faces,
      imageSize: imageSize,
      imageBytes: imageBytes,
      requireLiveness: true,
    );
  }

  Future<FaceLivenessMatchResult> verify({
    required List<Face> faces,
    required Size imageSize,
    required Uint8List imageBytes,
  }) {
    return _service.verifyWithStoredTemplate(
      faces: faces,
      imageSize: imageSize,
      imageBytes: imageBytes,
    );
  }

  FaceLivenessUiState toUi(FaceLivenessMatchResult result) {
    return FaceLivenessUiState.fromLivenessMatchResult(result);
  }

  void reset() {
    _service.reset();
  }

  void dispose() {
    _service.dispose();
  }
}

Enrollment and Verification Flows

Enrollment

final enrollResult = await service.enrollAndPersist(
  faceId: 'user_001',
  faces: faces,
  imageSize: imageSize,
  imageBytes: imageBytes,
  requireLiveness: true,
);

if (enrollResult.enrolledTemplate != null) {
  // Enrollment successful
}

If you want to persist outside the service, call enrollFirstTime and save template in your own store.

Verification

final result = await service.verifyWithStoredTemplate(
  faces: faces,
  imageSize: imageSize,
  imageBytes: imageBytes,
);

final uiState = FaceLivenessUiState.fromLivenessMatchResult(result);

You can also verify against a specific template with verifyWithTemplate.

UI Integration

Default UI:

FaceLivenessUi(
  preview: cameraPreviewWidget,
  state: uiState,
)

Custom UI:

FaceLivenessUi(
  preview: cameraPreviewWidget,
  state: uiState,
  builder: (context, state) {
    return Stack(
      children: [
        Positioned.fill(child: cameraPreviewWidget),
        Align(
          alignment: Alignment.bottomCenter,
          child: Text(state.message),
        ),
      ],
    );
  },
)

Configuration Reference

FaceLivenessConfig

Parameter Type Default Purpose
smileThreshold double 0.6 Smile confidence threshold
eyeOpenThreshold double 0.6 Blink open/close threshold
headEulerXThreshold double 10 Pitch threshold
headEulerYThreshold double 10 Yaw threshold
headEulerZThreshold double 10 Roll threshold
minimumFaceSize double 0.18 Lower face-area ratio bound
maximumFaceSize double 0.75 Upper face-area ratio bound
challengeTimeout Duration 12s Timeout per challenge
totalSessionTimeout Duration 45s Total session timeout
frameProcessingInterval Duration 180ms Recommended processing cadence
actions List smile, blink Challenge sequence
maxFailedAttempts int 4 Allowed challenge timeouts
randomizeActionOrder bool true Shuffle action order on reset

FaceMatchingConfig

Parameter Type Default Purpose
metric FaceSimilarityMetric euclidean Similarity metric
threshold double 1.0 Match threshold

Result Model and Failure Reasons

Key fields from FaceLivenessMatchResult:

  • isValidFace
  • isLivenessComplete
  • isMatchComplete
  • isMatch
  • nextAction
  • message
  • distance
  • threshold
  • similarityMetric
  • similarityScore
  • failureReason

Failure reasons to map in UX:

  • noFace
  • multipleFaces
  • invalidPosition
  • invalidHeadPose
  • challengeTimeout
  • challengeFailed
  • sessionTimeout
  • faceTooSmall
  • faceTooLarge
  • embeddingFailed
  • identityNotMatched
  • processingError

Performance and Tuning

  • Call warmUp once before first active session.
  • Keep one service instance per liveness screen/session.
  • Start with short challenge list for lower friction.
  • Tune thresholds after testing across real devices and lighting conditions.
  • Track failureReason counts to guide configuration improvements.

Security and Privacy

  • Treat face embeddings as sensitive biometric data.
  • Use encrypted storage for templates in production.
  • Avoid logging raw embeddings or full face frame bytes.
  • Define clear retention and deletion policies in your app.
  • Show consent language where legal requirements apply.

API Map

  • FaceLivenessMatchService: orchestration for liveness, enrollment, and verification.
  • FaceLivenessChecker: translates face detections into liveness decisions.
  • LivenessStateMachine: challenge progression, retries, and timeout logic.
  • FaceEmbeddingExtractor: FaceNet embedding extraction through TFLite.
  • FaceEnrollmentService: averaged template creation from multiple samples.
  • FaceSimilarity: Euclidean distance and cosine similarity helpers.
  • FaceTemplateStore: persistence contract for template storage.
  • FaceLivenessUi and FaceLivenessUiState: default and custom UI integration.

SEO and Discoverability

This package targets the following search intent:

  • Flutter face detection
  • Flutter face liveness
  • Flutter face verification
  • Face recognition Flutter package
  • Biometric authentication Flutter

Discoverability checklist:

  • Keep README examples up to date with API changes.
  • Add architecture image and demo screenshots in doc folder.
  • Publish frequent stable updates with clear changelog notes.
  • Keep package topics and description focused on core search terms.

Example App

Run the bundled demo:

cd example
flutter run

Validation

flutter analyze
flutter test

License

MIT License. See LICENSE.