main.dart 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. import 'dart:io';
  2. import 'package:flutter/material.dart';
  3. import 'package:intl/intl.dart' show DateFormat;
  4. import 'package:intl/date_symbol_data_local.dart';
  5. import 'dart:async';
  6. import 'package:flutter_sound/flutter_sound.dart';
  7. import 'package:flutter_sound/android_encoder.dart';
  8. void main() {
  9. runApp(new MyApp());
  10. }
  11. class MyApp extends StatefulWidget {
  12. @override
  13. _MyAppState createState() => new _MyAppState();
  14. }
  15. class _MyAppState extends State<MyApp> {
  16. bool _isRecording = false;
  17. String _path;
  18. // bool _isPlaying = false;
  19. StreamSubscription _recorderSubscription;
  20. StreamSubscription _dbPeakSubscription;
  21. StreamSubscription _playerSubscription;
  22. FlutterSound flutterSound;
  23. String _recorderTxt = '00:00:00';
  24. String _playerTxt = '00:00:00';
  25. double _dbLevel;
  26. double sliderCurrentPosition = 0.0;
  27. double maxDuration = 1.0;
  28. @override
  29. void initState() {
  30. super.initState();
  31. flutterSound = new FlutterSound();
  32. flutterSound.setSubscriptionDuration(0.01);
  33. flutterSound.setDbPeakLevelUpdate(0.8);
  34. flutterSound.setDbLevelEnabled(true);
  35. initializeDateFormatting();
  36. }
  37. void startRecorder() async{
  38. try {
  39. String path = await flutterSound.startRecorder(
  40. Platform.isIOS ? 'ios.aac' : 'android.aac',
  41. androidEncoder: AndroidEncoder.AAC,
  42. androidAudioSource: AndroidAudioSource.MIC,
  43. );
  44. print('startRecorder: $path');
  45. _recorderSubscription = flutterSound.onRecorderStateChanged.listen((e) {
  46. DateTime date = new DateTime.fromMillisecondsSinceEpoch(
  47. e.currentPosition.toInt(),
  48. isUtc: true);
  49. String txt = DateFormat('mm:ss:SS', 'en_GB').format(date);
  50. this.setState(() {
  51. this._recorderTxt = txt.substring(0, 8);
  52. });
  53. });
  54. _dbPeakSubscription =
  55. flutterSound.onRecorderDbPeakChanged.listen((value) {
  56. print("got update -> $value");
  57. setState(() {
  58. this._dbLevel = value;
  59. });
  60. });
  61. this.setState(() {
  62. this._isRecording = true;
  63. this._path = path;
  64. });
  65. } catch (err) {
  66. print('startRecorder error: $err');
  67. }
  68. }
  69. void stopRecorder() async{
  70. try {
  71. String result = await flutterSound.stopRecorder();
  72. print('stopRecorder: $result');
  73. if (_recorderSubscription != null) {
  74. _recorderSubscription.cancel();
  75. _recorderSubscription = null;
  76. }
  77. if (_dbPeakSubscription != null) {
  78. _dbPeakSubscription.cancel();
  79. _dbPeakSubscription = null;
  80. }
  81. this.setState(() {
  82. this._isRecording = false;
  83. });
  84. } catch (err) {
  85. print('stopRecorder error: $err');
  86. }
  87. }
  88. void startPlayer() async{
  89. try {
  90. String path = await flutterSound.startPlayer(this._path);
  91. await flutterSound.setVolume(1.0);
  92. print('startPlayer: $path');
  93. _playerSubscription = flutterSound.onPlayerStateChanged.listen((e) {
  94. if (e != null) {
  95. sliderCurrentPosition = e.currentPosition;
  96. maxDuration = e.duration;
  97. DateTime date = new DateTime.fromMillisecondsSinceEpoch(
  98. e.currentPosition.toInt(),
  99. isUtc: true);
  100. String txt = DateFormat('mm:ss:SS', 'en_GB').format(date);
  101. this.setState(() {
  102. //this._isPlaying = true;
  103. this._playerTxt = txt.substring(0, 8);
  104. });
  105. }
  106. });
  107. } catch (err) {
  108. print('error: $err');
  109. }
  110. }
  111. void stopPlayer() async{
  112. try {
  113. String result = await flutterSound.stopPlayer();
  114. print('stopPlayer: $result');
  115. if (_playerSubscription != null) {
  116. _playerSubscription.cancel();
  117. _playerSubscription = null;
  118. }
  119. this.setState(() {
  120. //this._isPlaying = false;
  121. });
  122. } catch (err) {
  123. print('error: $err');
  124. }
  125. }
  126. void pausePlayer() async{
  127. String result = await flutterSound.pausePlayer();
  128. print('pausePlayer: $result');
  129. }
  130. void resumePlayer() async{
  131. String result = await flutterSound.resumePlayer();
  132. print('resumePlayer: $result');
  133. }
  134. void seekToPlayer(int milliSecs) async{
  135. String result = await flutterSound.seekToPlayer(milliSecs);
  136. print('seekToPlayer: $result');
  137. }
  138. @override
  139. Widget build(BuildContext context) {
  140. return MaterialApp(
  141. home: Scaffold(
  142. appBar: AppBar(
  143. title: const Text('Flutter Sound'),
  144. ),
  145. body: ListView(
  146. children: <Widget>[
  147. Column(
  148. crossAxisAlignment: CrossAxisAlignment.center,
  149. mainAxisAlignment: MainAxisAlignment.center,
  150. children: <Widget>[
  151. Container(
  152. margin: EdgeInsets.only(top: 24.0, bottom:16.0),
  153. child: Text(
  154. this._recorderTxt,
  155. style: TextStyle(
  156. fontSize: 48.0,
  157. color: Colors.black,
  158. ),
  159. ),
  160. ),
  161. _isRecording ? LinearProgressIndicator(
  162. value: 100.0 / 160.0 * (this._dbLevel ?? 1) / 100,
  163. valueColor: AlwaysStoppedAnimation<Color>(Colors.green),
  164. backgroundColor: Colors.red,
  165. ) : Container()
  166. ],
  167. ),
  168. Row(
  169. children: <Widget>[
  170. Container(
  171. width: 56.0,
  172. height: 56.0,
  173. child: ClipOval(
  174. child: FlatButton(
  175. onPressed: () {
  176. if (!this._isRecording) {
  177. return this.startRecorder();
  178. }
  179. this.stopRecorder();
  180. },
  181. padding: EdgeInsets.all(8.0),
  182. child: Image(
  183. image: this._isRecording ? AssetImage('res/icons/ic_stop.png') : AssetImage('res/icons/ic_mic.png'),
  184. ),
  185. ),
  186. ),
  187. ),
  188. ],
  189. mainAxisAlignment: MainAxisAlignment.center,
  190. crossAxisAlignment: CrossAxisAlignment.center,
  191. ),
  192. Column(
  193. crossAxisAlignment: CrossAxisAlignment.center,
  194. mainAxisAlignment: MainAxisAlignment.center,
  195. children: <Widget>[
  196. Container(
  197. margin: EdgeInsets.only(top: 60.0, bottom:16.0),
  198. child: Text(
  199. this._playerTxt,
  200. style: TextStyle(
  201. fontSize: 48.0,
  202. color: Colors.black,
  203. ),
  204. ),
  205. ),
  206. ],
  207. ),
  208. Row(
  209. children: <Widget>[
  210. Container(
  211. width: 56.0,
  212. height: 56.0,
  213. child: ClipOval(
  214. child: FlatButton(
  215. onPressed: () {
  216. startPlayer();
  217. },
  218. padding: EdgeInsets.all(8.0),
  219. child: Image(
  220. image: AssetImage('res/icons/ic_play.png'),
  221. ),
  222. ),
  223. ),
  224. ),
  225. Container(
  226. width: 56.0,
  227. height: 56.0,
  228. child: ClipOval(
  229. child: FlatButton(
  230. onPressed: () {
  231. pausePlayer();
  232. },
  233. padding: EdgeInsets.all(8.0),
  234. child: Image(
  235. width: 36.0,
  236. height: 36.0,
  237. image: AssetImage('res/icons/ic_pause.png'),
  238. ),
  239. ),
  240. ),
  241. ),
  242. Container(
  243. width: 56.0,
  244. height: 56.0,
  245. child: ClipOval(
  246. child: FlatButton(
  247. onPressed: () {
  248. stopPlayer();
  249. },
  250. padding: EdgeInsets.all(8.0),
  251. child: Image(
  252. width: 28.0,
  253. height: 28.0,
  254. image: AssetImage('res/icons/ic_stop.png'),
  255. ),
  256. ),
  257. ),
  258. ),
  259. ],
  260. mainAxisAlignment: MainAxisAlignment.center,
  261. crossAxisAlignment: CrossAxisAlignment.center,
  262. ),
  263. Container(
  264. height: 56.0,
  265. child: Slider(
  266. value: sliderCurrentPosition,
  267. min: 0.0,
  268. max: maxDuration,
  269. onChanged: (double value) async{
  270. await flutterSound.seekToPlayer(value.toInt());
  271. },
  272. divisions: maxDuration.toInt()
  273. )
  274. )
  275. ],
  276. ),
  277. ),
  278. );
  279. }
  280. }