import 'dart:async'; import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:record/record.dart'; import 'package:path_provider/path_provider.dart'; class AudioRecorderButton extends StatefulWidget { final void Function(Uint8List bytes, String nombre) onRecorded; const AudioRecorderButton({super.key, required this.onRecorded}); @override State createState() => _AudioRecorderButtonState(); } class _AudioRecorderButtonState extends State { final _recorder = AudioRecorder(); bool _isRecording = false; int _seconds = 0; Timer? _timer; @override void dispose() { _timer?.cancel(); _recorder.dispose(); super.dispose(); } Future _toggleRecording() async { if (_isRecording) { await _stopRecording(); } else { await _startRecording(); } } Future _startRecording() async { final hasPermission = await _recorder.hasPermission(); if (!hasPermission) return; final dir = await getTemporaryDirectory(); final path = '${dir.path}/audio_${DateTime.now().millisecondsSinceEpoch}.m4a'; await _recorder.start( const RecordConfig(encoder: AudioEncoder.aacLc), path: path, ); setState(() { _isRecording = true; _seconds = 0; }); _timer = Timer.periodic(const Duration(seconds: 1), (t) { setState(() => _seconds++); }); } Future _stopRecording() async { _timer?.cancel(); final path = await _recorder.stop(); setState(() { _isRecording = false; _seconds = 0; }); if (path != null) { final file = File(path); final bytes = await file.readAsBytes(); final nombre = 'audio_${DateTime.now().millisecondsSinceEpoch}.m4a'; widget.onRecorded(bytes, nombre); await file.delete(); } } String _formatDuration(int seconds) { final mins = seconds ~/ 60; final secs = seconds % 60; return '${mins.toString().padLeft(2, '0')}:${secs.toString().padLeft(2, '0')}'; } @override Widget build(BuildContext context) { return FilledButton.tonal( onPressed: _toggleRecording, style: FilledButton.styleFrom( backgroundColor: _isRecording ? Theme.of(context).colorScheme.errorContainer : null, ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( _isRecording ? Icons.stop : Icons.mic, size: 18, color: _isRecording ? Theme.of(context).colorScheme.error : null, ), const SizedBox(width: 4), Text(_isRecording ? _formatDuration(_seconds) : 'Audio'), ], ), ); } }