recorder.dart 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. import 'dart:async';
  2. import 'dart:io';
  3. import 'package:flutter/material.dart';
  4. import 'package:fluttertoast/fluttertoast.dart';
  5. import 'package:path_provider/path_provider.dart';
  6. import 'package:permission_handler/permission_handler.dart';
  7. class RecorderView extends StatefulWidget {
  8. final Function save;
  9. const RecorderView({Key? key, required this.save}) : super(key: key);
  10. @override
  11. _RecorderViewState createState() => _RecorderViewState();
  12. }
  13. class _RecorderViewState extends State<RecorderView> {
  14. IconData _recordIcon = Icons.mic_none;
  15. MaterialColor colo = Colors.orange;
  16. RecordingStatus _currentStatus = RecordingStatus.Unset;
  17. bool stop = false;
  18. Recording? _current;
  19. // Recorder properties
  20. late FlutterAudioRecorder? audioRecorder;
  21. @override
  22. void initState() {
  23. super.initState();
  24. checkPermission();
  25. }
  26. // 权限检测
  27. void checkPermission() async {
  28. if (await Permission.contacts.request().isGranted) {
  29. // Either the permission was already granted before or the user just granted it.
  30. }
  31. // You can request multiple permissions at once.
  32. Map<Permission, PermissionStatus> statuses = await [
  33. Permission.microphone,
  34. Permission.storage,
  35. ].request();
  36. //bool hasPermission = await FlutterAudioRecorder.hasPermissions ?? false;
  37. if (statuses[Permission.microphone] == PermissionStatus.granted) {
  38. _currentStatus = RecordingStatus.Initialized;
  39. _recordIcon = Icons.mic;
  40. } else {}
  41. }
  42. @override
  43. void dispose() {
  44. _currentStatus = RecordingStatus.Unset;
  45. audioRecorder = null;
  46. super.dispose();
  47. }
  48. @override
  49. Widget build(BuildContext context) {
  50. return Stack(
  51. alignment: Alignment.center,
  52. children: [
  53. Column(
  54. children: [
  55. const SizedBox(
  56. height: 20,
  57. ),
  58. Text(
  59. (_current == null)
  60. ? "0:0:0:0"
  61. : _current!.duration.toString(),
  62. style: const TextStyle(color: Colors.black, fontSize: 20),
  63. ),
  64. const SizedBox(
  65. height: 20,
  66. ),
  67. stop == false
  68. ? RaisedButton(
  69. color: Colors.orange,
  70. onPressed: () async {
  71. await _onRecordButtonPressed();
  72. setState(() {});
  73. },
  74. shape: RoundedRectangleBorder(
  75. borderRadius: BorderRadius.circular(10),
  76. ),
  77. child: Column(
  78. children: [
  79. Container(
  80. width: 80,
  81. height: 80,
  82. child: Icon(
  83. _recordIcon,
  84. color: Colors.white,
  85. size: 80,
  86. ),
  87. ),
  88. const Padding(
  89. padding: EdgeInsets.all(8.0),
  90. child: Text(
  91. "Write Dailry",
  92. style: TextStyle(color: Colors.white),
  93. ),
  94. )
  95. ],
  96. ),
  97. )
  98. : Padding(
  99. padding: const EdgeInsets.all(8.0),
  100. child: Row(
  101. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  102. children: [
  103. RaisedButton(
  104. color: colo,
  105. onPressed: () async {
  106. await _onRecordButtonPressed();
  107. setState(() {});
  108. },
  109. shape: RoundedRectangleBorder(
  110. borderRadius: BorderRadius.circular(10),
  111. ),
  112. child: Container(
  113. width: 80,
  114. height: 80,
  115. child: Icon(
  116. _recordIcon,
  117. color: Colors.white,
  118. size: 50,
  119. ),
  120. ),
  121. ),
  122. RaisedButton(
  123. color: Colors.orange,
  124. onPressed: _currentStatus != RecordingStatus.Unset
  125. ? _stop
  126. : null,
  127. shape: RoundedRectangleBorder(
  128. borderRadius: BorderRadius.circular(10),
  129. ),
  130. child: Container(
  131. width: 80,
  132. height: 80,
  133. child: Icon(
  134. Icons.stop,
  135. color: Colors.white,
  136. size: 50,
  137. ),
  138. ),
  139. ),
  140. ],
  141. ),
  142. ),
  143. ],
  144. ),
  145. ],
  146. );
  147. }
  148. Future<void> _onRecordButtonPressed() async {
  149. switch (_currentStatus) {
  150. case RecordingStatus.Initialized:
  151. {
  152. _recordo();
  153. break;
  154. }
  155. case RecordingStatus.Recording:
  156. {
  157. _pause();
  158. break;
  159. }
  160. case RecordingStatus.Paused:
  161. {
  162. _resume();
  163. break;
  164. }
  165. case RecordingStatus.Stopped:
  166. {
  167. _recordo();
  168. break;
  169. }
  170. default:
  171. break;
  172. }
  173. }
  174. _initial() async {
  175. Directory? appDir = await getExternalStorageDirectory();
  176. String jrecord = 'Audiorecords';
  177. String dato = "${DateTime.now().millisecondsSinceEpoch.toString()}.wav";
  178. Directory appDirec = Directory("${appDir!.path}/$jrecord/");
  179. if (await appDirec.exists()) {
  180. String patho = "${appDirec.path}$dato";
  181. audioRecorder = FlutterAudioRecorder(patho, audioFormat: AudioFormat.WAV);
  182. await audioRecorder!.initialized;
  183. } else {
  184. appDirec.create(recursive: true);
  185. Fluttertoast.showToast(msg: "Start Recording , Press Start");
  186. String patho = "${appDirec.path}$dato";
  187. audioRecorder = FlutterAudioRecorder(patho, audioFormat: AudioFormat.WAV);
  188. await audioRecorder!.initialized;
  189. }
  190. }
  191. _start() async {
  192. await audioRecorder!.start();
  193. var recording = await audioRecorder!.current(channel: 0);
  194. setState(() {
  195. _current = recording!;
  196. });
  197. const tick = const Duration(milliseconds: 50);
  198. Timer.periodic(tick, (Timer t) async {
  199. if (_currentStatus == RecordingStatus.Stopped) {
  200. t.cancel();
  201. }
  202. var current = await audioRecorder!.current(channel: 0);
  203. // print(current.status);
  204. setState(() {
  205. _current = current!;
  206. _currentStatus = _current!.status!;
  207. });
  208. });
  209. }
  210. _resume() async {
  211. await audioRecorder!.resume();
  212. Fluttertoast.showToast(msg: "Resume Recording");
  213. setState(() {
  214. _recordIcon = Icons.pause;
  215. colo = Colors.red;
  216. });
  217. }
  218. _pause() async {
  219. await audioRecorder!.pause();
  220. Fluttertoast.showToast(msg: "Pause Recording");
  221. setState(() {
  222. _recordIcon = Icons.mic;
  223. colo = Colors.green;
  224. });
  225. }
  226. _stop() async {
  227. var result = await audioRecorder!.stop();
  228. Fluttertoast.showToast(msg: "Stop Recording , File Saved");
  229. widget.save();
  230. setState(() {
  231. _current = result!;
  232. _currentStatus = _current!.status!;
  233. _current!.duration = null;
  234. _recordIcon = Icons.mic;
  235. stop = false;
  236. });
  237. }
  238. Future<void> _recordo() async {
  239. Map<Permission, PermissionStatus> statuses = await [
  240. Permission.microphone,
  241. Permission.storage,
  242. ].request();
  243. print(statuses[Permission.microphone]);
  244. print(statuses[Permission.storage]);
  245. if (statuses[Permission.microphone] == PermissionStatus.granted) {
  246. /* }
  247. bool hasPermission = await FlutterAudioRecorder.hasPermissions ?? false;
  248. if (hasPermission) {*/
  249. await _initial();
  250. await _start();
  251. Fluttertoast.showToast(msg: "Start Recording");
  252. setState(() {
  253. _currentStatus = RecordingStatus.Recording;
  254. _recordIcon = Icons.pause;
  255. colo = Colors.red;
  256. stop = true;
  257. });
  258. } else {
  259. Fluttertoast.showToast(msg: "Allow App To Use Mic");
  260. }
  261. }
  262. }