Commit b1869cf8c5a103abd2206171c56033fe68ce78c8
1 parent
d5fb5080
背景音乐添加
Showing
11 changed files
with
187 additions
and
77 deletions
lib/pages/games/bloc.dart
... | ... | @@ -2,17 +2,17 @@ import 'package:bloc/bloc.dart'; |
2 | 2 | import 'package:flutter/cupertino.dart'; |
3 | 3 | import 'package:flutter/services.dart'; |
4 | 4 | import 'package:wow_english/common/extension/string_extension.dart'; |
5 | +import 'package:wow_english/utils/audioplayer_util.dart'; | |
5 | 6 | |
6 | 7 | import 'event.dart'; |
7 | 8 | import 'game_entity.dart'; |
8 | 9 | import 'state.dart'; |
9 | 10 | |
10 | 11 | class GamesBloc extends Bloc<GamesEvent, GamesState> { |
11 | - | |
12 | 12 | late MethodChannel _methodChannel; |
13 | 13 | |
14 | 14 | //手动初始化4个GameEntity对象 |
15 | - final List<GameEntity> _games = [ | |
15 | + final List<GameEntity> _games = [ | |
16 | 16 | GameEntity() |
17 | 17 | ..id = 1 |
18 | 18 | ..imageName = 'game_food_1'.assetPng |
... | ... | @@ -31,7 +31,7 @@ class GamesBloc extends Bloc<GamesEvent, GamesState> { |
31 | 31 | ..name = 'Animal' |
32 | 32 | ]; |
33 | 33 | |
34 | - List<GameEntity> get listData => _games; | |
34 | + List<GameEntity> get listData => _games; | |
35 | 35 | |
36 | 36 | GamesBloc() : super(GamesState().init()) { |
37 | 37 | on<InitEvent>(_init); |
... | ... | @@ -39,13 +39,16 @@ class GamesBloc extends Bloc<GamesEvent, GamesState> { |
39 | 39 | } |
40 | 40 | |
41 | 41 | void _init(InitEvent event, Emitter<GamesState> emit) async { |
42 | + AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.inMyTummy); | |
42 | 43 | emit(state.clone()); |
43 | 44 | } |
44 | 45 | |
45 | 46 | void _gotoGamePage(GotoGamePageEvent event, Emitter<GamesState> emit) async { |
47 | + AudioPlayerUtil.getInstance().pause(); | |
46 | 48 | try { |
47 | 49 | _methodChannel = const MethodChannel('wow_english/game_method_channel'); |
48 | - await _methodChannel.invokeMethod('openGamePage', { "gameId": event.gameId }); | |
50 | + await _methodChannel | |
51 | + .invokeMethod('openGamePage', {"gameId": event.gameId}); | |
49 | 52 | } on PlatformException catch (e) { |
50 | 53 | debugPrint("Failed to go to native page: '${e.message}'."); |
51 | 54 | } | ... | ... |
lib/pages/home/bloc.dart
... | ... | @@ -2,6 +2,7 @@ import 'package:audioplayers/audioplayers.dart'; |
2 | 2 | import 'package:bloc/bloc.dart'; |
3 | 3 | import 'package:wow_english/common/core/user_util.dart'; |
4 | 4 | import 'package:wow_english/common/extension/string_extension.dart'; |
5 | +import 'package:wow_english/utils/audioplayer_util.dart'; | |
5 | 6 | |
6 | 7 | import '../../common/core/app_config_helper.dart'; |
7 | 8 | import '../../common/request/dao/system_dao.dart'; |
... | ... | @@ -17,16 +18,10 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> { |
17 | 18 | } |
18 | 19 | |
19 | 20 | bool exchangeResult = false; |
20 | - late AudioPlayer audioPlayer; | |
21 | - late AudioPlayer studyPlayer; | |
22 | - late AudioPlayer gamePlayer; | |
23 | 21 | |
24 | 22 | void _init(InitEvent event, Emitter<HomeState> emit) async { |
25 | 23 | if (UserUtil.isLogined()) { |
26 | - audioPlayer = AudioPlayer(playerId: 'audio'); | |
27 | - gamePlayer = AudioPlayer(playerId: 'game'); | |
28 | - studyPlayer = AudioPlayer(playerId: 'study'); | |
29 | - audioPlayer.play(AssetSource('welcome_to_wow'.assetMp3)); | |
24 | + AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.welcomeToWow); | |
30 | 25 | } |
31 | 26 | await _checkUpdate(emit); |
32 | 27 | } | ... | ... |
lib/pages/home/view.dart
... | ... | @@ -12,6 +12,7 @@ import 'package:wow_english/pages/home/state.dart'; |
12 | 12 | import 'package:wow_english/pages/home/widgets/BaseHomeHeaderWidget.dart'; |
13 | 13 | import 'package:wow_english/pages/shop/exchane/bloc/exchange_lesson_bloc.dart'; |
14 | 14 | import 'package:wow_english/pages/user/bloc/user_bloc.dart'; |
15 | +import 'package:wow_english/utils/audioplayer_util.dart'; | |
15 | 16 | |
16 | 17 | import '../../common/core/user_util.dart'; |
17 | 18 | import '../../common/dialogs/show_dialog.dart'; |
... | ... | @@ -60,6 +61,8 @@ class _HomePageView extends StatelessWidget { |
60 | 61 | children: [ |
61 | 62 | BaseHomeHeaderWidget( |
62 | 63 | callBack: (value) => { |
64 | + AudioPlayerUtil.getInstance() | |
65 | + .playAudio(AudioPlayerUtilType.touch), | |
63 | 66 | bloc.exchangeResult = value['exchange'], |
64 | 67 | bloc.add(ExchangeSuccessEvent()) |
65 | 68 | }), |
... | ... | @@ -71,8 +74,8 @@ class _HomePageView extends StatelessWidget { |
71 | 74 | child: GestureDetector( |
72 | 75 | onTap: () { |
73 | 76 | _checkPermission(() { |
74 | - bloc.studyPlayer | |
75 | - .play(AssetSource('class_time'.assetMp3)); | |
77 | + AudioPlayerUtil.getInstance() | |
78 | + .playAudio(AudioPlayerUtilType.classTime); | |
76 | 79 | Future.delayed(const Duration(seconds: 1), () { |
77 | 80 | pushNamed(AppRouteName.courseUnit) |
78 | 81 | .then((value) => { |
... | ... | @@ -108,29 +111,38 @@ class _HomePageView extends StatelessWidget { |
108 | 111 | ), |
109 | 112 | ), |
110 | 113 | ), |
111 | - Expanded( | |
112 | - child: BlocBuilder<UserBloc, UserState>( | |
113 | - builder: (context, userState) { | |
114 | - return GestureDetector( | |
115 | - onTap: () { | |
116 | - _checkPermission(() { | |
117 | - Navigator.of(context).pushNamed( | |
118 | - AppRouteName.webView, | |
119 | - arguments: { | |
120 | - 'urlStr': AppConsts.xiaoeShopUrl, | |
121 | - 'webViewTitle': 'Wow精选' | |
122 | - }); | |
123 | - }, bloc); | |
124 | - }, | |
125 | - child: Column( | |
126 | - mainAxisAlignment: MainAxisAlignment.center, | |
127 | - children: [ | |
128 | - Image.asset('xe_shop'.assetPng, | |
129 | - width: 140.5.w, height: 172.h), | |
130 | - 44.verticalSpace | |
131 | - ], | |
132 | - )); | |
133 | - }), | |
114 | + Offstage( | |
115 | + offstage: AppConfigHelper.shouldHidePay() || | |
116 | + !UserUtil.isLogined(), | |
117 | + child: Expanded( | |
118 | + child: BlocBuilder<UserBloc, UserState>( | |
119 | + builder: (context, userState) { | |
120 | + return GestureDetector( | |
121 | + onTap: () { | |
122 | + _checkPermission(() { | |
123 | + AudioPlayerUtil.getInstance().pause(); | |
124 | + Navigator.of(context).pushNamed( | |
125 | + AppRouteName.webView, | |
126 | + arguments: { | |
127 | + 'urlStr': AppConsts.xiaoeShopUrl, | |
128 | + 'webViewTitle': 'Wow精选' | |
129 | + }).then((value) => { | |
130 | + AudioPlayerUtil.getInstance() | |
131 | + .playAudio( | |
132 | + AudioPlayerUtilType.touch), | |
133 | + }); | |
134 | + }, bloc); | |
135 | + }, | |
136 | + child: Column( | |
137 | + mainAxisAlignment: MainAxisAlignment.center, | |
138 | + children: [ | |
139 | + Image.asset('xe_shop'.assetPng, | |
140 | + width: 140.5.w, height: 172.h), | |
141 | + 44.verticalSpace | |
142 | + ], | |
143 | + )); | |
144 | + }), | |
145 | + ), | |
134 | 146 | ), |
135 | 147 | Expanded( |
136 | 148 | child: BlocBuilder<UserBloc, UserState>( |
... | ... | @@ -138,9 +150,14 @@ class _HomePageView extends StatelessWidget { |
138 | 150 | return GestureDetector( |
139 | 151 | onTap: () { |
140 | 152 | _checkPermission(() { |
141 | - bloc.gamePlayer.play( | |
142 | - AssetSource('game_time'.assetMp3)); | |
143 | - pushNamed(AppRouteName.games); | |
153 | + AudioPlayerUtil.getInstance().playAudio( | |
154 | + AudioPlayerUtilType.gameTime); | |
155 | + pushNamed(AppRouteName.games) | |
156 | + .then((value) => { | |
157 | + AudioPlayerUtil.getInstance() | |
158 | + .playAudio(AudioPlayerUtilType | |
159 | + .touch), | |
160 | + }); | |
144 | 161 | }, bloc); |
145 | 162 | }, |
146 | 163 | child: Column( |
... | ... | @@ -189,6 +206,8 @@ class _HomePageView extends StatelessWidget { |
189 | 206 | }, rightTap: () { |
190 | 207 | popPage(); |
191 | 208 | pushNamed(AppRouteName.shop).then((value) { |
209 | + AudioPlayerUtil.getInstance() | |
210 | + .playAudio(AudioPlayerUtilType.touch); | |
192 | 211 | if (value != null) { |
193 | 212 | bloc.exchangeResult = value['exchange']; |
194 | 213 | bloc.add(ExchangeSuccessEvent()); | ... | ... |
lib/pages/home/widgets/BaseHomeHeaderWidget.dart
... | ... | @@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; |
3 | 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
4 | 4 | import 'package:wow_english/common/core/app_config_helper.dart'; |
5 | 5 | import 'package:wow_english/common/extension/string_extension.dart'; |
6 | +import 'package:wow_english/utils/audioplayer_util.dart'; | |
6 | 7 | |
7 | 8 | import '../../../common/core/user_util.dart'; |
8 | 9 | import '../../../models/course_entity.dart'; |
... | ... | @@ -84,6 +85,7 @@ class BaseHomeHeaderWidget extends StatelessWidget { |
84 | 85 | !UserUtil.isLogined(), |
85 | 86 | child: GestureDetector( |
86 | 87 | onTap: () => { |
88 | + AudioPlayerUtil.getInstance().pause(), | |
87 | 89 | pushNamed(AppRouteName.shop).then((value) { |
88 | 90 | if (value != null) { |
89 | 91 | if (callBack == null) { |
... | ... | @@ -115,6 +117,7 @@ class BaseHomeHeaderWidget extends StatelessWidget { |
115 | 117 | |
116 | 118 | void onUserClick() { |
117 | 119 | if (UserUtil.isLogined()) { |
120 | + AudioPlayerUtil.getInstance().pause(); | |
118 | 121 | pushNamed(AppRouteName.user).then((value) { |
119 | 122 | if (value != null) { |
120 | 123 | if (callBack == null) { | ... | ... |
lib/pages/section/bloc/section_bloc.dart
... | ... | @@ -9,6 +9,7 @@ import 'package:wow_english/common/request/dao/lesson_dao.dart'; |
9 | 9 | import 'package:wow_english/common/request/exception.dart'; |
10 | 10 | import 'package:wow_english/common/request/dao/listen_dao.dart'; |
11 | 11 | import 'package:wow_english/models/course_process_entity.dart'; |
12 | +import 'package:wow_english/utils/audioplayer_util.dart'; | |
12 | 13 | import 'package:wow_english/utils/loading.dart'; |
13 | 14 | import 'package:wow_english/utils/toast_util.dart'; |
14 | 15 | |
... | ... | @@ -45,8 +46,6 @@ class SectionBloc extends Bloc<SectionEvent, SectionState> { |
45 | 46 | ///单元列表是否有刷新,有的话返回上一页时通知其刷新接口数据 |
46 | 47 | bool courseUnitEntityChanged = false; |
47 | 48 | |
48 | - late AudioPlayer audioPlayer; // 点击播放器 | |
49 | - late AudioPlayer backgroundPlayer; // 背景播放器 | |
50 | 49 | ///courseUnitId与课程环节列表的映射 |
51 | 50 | final Map<int, List<CourseSectionEntity>?> _courseSectionDatasMap = {}; |
52 | 51 | |
... | ... | @@ -66,25 +65,12 @@ class SectionBloc extends Bloc<SectionEvent, SectionState> { |
66 | 65 | on<RequestVideoLessonEvent>(_requestVideoLesson); |
67 | 66 | on<CurrentUnitIndexChangeEvent>(_pageControllerChange); |
68 | 67 | on<InitEvent>((event, emit) { |
69 | - audioPlayer = AudioPlayer(playerId: 'section'); | |
70 | - backgroundPlayer = AudioPlayer(playerId: 'back'); | |
71 | - backgroundPlayer.play(AssetSource('count_with_me_instrumental'.assetMp3)); | |
72 | - | |
73 | - backgroundPlayer.onPlayerStateChanged.listen((event) async { | |
74 | - if (event == PlayerState.completed) { | |
75 | - // 播放结束再次播放 | |
76 | - backgroundPlayer | |
77 | - .play(AssetSource('count_with_me_instrumental'.assetMp3)); | |
78 | - } | |
79 | - }); | |
68 | + AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.countWithMe); | |
80 | 69 | }); |
81 | 70 | } |
82 | 71 | @override |
83 | 72 | Future<void> close() { |
84 | - audioPlayer.release(); | |
85 | - audioPlayer.dispose(); | |
86 | - backgroundPlayer.release(); | |
87 | - backgroundPlayer.dispose(); | |
73 | + AudioPlayerUtil.getInstance().pause(); | |
88 | 74 | return super.close(); |
89 | 75 | } |
90 | 76 | ... | ... |
lib/pages/section/bloc/section_state.dart
lib/pages/section/section_page.dart
... | ... | @@ -12,6 +12,8 @@ import 'package:wow_english/pages/section/widgets/section_item.dart'; |
12 | 12 | import 'package:wow_english/pages/section/widgets/section_bouns_item.dart'; |
13 | 13 | import 'package:wow_english/pages/section/widgets/section_header_widget.dart'; |
14 | 14 | import 'package:wow_english/route/route.dart'; |
15 | +import 'package:wow_english/utils/audioplayer_util.dart'; | |
16 | +import 'package:wow_english/utils/log_util.dart'; | |
15 | 17 | import 'package:wow_english/utils/toast_util.dart'; |
16 | 18 | |
17 | 19 | import '../../models/course_section_entity.dart'; |
... | ... | @@ -89,23 +91,23 @@ class _SectionPageView extends StatelessWidget { |
89 | 91 | currentTime: dataMap['currentTime'], |
90 | 92 | autoNextSection: dataMap['nextSection'])); |
91 | 93 | } |
92 | - if (bloc.backgroundPlayer.state == PlayerState.paused) { | |
93 | - bloc.backgroundPlayer.resume(); | |
94 | - } | |
94 | + AudioPlayerUtil.getInstance() | |
95 | + .playAudio(AudioPlayerUtilType.countWithMe); | |
95 | 96 | }); |
96 | 97 | return; |
97 | 98 | } |
98 | 99 | |
99 | 100 | if (state is RequestEnterClassState) { |
100 | - bloc.backgroundPlayer.pause(); | |
101 | 101 | if (state.courseType != SectionType.practice.value && |
102 | 102 | state.courseType != SectionType.pictureBook.value) { |
103 | 103 | ///视频类型 |
104 | 104 | ///获取视频课程内容 |
105 | 105 | if (state.courseType == 1) { |
106 | - bloc.audioPlayer.play(AssetSource('music_time'.assetMp3)); | |
106 | + AudioPlayerUtil.getInstance() | |
107 | + .playAudio(AudioPlayerUtilType.musicTime); | |
107 | 108 | } else { |
108 | - bloc.audioPlayer.play(AssetSource('video_time'.assetMp3)); | |
109 | + AudioPlayerUtil.getInstance() | |
110 | + .playAudio(AudioPlayerUtilType.videoTime); | |
109 | 111 | } |
110 | 112 | Future.delayed(const Duration(seconds: 1), () { |
111 | 113 | bloc.add(RequestVideoLessonEvent( |
... | ... | @@ -116,7 +118,8 @@ class _SectionPageView extends StatelessWidget { |
116 | 118 | } |
117 | 119 | |
118 | 120 | if (state.courseType == SectionType.pictureBook.value) { |
119 | - bloc.audioPlayer.play(AssetSource('reading_time'.assetMp3)); | |
121 | + AudioPlayerUtil.getInstance() | |
122 | + .playAudio(AudioPlayerUtilType.readingTime); | |
120 | 123 | Future.delayed(const Duration(seconds: 1), () { |
121 | 124 | //绘本 |
122 | 125 | pushNamed(AppRouteName.reading, |
... | ... | @@ -130,9 +133,8 @@ class _SectionPageView extends StatelessWidget { |
130 | 133 | currentStep: dataMap['currentStep'], |
131 | 134 | autoNextSection: dataMap['nextSection'], |
132 | 135 | )); |
133 | - if (bloc.backgroundPlayer.state == PlayerState.paused) { | |
134 | - bloc.backgroundPlayer.resume(); | |
135 | - } | |
136 | + AudioPlayerUtil.getInstance() | |
137 | + .playAudio(AudioPlayerUtilType.countWithMe); | |
136 | 138 | } |
137 | 139 | }); |
138 | 140 | }); |
... | ... | @@ -142,7 +144,8 @@ class _SectionPageView extends StatelessWidget { |
142 | 144 | |
143 | 145 | if (state.courseType == SectionType.practice.value) { |
144 | 146 | //练习 |
145 | - bloc.audioPlayer.play(AssetSource('quiz_time'.assetMp3)); | |
147 | + AudioPlayerUtil.getInstance() | |
148 | + .playAudio(AudioPlayerUtilType.quizTime); | |
146 | 149 | Future.delayed(const Duration(seconds: 1), () { |
147 | 150 | pushNamed(AppRouteName.topicPic, |
148 | 151 | arguments: {'courseLessonId': state.courseLessonId}) |
... | ... | @@ -154,9 +157,8 @@ class _SectionPageView extends StatelessWidget { |
154 | 157 | currentStep: dataMap['currentStep'], |
155 | 158 | autoNextSection: dataMap['nextSection'])); |
156 | 159 | } |
157 | - if (bloc.backgroundPlayer.state == PlayerState.paused) { | |
158 | - bloc.backgroundPlayer.resume(); | |
159 | - } | |
160 | + AudioPlayerUtil.getInstance() | |
161 | + .playAudio(AudioPlayerUtilType.countWithMe); | |
160 | 162 | }); |
161 | 163 | }); |
162 | 164 | return; | ... | ... |
lib/pages/unit/bloc.dart
1 | 1 | import 'package:bloc/bloc.dart'; |
2 | 2 | import 'package:wow_english/pages/unit/widget/home_tab_header_widget.dart'; |
3 | +import 'package:wow_english/utils/audioplayer_util.dart'; | |
3 | 4 | |
4 | 5 | import '../../common/request/dao/lesson_dao.dart'; |
5 | 6 | import '../../common/request/exception.dart'; |
... | ... | @@ -24,6 +25,9 @@ class UnitBloc extends Bloc<UnitEvent, UnitState> { |
24 | 25 | |
25 | 26 | UnitBloc(CourseModuleEntity? courseEntity) : super(UnitState().init()) { |
26 | 27 | on<RequestUnitDataEvent>(_requestUnitDatas); |
28 | + on<UnitInitEvent>((event, emit) { | |
29 | + AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.inMyTummy); | |
30 | + }); | |
27 | 31 | } |
28 | 32 | |
29 | 33 | void _requestUnitDatas( |
... | ... | @@ -45,15 +49,26 @@ class UnitBloc extends Bloc<UnitEvent, UnitState> { |
45 | 49 | } |
46 | 50 | |
47 | 51 | void headerActionEvent(HeaderActionType type) { |
52 | + AudioPlayerUtil.getInstance().pause(); | |
48 | 53 | if (type == HeaderActionType.video) { |
49 | 54 | pushNamed(AppRouteName.reAfter); |
50 | 55 | } else if (type == HeaderActionType.phase) { |
51 | - pushNamed(AppRouteName.courseModule); | |
56 | + pushNamed(AppRouteName.courseModule).then((value) => { | |
57 | + AudioPlayerUtil.getInstance() | |
58 | + .playAudio(AudioPlayerUtilType.inMyTummy) | |
59 | + }); | |
60 | + ; | |
52 | 61 | } else if (type == HeaderActionType.listen) { |
53 | - pushNamed(AppRouteName.listen); | |
62 | + pushNamed(AppRouteName.listen).then((value) => { | |
63 | + AudioPlayerUtil.getInstance() | |
64 | + .playAudio(AudioPlayerUtilType.inMyTummy) | |
65 | + }); | |
54 | 66 | } else if (type == HeaderActionType.shop) { |
55 | - pushNamed(AppRouteName.shop) | |
56 | - .then((value) => {exchangeResult = value['exchange']}); | |
67 | + pushNamed(AppRouteName.shop).then((value) => { | |
68 | + AudioPlayerUtil.getInstance() | |
69 | + .playAudio(AudioPlayerUtilType.inMyTummy), | |
70 | + exchangeResult = value['exchange'] | |
71 | + }); | |
57 | 72 | } else if (type == HeaderActionType.user) { |
58 | 73 | pushNamed(AppRouteName.user); |
59 | 74 | } | ... | ... |
lib/pages/unit/event.dart
lib/pages/unit/view.dart
... | ... | @@ -5,6 +5,7 @@ import 'package:wow_english/pages/unit/state.dart'; |
5 | 5 | import 'package:wow_english/pages/unit/widget/course_unit_item.dart'; |
6 | 6 | import 'package:wow_english/pages/unit/widget/home_tab_header_widget.dart'; |
7 | 7 | import 'package:wow_english/route/route.dart'; |
8 | +import 'package:wow_english/utils/audioplayer_util.dart'; | |
8 | 9 | |
9 | 10 | import '../../models/course_module_entity.dart'; |
10 | 11 | import '../../models/course_unit_entity.dart'; |
... | ... | @@ -23,6 +24,7 @@ class UnitPage extends StatelessWidget { |
23 | 24 | Widget build(BuildContext context) { |
24 | 25 | return BlocProvider( |
25 | 26 | create: (BuildContext context) => UnitBloc(courseModuleEntity) |
27 | + ..add(UnitInitEvent()) | |
26 | 28 | ..add(RequestUnitDataEvent(courseModuleEntity?.id)), |
27 | 29 | child: Builder(builder: (context) => _buildPage(context)), |
28 | 30 | ); |
... | ... | @@ -41,6 +43,8 @@ class UnitPage extends StatelessWidget { |
41 | 43 | HomeTabHeaderWidget( |
42 | 44 | courseModuleCode: bloc.getCourseModuleCode(), |
43 | 45 | onBack: () { |
46 | + AudioPlayerUtil.getInstance() | |
47 | + .playAudio(AudioPlayerUtilType.touch); | |
44 | 48 | popPage(data: {'exchange': bloc.exchangeResult}); |
45 | 49 | }, |
46 | 50 | actionTap: (HeaderActionType type) { |
... | ... | @@ -63,12 +67,14 @@ class UnitPage extends StatelessWidget { |
63 | 67 | showToast('当前单元课程暂未解锁'); |
64 | 68 | return; |
65 | 69 | } |
66 | - | |
70 | + AudioPlayerUtil.getInstance().pause(); | |
67 | 71 | pushNamed(AppRouteName.courseSection, |
68 | 72 | arguments: { |
69 | 73 | 'courseUnitEntity': bloc.unitData, |
70 | 74 | 'courseUnitId': data.id |
71 | 75 | }).then((value) { |
76 | + AudioPlayerUtil.getInstance() | |
77 | + .playAudio(AudioPlayerUtilType.inMyTummy); | |
72 | 78 | if (value != null) { |
73 | 79 | Map<String, dynamic> dataMap = |
74 | 80 | value as Map<String, dynamic>; | ... | ... |
lib/utils/audioplayer_util.dart
0 → 100644
1 | +import 'package:audioplayers/audioplayers.dart'; | |
2 | +import 'package:wow_english/common/extension/string_extension.dart'; | |
3 | + | |
4 | +enum AudioPlayerUtilType { | |
5 | + welcomeToWow('welcome_to_wow'), | |
6 | + classTime('class_time'), | |
7 | + gameTime('game_time'), | |
8 | + musicTime('music_time'), | |
9 | + readingTime('reading_time'), | |
10 | + videoTime('video_time'), | |
11 | + quizTime('quiz_time'), | |
12 | + countWithMe('count_with_me_instrumental'), | |
13 | + inMyTummy('in_my_tummy_instrumental'), | |
14 | + touch('touch_instrumental'); | |
15 | + | |
16 | + const AudioPlayerUtilType(this.path); | |
17 | + | |
18 | + final String path; | |
19 | +} | |
20 | + | |
21 | +class AudioPlayerUtil { | |
22 | + static AudioPlayerUtil? _instance; | |
23 | + late AudioPlayer audioPlayer; | |
24 | + late AudioPlayerUtilType currentType; | |
25 | + | |
26 | + // 私有构造函数 | |
27 | + AudioPlayerUtil._internal() { | |
28 | + audioPlayer = AudioPlayer(); | |
29 | + audioPlayer.onPlayerStateChanged.listen((event) async { | |
30 | + if (event == PlayerState.completed) { | |
31 | + // 播放结束再次播放 | |
32 | + if (currentType == AudioPlayerUtilType.inMyTummy) { | |
33 | + AudioPlayerUtil.getInstance() | |
34 | + .playAudio(AudioPlayerUtilType.inMyTummy); | |
35 | + } | |
36 | + if (currentType == AudioPlayerUtilType.countWithMe) { | |
37 | + AudioPlayerUtil.getInstance() | |
38 | + .playAudio(AudioPlayerUtilType.countWithMe); | |
39 | + } | |
40 | + if (currentType == AudioPlayerUtilType.welcomeToWow) { | |
41 | + AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.touch); | |
42 | + } | |
43 | + if (currentType == AudioPlayerUtilType.touch) { | |
44 | + AudioPlayerUtil.getInstance().playAudio(AudioPlayerUtilType.touch); | |
45 | + } | |
46 | + } | |
47 | + }); | |
48 | + } | |
49 | + | |
50 | + static AudioPlayerUtil getInstance() { | |
51 | + _instance ??= AudioPlayerUtil._internal(); | |
52 | + return _instance!; | |
53 | + } | |
54 | + | |
55 | +// 播放音频 | |
56 | + Future<void> playAudio(AudioPlayerUtilType type) async { | |
57 | + currentType = type; | |
58 | + String path = type.path; | |
59 | + await audioPlayer.play(AssetSource(path.assetMp3), volume: 0.5); | |
60 | + await audioPlayer.onPlayerComplete.first; | |
61 | + } | |
62 | + | |
63 | + // stop | |
64 | + void stop() { | |
65 | + audioPlayer.stop(); | |
66 | + } | |
67 | + | |
68 | + // pause | |
69 | + void pause() { | |
70 | + if (audioPlayer.state == PlayerState.playing) { | |
71 | + audioPlayer.pause(); | |
72 | + } | |
73 | + } | |
74 | + | |
75 | + // resume | |
76 | + void resume() { | |
77 | + if (audioPlayer.state == PlayerState.paused) { | |
78 | + audioPlayer.resume(); | |
79 | + } | |
80 | + } | |
81 | +} | ... | ... |