import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:video_player/video_player.dart'; import 'package:wow_english/models/read_content_entity.dart'; import '../bloc/repeat_after_content_bloc.dart'; class RepeatVideoWidget extends StatefulWidget { const RepeatVideoWidget({super.key, this.videoUrl, required this.videoUrls}); final String? videoUrl; final List videoUrls; @override State createState() { return _RepeatVideoWidgetState(); } } class _RepeatVideoWidgetState extends State { VideoPlayerController? _controller; String _currentTime = '00:00'; String _totalTime = '00:00'; double _playDegree = 0.5; int _currentPlayIndex = 0; String formatDuration(Duration duration) { String minutes = duration.inMinutes.remainder(60).toString().padLeft(2, '0'); String seconds = duration.inSeconds.remainder(60).toString().padLeft(2, '0'); return "$minutes:$seconds"; } void _addListener() { _controller!.addListener(() { if(_controller!.value.isInitialized) { if (_controller!.value.isPlaying) { setState(() { double currentSecond = (_controller!.value.position.inMinutes.remainder(60)*60+_controller!.value.position.inSeconds.remainder(60)).toDouble(); int totalSecond = _controller!.value.duration.inMinutes.remainder(60)*60+_controller!.value.duration.inSeconds.remainder(60); _currentTime = formatDuration(_controller!.value.position); _playDegree = currentSecond/totalSecond; if(_playDegree < 0) { _playDegree = 0.0; } if(_playDegree > 1) { _playDegree = 1.0; } }); } } }); } @override void initState() { super.initState(); var videoUrl = ''; if(widget.videoUrls.isNotEmpty) { videoUrl = widget.videoUrls[_currentPlayIndex]?.videoUrl??''; } _initVideo(videoUrl); } @override Widget build(BuildContext context) { return Center( child: _controller!.value.isInitialized ? BlocListener( listener: (context, state){ if (state is VideoPlayChangeState) { if (context.read().videoPlaying) { _controller!.play(); } else { _controller!.pause(); } } if (state is ChangeVideoPlayIndexState) { if(state.isNext) { if (_currentPlayIndex != (widget.videoUrls.length-1)) { _currentPlayIndex++; _destroyVideo(); _initVideo(widget.videoUrls[_currentPlayIndex]!.videoUrl!); } } else { if (_currentPlayIndex > 0) { _currentPlayIndex--; _destroyVideo(); _initVideo(widget.videoUrls[_currentPlayIndex]!.videoUrl!); } } } }, child: SizedBox( child: Column( children: [ Expanded( child: Stack( children: [ Container( width: double.infinity, height: double.infinity, alignment: Alignment.center, decoration: BoxDecoration( color: Colors.black, border: Border.all( width: 1.0, color: const Color(0xFF140C10), ), borderRadius: BorderRadius.circular(5.r) ), child: AspectRatio( aspectRatio: _controller!.value.aspectRatio, child: VideoPlayer(_controller!), ), ), Positioned( left: 0, right: 0, bottom: 0, child: LinearProgressIndicator( color: const Color(0xFF78B72D), backgroundColor: const Color(0xFF7E756C), value: _playDegree, )) ], ), ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(_currentTime), Text(_totalTime), ], ) ], ), ) ) : Container( color: Colors.white, child: Text( '视频加载中....', style: TextStyle( fontSize: 20.sp, color: Colors.black ), ), ), ); } void _initVideo(String videoUrl) { _controller = VideoPlayerController.network(widget.videoUrl??'') ..initialize().then((_){ setState(() { _currentTime = formatDuration(_controller!.value.position); _totalTime = formatDuration(_controller!.value.duration); _controller!.setLooping(false); _controller!.setVolume(100); _controller!.play(); }); _addListener(); }); } void _destroyVideo() { _controller?.dispose(); _controller?.removeListener(() {}); } @override void dispose() { _destroyVideo(); super.dispose(); } }