Moderation / Moderation · Flutter

Moderation · Flutter

Use Nosmai Moderation in a Flutter app — image, video, text and live-camera moderation.

Install

Add the plugin to pubspec.yaml, then flutter pub get.

dependencies:
  nosmai_moderation_sdk: ^1.0.0

Android — bundle the native AAR in your host app. Download nosmai-detection.aar from the Android releases, put it in android/app/libs/, and reference it:

android {
  defaultConfig {
    minSdk = 24
    ndk { abiFilters += "arm64-v8a" }
  }
}
dependencies {
  implementation(files("libs/nosmai-detection.aar"))
}

iOS needs no extra step — pod install pulls the native SDK with the plugin.

Requirements: Flutter 3+, Android minSdk 24 (arm64-v8a), iOS 14+. For live camera add the camera permission to AndroidManifest.xml / NSCameraUsageDescription in Info.plist (the example uses permission_handler). For iOS App Store uploads also set ITSAppUsesNonExemptEncryption = NO in Info.plist (the SDK only encrypts its own bundled models — export-compliance exempt).

Distribute Android as an App Bundle (AAB) — the SDK ships arm64-v8a only, so Play hides it from 32-bit-only devices, and it won’t run on x86_64 emulators.

Initialize

Call once at startup with your license key. It runs natively on a background thread.

import 'package:nosmai_moderation_sdk/nosmai_moderation_sdk.dart';

final res = await NosmaiModeration.initialize('NOSMAI-XXXX');
if (!res.success) {
  debugPrint('Nosmai init failed: ${res.error}');
}

Moderate an image

Pass a file path (e.g. from image_picker). Returns a NosmaiResult.

final r = await NosmaiModeration.analyzeImage(file.path);
if (r.isUnsafe) {
  // r.detections -> [{category, confidence}], r.nsfw -> safe/warn/block
  for (final d in r.detections) {
    print('${d?.category?.name} ${(d!.confidence! * 100).round()}%');
  }
}

Moderate a video

Samples one frame every frameIntervalMs and aggregates.

final v = await NosmaiModeration.analyzeVideo(file.path, 500);
if (v.isUnsafe) {
  print('categories: ${v.categories}, frames: ${v.framesAnalyzed}');
}

Moderate text

Call initialize first (it validates the license), then load the text model once (it is larger), then moderate messages.

await NosmaiModeration.initializeText();          // after initialize()

final t = await NosmaiModeration.moderateText('some message');
if (t.blocked) {
  // t.layer (blocklist/classifier), t.category, t.matchedWord
  print('blocked: ${t.category?.name}');
}

Live camera

The camera, frame capture and detection all run natively; only the per-frame NosmaiResult crosses to Dart.

import 'package:permission_handler/permission_handler.dart';

// 1. show the native preview
const NosmaiCameraPreview();

// 2. start + listen, after granting camera permission
await Permission.camera.request();
final sub = NosmaiLive.results().listen(
  (r) => setState(() => _verdict = r.isUnsafe ? 'UNSAFE' : 'SAFE'),
  onError: (e) => debugPrint('camera failed to start: $e'),  // permission / no camera
);
await NosmaiLive.start(facing: NosmaiCameraFacing.back);  // .front also supported; falls
                                                          // back to the other if unavailable

// 3. on leave — always stop, the camera does not stop itself on widget dispose
await NosmaiLive.stop();
sub.cancel();

Thresholds

Adjust any object class or NSFW bar at runtime (lower is stricter).

NosmaiModeration.setThreshold(NosmaiCategory.weapon, 0.7);
NosmaiModeration.setNsfwThreshold(NosmaiNsfwClass.explicit, 0.45); // BLOCK
NosmaiModeration.setNsfwThreshold(NosmaiNsfwClass.sexy, 0.55);     // WARN

Cleanup

NosmaiModeration.shutdown();

NOTE

analyzeImage, analyzeVideo, moderateText and initialize are async — they run native inference off the platform thread, so the UI never blocks.

Nosmai

We make advanced camera and AI technology accessible to every developer. By packaging hard problems into simple

developers
legal
newsletter

Product updates and release notes. No spam.

© 2026 nosmai, inc · all rights reserved