recorder.dart 9.1 KB

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