start method
Start recording the widget
Implementation
Future<void> start() async {
if (_isRecording) {
debugPrint('[WidgetRecorder] ⚠️ Already recording');
return;
}
// Handle permission automatically if audio recording is enabled
if (recordAudio) {
final hasPermission = await _handlePermission();
if (!hasPermission) {
debugPrint('[WidgetRecorder] ❌ Permission denied');
_handleError('Microphone permission denied');
return;
}
}
_isRecording = true;
try {
debugPrint('[WidgetRecorder] 🎬 Starting recording...');
// Get temporary directory and create output path
final dir = await getTemporaryDirectory();
_outputPath =
'${dir.path}/widget_rec_${DateTime.now().millisecondsSinceEpoch}.mp4';
final renderObject = _boundaryKey.currentContext?.findRenderObject();
if (renderObject == null) {
throw Exception('Widget not found. Ensure WidgetRecorder is built.');
}
_size = (renderObject as RenderRepaintBoundary).size;
// Round dimensions down to the nearest multiple of 16 for perfect encoding
final int validWidth = (_size!.width.toInt() ~/ 16) * 16;
final int validHeight = (_size!.height.toInt() ~/ 16) * 16;
debugPrint('[WidgetRecorder] 📐 Recording: ${validWidth}x$validHeight @ $_fps fps (Audio: $recordAudio)');
await _channel.invokeMethod('startRecording', {
'width': validWidth,
'height': validHeight,
'fps': _fps,
'outputPath': _outputPath,
'recordAudio': recordAudio,
});
_timer = Timer.periodic(
Duration(milliseconds: 1000 ~/ _fps),
(_) => _captureFrame(),
);
debugPrint('[WidgetRecorder] ✅ Recording started');
} catch (e) {
debugPrint('[WidgetRecorder] ❌ Error starting: $e');
_handleError(e.toString());
}
}