screen_record_plus 1.1.0
screen_record_plus: ^1.1.0 copied to clipboard
Native screen recording with coordinate-based capture for Android and iOS.
Screen Record Plus #
Native screen recording library for Flutter using platform-specific APIs (Android MediaProjection and iOS ReplayKit) with FFmpeg-powered region cropping.
Features #
- ✅ 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 Support #
| Platform | Minimum Version | API Used |
|---|---|---|
| Android | API 21 (Lollipop) | MediaProjection + MediaRecorder |
| iOS | 11.0 | ReplayKit (RPScreenRecorder) |
Installation #
Add to your pubspec.yaml:
dependencies:
screen_record_plus: ^1.0.0
Usage #
Basic Recording #
import '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}');
Recording with Coordinates #
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 cropped
How 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.
Recording a Specific Widget #
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();
}
Check Platform Support #
final isSupported = await NativeScreenRecorder.isSupported();
if (isSupported) {
// Start recording
}
Export with Progress Callback #
await controller.exporter.exportVideo(
multiCache: false,
cacheFolder: "recordings",
onProgress: (result) {
print('Status: ${result.status}, Progress: ${result.percent}');
},
);
Platform-Specific Setup #
Android #
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.
iOS #
Add to your Info.plist:
<key>NSMicrophoneUsageDescription</key>
<string>This app needs microphone access for screen recording</string>
Minimum iOS version: 11.0
API Reference #
ScreenRecorderController #
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
Exporter #
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")
NativeScreenRecorder #
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
Example #
See the example folder for a complete working example.
Technical Details #
Recording Process #
- 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
Android Implementation #
- Uses MediaProjection API for screen capture
- MediaRecorder for video encoding
- H.264 codec at 30fps, 5 Mbps bitrate
- Outputs MP4 format
iOS Implementation #
- Uses ReplayKit (RPScreenRecorder) for screen capture
- AVAssetWriter for video encoding
- H.264 codec with configurable quality
- Outputs MP4 format
Video Cropping #
- 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
Migration from v0.x #
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.
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
License #
See LICENSE file for details.
App Demo #
Store: