Blame view

lib/pages/reading/bloc/reading_bloc.dart 8 KB
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';
2a427e12   吴启风   feat:绘本静态ui基本完成
7
  import 'package:wow_english/pages/reading/widgets/ReadingModeType.dart';
1dc46cf7   吴启风   feat:绘本ui
8
  
a506beff   吴启风   feat:先声sdk方法找不到问题...
9
10
11
12
  import '../../../common/request/dao/listen_dao.dart';
  import '../../../common/request/exception.dart';
  import '../../../models/course_process_entity.dart';
  import '../../../utils/loading.dart';
53e9e6db   吴启风   feat:绘本语音评测逻辑
13
  import 'dart:convert';
a506beff   吴启风   feat:先声sdk方法找不到问题...
14
  
1dc46cf7   吴启风   feat:绘本ui
15
16
17
  part 'reading_event.dart';
  part 'reading_state.dart';
  
53e9e6db   吴启风   feat:绘本语音评测逻辑
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  enum VoicePlayState {
    ///未知
    unKnow,
  
    ///播放中
    playing,
  
    ///播放完成
    completed,
  
    ///播放终止
    stop
  }
  
1dc46cf7   吴启风   feat:绘本ui
32
  class ReadingPageBloc extends Bloc<ReadingPageEvent, ReadingPageState> {
2a427e12   吴启风   feat:绘本静态ui基本完成
33
34
    final PageController pageController;
  
53e9e6db   吴启风   feat:绘本语音评测逻辑
35
36
    final String courseLessonId;
  
2a427e12   吴启风   feat:绘本静态ui基本完成
37
38
39
40
41
42
43
44
45
46
    ///当前页索引
    int _currentPage = 0;
  
    ///当前播放模式
    ReadingModeType _currentMode = ReadingModeType.auto;
  
    int get currentPage => _currentPage + 1;
  
    ReadingModeType get currentMode => _currentMode;
  
a506beff   吴启风   feat:先声sdk方法找不到问题...
47
48
49
50
51
52
53
54
55
    CourseProcessEntity? _entity;
  
    CourseProcessEntity? get entity => _entity;
  
    ///正在评测
    bool _isRecording = false;
  
    bool get isRecording => _isRecording;
  
53e9e6db   吴启风   feat:绘本语音评测逻辑
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
    ///原始音频是否正在播放
    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方法找不到问题...
71
72
73
74
    late MethodChannel methodChannel;
  
    late AudioPlayer audioPlayer;
  
53e9e6db   吴启风   feat:绘本语音评测逻辑
75
76
    ReadingPageBloc(this.pageController, this.courseLessonId)
        : super(ReadingPageInitial()) {
2a427e12   吴启风   feat:绘本静态ui基本完成
77
      on<CurrentPageIndexChangeEvent>(_pageControllerChange);
53e9e6db   吴启风   feat:绘本语音评测逻辑
78
      on<CurrentModeChangeEvent>(_playModeChange);
2a427e12   吴启风   feat:绘本静态ui基本完成
79
80
81
      // pageController.addListener(() {
      //   _currentPage = pageController.page!.round();
      // });
a506beff   吴启风   feat:先声sdk方法找不到问题...
82
      on<RequestDataEvent>(_requestData);
53e9e6db   吴启风   feat:绘本语音评测逻辑
83
      on<InitBlocEvent>((event, emit) {
a506beff   吴启风   feat:先声sdk方法找不到问题...
84
85
        //音频播放器
        audioPlayer = AudioPlayer();
53e9e6db   吴启风   feat:绘本语音评测逻辑
86
87
        audioPlayer.onPlayerStateChanged.listen((event) async {
          debugPrint('播放状态变化');
a506beff   吴启风   feat:先声sdk方法找不到问题...
88
          if (event == PlayerState.completed) {
53e9e6db   吴启风   feat:绘本语音评测逻辑
89
90
91
92
93
94
95
            debugPrint('播放完成');
            _voicePlayState = VoicePlayState.completed;
          }
          if (event == PlayerState.stopped) {
            debugPrint('播放结束');
            _voicePlayState = VoicePlayState.stop;
          }
a506beff   吴启风   feat:先声sdk方法找不到问题...
96
  
53e9e6db   吴启风   feat:绘本语音评测逻辑
97
98
99
100
101
102
          if (event == PlayerState.playing) {
            debugPrint('正在播放中');
            _voicePlayState = VoicePlayState.playing;
          }
          if (isClosed) {
            return;
a506beff   吴启风   feat:先声sdk方法找不到问题...
103
          }
53e9e6db   吴启风   feat:绘本语音评测逻辑
104
          add(VoicePlayStateChangeEvent());
a506beff   吴启风   feat:先声sdk方法找不到问题...
105
106
        });
  
53e9e6db   吴启风   feat:绘本语音评测逻辑
107
108
109
        methodChannel =
            const MethodChannel('wow_english/sing_sound_method_channel');
        methodChannel.invokeMethod('initVoiceSdk', {}); //初始化评测
a506beff   吴启风   feat:先声sdk方法找不到问题...
110
        methodChannel.setMethodCallHandler((call) async {
53e9e6db   吴启风   feat:绘本语音评测逻辑
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
          if (call.method == 'voiceResult') {
            //评测结果
            add(XSVoiceResultEvent(call.arguments));
            return;
          }
  
          if (call.method == 'voiceStart') {
            //评测开始
            if (kDebugMode) {
              print('评测开始');
            }
            return;
          }
  
          if (call.method == 'voiceEnd') {
            //评测结束
            if (kDebugMode) {
              print('评测结束');
            }
            return;
          }
  
          if (call.method == 'voiceFail') {
            //评测失败
            EasyLoading.showToast('评测失败');
            return;
a506beff   吴启风   feat:先声sdk方法找不到问题...
137
138
139
          }
        });
      });
53e9e6db   吴启风   feat:绘本语音评测逻辑
140
      on<VoicePlayStateChangeEvent>(_voicePlayStateChange);
a506beff   吴启风   feat:先声sdk方法找不到问题...
141
      on<PlayOriginalAudioEvent>(_playOriginalAudio);
53e9e6db   吴启风   feat:绘本语音评测逻辑
142
143
144
      on<XSVoiceInitEvent>(_initVoiceSdk);
      on<XSVoiceStartEvent>(_voiceXsStart);
      on<XSVoiceStopEvent>(_voiceXsStop);
a506beff   吴启风   feat:先声sdk方法找不到问题...
145
      on<XSVoiceResultEvent>(_voiceXsResult);
53e9e6db   吴启风   feat:绘本语音评测逻辑
146
147
  
      on<PlayRecordAudioEvent>(_playRecordAudio);
2a427e12   吴启风   feat:绘本静态ui基本完成
148
149
150
151
152
    }
  
    @override
    Future<void> close() {
      pageController.dispose();
a506beff   吴启风   feat:先声sdk方法找不到问题...
153
154
      audioPlayer.release();
      audioPlayer.dispose();
2a427e12   吴启风   feat:绘本静态ui基本完成
155
156
157
      return super.close();
    }
  
a506beff   吴启风   feat:先声sdk方法找不到问题...
158
159
    void _pageControllerChange(CurrentPageIndexChangeEvent event,
        Emitter<ReadingPageState> emitter) async {
2a427e12   吴启风   feat:绘本静态ui基本完成
160
      _currentPage = event.pageIndex;
53e9e6db   吴启风   feat:绘本语音评测逻辑
161
      _playOriginalAudioInner(null);
2a427e12   吴启风   feat:绘本静态ui基本完成
162
163
164
      emitter(CurrentPageIndexState());
    }
  
53e9e6db   吴启风   feat:绘本语音评测逻辑
165
    void _playModeChange(
a506beff   吴启风   feat:先声sdk方法找不到问题...
166
        CurrentModeChangeEvent event, Emitter<ReadingPageState> emitter) async {
2a427e12   吴启风   feat:绘本静态ui基本完成
167
168
169
170
171
172
      if (_currentMode == ReadingModeType.auto) {
        _currentMode = ReadingModeType.manual;
      } else {
        _currentMode = ReadingModeType.auto;
      }
      emitter(CurrentModeState());
1dc46cf7   吴启风   feat:绘本ui
173
    }
a506beff   吴启风   feat:先声sdk方法找不到问题...
174
175
176
177
178
179
  
    ///请求数据
    void _requestData(
        RequestDataEvent event, Emitter<ReadingPageState> emitter) async {
      try {
        await loading(() async {
53e9e6db   吴启风   feat:绘本语音评测逻辑
180
          _entity = await ListenDao.process(courseLessonId);
a506beff   吴启风   feat:先声sdk方法找不到问题...
181
182
183
184
185
186
187
188
189
190
          print("reading page entity: ${_entity!.toJson()}");
          emitter(RequestDataState());
        });
      } catch (e) {
        if (e is ApiException) {
          EasyLoading.showToast(e.message ?? '请求失败,请检查网络连接');
        }
      }
    }
  
53e9e6db   吴启风   feat:绘本语音评测逻辑
191
192
193
194
195
196
197
198
199
200
201
    /// 播放绘本原音
    void _playOriginalAudio(
        PlayOriginalAudioEvent event, Emitter<ReadingPageState> emitter) async {
      _playOriginalAudioInner(event.url);
    }
  
    void _playOriginalAudioInner(String? audioUrl) {
      print("_playOriginalAudio url=$audioUrl");
      audioUrl ??= currentPageData()?.audioUrl ?? '';
      _playAudio(audioUrl);
      _isOriginAudioPlaying = true;
a506beff   吴启风   feat:先声sdk方法找不到问题...
202
203
    }
  
53e9e6db   吴启风   feat:绘本语音评测逻辑
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
    /// 播放录音
    void _playRecordAudio(
        PlayRecordAudioEvent event, Emitter<ReadingPageState> emitter) async {
      _playRecordAudioInner();
    }
  
    void _playRecordAudioInner() {
      final recordAudioUrl = currentPageData()?.recordUrl;
      print("_playRecordAudioInner url=${currentPageData()?.recordUrl}");
      _playAudio(recordAudioUrl);
      _isRecordAudioPlaying = true;
    }
  
    void _playAudio(String? audioUrl) async {
      await audioPlayer.stop();
      if (audioUrl!.isNotEmpty) {
        await audioPlayer.play(UrlSource(audioUrl));
a506beff   吴启风   feat:先声sdk方法找不到问题...
221
222
223
224
225
226
227
228
229
230
231
232
      }
    }
  
    int dataCount() {
      // print("dataCount=${_entity?.readings?.length ?? 0}");
      return _entity?.readings?.length ?? 0;
    }
  
    CourseProcessReadings? currentPageData() {
      return _entity?.readings?[_currentPage];
    }
  
53e9e6db   吴启风   feat:绘本语音评测逻辑
233
234
235
236
237
238
    ///初始化SDK
    _initVoiceSdk(
        XSVoiceInitEvent event, Emitter<ReadingPageState> emitter) async {
      methodChannel.invokeMethod('initVoiceSdk', event.data);
    }
  
a506beff   吴启风   feat:先声sdk方法找不到问题...
239
    ///先声测试
53e9e6db   吴启风   feat:绘本语音评测逻辑
240
241
242
    void _voiceXsStart(
        XSVoiceStartEvent event, Emitter<ReadingPageState> emitter) async {
      _stopAudio();
a506beff   吴启风   feat:先声sdk方法找不到问题...
243
244
245
246
247
248
249
250
      startRecord(event.content);
      emitter(XSVoiceTestState());
    }
  
    void startRecord(String content) async {
      if (_isRecording == true) {
        return;
      }
a506beff   吴启风   feat:先声sdk方法找不到问题...
251
      methodChannel.invokeMethod(
53e9e6db   吴启风   feat:绘本语音评测逻辑
252
          'startVoice', {'word': 'how old are you', 'type': '0', 'userId': '1'});
a506beff   吴启风   feat:先声sdk方法找不到问题...
253
254
255
      _isRecording = true;
    }
  
53e9e6db   吴启风   feat:绘本语音评测逻辑
256
257
258
259
260
261
262
263
264
265
266
267
    void _voiceXsResult(
        XSVoiceResultEvent event, Emitter<ReadingPageState> emitter) async {
      final Map args = json.decode(event.message);
      final result = args['result'];
      print("_voiceXsResult result=${result}");
      if (result != null) {
        final overall = result['overall'].toString();
        EasyLoading.showToast('测评成功,分数是$overall',
            duration: const Duration(seconds: 10));
        currentPageData()?.recordScore = overall;
        currentPageData()?.recordUrl = args['audioUrl'] + '.mp3';
        _playRecordAudioInner();
a506beff   吴启风   feat:先声sdk方法找不到问题...
268
      } else {
53e9e6db   吴启风   feat:绘本语音评测逻辑
269
        EasyLoading.showToast('测评失败', duration: const Duration(seconds: 10));
a506beff   吴启风   feat:先声sdk方法找不到问题...
270
271
272
273
      }
      _isRecording = false;
      emitter(XSVoiceTestState());
    }
53e9e6db   吴启风   feat:绘本语音评测逻辑
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
  
    ///终止评测
    void _voiceXsStop(
        XSVoiceStopEvent event, Emitter<ReadingPageState> emitter) async {
      methodChannel.invokeMethod('stopVoice');
    }
  
    void _voicePlayStateChange(VoicePlayStateChangeEvent event,
        Emitter<ReadingPageState> emitter) async {
      emitter(VoicePlayStateChange());
    }
  
    void _stopAudio() async {
      await audioPlayer.stop();
      _isOriginAudioPlaying = false;
      _isRecordAudioPlaying = false;
    }
1dc46cf7   吴启风   feat:绘本ui
291
  }