Advertisement
bafplus2

record main.dart

Aug 2nd, 2021
1,321
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 11.63 KB | None | 0 0
  1. import 'dart:async';
  2. import 'dart:io';
  3.  
  4. import 'package:flutter/material.dart';
  5. import 'package:intl/intl.dart';
  6. import 'package:just_audio/just_audio.dart' as ap;
  7. import 'package:mailer/mailer.dart';
  8. import 'package:mailer/smtp_server.dart';
  9. import 'package:record/record.dart';
  10.  
  11. class AudioRecorder extends StatefulWidget {
  12.   final void Function(String path) onStop;
  13.  
  14.   const AudioRecorder({required this.onStop});
  15.  
  16.   @override
  17.   _AudioRecorderState createState() => _AudioRecorderState();
  18. }
  19.  
  20. class _AudioRecorderState extends State<AudioRecorder> {
  21.   bool _isRecording = false;
  22.   bool _isPaused = false;
  23.   int _recordDuration = 0;
  24.   Timer? _timer;
  25.   Timer? _ampTimer;
  26.   final _audioRecorder = Record();
  27.  
  28.   @override
  29.   void initState() {
  30.     _isRecording = false;
  31.     super.initState();
  32.   }
  33.  
  34.   @override
  35.   void dispose() {
  36.     _timer?.cancel();
  37.     _ampTimer?.cancel();
  38.     _audioRecorder.dispose();
  39.     super.dispose();
  40.   }
  41.  
  42.   @override
  43.   Widget build(BuildContext context) {
  44.     return MaterialApp(
  45.       home: Scaffold(
  46.         body: Column(
  47.           mainAxisAlignment: MainAxisAlignment.center,
  48.           children: [
  49.             Row(
  50.               mainAxisAlignment: MainAxisAlignment.center,
  51.               children: <Widget>[
  52.                 _buildRecordStopControl(),
  53.                 const SizedBox(width: 20),
  54.                 _buildPauseResumeControl(),
  55.                 const SizedBox(width: 20),
  56.                 _buildText(),
  57.               ],
  58.             ),
  59.           ],
  60.         ),
  61.       ),
  62.     );
  63.   }
  64.  
  65.   Widget _buildRecordStopControl() {
  66.     late Icon icon;
  67.     late Color color;
  68.  
  69.     if (_isRecording || _isPaused) {
  70.       icon = Icon(Icons.stop, color: Colors.red, size: 30);
  71.       color = Colors.red.withOpacity(0.1);
  72.     } else {
  73.       final theme = Theme.of(context);
  74.       icon = Icon(Icons.mic, color: theme.primaryColor, size: 30);
  75.       color = theme.primaryColor.withOpacity(0.1);
  76.     }
  77.  
  78.     return ClipOval(
  79.       child: Material(
  80.         color: color,
  81.         child: InkWell(
  82.           child: SizedBox(width: 56, height: 56, child: icon),
  83.           onTap: () {
  84.             _isRecording ? _stop() : _start();
  85.           },
  86.         ),
  87.       ),
  88.     );
  89.   }
  90.  
  91.   Widget _buildPauseResumeControl() {
  92.     if (!_isRecording && !_isPaused) {
  93.       return const SizedBox.shrink();
  94.     }
  95.  
  96.     late Icon icon;
  97.     late Color color;
  98.  
  99.     if (!_isPaused) {
  100.       icon = Icon(Icons.pause, color: Colors.red, size: 30);
  101.       color = Colors.red.withOpacity(0.1);
  102.     } else {
  103.       final theme = Theme.of(context);
  104.       icon = Icon(Icons.play_arrow, color: Colors.red, size: 30);
  105.       color = theme.primaryColor.withOpacity(0.1);
  106.     }
  107.  
  108.     return ClipOval(
  109.       child: Material(
  110.         color: color,
  111.         child: InkWell(
  112.           child: SizedBox(width: 56, height: 56, child: icon),
  113.           onTap: () {
  114.             _isPaused ? _resume() : _pause();
  115.           },
  116.         ),
  117.       ),
  118.     );
  119.   }
  120.  
  121.   Widget _buildText() {
  122.     if (_isRecording || _isPaused) {
  123.       return _buildTimer();
  124.     }
  125.  
  126.     return Text("");
  127.   }
  128.  
  129.   Widget _buildTimer() {
  130.     final String minutes = _formatNumber(_recordDuration ~/ 60);
  131.     final String seconds = _formatNumber(_recordDuration % 60);
  132.  
  133.     return Text(
  134.       '$minutes : $seconds',
  135.       style: TextStyle(color: Colors.red),
  136.     );
  137.   }
  138.  
  139.   String _formatNumber(int number) {
  140.     String numberStr = number.toString();
  141.     if (number < 10) {
  142.       numberStr = '0' + numberStr;
  143.     }
  144.  
  145.     return numberStr;
  146.   }
  147.  
  148.   Future<void> _start() async {
  149.     try {
  150.       if (await _audioRecorder.hasPermission()) {
  151.         await _audioRecorder.start();
  152.  
  153.         bool isRecording = await _audioRecorder.isRecording();
  154.         setState(() {
  155.           _isRecording = isRecording;
  156.           _recordDuration = 0;
  157.         });
  158.  
  159.         _startTimer();
  160.       }
  161.     } catch (e) {
  162.       print(e);
  163.     }
  164.   }
  165.  
  166.   Future<void> _stop() async {
  167.     _timer?.cancel();
  168.     _ampTimer?.cancel();
  169.     final path = await _audioRecorder.stop();
  170.  
  171.     widget.onStop(path!);
  172.  
  173.     setState(() => _isRecording = false);
  174.   }
  175.  
  176.   Future<void> _pause() async {
  177.     _timer?.cancel();
  178.     _ampTimer?.cancel();
  179.     await _audioRecorder.pause();
  180.  
  181.     setState(() => _isPaused = true);
  182.   }
  183.  
  184.   Future<void> _resume() async {
  185.     _startTimer();
  186.     await _audioRecorder.resume();
  187.  
  188.     setState(() => _isPaused = false);
  189.   }
  190.  
  191.   void _startTimer() {
  192.     _timer?.cancel();
  193.     _ampTimer?.cancel();
  194.  
  195.     _timer = Timer.periodic(const Duration(seconds: 1), (Timer t) {
  196.       setState(() => _recordDuration++);
  197.     });
  198.  
  199.     _ampTimer =
  200.         Timer.periodic(const Duration(milliseconds: 200), (Timer t) async {
  201.       setState(() {});
  202.     });
  203.   }
  204. }
  205.  
  206. void main() {
  207.   runApp(MyApp());
  208. }
  209.  
  210. class MyApp extends StatefulWidget {
  211.   @override
  212.   _MyAppState createState() => _MyAppState();
  213. }
  214.  
  215. class _MyAppState extends State<MyApp> {
  216.   bool showPlayer = false;
  217.   ap.AudioSource? audioSource;
  218.  
  219.   @override
  220.   void initState() {
  221.     showPlayer = false;
  222.     super.initState();
  223.   }
  224.  
  225.   @override
  226.   Widget build(BuildContext context) {
  227.     return MaterialApp(
  228.       home: Scaffold(
  229.         body: Center(
  230.           child: showPlayer
  231.               ? Padding(
  232.                   padding: EdgeInsets.symmetric(horizontal: 25),
  233.                   child: AudioPlayer(
  234.                     source: audioSource!,
  235.                     onDelete: () {
  236.                       setState(() => showPlayer = false);
  237.                     },
  238.                   ),
  239.                 )
  240.               : AudioRecorder(
  241.                   onStop: (path) {
  242.                     setState(() {
  243.                       audioSource = ap.AudioSource.uri(Uri.parse(path));
  244.                       showPlayer = true;
  245.                     });
  246.                   },
  247.                 ),
  248.         ),
  249.       ),
  250.     );
  251.   }
  252. }
  253.  
  254. class AudioPlayer extends StatefulWidget {
  255.   /// Path from where to play recorded audio
  256.   final ap.AudioSource source;
  257.  
  258.   /// Callback when audio file should be removed
  259.   /// Setting this to null hides the delete button
  260.   final VoidCallback onDelete;
  261.  
  262.   const AudioPlayer({
  263.     required this.source,
  264.     required this.onDelete,
  265.   });
  266.  
  267.   @override
  268.   AudioPlayerState createState() => AudioPlayerState();
  269. }
  270.  
  271. class AudioPlayerState extends State<AudioPlayer> {
  272.   static const double _controlSize = 56;
  273.   static const double _deleteBtnSize = 24;
  274.  
  275.   final _audioPlayer = ap.AudioPlayer();
  276.   late StreamSubscription<ap.PlayerState> _playerStateChangedSubscription;
  277.   late StreamSubscription<Duration?> _durationChangedSubscription;
  278.   late StreamSubscription<Duration> _positionChangedSubscription;
  279.  
  280.   @override
  281.   void initState() {
  282.     _playerStateChangedSubscription =
  283.         _audioPlayer.playerStateStream.listen((state) async {
  284.       if (state.processingState == ap.ProcessingState.completed) {
  285.         await stop();
  286.       }
  287.       setState(() {});
  288.     });
  289.     _positionChangedSubscription =
  290.         _audioPlayer.positionStream.listen((position) => setState(() {}));
  291.     _durationChangedSubscription =
  292.         _audioPlayer.durationStream.listen((duration) => setState(() {}));
  293.     _init();
  294.  
  295.     super.initState();
  296.   }
  297.  
  298.   Future<void> _init() async {
  299.     await _audioPlayer.setAudioSource(widget.source);
  300.   }
  301.  
  302.   @override
  303.   void dispose() {
  304.     _playerStateChangedSubscription.cancel();
  305.     _positionChangedSubscription.cancel();
  306.     _durationChangedSubscription.cancel();
  307.     _audioPlayer.dispose();
  308.     super.dispose();
  309.   }
  310.  
  311.   @override
  312.   Widget build(BuildContext context) {
  313.     return LayoutBuilder(
  314.       builder: (context, constraints) {
  315.         return Column(
  316.           mainAxisSize: MainAxisSize.max,
  317.           mainAxisAlignment: MainAxisAlignment.spaceBetween,
  318.           children: <Widget>[
  319.             _buildControl(),
  320.             _buildSlider(constraints.maxWidth),
  321.             IconButton(
  322.               icon: Icon(Icons.delete,
  323.                   color: const Color(0xFF73748D), size: _deleteBtnSize),
  324.               onPressed: () {
  325.                 _audioPlayer.stop().then((value) => widget.onDelete());
  326.               },
  327.             ),
  328.             ElevatedButton(
  329.               style: ElevatedButton.styleFrom(
  330.                 minimumSize: Size(175, 50),
  331.                 primary: Colors.white,
  332.                 onPrimary: Colors.black,
  333.               ),
  334.               child: Text('verstuur',
  335.                   style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
  336.               onPressed: () {
  337.                 audioVerzenden();
  338.                 //Navigator.of(context).pop();
  339.               },
  340.             )
  341.           ],
  342.         );
  343.       },
  344.     );
  345.   }
  346.  
  347.   Widget _buildControl() {
  348.     Icon icon;
  349.     Color color;
  350.  
  351.     if (_audioPlayer.playerState.playing) {
  352.       icon = Icon(Icons.pause, color: Colors.red, size: 30);
  353.       color = Colors.red.withOpacity(0.1);
  354.     } else {
  355.       final theme = Theme.of(context);
  356.       icon = Icon(Icons.play_arrow, color: theme.primaryColor, size: 30);
  357.       color = theme.primaryColor.withOpacity(0.1);
  358.     }
  359.  
  360.     return ClipOval(
  361.       child: Material(
  362.         color: color,
  363.         child: InkWell(
  364.           child:
  365.               SizedBox(width: _controlSize, height: _controlSize, child: icon),
  366.           onTap: () {
  367.             if (_audioPlayer.playerState.playing) {
  368.               pause();
  369.             } else {
  370.               play();
  371.             }
  372.           },
  373.         ),
  374.       ),
  375.     );
  376.   }
  377.  
  378.   Widget _buildSlider(double widgetWidth) {
  379.     final position = _audioPlayer.position;
  380.     final duration = _audioPlayer.duration;
  381.     bool canSetValue = false;
  382.     if (duration != null) {
  383.       canSetValue = position.inMilliseconds > 0;
  384.       canSetValue &= position.inMilliseconds < duration.inMilliseconds;
  385.     }
  386.  
  387.     double width = widgetWidth - _controlSize - _deleteBtnSize;
  388.     width -= _deleteBtnSize;
  389.  
  390.     return SizedBox(
  391.       width: width,
  392.       child: Slider(
  393.         activeColor: Theme.of(context).primaryColor,
  394.         inactiveColor: Theme.of(context).accentColor,
  395.         onChanged: (v) {
  396.           if (duration != null) {
  397.             final position = v * duration.inMilliseconds;
  398.             _audioPlayer.seek(Duration(milliseconds: position.round()));
  399.           }
  400.         },
  401.         value: canSetValue && duration != null
  402.             ? position.inMilliseconds / duration.inMilliseconds
  403.             : 0.0,
  404.       ),
  405.     );
  406.   }
  407.  
  408.   Future<void> play() {
  409.     return _audioPlayer.play();
  410.   }
  411.  
  412.   Future<void> pause() {
  413.     return _audioPlayer.pause();
  414.   }
  415.  
  416.   Future<void> stop() async {
  417.     await _audioPlayer.stop();
  418.     return _audioPlayer.seek(const Duration(milliseconds: 0));
  419.   }
  420.  
  421.   audioVerzenden() async {
  422.     final smtpServer = SmtpServer("server",
  423.         username: 'username',
  424.         password: 'password',
  425.         allowInsecure: true,
  426.         ignoreBadCertificate: true);
  427.  
  428.     final datumOpmaak = DateFormat('dd-MM-yyyy H:mm');
  429.  
  430.     // Create our message.
  431.     final message = Message()
  432.       ..from = Address('from@email.com', 'From name')
  433.       ..recipients.add('reciepient@gmail.com')
  434.       ..subject =
  435.           'Test Dart Mailer library :: 😀 :: ${datumOpmaak.format(DateTime.now())}'
  436.       ..text = 'This is the plain text.\nThis is line 2 of the text part.'
  437.       ..attachments = [FileAttachment(File.fromUri(Uri.parse(filePath)))];
  438.  
  439.     try {
  440.       final sendReport = await send(message, smtpServer);
  441.       print('Message sent: ' + sendReport.toString());
  442.     } on MailerException catch (e) {
  443.       print('Message not sent.');
  444.       for (var p in e.problems) {
  445.         print('Problem: ${p.code}: ${p.msg}');
  446.       }
  447.     }
  448.   }
  449. // DONE
  450.  
  451. }
  452.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement