flutter_mp_pose_landmarker 0.1.8
flutter_mp_pose_landmarker: ^0.1.8 copied to clipboard
A Flutter plugin for real-time pose detection using MediaPipe and native CameraX.
Changelog #
0.1.8 - 2026-04-27 #
Fix #
- use uptimeMillis() instead of imageProxy timestamp to prevent duplicate timestamps
0.1.7 - 2026-04-21 #
Improvements #
- Improved camera stream stability with safer helper initialization.
- Added frame timestamp validation to prevent duplicate/out-of-order processing.
- Introduced camera state flags for better lifecycle handling.
Pose Processing #
- Fixed live stream inference timing using
imageProxytimestamps. - Reduced MediaPipe warnings by filtering invalid frames.
- Improved GPU → CPU fallback handling and logging.
Image Processing #
- Made YUV → RGB conversion thread-safe.
- Fixed NV21 conversion (correct stride/pixel handling).
- Added strict bitmap validation (size, config, and recycling checks).
Stability #
- Ensured
imageProxy.close()is always called to avoid pipeline blocking. - Reduced race conditions in live stream processing.
Cleanup #
- Refactored helper initialization and removed redundant null checks.
- Simplified bitmap rotation and MediaPipe pipeline setup.
0.1.6 - 2026-04-13 #
0.1.5 - 2026-03-17 #
Fixed #
- Camera is no longer initialized eagerly on activity attach. It now starts
only when a Dart listener subscribes to
poseLandmarkStream(onListen) and is fully released when the subscription is cancelled (onCancel). This fixes a conflict where the plugin held the camera hardware even when no pose detection was active, preventing thecamerapackage and other consumers from opening the camera on other screens.
Changed #
CameraManager.startCamera()is no longer called insideonAttachedToActivity. The plugin now only constructs the manager at attach time and defers all hardware access to stream subscription time.onCancelnow callsreleaseCamera()(unbindsProcessCameraProvider) in addition todisableAnalysis(), ensuring the hardware is fully freed.- Stream listener guards added (
!mountedcheck) to preventsetStatecalls after widget disposal. IPoseManagerextended withreleaseCamera()to formalize the release contract across bothCameraManagerandMockPoseManager.MockPoseManager.releaseCamera()implemented as a no-op.
Example app #
_poseSubscriptionchanged fromlateto nullable (?) sodispose()is safe even if the stream was never started.- Replaced deprecated
withOpacity()calls withwithAlpha(). - Replaced
print()calls withdebugPrint(). - Repeated stat label containers extracted into a
_StatChipwidget.
0.1.4 - 2026-03-13 #
Added #
Security & Anti-Spoofing
-
Emulator Detection System
- Created
EmulatorDetectorutility class to identify Android emulators at runtime - Provides boolean flag for emulator presence
- Created
-
Mock Pose Manager
- Implemented
MockPoseManagerclass as safe fallback for emulator environments - Prevents pose analysis manipulation on virtual devices
- Returns mock/empty pose data to maintain API consistency
- Implements
IPoseManagerinterface for seamless integration
- Implemented
Architecture Improvements
- IPoseManager Interface
- Created abstraction layer for pose management
- Defined contract methods:
setEventSink(events: EventChannel.EventSink?)enableAnalysis()disableAnalysis()pauseAnalysis()resumeAnalysis()dispose()
- Enables strategy pattern for real vs. mock pose managers
Changed #
CameraManager Refactoring
- Interface Implementation (
CameraManager.kt)- Implemented
IPoseManagerinterface - Added
overridemodifiers to interface methods:- Line 179:
override fun setEventSink() - Line 183:
override fun enableAnalysis() - Line 212:
override fun disableAnalysis() - Line 219:
override fun pauseAnalysis() - Line 225:
override fun resumeAnalysis() - Line 231:
override fun dispose()
- Line 179:
- Ensures compile-time contract enforcement
- Implemented
Plugin Initialization
- FlutterMpPoseLandmarkerPlugin Updates (
FlutterMpPoseLandmarkerPlugin.kt)- Line 117: Added emulator detection on plugin initialization
poseManager = if (EmulatorDetector.isEmulator(context)) {
MockPoseManager()
} else {
CameraManager(context, textureRegistry)
}
- Line 131: Updated pose manager references to use abstracted interface
- Dynamically selects real or mock manager based on device type
Security Impact #
- Data Integrity Protection
- Prevents spoofing of pose landmark data on emulated devices
- Ensures exercises are performed on real devices
- Protects against automated bot manipulation in fitness apps
- Maintains trust in pose tracking for medical/therapeutic use cases
- Making Sure app devs has no problem working with emulators with the mock service
Technical Details #
-
Files Modified:
android/src/main/kotlin/com/carecode/flutter_mp_pose_lm/CameraManager.ktandroid/src/main/kotlin/com/carecode/flutter_mp_pose_lm/FlutterMpPoseLandmarkerPlugin.kt
-
Files Added:
android/src/main/kotlin/com/carecode/flutter_mp_pose_lm/IPoseManager.kt(interface)android/src/main/kotlin/com/carecode/flutter_mp_pose_lm/MockPoseManager.ktandroid/src/main/kotlin/com/carecode/flutter_mp_pose_lm/EmulatorDetector.kt
-
Dependencies:
- No new external dependencies required
- Uses Android Build class for device detection
- Compatible with existing MediaPipe pose detection pipeline
Breaking Changes #
- None - Changes are backward compatible with existing API
Migration Guide #
No migration required. The changes are transparent to Flutter/Dart layer consumers. Existing code will continue to work without modifications.
0.1.3 - 2025-12-04 #
Fixed #
- Removed leftover
print()debug statements. - Updated license information and added LICENSE file.
0.1.2 - 2025-11-28 #
Added #
- Camera permission check before starting detection.
- Configurable confidence thresholds:
minPoseDetectionConfidenceminPoseTrackingConfidenceminPosePresenceConfidence
- Runtime configuration via
PoseLandmarker.setConfig(). - Camera controls:
- Start / Stop / Pause / Resume detection.
- Logging toggle to enable/disable plugin logs.
- FPS counter for performance monitoring.
- Platform interface tests.
- Integration tests.
Changed #
- All confidence thresholds can now be updated dynamically at runtime via
setConfig().