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