flutter_web_record
A powerful Flutter web package for screen recording with audio support, pause/resume controls, customizable UI, and built-in preview functionality.
Features
- π₯ Screen Recording - Capture screen with customizable quality settings
- π€ Multiple Audio Modes - System audio, microphone, both, or none
- βΈοΈ Pause/Resume - Full control during recording
- π¨ Customizable UI - Fully customizable recording indicator and controls
- ποΈ Preview Dialog - Optional preview before saving
- π¦ Easy Integration - Returns video as bytes for upload/storage
- π Web Only - Uses browser MediaRecorder API
Screenshots
Screen Share Selection
Recording Controls
Preview Dialog
Recordings List
Video Details & Playback
Platform Support
| Platform | Support |
|---|---|
| Web | β |
| Android | β |
| iOS | β |
| Windows | β |
| macOS | β |
| Linux | β |
Browser Compatibility
| Browser | Support | Notes |
|---|---|---|
| Chrome | β 72+ | Full support |
| Edge | β 79+ | Full support |
| Opera | β 60+ | Full support |
| Safari | β tested on V26 | Supported |
| Firefox | β οΈ | Requires flag |
Installation
Add this to your package's pubspec.yaml:
dependencies:
flutter_web_record: ^0.1.0
Then run:
flutter pub get
Quick Start
import 'package:flutter/material.dart';
import 'package:flutter_web_record/flutter_web_record.dart';
class MyRecordingScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () async {
await ScreenRecorder.startRecording(
context,
onRecordingComplete: (result) {
print('Recording saved: ${result.fileName}');
print('Size: ${result.fileBytes.length} bytes');
// Upload or process the video
},
onRecordingCancelled: () {
print('Recording cancelled');
},
);
},
child: Text('Start Recording'),
),
),
);
}
}
Usage Examples
Basic Recording
final result = await ScreenRecorder.startRecording(
context,
onRecordingComplete: (result) {
// Handle completed recording
print('Duration: ${result.durationSeconds}s');
print('File: ${result.fileName}');
},
);
With Preview Dialog
await ScreenRecorder.startRecording(
context,
showPreview: true, // User can preview before saving
onRecordingComplete: (result) {
// Only called if user confirms in preview
uploadVideo(result.fileBytes);
},
);
Custom Quality Settings
await ScreenRecorder.startRecording(
context,
recordingConfig: RecordingConfig(
idealWidth: 1920,
idealHeight: 1080,
idealFrameRate: 60,
videoBitsPerSecond: 8000000, // 8 Mbps
captureAudio: true,
showCursor: true,
audioCaptureMode: AudioCaptureMode.both, // System + Mic
),
);
Custom UI Styling
await ScreenRecorder.startRecording(
context,
indicatorConfig: RecordingIndicatorConfig(
recordingColor: Colors.red,
pausedColor: Colors.orange,
backgroundColor: Colors.black87,
position: Alignment.topLeft,
borderRadius: 16.0,
timeTextStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
controlConfig: ControlButtonConfig(
pauseColor: Colors.blue,
stopColor: Colors.red,
cancelColor: Colors.grey,
buttonSize: 40.0,
iconSize: 20.0,
),
);
Audio Capture Modes
// No audio
audioCaptureMode: AudioCaptureMode.none
// System audio only (what you hear on computer)
audioCaptureMode: AudioCaptureMode.system
// Microphone only
audioCaptureMode: AudioCaptureMode.microphone
// Both system and microphone
audioCaptureMode: AudioCaptureMode.both
Custom Position
indicatorConfig: RecordingIndicatorConfig(
// Use predefined positions
position: Alignment.bottomRight,
// Or use custom offset
customOffset: Offset(20, 20),
)
With Logging
await ScreenRecorder.startRecording(
context,
enableLogging: true, // Logs to DevTools (debug mode only)
onLog: (message, {level, error, stackTrace}) {
// Custom logging callback
if (level == RecordingLogLevel.error) {
print('β ERROR: $message');
} else {
print('πΉ $message');
}
},
);
Disable Logging
await ScreenRecorder.startRecording(
context,
enableLogging: false, // Silent mode
);
Configuration Options
RecordingConfig
| Property | Type | Default | Description |
|---|---|---|---|
idealWidth |
int |
1920 |
Target video width |
idealHeight |
int |
1080 |
Target video height |
idealFrameRate |
int |
30 |
Target frame rate |
videoBitsPerSecond |
int |
5000000 |
Video bitrate (5 Mbps) |
captureAudio |
bool |
true |
Enable audio capture |
showCursor |
bool |
true |
Show cursor in recording |
audioCaptureMode |
AudioCaptureMode |
system |
Audio source |
RecordingIndicatorConfig
| Property | Type | Default | Description |
|---|---|---|---|
recordingColor |
Color |
Colors.red |
Recording indicator color |
pausedColor |
Color |
Colors.orange |
Paused state color |
backgroundColor |
Color |
Colors.black87 |
Indicator background |
borderWidth |
double |
2.0 |
Border thickness |
borderRadius |
double |
12.0 |
Corner radius |
position |
Alignment |
topRight |
Indicator position |
customOffset |
Offset? |
null |
Custom position |
timeTextStyle |
TextStyle? |
null |
Time display style |
statusTextStyle |
TextStyle? |
null |
Status text style |
ControlButtonConfig
| Property | Type | Default | Description |
|---|---|---|---|
pauseIcon |
IconData? |
Icons.pause |
Pause button icon |
playIcon |
IconData? |
Icons.play_arrow |
Resume button icon |
stopIcon |
IconData? |
Icons.stop |
Stop button icon |
cancelIcon |
IconData? |
Icons.close |
Cancel button icon |
pauseColor |
Color |
Colors.orange |
Pause button color |
stopColor |
Color |
Colors.red |
Stop button color |
cancelColor |
Color |
Colors.grey |
Cancel button color |
buttonSize |
double |
32.0 |
Button size |
iconSize |
double |
18.0 |
Icon size |
spacing |
double |
8.0 |
Button spacing |
RecordingResult
The RecordingResult object contains:
class RecordingResult {
final Uint8List fileBytes; // Video data
final String fileName; // Generated filename
final String mimeType; // 'video/webm'
final String blobUrl; // Blob URL for preview
final int durationSeconds; // Recording duration
Map<String, dynamic> toMap(); // Convert to map
}
Logging
The package provides flexible logging options:
// View logs in Flutter DevTools (debug mode only)
enableLogging: true // Default
// Custom logging callback
onLog: (message, {level, error, stackTrace}) {
switch (level) {
case RecordingLogLevel.debug:
debugPrint('π $message');
break;
case RecordingLogLevel.info:
print('βΉοΈ $message');
break;
case RecordingLogLevel.warning:
print('β οΈ $message');
break;
case RecordingLogLevel.error:
print('β $message: $error');
break;
}
}
// Completely disable logging
enableLogging: false
Log Levels
RecordingLogLevel.debug- Detailed info (tracks, chunks)RecordingLogLevel.info- General info (started, stopped)RecordingLogLevel.warning- Warnings (mic unavailable)RecordingLogLevel.error- Errors with stack traces
Permissions
The browser will prompt users to:
- Select screen/window/tab - Choose what to record
- Grant audio permissions - If audio capture is enabled
Users must grant these permissions for recording to work.
Common Use Cases
Upload to Server
onRecordingComplete: (result) async {
final response = await http.post(
Uri.parse('https://api.example.com/upload'),
headers: {'Content-Type': 'video/webm'},
body: result.fileBytes,
);
print('Uploaded: ${response.statusCode}');
}
Save to Local Storage
onRecordingComplete: (result) {
// Trigger browser download
final anchor = html.AnchorElement(href: result.blobUrl)
..setAttribute('download', result.fileName)
..click();
}
Convert to Base64
onRecordingComplete: (result) {
final base64Video = base64Encode(result.fileBytes);
// Send to API or save to database
}
Example App
Check the example folder for a complete working demo with all features.
To run the example:
cd example
flutter run -d chrome
Troubleshooting
Recording doesn't start
- Ensure you're running on web platform
- Check browser compatibility
- User must grant screen capture permission
No audio in recording
- Some browsers don't support system audio capture
- Check
audioCaptureModesetting - User must grant microphone permission
Poor video quality
- Increase
videoBitsPerSecondinRecordingConfig - Increase
idealWidthandidealHeight - Increase
idealFrameRatefor smoother video
Large file sizes
- Decrease
videoBitsPerSecond - Lower
idealWidthandidealHeight - Reduce
idealFrameRate
Limitations
- Web platform only (uses browser MediaRecorder API)
- Safari not supported (no Screen Capture API)
- System audio may not work in all browsers
- WebM format only
- Maximum recording length depends on browser memory
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- π§ Report issues on GitHub
- π¬ Questions? Open a discussion
- β Star the repo if you find it useful!
Changelog
See CHANGELOG.md for version history.