a506beff
吴启风
feat:先声sdk方法找不到问题...
|
1
|
import 'package:audioplayers/audioplayers.dart';
|
1dc46cf7
吴启风
feat:绘本ui
|
2
|
import 'package:flutter/cupertino.dart';
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
3
4
|
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
|
1dc46cf7
吴启风
feat:绘本ui
|
5
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
6
|
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
fd737d6a
吴启风
feat:绘本作答结果以单词为单位...
|
7
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
6051f850
吴启风
feat:带隐私合规权限申请描述的...
|
8
|
import 'package:permission_handler/permission_handler.dart';
|
d0623cfd
吴启风
feat:绘本作答结果动效
|
9
|
import 'package:wow_english/common/extension/string_extension.dart';
|
2a427e12
吴启风
feat:绘本静态ui基本完成
|
10
|
import 'package:wow_english/pages/reading/widgets/ReadingModeType.dart';
|
820997e6
吴启风
feat:过渡页-绘本环节
|
11
12
13
|
import 'package:wow_english/pages/section/subsection/base_section/bloc.dart';
import 'package:wow_english/pages/section/subsection/base_section/event.dart';
import 'package:wow_english/pages/section/subsection/base_section/state.dart';
|
1dc46cf7
吴启风
feat:绘本ui
|
14
|
|
dae7f2fd
吴启风
feat:增加android端先声...
|
15
|
import '../../../common/core/user_util.dart';
|
e811f164
吴启风
feat:权限申请页面增加隐私合规...
|
16
|
import '../../../common/permission/permissionRequester.dart';
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
17
18
|
import '../../../common/request/dao/listen_dao.dart';
import '../../../common/request/exception.dart';
|
d0623cfd
吴启风
feat:绘本作答结果动效
|
19
20
|
import '../../../common/utils/click_with_music_controller.dart';
import '../../../common/utils/show_star_reward_dialog.dart';
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
21
|
import '../../../models/course_process_entity.dart';
|
fd737d6a
吴启风
feat:绘本作答结果以单词为单位...
|
22
|
import '../../../models/singsound_result_detail_entity.dart';
|
d0623cfd
吴启风
feat:绘本作答结果动效
|
23
|
import '../../../models/voice_result_type.dart';
|
820997e6
吴启风
feat:过渡页-绘本环节
|
24
|
import '../../../route/route.dart';
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
25
|
import '../../../utils/loading.dart';
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
26
|
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
27
|
import '../../../utils/log_util.dart';
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
28
|
|
1dc46cf7
吴启风
feat:绘本ui
|
29
|
part 'reading_event.dart';
|
d0623cfd
吴启风
feat:绘本作答结果动效
|
30
|
|
1dc46cf7
吴启风
feat:绘本ui
|
31
32
|
part 'reading_state.dart';
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
enum VoicePlayState {
///未知
unKnow,
///播放中
playing,
///播放完成
completed,
///播放终止
stop
}
|
820997e6
吴启风
feat:过渡页-绘本环节
|
47
48
|
class ReadingPageBloc
extends BaseSectionBloc<ReadingPageEvent, ReadingPageState> {
|
2a427e12
吴启风
feat:绘本静态ui基本完成
|
49
50
|
final PageController pageController;
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
51
52
|
final String courseLessonId;
|
2a427e12
吴启风
feat:绘本静态ui基本完成
|
53
54
55
56
|
///当前页索引
int _currentPage = 0;
///当前播放模式
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
57
|
ReadingModeType _currentMode = ReadingModeType.manual;
|
2a427e12
吴启风
feat:绘本静态ui基本完成
|
58
59
60
61
62
|
int get currentPage => _currentPage + 1;
ReadingModeType get currentMode => _currentMode;
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
63
64
65
66
67
68
69
70
71
|
CourseProcessEntity? _entity;
CourseProcessEntity? get entity => _entity;
///正在评测
bool _isRecording = false;
bool get isRecording => _isRecording;
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
///原始音频是否正在播放
bool _isOriginAudioPlaying = false;
bool get isOriginAudioPlaying => _isOriginAudioPlaying;
///录音音频是否正在播放
bool _isRecordAudioPlaying = false;
bool get isRecordAudioPlaying => _isRecordAudioPlaying;
///正在播放音频状态
VoicePlayState _voicePlayState = VoicePlayState.unKnow;
VoicePlayState get voicePlayState => _voicePlayState;
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
87
88
89
90
|
late MethodChannel methodChannel;
late AudioPlayer audioPlayer;
|
6051f850
吴启风
feat:带隐私合规权限申请描述的...
|
91
92
93
|
final BuildContext context;
ReadingPageBloc(this.context, this.pageController, this.courseLessonId)
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
94
|
: super(ReadingPageInitial()) {
|
2a427e12
吴启风
feat:绘本静态ui基本完成
|
95
|
on<CurrentPageIndexChangeEvent>(_pageControllerChange);
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
96
|
on<CurrentModeChangeEvent>(_playModeChange);
|
2a427e12
吴启风
feat:绘本静态ui基本完成
|
97
98
99
|
// pageController.addListener(() {
// _currentPage = pageController.page!.round();
// });
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
100
|
on<RequestDataEvent>(_requestData);
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
101
|
on<InitBlocEvent>((event, emit) {
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
102
103
|
//音频播放器
audioPlayer = AudioPlayer();
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
104
|
audioPlayer.onPlayerStateChanged.listen((event) async {
|
2ee6209a
吴启风
feat:绘本播放状态优化
|
105
|
Log.d("播放状态变化 event=$event");
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
106
|
if (event == PlayerState.completed) {
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
107
108
|
debugPrint('播放完成');
_voicePlayState = VoicePlayState.completed;
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
109
|
_onAudioPlayComplete();
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
110
111
112
113
|
}
if (event == PlayerState.stopped) {
debugPrint('播放结束');
_voicePlayState = VoicePlayState.stop;
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
114
|
}
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
115
|
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
116
117
118
119
|
if (event == PlayerState.playing) {
debugPrint('正在播放中');
_voicePlayState = VoicePlayState.playing;
}
|
2ee6209a
吴启风
feat:绘本播放状态优化
|
120
121
122
123
124
125
|
if (event == PlayerState.disposed) {
debugPrint('播放器释放');
_voicePlayState = VoicePlayState.unKnow;
}
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
126
127
|
if (isClosed) {
return;
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
128
|
}
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
129
|
add(VoicePlayStateChangeEvent());
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
130
131
|
});
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
132
133
134
|
methodChannel =
const MethodChannel('wow_english/sing_sound_method_channel');
methodChannel.invokeMethod('initVoiceSdk', {}); //初始化评测
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
135
|
methodChannel.setMethodCallHandler((call) async {
|
6051f850
吴启风
feat:带隐私合规权限申请描述的...
|
136
137
|
Log.d(
"setMethodCallHandler method=${call.method} arguments=${call.arguments}");
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
138
139
|
if (call.method == 'voiceResult') {
//评测结果
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
140
141
142
|
await audioPlayer.setAudioContext(AudioContext());
await audioPlayer.setBalance(0.0);
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
143
144
145
146
147
148
149
150
151
|
add(XSVoiceResultEvent(call.arguments));
return;
}
if (call.method == 'voiceStart') {
//评测开始
if (kDebugMode) {
print('评测开始');
}
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
152
153
|
_isRecording = true;
add(OnXSVoiceStateChangeEvent());
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
154
155
156
|
return;
}
|
46c68b45
吴启风
feat:翻页取消先声评测&增加先...
|
157
158
|
if (call.method == 'voiceEnd' || call.method == 'voiceCancel') {
//评测结束or评测取消
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
159
|
if (kDebugMode) {
|
46c68b45
吴启风
feat:翻页取消先声评测&增加先...
|
160
|
print(call.method == 'voiceEnd' ? '评测结束' : '评测取消');
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
161
|
}
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
162
163
164
|
await audioPlayer.setAudioContext(AudioContext());
await audioPlayer.setBalance(0.0);
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
165
|
_isRecording = false;
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
166
|
add(OnXSVoiceStateChangeEvent());
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
167
168
169
170
171
|
return;
}
if (call.method == 'voiceFail') {
//评测失败
|
46c68b45
吴启风
feat:翻页取消先声评测&增加先...
|
172
|
_isRecording = false;
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
173
174
175
|
await audioPlayer.setAudioContext(AudioContext());
await audioPlayer.setBalance(0.0);
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
176
177
|
EasyLoading.showToast('评测失败');
return;
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
178
179
180
|
}
});
});
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
181
|
on<VoicePlayStateChangeEvent>(_voicePlayStateChange);
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
182
|
on<PlayOriginalAudioEvent>(_playOriginalAudio);
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
183
184
185
|
on<XSVoiceInitEvent>(_initVoiceSdk);
on<XSVoiceStartEvent>(_voiceXsStart);
on<XSVoiceStopEvent>(_voiceXsStop);
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
186
|
on<XSVoiceResultEvent>(_voiceXsResult);
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
187
|
on<OnXSVoiceStateChangeEvent>(_onVoiceXsStateChange);
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
188
189
|
on<PlayRecordAudioEvent>(_playRecordAudio);
|
2a427e12
吴启风
feat:绘本静态ui基本完成
|
190
191
192
193
194
|
}
@override
Future<void> close() {
pageController.dispose();
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
195
196
|
audioPlayer.release();
audioPlayer.dispose();
|
081fbff7
吴启风
feat:性能优化-录音内存泄漏
|
197
|
_voiceXsCancel(force: true);
|
2a427e12
吴启风
feat:绘本静态ui基本完成
|
198
199
200
|
return super.close();
}
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
201
202
|
void _pageControllerChange(CurrentPageIndexChangeEvent event,
Emitter<ReadingPageState> emitter) async {
|
2a427e12
吴启风
feat:绘本静态ui基本完成
|
203
|
_currentPage = event.pageIndex;
|
46c68b45
吴启风
feat:翻页取消先声评测&增加先...
|
204
|
_voiceXsCancel();
|
2ee6209a
吴启风
feat:绘本播放状态优化
|
205
|
_playOriginalAudioInner(null, forcePlay: true);
|
2a427e12
吴启风
feat:绘本静态ui基本完成
|
206
207
208
|
emitter(CurrentPageIndexState());
}
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
209
|
void _playModeChange(
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
210
|
CurrentModeChangeEvent event, Emitter<ReadingPageState> emitter) async {
|
2a427e12
吴启风
feat:绘本静态ui基本完成
|
211
212
213
214
215
216
|
if (_currentMode == ReadingModeType.auto) {
_currentMode = ReadingModeType.manual;
} else {
_currentMode = ReadingModeType.auto;
}
emitter(CurrentModeState());
|
1dc46cf7
吴启风
feat:绘本ui
|
217
|
}
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
218
219
220
221
222
223
|
///请求数据
void _requestData(
RequestDataEvent event, Emitter<ReadingPageState> emitter) async {
try {
await loading(() async {
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
224
|
_entity = await ListenDao.process(courseLessonId);
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
225
|
Log.d("reading page entity: ${_entity!.toJson()}");
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
226
227
228
229
230
231
232
233
234
|
emitter(RequestDataState());
});
} catch (e) {
if (e is ApiException) {
EasyLoading.showToast(e.message ?? '请求失败,请检查网络连接');
}
}
}
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
235
236
237
238
239
240
|
/// 播放绘本原音
void _playOriginalAudio(
PlayOriginalAudioEvent event, Emitter<ReadingPageState> emitter) async {
_playOriginalAudioInner(event.url);
}
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
241
|
///播放原音音频
|
2ee6209a
吴启风
feat:绘本播放状态优化
|
242
243
|
/// - [force]: 是否强制播放(true:不管当前状态如何,都会播放目标原音音频,比如翻页场景)
/// (false:如果正在播放,暂停播放,比如点击播放按钮场景)
|
93efa69f
biao
删除评测代码
|
244
245
|
void _playOriginalAudioInner(String? audioUrl,
{bool forcePlay = false}) async {
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
246
|
if (_isRecordAudioPlaying) {
|
2ee6209a
吴启风
feat:绘本播放状态优化
|
247
|
await audioPlayer.stop();
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
248
249
|
_isRecordAudioPlaying = false;
}
|
6051f850
吴启风
feat:带隐私合规权限申请描述的...
|
250
251
|
Log.d(
"_playOriginalAudio _isRecordAudioPlaying=$_isRecordAudioPlaying _isOriginAudioPlaying=$_isOriginAudioPlaying url=$audioUrl");
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
252
|
if (_isOriginAudioPlaying) {
|
75e0dcd2
吴启风
feat:修复绘本音频ios听筒出声
|
253
|
await audioPlayer.stop();
|
2ee6209a
吴启风
feat:绘本播放状态优化
|
254
255
256
257
258
259
|
_isOriginAudioPlaying = false;
if (forcePlay) {
audioUrl ??= currentPageData()?.audioUrl ?? '';
await _playAudio(audioUrl);
_isOriginAudioPlaying = true;
}
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
260
|
} else {
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
261
|
audioUrl ??= currentPageData()?.audioUrl ?? '';
|
2ee6209a
吴启风
feat:绘本播放状态优化
|
262
263
|
await _playAudio(audioUrl);
_isOriginAudioPlaying = true;
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
264
|
}
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
265
266
|
}
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
267
268
269
270
271
272
|
/// 播放录音
void _playRecordAudio(
PlayRecordAudioEvent event, Emitter<ReadingPageState> emitter) async {
_playRecordAudioInner();
}
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
273
|
Future<void> _playRecordAudioInner() async {
|
2ee6209a
吴启风
feat:绘本播放状态优化
|
274
|
Log.d(
|
93efa69f
biao
删除评测代码
|
275
|
"_playRecordAudioInner _isOriginAudioPlaying=$_isOriginAudioPlaying _isRecordAudioPlaying=$_isRecordAudioPlaying url=${currentPageData()?.recordUrl}");
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
276
|
if (_isOriginAudioPlaying) {
|
2ee6209a
吴启风
feat:绘本播放状态优化
|
277
278
|
///如果正在播放原音,暂停
await audioPlayer.stop();
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
279
280
|
_isOriginAudioPlaying = false;
}
|
2ee6209a
吴启风
feat:绘本播放状态优化
|
281
|
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
282
|
if (_isRecordAudioPlaying) {
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
283
|
await audioPlayer.stop();
|
2ee6209a
吴启风
feat:绘本播放状态优化
|
284
|
_isRecordAudioPlaying = false;
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
285
|
} else {
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
286
|
final recordAudioUrl = currentPageData()?.recordUrl;
|
2ee6209a
吴启风
feat:绘本播放状态优化
|
287
288
|
await _playAudio(recordAudioUrl);
_isRecordAudioPlaying = true;
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
289
|
}
|
ad37b653
吴启风
feat:1、完成微信支付;2、商...
|
290
|
// emitter(VoicePlayStateChange());
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
291
292
|
}
|
2ee6209a
吴启风
feat:绘本播放状态优化
|
293
|
Future<void> _playAudio(String? audioUrl) async {
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
294
|
if (audioUrl!.isNotEmpty) {
|
1f5969b8
biao
修复 练习和绘本播放音频问题
|
295
296
|
await audioPlayer.play(UrlSource(audioUrl),
balance: 0.0, ctx: AudioContext());
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
297
298
299
300
|
}
}
int dataCount() {
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
301
302
303
304
305
306
307
|
return _entity?.readings?.length ?? 0;
}
CourseProcessReadings? currentPageData() {
return _entity?.readings?[_currentPage];
}
|
4d8b0da4
吴启风
feat:绘本跟读底部ui优化
|
308
309
310
311
312
|
///当前页绘本跟读内容
String readingContent() {
return currentPageData()?.word?.trim() ?? '';
}
|
fd737d6a
吴启风
feat:绘本作答结果以单词为单位...
|
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
|
/// 结合单词分数返回带颜色的TextSpan数组
List<TextSpan>? displayContent() {
// return _textController.text.isNotEmpty ? _textController.text : readingContent();
// 创建用于展示每个单词的 TextSpan 列表
if (currentPageData() == null) {
return null;
}
List<SingsoundResultDetailEntity> resultDetails;
if (currentPageData()?.resultDetails != null) {
resultDetails = currentPageData()!.resultDetails!;
} else {
List<String>? wordList = currentPageData()?.word?.split(RegExp(r'\s+'));
resultDetails = wordList!
.map(
(word) => SingsoundResultDetailEntity.withCharAndScore(word, 0))
.toList();
}
List<TextSpan> textSpans = resultDetails.asMap().entries.map((entry) {
int index = entry.key;
SingsoundResultDetailEntity detail = entry.value;
// Check if this is the last word in the list
bool isLastWord = index == resultDetails.length - 1;
return TextSpan(
text: '${detail.char}${isLastWord ? '' : ' '}',
style: TextStyle(
color: detail.score > 80
? const Color(0XFF35C137)
: const Color(0xFF333333),
fontSize: 20.sp,
),
);
}).toList();
return textSpans;
}
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
348
|
void nextPage() {
|
820997e6
吴启风
feat:过渡页-绘本环节
|
349
350
351
352
353
354
355
356
357
358
359
|
if (currentPage >= dataCount()) {
sectionComplete(() {
popPage(data: {
'currentStep': currentPage,
'courseLessonId': courseLessonId,
'isCompleted': true,
'nextSection': true
});
}, againSectionTap: () {
pageController.jumpToPage(0);
});
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
360
361
362
|
} else {
_currentPage += 1;
pageController.nextPage(
|
8df5fbf9
吴启风
feat:单元列表页由于ios嵌套...
|
363
|
duration: const Duration(milliseconds: 250),
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
364
365
366
367
368
|
curve: Curves.ease,
);
}
}
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
369
370
371
372
373
374
|
///初始化SDK
_initVoiceSdk(
XSVoiceInitEvent event, Emitter<ReadingPageState> emitter) async {
methodChannel.invokeMethod('initVoiceSdk', event.data);
}
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
375
|
///先声测试
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
376
377
|
void _voiceXsStart(
XSVoiceStartEvent event, Emitter<ReadingPageState> emitter) async {
|
2ee6209a
吴启风
feat:绘本播放状态优化
|
378
|
await _stopAudio();
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
379
|
startRecord(event.content);
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
380
381
|
}
|
2ee6209a
吴启风
feat:绘本播放状态优化
|
382
|
///开始录音
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
383
|
void startRecord(String content) async {
|
6051f850
吴启风
feat:带隐私合规权限申请描述的...
|
384
|
// 调用封装好的权限检查和请求方法
|
d0623cfd
吴启风
feat:绘本作答结果动效
|
385
386
|
bool result = await requestPermission(
context, Permission.microphone, "录音", "用于开启录音,识别您的开口作答并给出反馈");
|
6051f850
吴启风
feat:带隐私合规权限申请描述的...
|
387
|
if (result) {
|
820997e6
吴启风
feat:过渡页-绘本环节
|
388
389
390
391
392
|
methodChannel.invokeMethod('startVoice', {
'word': content,
'type': '0',
'userId': UserUtil.getUser()?.id.toString()
});
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
393
|
}
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
394
395
|
}
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
396
397
|
void _voiceXsResult(
XSVoiceResultEvent event, Emitter<ReadingPageState> emitter) async {
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
398
399
400
401
|
final Map args = event.message as Map;
final result = args['result'] as Map;
Log.d("_voiceXsResult result=$result");
final overall = result['overall'].toString();
|
fd737d6a
吴启风
feat:绘本作答结果以单词为单位...
|
402
403
404
405
406
407
408
409
410
|
List<dynamic> resultDetailsJsons = result['details'];
// 提取 score 和 char 字段
List<SingsoundResultDetailEntity> detailEntities = [];
for (var detail in resultDetailsJsons) {
int score = detail['score'] as int;
String char = detail['char'] as String;
detailEntities
.add(SingsoundResultDetailEntity.withCharAndScore(char, score));
}
|
d0623cfd
吴启风
feat:绘本作答结果动效
|
411
412
413
414
|
///todo 后面可以考虑要不要传自己的服务器
final recordFileUrl = args['audioUrl'].toString();
int score = int.parse(overall);
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
415
|
currentPageData()?.recordScore = overall;
|
d0623cfd
吴启风
feat:绘本作答结果动效
|
416
|
currentPageData()?.recordUrl = recordFileUrl.assetMp3;
|
fd737d6a
吴启风
feat:绘本作答结果以单词为单位...
|
417
418
|
currentPageData()?.resultDetails = detailEntities;
add(OnXSVoiceStateChangeEvent());
|
93efa69f
biao
删除评测代码
|
419
|
|
d0623cfd
吴启风
feat:绘本作答结果动效
|
420
421
422
|
final voiceResult = VoiceResultType.fromScore(score);
if (voiceResult.lottieFilePath != null) {
showCheerRewardDialog(context, lottieFile: voiceResult.lottieFilePath!);
|
820997e6
吴启风
feat:过渡页-绘本环节
|
423
|
}
|
d0623cfd
吴启风
feat:绘本作答结果动效
|
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
|
await ClickWithMusicController.instance
.playMusicAndPerformAction(context, voiceResult.audioType, () async {
///完成录音后紧接着播放录音
await _playRecordAudioInner();
if (isLastPage()) {
sectionComplete(() {
popPage(data: {
'currentStep': currentPage,
'courseLessonId': courseLessonId,
'isCompleted': true,
'nextSection': true
});
}, againSectionTap: () {
_resetLocalResult();
pageController.jumpToPage(0);
});
}
});
|
a506beff
吴启风
feat:先声sdk方法找不到问题...
|
442
|
}
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
443
444
445
446
447
448
449
|
///终止评测
void _voiceXsStop(
XSVoiceStopEvent event, Emitter<ReadingPageState> emitter) async {
methodChannel.invokeMethod('stopVoice');
}
|
6b0947ca
吴启风
feat:绘本增加initVoic...
|
450
|
///取消评测(用于处理退出页面后录音未停止等异常情况的保护操作)
|
081fbff7
吴启风
feat:性能优化-录音内存泄漏
|
451
|
void _voiceXsCancel({bool force = false}) {
|
46c68b45
吴启风
feat:翻页取消先声评测&增加先...
|
452
|
Log.d("取消评测 _voiceXsCancel _isRecording=$_isRecording");
|
081fbff7
吴启风
feat:性能优化-录音内存泄漏
|
453
|
if (_isRecording || force) {
|
46c68b45
吴启风
feat:翻页取消先声评测&增加先...
|
454
455
|
methodChannel.invokeMethod('cancelVoice');
}
|
6b0947ca
吴启风
feat:绘本增加initVoic...
|
456
457
|
}
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
458
459
460
461
462
|
void _voicePlayStateChange(VoicePlayStateChangeEvent event,
Emitter<ReadingPageState> emitter) async {
emitter(VoicePlayStateChange());
}
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
463
464
465
466
467
|
void _onAudioPlayComplete() {
if (_isRecordAudioPlaying && _currentMode == ReadingModeType.auto) {
nextPage();
}
|
820997e6
吴启风
feat:过渡页-绘本环节
|
468
469
470
|
Log.d(
"_onAudioPlayComplete _isOriginAudioPlaying=$_isOriginAudioPlaying _voicePlayState=$_voicePlayState recordUrl=${currentPageData()?.recordUrl?.isNotEmpty}");
if (_isOriginAudioPlaying &&
|
820997e6
吴启风
feat:过渡页-绘本环节
|
471
|
currentPageData()?.recordUrl?.isNotEmpty != true) {
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
472
473
474
475
476
477
478
479
|
///如果刚刚完成原音播放&&录音为空,则开始录音
startRecord(currentPageData()?.word ?? '');
}
_isOriginAudioPlaying = false;
_isRecordAudioPlaying = false;
}
|
2ee6209a
吴启风
feat:绘本播放状态优化
|
480
|
Future<void> _stopAudio() async {
|
53e9e6db
吴启风
feat:绘本语音评测逻辑
|
481
482
483
484
|
await audioPlayer.stop();
_isOriginAudioPlaying = false;
_isRecordAudioPlaying = false;
}
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
485
|
|
820997e6
吴启风
feat:过渡页-绘本环节
|
486
487
|
void _onVoiceXsStateChange(OnXSVoiceStateChangeEvent event,
Emitter<ReadingPageState> emitter) async {
|
ad37b653
吴启风
feat:1、完成微信支付;2、商...
|
488
|
emitter(XSVoiceTestState());
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
489
|
}
|
065022b7
吴启风
feat:绘本评测反馈弹窗+原音播...
|
490
|
|
820997e6
吴启风
feat:过渡页-绘本环节
|
491
492
493
494
495
496
497
498
499
500
501
502
503
|
///是否是最后一页
bool isLastPage() {
return currentPage == dataCount();
}
///重置数据
void _resetLocalResult() {
_entity?.readings?.forEach((element) {
element.recordScore = null;
element.recordUrl = null;
});
}
}
|