[{"data":1,"prerenderedAt":22},["ShallowReactive",2],{"articolo-riproduzione-video-in-flutter-con-video-player-e-chewie":3,"comments-article-riproduzione-video-in-flutter-con-video-player-e-chewie":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},38,"Riproduzione video in Flutter con video_player e Chewie","riproduzione-video-in-flutter-con-video-player-e-chewie","Guida pratica per integrare video locali e in streaming nelle tue app Flutter usando il pacchetto video_player e arricchendo l'esperienza con i controlli di Chewie.","## Perché la riproduzione video è importante\n\nSempre più applicazioni integrano contenuti video: tutorial, corsi online, feed social, streaming di eventi. In Flutter la gestione dei video passa dal pacchetto ufficiale `video_player`, mantenuto dal team di Google, che sfrutta le API native (ExoPlayer su Android e AVPlayer su iOS) e HTML5 sul Web.\n\nIn questa guida vedremo come riprodurre video locali e in streaming, come gestire il ciclo di vita del controller e come aggiungere una UI di controlli professionale con il pacchetto `chewie`.\n\n## Installazione delle dipendenze\n\nAggiungi i pacchetti al tuo `pubspec.yaml`:\n\n```yaml\ndependencies:\n  video_player: ^2.9.1\n  chewie: ^1.8.5\n```\n\n### Configurazione delle piattaforme\n\nPer riprodurre video da internet su **Android**, assicurati di avere il permesso di rete in `android\u002Fapp\u002Fsrc\u002Fmain\u002FAndroidManifest.xml`:\n\n```xml\n\u003Cuses-permission android:name=\"android.permission.INTERNET\"\u002F>\n```\n\nSu **iOS**, se il video usa HTTP (non HTTPS), devi abilitare le eccezioni ATS nel file `ios\u002FRunner\u002FInfo.plist`:\n\n```xml\n\u003Ckey>NSAppTransportSecurity\u003C\u002Fkey>\n\u003Cdict>\n  \u003Ckey>NSAllowsArbitraryLoads\u003C\u002Fkey>\n  \u003Ctrue\u002F>\n\u003C\u002Fdict>\n```\n\n## Riproduzione base con video_player\n\nIl cuore del pacchetto è il `VideoPlayerController`. Va inizializzato in modo asincrono e va sempre rilasciato con `dispose()` per evitare memory leak.\n\n```dart\nimport 'package:flutter\u002Fmaterial.dart';\nimport 'package:video_player\u002Fvideo_player.dart';\n\nclass VideoBaseScreen extends StatefulWidget {\n  const VideoBaseScreen({super.key});\n\n  @override\n  State\u003CVideoBaseScreen> createState() => _VideoBaseScreenState();\n}\n\nclass _VideoBaseScreenState extends State\u003CVideoBaseScreen> {\n  late final VideoPlayerController _controller;\n\n  @override\n  void initState() {\n    super.initState();\n    _controller = VideoPlayerController.networkUrl(\n      Uri.parse(\n        'https:\u002F\u002Fflutter.github.io\u002Fassets-for-api-docs\u002Fassets\u002Fvideos\u002Fbee.mp4',\n      ),\n    )..initialize().then((_) {\n        setState(() {}); \u002F\u002F ridisegna quando il video è pronto\n      });\n  }\n\n  @override\n  void dispose() {\n    _controller.dispose();\n    super.dispose();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      body: Center(\n        child: _controller.value.isInitialized\n            ? AspectRatio(\n                aspectRatio: _controller.value.aspectRatio,\n                child: VideoPlayer(_controller),\n              )\n            : const CircularProgressIndicator(),\n      ),\n      floatingActionButton: FloatingActionButton(\n        onPressed: () {\n          setState(() {\n            _controller.value.isPlaying\n                ? _controller.pause()\n                : _controller.play();\n          });\n        },\n        child: Icon(\n          _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,\n        ),\n      ),\n    );\n  }\n}\n```\n\n### Costruttori disponibili\n\nIl controller offre diverse sorgenti:\n\n- `VideoPlayerController.networkUrl(Uri)` — video in streaming da URL.\n- `VideoPlayerController.asset('assets\u002Fvideo.mp4')` — video incluso nell'app.\n- `VideoPlayerController.file(File)` — video dal file system del dispositivo.\n\nRicorda di dichiarare gli asset video nel `pubspec.yaml`:\n\n```yaml\nflutter:\n  assets:\n    - assets\u002Fvideo.mp4\n```\n\n## Aggiungere la barra di avanzamento\n\nIl pacchetto include il widget `VideoProgressIndicator`, che mostra lo stato di buffering e permette lo scrubbing:\n\n```dart\nVideoProgressIndicator(\n  _controller,\n  allowScrubbing: true,\n  colors: const VideoProgressColors(\n    playedColor: Colors.red,\n    bufferedColor: Colors.grey,\n  ),\n)\n```\n\n## Controlli professionali con Chewie\n\nCostruire da zero una UI completa (play\u002Fpausa, fullscreen, timeline, velocità di riproduzione) è laborioso. `chewie` fornisce tutto questo con pochissimo codice, avvolgendo il `VideoPlayerController`.\n\n```dart\nimport 'package:chewie\u002Fchewie.dart';\nimport 'package:flutter\u002Fmaterial.dart';\nimport 'package:video_player\u002Fvideo_player.dart';\n\nclass ChewieScreen extends StatefulWidget {\n  const ChewieScreen({super.key});\n\n  @override\n  State\u003CChewieScreen> createState() => _ChewieScreenState();\n}\n\nclass _ChewieScreenState extends State\u003CChewieScreen> {\n  late final VideoPlayerController _videoController;\n  ChewieController? _chewieController;\n\n  @override\n  void initState() {\n    super.initState();\n    _init();\n  }\n\n  Future\u003Cvoid> _init() async {\n    _videoController = VideoPlayerController.networkUrl(\n      Uri.parse(\n        'https:\u002F\u002Fflutter.github.io\u002Fassets-for-api-docs\u002Fassets\u002Fvideos\u002Fbee.mp4',\n      ),\n    );\n    await _videoController.initialize();\n\n    _chewieController = ChewieController(\n      videoPlayerController: _videoController,\n      autoPlay: false,\n      looping: false,\n      allowPlaybackSpeedChanging: true,\n      aspectRatio: _videoController.value.aspectRatio,\n      errorBuilder: (context, errorMessage) {\n        return Center(child: Text(errorMessage));\n      },\n    );\n    setState(() {});\n  }\n\n  @override\n  void dispose() {\n    _videoController.dispose();\n    _chewieController?.dispose();\n    super.dispose();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(title: const Text('Chewie Player')),\n      body: Center(\n        child: _chewieController != null &&\n                _chewieController!\n                    .videoPlayerController.value.isInitialized\n            ? Chewie(controller: _chewieController!)\n            : const CircularProgressIndicator(),\n      ),\n    );\n  }\n}\n```\n\n### Opzioni utili di ChewieController\n\n- `autoPlay` e `looping` per il comportamento di riproduzione.\n- `allowFullScreen` e `deviceOrientationsOnEnterFullScreen` per gestire il fullscreen.\n- `allowPlaybackSpeedChanging` con `playbackSpeeds` per le velocità.\n- `materialProgressColors` \u002F `cupertinoProgressColors` per personalizzare i colori.\n- `showControlsOnInitialize` per mostrare i controlli all'avvio.\n\n## Gestire il ciclo di vita\n\nUn errore comune è non mettere in pausa il video quando l'app va in background o quando l'utente naviga altrove. Con `WidgetsBindingObserver` puoi intercettare i cambi di stato:\n\n```dart\n@override\nvoid didChangeAppLifecycleState(AppLifecycleState state) {\n  if (state == AppLifecycleState.paused) {\n    _videoController.pause();\n  }\n}\n```\n\nNon dimenticare di registrare (`addObserver`) e rimuovere (`removeObserver`) l'observer rispettivamente in `initState` e `dispose`.\n\n## Consigli pratici\n\n- **Non ricreare il controller a ogni build**: inizializzalo una sola volta in `initState`.\n- **Chiama sempre `dispose()`** su entrambi i controller per liberare risorse native.\n- **Per lo streaming HLS\u002FDASH** usa direttamente l'URL del manifest (`.m3u8`); le piattaforme native lo supportano nativamente.\n- **Gestisci gli errori** tramite `errorBuilder` di Chewie o ascoltando `controller.value.hasError`.\n- **Su liste con molti video**, valuta il lazy loading e metti in pausa quelli fuori dallo schermo per non saturare la memoria.\n\n## Conclusioni\n\nCon `video_player` hai il controllo completo e a basso livello sulla riproduzione, mentre `chewie` ti offre un'interfaccia pronta all'uso e altamente personalizzabile. La combinazione dei due copre la maggior parte dei casi d'uso, dai semplici video introduttivi ai player di streaming completi. La chiave per un'esperienza fluida resta sempre la corretta gestione del ciclo di vita dei controller.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Farticles\u002F3dd0ce57-e336-407e-9053-75276e98c502.jpg",null,"published","2026-07-12T04:00:47+00:00","Video in Flutter: video_player e Chewie","Guida pratica alla riproduzione di video locali e in streaming in Flutter con video_player e Chewie, con esempi di codice e best practice.",{"id":16,"name":17,"slug":18},1,"Guide","guide",{"id":16,"name":20},"Flutter Bot",[],1785219601965]