Native screen recording library for Flutter using platform-specific APIs (Android MediaProjection and iOS ReplayKit) with FFmpeg-powered region cropping.
- âś… Native screen recording (Android & iOS)
- âś… Region-specific recording with automatic video cropping
- âś… Widget-based recording using GlobalKey
- âś… Video export with customizable settings
- âś… High-quality MP4 output with H.264 encoding
| Platform | Minimum Version | API Used |
|---|---|---|
| Android | API 21 (Lollipop) | MediaProjection + MediaRecorder |
| iOS | 11.0 | ReplayKit (RPScreenRecorder) |
Add to your pubspec.yaml:
dependencies:
screen_record_plus: ^1.0.0import 'package:screen_record_plus/screen_record_plus.dart';
// Create controller
final controller = ScreenRecorderController();
// Start recording (full screen)
await controller.start();
// Stop recording
await controller.stop();
// Export video
final file = await controller.exporter.exportVideo(
multiCache: true,
cacheFolder: "my_recordings",
);
print('Video saved to: ${file?.path}');Capture a specific region of the screen. The full screen is recorded, then the video is automatically cropped to the specified region during export:
// Record a 400x400 region starting at position (100, 100)
final controller = ScreenRecorderController(
recordingRect: Rect.fromLTWH(100, 100, 400, 400),
);
await controller.start();
// ... recording ...
await controller.stop();
final file = await controller.exporter.exportVideo(); // Automatically croppedHow it works: The native APIs record the full screen, then FFmpeg crops the video to your specified region during export. This ensures you only get the part of the screen you want.
Easily record a specific widget using GlobalKey:
// Create a GlobalKey and attach it to your widget
final key = GlobalKey();
Widget build(BuildContext context) {
return Container(
key: key,
child: YourWidget(),
);
}
// Get the widget's position and size
final rect = ScreenRecorderController.getWidgetRect(key);
if (rect != null) {
final controller = ScreenRecorderController(recordingRect: rect);
await controller.start();
// ... recording ...
await controller.stop();
final file = await controller.exporter.exportVideo();
}final isSupported = await NativeScreenRecorder.isSupported();
if (isSupported) {
// Start recording
}await controller.exporter.exportVideo(
multiCache: false,
cacheFolder: "recordings",
onProgress: (result) {
print('Status: ${result.status}, Progress: ${result.percent}');
},
);Add permissions to AndroidManifest.xml:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />Note: User will be prompted for screen recording permission on first use.
Add to your Info.plist:
<key>NSMicrophoneUsageDescription</key>
<string>This app needs microphone access for screen recording</string>Minimum iOS version: 11.0
Main controller for screen recording.
ScreenRecorderController({
Rect? recordingRect, // Optional: specify recording region
})Methods:
Future<void> start()- Start recordingFuture<void> stop()- Stop recordingFuture<void> clearCacheFolder(String cacheFolder)- Clear cached filesExporter get exporter- Get exporter instanceDuration? get duration- Get recording duration
Handles video export operations.
Methods:
Future<File?> exportVideo({...})- Export recorded video
Parameters:
ValueChanged<ExportResult>? onProgress- Progress callbackbool multiCache- Create unique filename for each export (default: false)String cacheFolder- Cache folder name (default: "ScreenRecordVideos")
Static class for native platform operations.
Methods:
static Future<bool> startRecording({double? x, y, width, height})- Start native recordingstatic Future<bool> stopRecording()- Stop recordingstatic Future<String?> exportVideo({required String outputPath})- Export videostatic Future<bool> isSupported()- Check if native recording is supportedstatic Future<bool> isRecording()- Check if currently recording
See the example folder for a complete working example.
- Capture: Native APIs (MediaProjection/ReplayKit) record the full screen
- Export: Video is exported to temporary location
- Crop: If
recordingRectis specified, FFmpeg crops the video to that region - Output: Final cropped video is saved to cache folder
- Uses MediaProjection API for screen capture
- MediaRecorder for video encoding
- H.264 codec at 30fps, 5 Mbps bitrate
- Outputs MP4 format
- Uses ReplayKit (RPScreenRecorder) for screen capture
- AVAssetWriter for video encoding
- H.264 codec with configurable quality
- Outputs MP4 format
- Uses FFmpeg for post-recording video cropping
- Cropping happens automatically during export when
recordingRectis specified - No quality loss during cropping (uses stream copy for audio)
- Note: Package size increases by ~100MB due to FFmpeg inclusion
Version 1.0.0 removed widget-based recording mode. Version 1.1.0 re-adds FFmpeg for video cropping functionality. If you were using:
Before (v0.x):
ScreenRecorderController(
recordingMode: RecordingMode.widget, // Removed
pixelRatio: 3.0, // Removed
skipFramesBetweenCaptures: 2, // Removed
)After (v1.0.0):
ScreenRecorderController(
recordingRect: Rect.fromLTWH(0, 0, 400, 400), // Optional
)The ScreenRecorder widget is no longer needed. All recording is now done using native platform APIs.
Contributions are welcome! Please feel free to submit a Pull Request.
See LICENSE file for details.
Store:
