import 'package:flutter/material.dart'; import 'package:video_player/video_player.dart'; import 'package:chewie/chewie.dart'; import '../models/xtream_models.dart'; class PlayerScreen extends StatefulWidget { final XtreamStream stream; final bool isLive; const PlayerScreen({super.key, required this.stream, this.isLive = true}); @override State createState() => _PlayerScreenState(); } class _PlayerScreenState extends State { VideoPlayerController? _videoController; ChewieController? _chewieController; bool _isLoading = true; String? _error; @override void initState() { super.initState(); _initPlayer(); } Future _initPlayer() async { try { _chewieController?.dispose(); _chewieController = null; await _videoController?.dispose(); _videoController = null; final url = widget.stream.url; if (url == null || url.isEmpty) { throw Exception('No stream URL available'); } final videoController = VideoPlayerController.networkUrl( Uri.parse(url), videoPlayerOptions: VideoPlayerOptions( allowBackgroundPlayback: false, mixWithOthers: false, ), ); await videoController.initialize(); _videoController = videoController; _chewieController = ChewieController( videoPlayerController: videoController, autoPlay: true, looping: widget.isLive, aspectRatio: videoController.value.aspectRatio, allowFullScreen: true, allowMuting: true, showControls: true, placeholder: Container( color: Colors.black, child: const Center( child: CircularProgressIndicator(color: Colors.red), ), ), errorBuilder: (context, errorMessage) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.error, color: Colors.red, size: 48), const SizedBox(height: 16), Text( errorMessage, style: const TextStyle(color: Colors.white), textAlign: TextAlign.center, ), ], ), ); }, ); setState(() { _isLoading = false; }); } catch (e) { setState(() { _error = e.toString(); _isLoading = false; }); } } @override void dispose() { _videoController?.dispose(); _chewieController?.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, appBar: AppBar( backgroundColor: Colors.transparent, elevation: 0, title: Text( widget.stream.name, style: const TextStyle(color: Colors.white), ), iconTheme: const IconThemeData(color: Colors.white), ), body: Center( child: _isLoading ? const CircularProgressIndicator(color: Colors.red) : _error != null ? _buildError() : _chewieController != null ? Chewie(controller: _chewieController!) : const Text( 'No video available', style: TextStyle(color: Colors.white), ), ), ); } Widget _buildError() { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.error_outline, color: Colors.red, size: 64), const SizedBox(height: 16), Padding( padding: const EdgeInsets.all(16), child: Text( _error ?? 'Unknown error', style: const TextStyle(color: Colors.white), textAlign: TextAlign.center, ), ), const SizedBox(height: 24), ElevatedButton.icon( onPressed: () { setState(() { _isLoading = true; _error = null; }); _initPlayer(); }, icon: const Icon(Icons.refresh), label: const Text('Retry'), style: ElevatedButton.styleFrom( backgroundColor: Colors.red, foregroundColor: Colors.white, ), ), ], ); } }