startCamera method

  1. @override
Future<int> startCamera({
  1. required CameraConfig cameraConfig,
  2. HandConfig? handConfig,
  3. FaceConfig? faceConfig,
  4. AnimalConfig? animalConfig,
  5. PoseConfig? poseConfig,
  6. required ModelPaths models,
})
override

Implementation

@override
Future<int> startCamera({
  required CameraConfig cameraConfig,
  HandConfig? handConfig,
  FaceConfig? faceConfig,
  AnimalConfig? animalConfig,
  PoseConfig? poseConfig,
  required ModelPaths models,
}) async {
  // Clamp to 1-60 if set, 0 means no throttle
  final maxResults = cameraConfig.maxResultsPerSecond <= 0
      ? 0
      : cameraConfig.maxResultsPerSecond.clamp(1, 60);

  final result = await _commandChannel.invokeMethod<int>('startCamera', {
    'cameraFacing': cameraConfig.facing.index,
    'resolution': cameraConfig.resolution.index,
    'maxResultsPerSecond': maxResults,
    'enableHand': handConfig != null,
    'enableFace': faceConfig != null,
    'enableAnimal': animalConfig != null,
    'enablePose': poseConfig != null,
    // Model file paths — native loads each enabled model from these. Core bundles none.
    if (handConfig != null) 'handModelPath': models.handModel,
    if (faceConfig?.detectEmotion == true)
      'emotionModelPath': models.emotionModel,
    if (animalConfig != null) ...{
      'animalModelPath': models.animalModel,
      'animalScoreThreshold': animalConfig.scoreThreshold,
      'animalMaxResults': animalConfig.maxResults,
      if (animalConfig.allowedCategories != null)
        'animalAllowedCategories': animalConfig.allowedCategories!.toList(),
      if (animalConfig.deniedCategories != null)
        'animalDeniedCategories': animalConfig.deniedCategories!.toList(),
      'detectBreed': animalConfig.detectBreed,
      if (animalConfig.detectBreed) 'breedModelPath': models.breedModel,
      'breedMaxResults': animalConfig.breedMaxResults,
      'breedClassifiableCategories':
          animalConfig.breedClassifiableCategories.toList(),
      'breedScoreThreshold': animalConfig.breedScoreThreshold,
      if (animalConfig.breedAllowedCategories != null)
        'breedAllowedCategories': animalConfig.breedAllowedCategories!.toList(),
      if (animalConfig.breedDeniedCategories != null)
        'breedDeniedCategories': animalConfig.breedDeniedCategories!.toList(),
      if (animalConfig.displayNamesLocale != null)
        'displayNamesLocale': animalConfig.displayNamesLocale,
      if (animalConfig.rotationDegrees != null)
        'rotationDegrees': animalConfig.rotationDegrees,
    },
    if (poseConfig != null) ...{
      // Model path is start-time-only; native loads the .task from here.
      'poseModelPath': models.poseModel,
      'numPoses': poseConfig.numPoses,
      'minPoseDetectionConfidence': poseConfig.minPoseDetectionConfidence,
      'minPosePresenceConfidence': poseConfig.minPosePresenceConfidence,
      'minPoseTrackingConfidence': poseConfig.minTrackingConfidence,
    },
    if (handConfig != null) ...{
      'maxHands': handConfig.maxHands,
      'minDetectionConfidence': handConfig.minDetectionConfidence,
      'minPresenceConfidence': handConfig.minPresenceConfidence,
      'minTrackingConfidence': handConfig.minTrackingConfidence,
      // Each custom gesture serializes its fingerStates in thumb→pinky order.
      'customGestures': handConfig.customGestures
          .map(
            (g) => {
              'name': g.name,
              'fingerStates': [
                _fingerStateToNative(g.fingerStates[Finger.thumb]),
                _fingerStateToNative(g.fingerStates[Finger.indexFinger]),
                _fingerStateToNative(g.fingerStates[Finger.middle]),
                _fingerStateToNative(g.fingerStates[Finger.ring]),
                _fingerStateToNative(g.fingerStates[Finger.pinky]),
              ],
            },
          )
          .toList(),
      ..._serializeGestureFilters(handConfig),
    },
    if (faceConfig != null) ...{
      'detectEmotion': faceConfig.detectEmotion,
      'detectLandmarks': faceConfig.detectLandmarks,
      'detectContours': faceConfig.detectContours,
      'minFaceSize': faceConfig.minFaceSize,
      'enableFaceTracking': faceConfig.enableTracking,
      'minEmotionConfidence': faceConfig.minEmotionConfidence,
      'accurateMode': faceConfig.accurateMode,
    },
  });
  // result! is safe: native always returns an int on success, throws on failure.
  return result!;
}