@@ -19,16 +19,17 @@ class VideoPreviewer extends StatefulWidget {
19
19
}
20
20
21
21
class _VideoPreviewerState extends State <VideoPreviewer > {
22
- VideoPlayerController ? _videoController;
22
+ late VideoPlayerController _videoController;
23
+ late Future <void > _initializeVideoPlayerFuture;
23
24
bool _isPlaying = false ;
24
- File ? _tempVideoFile;
25
+ late File _tempVideoFile;
25
26
bool _showControls = false ;
26
27
27
28
@override
28
29
void initState () {
29
30
super .initState ();
30
31
registerWithAllPlatforms ();
31
- _initializeVideoPlayer ();
32
+ _initializeVideoPlayerFuture = _initializeVideoPlayer ();
32
33
}
33
34
34
35
void registerWithAllPlatforms () {
@@ -39,21 +40,20 @@ class _VideoPreviewerState extends State<VideoPreviewer> {
39
40
}
40
41
}
41
42
42
- void _initializeVideoPlayer () async {
43
+ Future < void > _initializeVideoPlayer () async {
43
44
final tempDir = await getTemporaryDirectory ();
44
45
_tempVideoFile = File (
45
46
'${tempDir .path }/temp_video_${DateTime .now ().millisecondsSinceEpoch }' );
46
47
try {
47
- await _tempVideoFile? .writeAsBytes (widget.videoBytes);
48
- _videoController = VideoPlayerController .file (_tempVideoFile! )
49
- ..initialize ().then ((_) {
50
- if (mounted) {
51
- setState (() {
52
- _videoController! .play ();
53
- _videoController! .setLooping (true );
54
- });
55
- }
48
+ await _tempVideoFile.writeAsBytes (widget.videoBytes);
49
+ _videoController = VideoPlayerController .file (_tempVideoFile);
50
+ await _videoController.initialize ();
51
+ if (mounted) {
52
+ setState (() {
53
+ _videoController.play ();
54
+ _videoController.setLooping (true );
56
55
});
56
+ }
57
57
} catch (e) {
58
58
debugPrint ("VideoPreviewer _initializeVideoPlayer(): $e " );
59
59
return ;
@@ -69,74 +69,78 @@ class _VideoPreviewerState extends State<VideoPreviewer> {
69
69
backgroundColor: iconColor.withValues (alpha: 0.3 ),
70
70
);
71
71
return Scaffold (
72
- body: MouseRegion (
73
- onEnter: (_) => setState (() => _showControls = true ),
74
- onExit: (_) => setState (() => _showControls = false ),
75
- child: Stack (
76
- children: [
77
- Center (
78
- child: _videoController? .value.isInitialized == true
79
- ? AspectRatio (
80
- aspectRatio: _videoController! .value.aspectRatio,
81
- child: VideoPlayer (_videoController! ),
82
- )
83
- : const CircularProgressIndicator (),
84
- ),
85
- Positioned (
86
- left: 0 ,
87
- right: 0 ,
88
- bottom: 0 ,
89
- child: _videoController? .value.isInitialized == true
90
- ? SizedBox (
91
- height: 50.0 ,
92
- child: VideoProgressIndicator (
93
- _videoController! ,
94
- allowScrubbing: true ,
95
- padding: const EdgeInsets .all (20 ),
96
- colors: progressBarColors,
72
+ body: FutureBuilder (
73
+ future: _initializeVideoPlayerFuture,
74
+ builder: (context, snapshot) {
75
+ if (snapshot.connectionState == ConnectionState .done) {
76
+ if (_videoController.value.isInitialized) {
77
+ return MouseRegion (
78
+ onEnter: (_) => setState (() => _showControls = true ),
79
+ onExit: (_) => setState (() => _showControls = false ),
80
+ child: Stack (
81
+ children: [
82
+ Center (
83
+ child: AspectRatio (
84
+ aspectRatio: _videoController.value.aspectRatio,
85
+ child: VideoPlayer (_videoController),
86
+ ),
87
+ ),
88
+ Positioned (
89
+ left: 0 ,
90
+ right: 0 ,
91
+ bottom: 0 ,
92
+ child: SizedBox (
93
+ height: 50.0 ,
94
+ child: VideoProgressIndicator (
95
+ _videoController,
96
+ allowScrubbing: true ,
97
+ padding: const EdgeInsets .all (20 ),
98
+ colors: progressBarColors,
99
+ ),
97
100
),
98
- )
99
- : Container (height: 0 ),
100
- ),
101
- if (_showControls)
102
- Center (
103
- child: GestureDetector (
104
- onTap: () {
105
- if (_videoController! .value.isPlaying) {
106
- _videoController! .pause ();
107
- } else {
108
- _videoController! .play ();
109
- }
110
- setState (() {
111
- _isPlaying = ! _isPlaying;
112
- });
113
- },
114
- child: Container (
115
- color: Colors .transparent,
116
- child: Icon (
117
- _isPlaying ? Icons .play_arrow : Icons .pause,
118
- size: 64 ,
119
- color: iconColor,
120
101
),
121
- ),
102
+ if (_showControls)
103
+ Center (
104
+ child: GestureDetector (
105
+ onTap: () {
106
+ if (_videoController.value.isPlaying) {
107
+ _videoController.pause ();
108
+ } else {
109
+ _videoController.play ();
110
+ }
111
+ setState (() {
112
+ _isPlaying = ! _isPlaying;
113
+ });
114
+ },
115
+ child: Container (
116
+ color: Colors .transparent,
117
+ child: Icon (
118
+ _isPlaying ? Icons .play_arrow : Icons .pause,
119
+ size: 64 ,
120
+ color: iconColor,
121
+ ),
122
+ ),
123
+ ),
124
+ ),
125
+ ],
122
126
),
123
- ),
124
- ],
125
- ),
127
+ );
128
+ }
129
+ }
130
+ return const Center (child: CircularProgressIndicator ());
131
+ },
126
132
),
127
133
);
128
134
}
129
135
130
136
@override
131
137
void dispose () {
132
- _videoController? .pause ();
133
- _videoController? .dispose ();
138
+ _videoController.pause ();
139
+ _videoController.dispose ();
134
140
if (! kIsRunningTests) {
135
141
Future .delayed (const Duration (seconds: 1 ), () async {
136
142
try {
137
- if (_tempVideoFile != null ) {
138
- await _tempVideoFile! .delete ();
139
- }
143
+ await _tempVideoFile.delete ();
140
144
} catch (e) {
141
145
debugPrint ("VideoPreviewer dispose(): $e " );
142
146
return ;
0 commit comments