DeepAR Flutter Plus

An enhanced version of the official DeepAR Flutter SDK that adds support for loading effects from assets, file paths, and URLs with caching. This makes it possible to load effects that are downloaded or stored anywhere on the device's filesystem, or directly from the internet with automatic caching.

This plugin is a fork of the official SDK for DeepAR. Platforms supported: Android & iOS.

The current version of plugin supports:

  • Load effects from assets, file paths, and URLs with caching ✨ (New!)
  • Live AR previews ✅
  • Take screenshots ✅
  • Record Videos ✅
  • Flip camera ✅
  • Toggle Flash ✅
Support Android iOS
SDK 23+ iOS 13.0+

⚠️ BREAKING CHANGE in v0.1.7: The initialize() method now returns an InitializeResult object with success and message properties instead of just a boolean. See the initialization section for updated usage.

New in v0.1.9: Updated iOS implementation for the latest DeepAR SDK with improved compatibility and effect loading.

New in v0.1.8: Improved iOS camera initialization with better error handling and platform view creation.

Installation

Please visit the developer website to create a project and generate your separate license keys for both platforms.

Once done, please add the latest deepar_flutter_plus dependency to your pubspec.yaml.

Android:

  1. compileSdkVersion should be 33 or more.
  2. minSdkVersion should be 23 or more.
  3. Download the native android dependencies from the downloads section and paste it in your flutter project at android/app/libs/deepar.aar.
  4. Make sure to pub clean & flutter pub upgrade to fetch latest working code.

iOS:

  1. iOS 13.0+ is required.
  2. If you encounter the error 'deepar_flutter-Swift.h' file not found, make sure you're using the latest version of the plugin which fixes this issue.

Also add the following permission requests in your AndroidManifest.xml

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"  />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />

Ensure to add these rules to proguard-rules.pro else app might crash in release build

-keepclassmembers class ai.deepar.ar.DeepAR { *; }
-keepclassmembers class ai.deepar.ar.core.videotexture.VideoTextureAndroidJava { *; }
-keep class ai.deepar.ar.core.videotexture.VideoTextureAndroidJava

iOS:

  1. Ensure your app iOS deployment version is 13.0+.
  2. Do a flutter clean & install pods.
  3. To handle camera and microphone permissions, please add the following strings to your info.plist.
  4. Make sure to pub clean & flutter pub upgrade to fetch latest working code.
<key>NSCameraUsageDescription</key>
<string>---Reason----</string>
<key>NSMicrophoneUsageDescription</key>
<string>---Reason----</string>
  1. Also add the following to your Podfile file:
post_install do |installer|
  installer.pods_project.targets.each do |target|
    ... # Here are some configurations automatically generated by flutter

    # Start of the deepar configuration
    target.build_configurations.each do |config|

      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

        ## dart: PermissionGroup.camera
         'PERMISSION_CAMERA=1',

        ## dart: PermissionGroup.microphone
         'PERMISSION_MICROPHONE=1',
      ]

    end
    # End of the permission_handler configuration
  end
end

Flutter:

  1. Initialize DeepArControllerPlus by passing in your license keys for both platforms.
final DeepArControllerPlus _controller = DeepArControllerPlus();
final result = await _controller.initialize(
    androidLicenseKey:"---android key---",
    iosLicenseKey:"---iOS key---",
    resolution: Resolution.medium);

if (result.success) {
  // Initialization successful
  print("Initialization successful: ${result.message}");

  // For iOS, you need to wait for the platform view to be fully created
  if (Platform.isIOS) {
    // Check initialization status periodically
    Timer.periodic(Duration(milliseconds: 500), (timer) {
      if (_controller.isInitialized) {
        print('iOS view is now fully initialized');
        setState(() {
          // Update your UI to show the camera preview
        });
        timer.cancel();
      } else if (timer.tick > 20) {
        // Timeout after 10 seconds
        print('Timeout waiting for iOS view initialization');
        timer.cancel();
      }
    });
  }
} else {
  // Initialization failed
  print("Initialization failed: ${result.message}");
}
  1. Place the DeepArPreviewPlus widget in your widget tree to display the preview.
@override
Widget build(BuildContext context) {
    return _controller.isInitialized
        ? DeepArPreviewPlus(_controller)
        : const Center(
            child: Text("Loading Preview")
        );
}

To display the preview in full screen, wrap DeepArPreviewPlus with Transform.scale() and use the correct scale factor as per preview area size. See example here.

  1. Load effects, filters, or masks using assets, file paths, or URLs:
// Using asset file
await _controller.switchEffect("assets/effects/my_effect.deepar");

// Using file path
await _controller.switchEffect("/path/to/effect/file.deepar");

// Using URL (automatically cached)
await _controller.switchEffect("https://example.com/effects/my_effect.deepar");

// Same applies for filters and masks
await _controller.switchFilter("https://example.com/filters/beauty.deepar");
await _controller.switchFaceMask("https://example.com/masks/funny_mask.deepar");

Note:

  • When using file paths, make sure the app has proper permissions to access the file location
  • When using URLs, effects are automatically cached for better performance and offline access
  1. To take a picture, use takeScreenshot() which returns the picture as file.
final File file = await _controller.takeScreenshot();
  1. To record a video, please use:
if (_controller.isRecording) {
    _controller.stopVideoRecording();
} else {
    final File videoFile = _controller.startVideoRecording();
}

For more info, please visit: Developer Help.