Commit 8fb5f8606a35fb4b298ad45468c9e3c205f52122
1 parent
d100908a
feat:先声录音状态优化
Showing
4 changed files
with
32 additions
and
45 deletions
lib/pages/practice/bloc/topic_picture_bloc.dart
@@ -26,20 +26,6 @@ part 'topic_picture_event.dart'; | @@ -26,20 +26,6 @@ part 'topic_picture_event.dart'; | ||
26 | 26 | ||
27 | part 'topic_picture_state.dart'; | 27 | part 'topic_picture_state.dart'; |
28 | 28 | ||
29 | -enum VoicePlayState { | ||
30 | - ///未知 | ||
31 | - unKnow, | ||
32 | - | ||
33 | - ///播放中 | ||
34 | - playing, | ||
35 | - | ||
36 | - ///播放完成 | ||
37 | - completed, | ||
38 | - | ||
39 | - ///播放终止 | ||
40 | - stop | ||
41 | -} | ||
42 | - | ||
43 | class TopicPictureBloc | 29 | class TopicPictureBloc |
44 | extends BaseSectionBloc<TopicPictureEvent, TopicPictureState> with WidgetsBindingObserver { | 30 | extends BaseSectionBloc<TopicPictureEvent, TopicPictureState> with WidgetsBindingObserver { |
45 | final PageController pageController; | 31 | final PageController pageController; |
@@ -57,9 +43,6 @@ class TopicPictureBloc | @@ -57,9 +43,6 @@ class TopicPictureBloc | ||
57 | ///正在评测 | 43 | ///正在评测 |
58 | bool _isRecording = false; | 44 | bool _isRecording = false; |
59 | 45 | ||
60 | - ///正在播放音频 | ||
61 | - VoicePlayState _voicePlayState = VoicePlayState.unKnow; | ||
62 | - | ||
63 | int get currentPage => _currentPage + 1; | 46 | int get currentPage => _currentPage + 1; |
64 | 47 | ||
65 | /// 选择题选中项 | 48 | /// 选择题选中项 |
@@ -67,8 +50,6 @@ class TopicPictureBloc | @@ -67,8 +50,6 @@ class TopicPictureBloc | ||
67 | 50 | ||
68 | bool get isRecording => _isRecording; | 51 | bool get isRecording => _isRecording; |
69 | 52 | ||
70 | - VoicePlayState get voicePlayState => _voicePlayState; | ||
71 | - | ||
72 | late MethodChannel methodChannel; | 53 | late MethodChannel methodChannel; |
73 | 54 | ||
74 | late AudioPlayer audioPlayer; | 55 | late AudioPlayer audioPlayer; |
@@ -77,6 +58,8 @@ class TopicPictureBloc | @@ -77,6 +58,8 @@ class TopicPictureBloc | ||
77 | 58 | ||
78 | final Color? moduleColor; | 59 | final Color? moduleColor; |
79 | 60 | ||
61 | + final String TAG = 'TopicPictureBloc'; | ||
62 | + | ||
80 | TopicPictureBloc( | 63 | TopicPictureBloc( |
81 | this.context, this.pageController, this.courseLessonId, this.moduleColor) | 64 | this.context, this.pageController, this.courseLessonId, this.moduleColor) |
82 | : super(TopicPictureInitial()) { | 65 | : super(TopicPictureInitial()) { |
@@ -90,24 +73,12 @@ class TopicPictureBloc | @@ -90,24 +73,12 @@ class TopicPictureBloc | ||
90 | on<XSVoiceStartEvent>(_voiceXsStart); | 73 | on<XSVoiceStartEvent>(_voiceXsStart); |
91 | on<XSVoiceStopEvent>(_voiceXsStop); | 74 | on<XSVoiceStopEvent>(_voiceXsStop); |
92 | on<VoicePlayEvent>(_questionVoicePlay); | 75 | on<VoicePlayEvent>(_questionVoicePlay); |
76 | + on<OnXSVoiceStateChangeEvent>(_onVoiceXsStateChange); | ||
93 | on<InitBlocEvent>((event, emit) { | 77 | on<InitBlocEvent>((event, emit) { |
94 | //音频播放器 | 78 | //音频播放器 |
95 | audioPlayer = AudioPlayer(); | 79 | audioPlayer = AudioPlayer(); |
96 | audioPlayer.onPlayerStateChanged.listen((event) async { | 80 | audioPlayer.onPlayerStateChanged.listen((event) async { |
97 | - debugPrint('播放状态变化 _voicePlayState=$_voicePlayState event=$event'); | ||
98 | - if (event == PlayerState.completed) { | ||
99 | - debugPrint('播放完成'); | ||
100 | - _voicePlayState = VoicePlayState.completed; | ||
101 | - } | ||
102 | - if (event == PlayerState.stopped) { | ||
103 | - debugPrint('播放结束'); | ||
104 | - _voicePlayState = VoicePlayState.stop; | ||
105 | - } | ||
106 | - | ||
107 | - if (event == PlayerState.playing) { | ||
108 | - debugPrint('正在播放中'); | ||
109 | - _voicePlayState = VoicePlayState.playing; | ||
110 | - } | 81 | + Log.d('$TAG onPlayerStateChanged event=$event'); |
111 | if (isClosed) { | 82 | if (isClosed) { |
112 | return; | 83 | return; |
113 | } | 84 | } |
@@ -130,16 +101,20 @@ class TopicPictureBloc | @@ -130,16 +101,20 @@ class TopicPictureBloc | ||
130 | if (kDebugMode) { | 101 | if (kDebugMode) { |
131 | print('评测开始'); | 102 | print('评测开始'); |
132 | } | 103 | } |
104 | + _isRecording = true; | ||
105 | + add(OnXSVoiceStateChangeEvent()); | ||
133 | return; | 106 | return; |
134 | } | 107 | } |
135 | 108 | ||
136 | - if (call.method == 'voiceEnd') { | 109 | + if (call.method == 'voiceEnd' || call.method == 'voiceCancel') { |
137 | await audioPlayer.setAudioContext(AudioContext()); | 110 | await audioPlayer.setAudioContext(AudioContext()); |
138 | await audioPlayer.setBalance(0.0); | 111 | await audioPlayer.setBalance(0.0); |
139 | //评测结束 | 112 | //评测结束 |
140 | if (kDebugMode) { | 113 | if (kDebugMode) { |
141 | - print('评测结束'); | 114 | + print(call.method == 'voiceEnd' ? '评测结束' : '评测取消'); |
142 | } | 115 | } |
116 | + _isRecording = false; | ||
117 | + add(OnXSVoiceStateChangeEvent()); | ||
143 | return; | 118 | return; |
144 | } | 119 | } |
145 | 120 | ||
@@ -148,6 +123,8 @@ class TopicPictureBloc | @@ -148,6 +123,8 @@ class TopicPictureBloc | ||
148 | await audioPlayer.setAudioContext(AudioContext()); | 123 | await audioPlayer.setAudioContext(AudioContext()); |
149 | await audioPlayer.setBalance(0.0); | 124 | await audioPlayer.setBalance(0.0); |
150 | 125 | ||
126 | + _isRecording = false; | ||
127 | + add(OnXSVoiceStateChangeEvent()); | ||
151 | EasyLoading.showToast('评测失败'); | 128 | EasyLoading.showToast('评测失败'); |
152 | return; | 129 | return; |
153 | } | 130 | } |
@@ -157,10 +134,15 @@ class TopicPictureBloc | @@ -157,10 +134,15 @@ class TopicPictureBloc | ||
157 | }); | 134 | }); |
158 | } | 135 | } |
159 | 136 | ||
137 | + void _onVoiceXsStateChange(OnXSVoiceStateChangeEvent event, | ||
138 | + Emitter<TopicPictureState> emitter) async { | ||
139 | + emitter(XSVoiceTestState()); | ||
140 | + } | ||
141 | + | ||
160 | @override | 142 | @override |
161 | Future<void> didChangeAppLifecycleState(AppLifecycleState state) async { | 143 | Future<void> didChangeAppLifecycleState(AppLifecycleState state) async { |
162 | super.didChangeAppLifecycleState(state); | 144 | super.didChangeAppLifecycleState(state); |
163 | - Log.d('TopicPictureBloc didChangeAppLifecycleState state=$state'); | 145 | + Log.d('$TAG didChangeAppLifecycleState state=$state'); |
164 | if (state == AppLifecycleState.paused) { | 146 | if (state == AppLifecycleState.paused) { |
165 | ///切到后台暂停音频播放、录音等 | 147 | ///切到后台暂停音频播放、录音等 |
166 | if (audioPlayer.state == PlayerState.playing) { | 148 | if (audioPlayer.state == PlayerState.playing) { |
@@ -197,7 +179,7 @@ class TopicPictureBloc | @@ -197,7 +179,7 @@ class TopicPictureBloc | ||
197 | void _pageControllerChange(CurrentPageIndexChangeEvent event, | 179 | void _pageControllerChange(CurrentPageIndexChangeEvent event, |
198 | Emitter<TopicPictureState> emitter) async { | 180 | Emitter<TopicPictureState> emitter) async { |
199 | await pageResetIfNeed(); | 181 | await pageResetIfNeed(); |
200 | - debugPrint('翻页 $_currentPage->${event.pageIndex}'); | 182 | + Log.d('$TAG _pageControllerChange $_currentPage->${event.pageIndex}'); |
201 | if (_currentPage == _entity?.topics?.length) { | 183 | if (_currentPage == _entity?.topics?.length) { |
202 | return; | 184 | return; |
203 | } | 185 | } |
@@ -276,8 +258,6 @@ class TopicPictureBloc | @@ -276,8 +258,6 @@ class TopicPictureBloc | ||
276 | 'type': event.type, | 258 | 'type': event.type, |
277 | 'userId': event.userId.toString() | 259 | 'userId': event.userId.toString() |
278 | }); | 260 | }); |
279 | - _isRecording = true; | ||
280 | - emitter(XSVoiceTestState()); | ||
281 | } | 261 | } |
282 | } | 262 | } |
283 | 263 | ||
@@ -321,6 +301,10 @@ class TopicPictureBloc | @@ -321,6 +301,10 @@ class TopicPictureBloc | ||
321 | emitter(VoicePlayStateChange()); | 301 | emitter(VoicePlayStateChange()); |
322 | } | 302 | } |
323 | 303 | ||
304 | + bool isAudioPlaying() { | ||
305 | + return audioPlayer.state == PlayerState.playing; | ||
306 | + } | ||
307 | + | ||
324 | // 题目音频播放 | 308 | // 题目音频播放 |
325 | void _questionVoicePlay( | 309 | void _questionVoicePlay( |
326 | VoicePlayEvent event, Emitter<TopicPictureState> emitter) async { | 310 | VoicePlayEvent event, Emitter<TopicPictureState> emitter) async { |
@@ -335,7 +319,6 @@ class TopicPictureBloc | @@ -335,7 +319,6 @@ class TopicPictureBloc | ||
335 | Future<void> pageResetIfNeed() async { | 319 | Future<void> pageResetIfNeed() async { |
336 | _optionSelectItem = -1; | 320 | _optionSelectItem = -1; |
337 | _isRecording = false; | 321 | _isRecording = false; |
338 | - _voicePlayState = VoicePlayState.stop; | ||
339 | 322 | ||
340 | await closePlayerResource(); | 323 | await closePlayerResource(); |
341 | await _voiceXsCancel(); | 324 | await _voiceXsCancel(); |
@@ -347,7 +330,7 @@ class TopicPictureBloc | @@ -347,7 +330,7 @@ class TopicPictureBloc | ||
347 | } | 330 | } |
348 | 331 | ||
349 | Future<void> closePlayerResource() async { | 332 | Future<void> closePlayerResource() async { |
350 | - if (voicePlayState == VoicePlayState.playing) { | 333 | + if (isAudioPlaying()) { |
351 | await audioPlayer.stop(); | 334 | await audioPlayer.stop(); |
352 | } | 335 | } |
353 | } | 336 | } |
lib/pages/practice/bloc/topic_picture_event.dart
@@ -30,6 +30,9 @@ class XSVoiceResultEvent extends TopicPictureEvent { | @@ -30,6 +30,9 @@ class XSVoiceResultEvent extends TopicPictureEvent { | ||
30 | XSVoiceResultEvent(this.message); | 30 | XSVoiceResultEvent(this.message); |
31 | } | 31 | } |
32 | 32 | ||
33 | +///先声评测状态 | ||
34 | +class OnXSVoiceStateChangeEvent extends TopicPictureEvent {} | ||
35 | + | ||
33 | ///音频播放状态变化 | 36 | ///音频播放状态变化 |
34 | class VoicePlayStateChangeEvent extends TopicPictureEvent {} | 37 | class VoicePlayStateChangeEvent extends TopicPictureEvent {} |
35 | 38 |
lib/pages/practice/topic_picture_page.dart
@@ -311,7 +311,7 @@ class _TopicPicturePage extends StatelessWidget { | @@ -311,7 +311,7 @@ class _TopicPicturePage extends StatelessWidget { | ||
311 | children: [ | 311 | children: [ |
312 | SpeakerWidget( | 312 | SpeakerWidget( |
313 | isPlaying: isCurrentPage && | 313 | isPlaying: isCurrentPage && |
314 | - bloc.voicePlayState == VoicePlayState.playing, | 314 | + bloc.isAudioPlaying(), |
315 | // 控制动画播放 | 315 | // 控制动画播放 |
316 | width: 32.w, | 316 | width: 32.w, |
317 | height: 32.w, | 317 | height: 32.w, |
@@ -392,7 +392,7 @@ class _TopicPicturePage extends StatelessWidget { | @@ -392,7 +392,7 @@ class _TopicPicturePage extends StatelessWidget { | ||
392 | children: [ | 392 | children: [ |
393 | SpeakerWidget( | 393 | SpeakerWidget( |
394 | isPlaying: isCurrentPage && | 394 | isPlaying: isCurrentPage && |
395 | - bloc.voicePlayState == VoicePlayState.playing, | 395 | + bloc.isAudioPlaying(), |
396 | width: 32.w, | 396 | width: 32.w, |
397 | height: 32.w, | 397 | height: 32.w, |
398 | onTap: () { | 398 | onTap: () { |
@@ -505,7 +505,7 @@ class _TopicPicturePage extends StatelessWidget { | @@ -505,7 +505,7 @@ class _TopicPicturePage extends StatelessWidget { | ||
505 | children: [ | 505 | children: [ |
506 | SpeakerWidget( | 506 | SpeakerWidget( |
507 | isPlaying: isCurrentPage && | 507 | isPlaying: isCurrentPage && |
508 | - bloc.voicePlayState == VoicePlayState.playing, | 508 | + bloc.isAudioPlaying(), |
509 | // 控制动画播放 | 509 | // 控制动画播放 |
510 | isClickable: !bloc.isRecording, | 510 | isClickable: !bloc.isRecording, |
511 | // 控制是否可点击 | 511 | // 控制是否可点击 |
lib/pages/reading/bloc/reading_bloc.dart
@@ -170,10 +170,11 @@ class ReadingPageBloc | @@ -170,10 +170,11 @@ class ReadingPageBloc | ||
170 | 170 | ||
171 | if (call.method == 'voiceFail') { | 171 | if (call.method == 'voiceFail') { |
172 | //评测失败 | 172 | //评测失败 |
173 | - _isRecording = false; | ||
174 | await audioPlayer.setAudioContext(AudioContext()); | 173 | await audioPlayer.setAudioContext(AudioContext()); |
175 | await audioPlayer.setBalance(0.0); | 174 | await audioPlayer.setBalance(0.0); |
176 | 175 | ||
176 | + _isRecording = false; | ||
177 | + add(OnXSVoiceStateChangeEvent()); | ||
177 | EasyLoading.showToast('评测失败'); | 178 | EasyLoading.showToast('评测失败'); |
178 | return; | 179 | return; |
179 | } | 180 | } |