119ba920
liangchengyou
feat:视频播放器
|
1
|
import 'package:common_utils/common_utils.dart';
|
119ba920
liangchengyou
feat:视频播放器
|
2
|
import 'package:flutter/material.dart';
|
cb38bc90
liangchengyou
feat:视频跟读逻辑处理
|
3
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
119ba920
liangchengyou
feat:视频播放器
|
4
|
import 'package:video_player/video_player.dart';
|
91fe517a
liangchengyou
feat:看视频功能开发
|
5
|
import 'package:wow_english/common/extension/string_extension.dart';
|
4b358e22
liangchengyou
feat:调整文件结构
|
6
7
|
import 'video_opera_widget.dart';
|
119ba920
liangchengyou
feat:视频播放器
|
8
9
|
class VideoWidget extends StatefulWidget {
|
842b7132
liangchengyou
feat:磨耳朵/练习页面调整
|
10
|
const VideoWidget({super.key, this.videoUrl = '',this.typeTitle});
|
119ba920
liangchengyou
feat:视频播放器
|
11
12
|
final String videoUrl;
|
842b7132
liangchengyou
feat:磨耳朵/练习页面调整
|
13
|
final String? typeTitle;
|
119ba920
liangchengyou
feat:视频播放器
|
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
@override
State<StatefulWidget> createState() {
return _VideoWidgetState();
}
}
class _VideoWidgetState extends State<VideoWidget> {
VideoPlayerController? _controller;
String _currentTime = '00:00';
String _totalTime = '00:00';
double _playDegree = 0.0;
bool _hiddenTipView = false;
TimerUtil? timerUtil;
String formatDuration(Duration duration) {
String hours = duration.inHours.toString().padLeft(2, '0');
String minutes = duration.inMinutes.remainder(60).toString().padLeft(2, '0');
String seconds = duration.inSeconds.remainder(60).toString().padLeft(2, '0');
return "$hours:$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;
});
}
}
});
}
//开始倒计时
void startTimer() {
if(timerUtil == null) {
timerUtil = TimerUtil(mInterval: 1000,mTotalTime: 1000*10);
timerUtil!.setOnTimerTickCallback((int tick) {
double currentTick = tick / 1000;
|
119ba920
liangchengyou
feat:视频播放器
|
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
if (currentTick.toInt() == 0) {//倒计时结束
setState(() {
_hiddenTipView = true;
});
timerUtil!.cancel();
timerUtil = null;
}
});
timerUtil!.startCountDown();
}
}
//取消倒计时
void cancelTimer() {
timerUtil!.cancel();
timerUtil = null;
}
|
91fe517a
liangchengyou
feat:看视频功能开发
|
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
void actionType(OperationType type) async {
if (type == OperationType.back) {
Navigator.pop(context);
} else if (type == OperationType.playState) {
if (_controller!.value.isPlaying) {
_controller!.pause();
} else {
_controller!.play();
}
setState(() {
});
}
}
|
119ba920
liangchengyou
feat:视频播放器
|
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
@override
void initState() {
super.initState();
_controller = VideoPlayerController.network(widget.videoUrl)
..initialize().then((_){
startTimer();
setState(() {
_currentTime = formatDuration(_controller!.value.position);
_totalTime = formatDuration(_controller!.value.duration);
_controller!.setLooping(true);
_controller!.setVolume(100);
_controller!.play();
});
_addListener();
});
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
_hiddenTipView = !_hiddenTipView;
if(!_hiddenTipView) {
startTimer();
} else {
if (timerUtil!.isActive()) {
cancelTimer();
}
}
});
},
onDoubleTap: () {
if(_controller!.value.isInitialized) {
if (_controller!.value.isPlaying) {
_controller!.pause();
} else {
_controller!.play();
}
|
91fe517a
liangchengyou
feat:看视频功能开发
|
129
130
131
|
setState(() {
});
|
119ba920
liangchengyou
feat:视频播放器
|
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
}
},
child: Center(
child: _controller!.value.isInitialized ? Stack(
alignment: Alignment.center,
children: [
SizedBox(
height: double.infinity,
width: double.infinity,
child: AspectRatio(
aspectRatio: _controller!.value.aspectRatio,
child: VideoPlayer(_controller!),
),
),
Offstage(
offstage: _hiddenTipView,
child: VideoOperaWidget(
|
842b7132
liangchengyou
feat:磨耳朵/练习页面调整
|
149
|
title: widget.typeTitle??'song',
|
119ba920
liangchengyou
feat:视频播放器
|
150
|
degree: _playDegree,
|
842b7132
liangchengyou
feat:磨耳朵/练习页面调整
|
151
152
|
totalTime: _totalTime,
currentTime: _currentTime,
|
91fe517a
liangchengyou
feat:看视频功能开发
|
153
154
155
156
|
isPlay: _controller!.value.isPlaying,
actionEvent: (OperationType type) {
actionType(type);
},
|
95e3448c
liangchengyou
feat:听音选图/选字
|
157
158
159
160
161
|
sliderChangeEvent: (double degree) {
int totalSecond = _controller!.value.duration.inMinutes.remainder(60)*60+_controller!.value.duration.inSeconds.remainder(60);
int positionSecond = (totalSecond * degree).toInt();
_controller!.seekTo(Duration(seconds: positionSecond));
},
|
91fe517a
liangchengyou
feat:看视频功能开发
|
162
163
164
165
166
167
168
169
170
171
|
),
),
Offstage(
offstage: _controller!.value.isPlaying,
child: IconButton(
onPressed: () {
_controller!.play();
},
icon: Image.asset(
'video_stop'.assetPng,
|
cb38bc90
liangchengyou
feat:视频跟读逻辑处理
|
172
173
|
width: 70.w,
height: 70.h,
|
91fe517a
liangchengyou
feat:看视频功能开发
|
174
|
),
|
119ba920
liangchengyou
feat:视频播放器
|
175
176
177
178
|
),
)
],
): Container(
|
95e3448c
liangchengyou
feat:听音选图/选字
|
179
|
color: Colors.white,
|
cb38bc90
liangchengyou
feat:视频跟读逻辑处理
|
180
181
182
183
184
185
186
|
child: Text(
'视频加载中....',
style: TextStyle(
fontSize: 20.sp,
color: Colors.black
),
),
|
119ba920
liangchengyou
feat:视频播放器
|
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
|
),
),
);
}
@override
void dispose() {
_controller?.dispose();
_controller?.removeListener(() {});
if (timerUtil != null) {
timerUtil!.cancel();
timerUtil = null;
}
super.dispose();
}
}
|