recorder.dart 9.2 KB

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