[{"data":1,"prerenderedAt":22},["ShallowReactive",2],{"articolo-registrazione-audio-e-video-in-flutter-guida-a-camera-e-record":3,"comments-article-registrazione-audio-e-video-in-flutter-guida-a-camera-e-record":21},{"id":4,"title":5,"slug":6,"excerpt":7,"body":8,"cover_image":9,"video_url":10,"status":11,"published_at":12,"meta_title":13,"meta_description":14,"category":15,"author":19},36,"Registrazione audio e video in Flutter: guida a camera e record","registrazione-audio-e-video-in-flutter-guida-a-camera-e-record","Impara a integrare fotocamera e registrazione audio nelle tue app Flutter usando i package camera e record, con anteprima live, scatto foto, cattura video e gestione dei permessi.","## Introduzione\n\nMolte app moderne richiedono l'accesso a fotocamera e microfono: dai social network alle app di note vocali, passando per lettori di QR code e videochiamate. In questa guida vedremo come integrare la cattura di **foto**, **video** e **audio** in Flutter usando due package solidi e mantenuti: [`camera`](https:\u002F\u002Fpub.dev\u002Fpackages\u002Fcamera) e [`record`](https:\u002F\u002Fpub.dev\u002Fpackages\u002Frecord).\n\n## Installazione\n\nAggiungiamo le dipendenze al `pubspec.yaml`:\n\n```yaml\ndependencies:\n  camera: ^0.11.0\n  record: ^5.1.2\n  path_provider: ^2.1.4\n  permission_handler: ^11.3.1\n```\n\n### Configurazione dei permessi\n\nSu **Android** (`android\u002Fapp\u002Fsrc\u002Fmain\u002FAndroidManifest.xml`):\n\n```xml\n\u003Cuses-permission android:name=\"android.permission.CAMERA\"\u002F>\n\u003Cuses-permission android:name=\"android.permission.RECORD_AUDIO\"\u002F>\n```\n\nAssicurati inoltre che `minSdkVersion` sia almeno 21.\n\nSu **iOS** (`ios\u002FRunner\u002FInfo.plist`):\n\n```xml\n\u003Ckey>NSCameraUsageDescription\u003C\u002Fkey>\n\u003Cstring>L'app usa la fotocamera per scattare foto e registrare video.\u003C\u002Fstring>\n\u003Ckey>NSMicrophoneUsageDescription\u003C\u002Fkey>\n\u003Cstring>L'app usa il microfono per registrare audio.\u003C\u002Fstring>\n```\n\n## Anteprima della fotocamera\n\nIl package `camera` fornisce un `CameraController` che gestisce l'inizializzazione del dispositivo e la sua anteprima. Il primo passo è recuperare la lista delle fotocamere disponibili.\n\n```dart\nimport 'package:camera\u002Fcamera.dart';\nimport 'package:flutter\u002Fmaterial.dart';\n\nlate List\u003CCameraDescription> cameras;\n\nFuture\u003Cvoid> main() async {\n  WidgetsFlutterBinding.ensureInitialized();\n  cameras = await availableCameras();\n  runApp(const MyApp());\n}\n```\n\nOra creiamo un widget con stato che inizializza il controller:\n\n```dart\nclass CameraScreen extends StatefulWidget {\n  const CameraScreen({super.key});\n\n  @override\n  State\u003CCameraScreen> createState() => _CameraScreenState();\n}\n\nclass _CameraScreenState extends State\u003CCameraScreen> {\n  late CameraController _controller;\n  late Future\u003Cvoid> _initFuture;\n\n  @override\n  void initState() {\n    super.initState();\n    _controller = CameraController(\n      cameras.first,\n      ResolutionPreset.high,\n      enableAudio: true,\n    );\n    _initFuture = _controller.initialize();\n  }\n\n  @override\n  void dispose() {\n    _controller.dispose();\n    super.dispose();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return FutureBuilder\u003Cvoid>(\n      future: _initFuture,\n      builder: (context, snapshot) {\n        if (snapshot.connectionState == ConnectionState.done) {\n          return CameraPreview(_controller);\n        }\n        return const Center(child: CircularProgressIndicator());\n      },\n    );\n  }\n}\n```\n\n> **Attenzione:** ricordati sempre di chiamare `dispose()` sul controller per liberare le risorse hardware, altrimenti la fotocamera resterà bloccata anche uscendo dalla schermata.\n\n## Scattare una foto\n\nUna volta inizializzato il controller, catturare un'immagine richiede una sola chiamata:\n\n```dart\nFuture\u003Cvoid> _scattaFoto() async {\n  try {\n    await _initFuture;\n    final XFile foto = await _controller.takePicture();\n    debugPrint('Foto salvata in: ${foto.path}');\n    \u002F\u002F foto.path punta a un file temporaneo\n  } catch (e) {\n    debugPrint('Errore durante lo scatto: $e');\n  }\n}\n```\n\nIl metodo restituisce un `XFile`, un'astrazione cross-platform che espone il percorso del file e i suoi byte tramite `readAsBytes()`.\n\n## Registrare un video\n\nLa registrazione video usa `startVideoRecording` e `stopVideoRecording`:\n\n```dart\nbool _inRegistrazione = false;\n\nFuture\u003Cvoid> _avviaVideo() async {\n  await _initFuture;\n  await _controller.startVideoRecording();\n  setState(() => _inRegistrazione = true);\n}\n\nFuture\u003Cvoid> _fermaVideo() async {\n  final XFile video = await _controller.stopVideoRecording();\n  setState(() => _inRegistrazione = false);\n  debugPrint('Video salvato in: ${video.path}');\n}\n```\n\n## Registrare solo audio con record\n\nQuando serve solo l'audio (es. note vocali) il package `camera` è eccessivo. Il package `record` è leggero e specializzato.\n\n```dart\nimport 'package:record\u002Frecord.dart';\nimport 'package:path_provider\u002Fpath_provider.dart';\nimport 'package:path\u002Fpath.dart' as p;\n\nfinal _recorder = AudioRecorder();\n\nFuture\u003Cvoid> _iniziaAudio() async {\n  if (await _recorder.hasPermission()) {\n    final dir = await getApplicationDocumentsDirectory();\n    final path = p.join(dir.path, 'nota_${DateTime.now().millisecondsSinceEpoch}.m4a');\n\n    await _recorder.start(\n      const RecordConfig(encoder: AudioEncoder.aacLc),\n      path: path,\n    );\n  }\n}\n\nFuture\u003CString?> _fermaAudio() async {\n  final path = await _recorder.stop();\n  debugPrint('Audio salvato in: $path');\n  return path;\n}\n```\n\n`AudioRecorder` gestisce internamente la richiesta del permesso microfono tramite `hasPermission()`, semplificando il flusso.\n\n### Monitorare l'ampiezza (visualizzazione onde)\n\nUn tocco professionale è mostrare la forma d'onda durante la registrazione. Il package espone uno stream dell'ampiezza:\n\n```dart\n_recorder\n    .onAmplitudeChanged(const Duration(milliseconds: 200))\n    .listen((amp) {\n  debugPrint('Ampiezza corrente: ${amp.current} dB');\n});\n```\n\n## Gestione robusta dei permessi\n\nSebbene entrambi i package gestiscano parzialmente i permessi, è buona pratica controllarli esplicitamente prima di aprire l'interfaccia, per offrire un messaggio chiaro all'utente:\n\n```dart\nimport 'package:permission_handler\u002Fpermission_handler.dart';\n\nFuture\u003Cbool> _verificaPermessi() async {\n  final statuses = await [\n    Permission.camera,\n    Permission.microphone,\n  ].request();\n\n  final tuttiConcessi = statuses.values.every((s) => s.isGranted);\n\n  if (statuses.values.any((s) => s.isPermanentlyDenied)) {\n    await openAppSettings();\n  }\n  return tuttiConcessi;\n}\n```\n\n## Best practice\n\n- **Rilascia sempre le risorse**: chiama `dispose()` sul `CameraController` e `dispose()` sull'`AudioRecorder` quando non servono più.\n- **Gestisci il ciclo di vita dell'app**: usa `WidgetsBindingObserver` per rilasciare la fotocamera quando l'app va in background (`AppLifecycleState.inactive`) e reinizializzarla al ritorno.\n- **Verifica lo stato prima di agire**: controlla `_controller.value.isInitialized` e `isRecordingVideo` per evitare eccezioni.\n- **Salva i file in modo persistente**: gli `XFile` restituiti sono temporanei; copiali in `getApplicationDocumentsDirectory()` se devono sopravvivere alla sessione.\n\n### Esempio di gestione del lifecycle\n\n```dart\nclass _CameraScreenState extends State\u003CCameraScreen>\n    with WidgetsBindingObserver {\n  @override\n  void didChangeAppLifecycleState(AppLifecycleState state) {\n    if (!_controller.value.isInitialized) return;\n    if (state == AppLifecycleState.inactive) {\n      _controller.dispose();\n    } else if (state == AppLifecycleState.resumed) {\n      _initFuture = _controller.initialize();\n    }\n  }\n}\n```\n\n## Conclusioni\n\nCon `camera` e `record` puoi coprire la stragrande maggioranza dei casi d'uso multimediali in Flutter, mantenendo il codice cross-platform. Ricorda che la vera sfida non è tanto scattare una foto, quanto **gestire correttamente permessi, ciclo di vita e risorse hardware**: seguendo le best practice viste qui eviterai i classici crash da fotocamera bloccata e offrirai un'esperienza fluida su Android e iOS.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Farticles\u002Fa03ab983-c534-42cc-9e46-8d4d649b108c.jpg",null,"published","2026-07-10T04:00:46+00:00","Camera e audio in Flutter: guida a camera e record","Guida pratica per registrare foto, video e audio in Flutter con i package camera e record: anteprima live, permessi e gestione del ciclo di vita.",{"id":16,"name":17,"slug":18},1,"Guide","guide",{"id":16,"name":20},"Flutter Bot",[],1785219602467]