import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:wow_english/common/request/dao/listen_dao.dart'; import '../../../common/request/exception.dart'; import '../../../models/read_content_entity.dart'; import '../../../utils/loading.dart'; import '../../../utils/toast_util.dart'; part 'repeat_after_content_event.dart'; part 'repeat_after_content_state.dart'; enum VoiceRecordState { ///未知 voiceRecordUnkonw, ///开始录音 voiceRecordStat, ///正在录音 voiceRecording, ///录音结束 voiceRecordEnd } enum VoicePlayState { ///未知 unKnow, ///播放中 playing, ///播放完成 completed, ///播放终止 stop } class RepeatAfterContentBloc extends Bloc { final String courseLessonId; ///是否正在播放视频 bool _videoPlaying = true; ///是否需要录音 bool _isRecord = false; Map? _voiceTestResult; int _recordNumber = 0; VoiceRecordState _voiceRecordState = VoiceRecordState.voiceRecordUnkonw; bool get videoPlaying => _videoPlaying; bool get isRecord => _isRecord; VoiceRecordState get voiceRecordState => _voiceRecordState; List? _entityList; List? get entityList => _entityList ; Map? get voiceTestResult => _voiceTestResult; late MethodChannel methodChannel; late AudioPlayer audioPlayer; RepeatAfterContentBloc(this.courseLessonId) : super(RepeatAfterContentInitial()) { on(_voiceRecordStateChange); on(_postFollowReadContent); on(_changeVideoPlayIndex); on(_videoPlayStateChange); on(_recordeVoicePlay); on(_voiceXsResult); on(_initVoiceSdk); on(_requestData); on(_voiceXsTest); on(_voiceXsStop); on(_voiceRecord); on((event, emit) { //音频播放器 audioPlayer = AudioPlayer(); audioPlayer.onPlayerStateChanged.listen((event) async { debugPrint('播放状态变化'); if (event == PlayerState.completed) { debugPrint('播放完成'); } if (event == PlayerState.stopped) { debugPrint('播放结束'); } if (event == PlayerState.playing) { debugPrint('正在播放中'); } if(isClosed) { return; } }); methodChannel = const MethodChannel('wow_english/sing_sound_method_channel'); methodChannel.setMethodCallHandler((call) async { if (call.method == 'voiceResult') {//评测结果 add(XSVoiceResultEvent(call.arguments)); add(PostFollowReadContentEvent()); return; } if (call.method == 'voiceStart') {//评测开始 debugPrint('评测开始'); return; } if (call.method == 'voiceEnd') {//评测结束 debugPrint('评测结束'); return; } if (call.method == 'voiceFail') {//评测失败 showToast('评测失败'); return; } }); }); } ///请求数据 void _requestData(RequestDataEvent event,Emitter emitter) async { try { await loading(() async { _entityList = await ListenDao.readContent(courseLessonId); emitter(RequestDataState()); }); } catch (e) { if (e is ApiException) { showToast(e.message??'请求失败,请检查网络连接'); } } } ///跟读结果 void _postFollowReadContent(PostFollowReadContentEvent event,Emitter emitter) async { try { await loading(() async { _entityList = await ListenDao.followResult(_recordNumber.toString(),courseLessonId); }); } catch (e) { if (e is ApiException) { } } } void _videoPlayStateChange(VideoPlayChangeEvent event,Emitter emitter) async { _videoPlaying = !_videoPlaying; emitter(VideoPlayChangeState()); } void _voiceRecord(VoiceRecordEvent event,Emitter emitter) async { _isRecord = !_isRecord; emitter(VoiceRecordChangeState()); } void _voiceRecordStateChange(VoiceRecordStateChangeEvent event,Emitter emitter) async { _voiceRecordState = event.voiceRecordState; emitter(VoiceRecordStateChange()); } _initVoiceSdk(XSVoiceInitEvent event,Emitter emitter) async { methodChannel.invokeMethod('initVoiceSdk',event.data); } ///先声测试 void _voiceXsTest(XSVoiceTestEvent event,Emitter emitter) async { await audioPlayer.stop(); methodChannel.invokeMethod( 'startVoice', {'word':event.testWord,'type':event.type,'userId':event.userId.toString()} ); _recordNumber++; emitter(XSVoiceTestState()); } ///终止评测 void _voiceXsStop(XSVoiceStopEvent event,Emitter emitter) async { methodChannel.invokeMethod('stopVoice'); } ///先声评测结果 void _voiceXsResult(XSVoiceResultEvent event,Emitter emitter) async { final Map args = event.message as Map; final result = args['result'] as Map; final overall = result['overall'].toString(); final audioUrl = args['audioUrl'].toString(); _voiceTestResult = {'overall':overall,'audioUrl':audioUrl}; emitter(XSVoiceTestState()); } ///播放声音 void _recordeVoicePlay(RecordeVoicePlayEvent event,Emitter emitter) async { await audioPlayer.stop(); assert(event.audioUrl.isNotEmpty); await audioPlayer.play(UrlSource(event.audioUrl)); } ///更改播放的视频 void _changeVideoPlayIndex(ChangeVideoPlayIndexEvent event,Emitter emitter) async { emitter(ChangeVideoPlayIndexState(event.isNext)); } }