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