Untitled

 avatar
unknown
dart
2 years ago
6.5 kB
8
Indexable
import 'dart:async';
import 'dart:io';
import 'package:audio_session/audio_session.dart';
import 'package:co_meeting_system/App/Models/Main/Comment.dart';
import 'package:co_meeting_system/App/Services/AuthenticationService/Core/manager.dart';
import 'package:co_meeting_system/App/Services/PermissionService/permission_handler_service.dart';
import 'package:co_meeting_system/App/Utilities/Constants/AppColors.dart';
import 'package:co_meeting_system/App/Widgets/CustomButton.dart';
import 'package:flutter/material.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:flutter_sound_platform_interface/flutter_sound_recorder_platform_interface.dart';
import 'package:get/get.dart';
import 'package:path_provider/path_provider.dart';

typedef fn = void Function();
const theSource = AudioSource.microphone;

class RecordAndSendVoiceComment extends StatefulWidget {
  final int commentFor, relationId;
  final Function addedFunction;

  RecordAndSendVoiceComment(
      {required this.commentFor,
      required this.relationId,
      required this.addedFunction});

  @override
  _RecordAndSendVoiceCommentState createState() =>
      _RecordAndSendVoiceCommentState();
}

class _RecordAndSendVoiceCommentState extends State<RecordAndSendVoiceComment>
    with SingleTickerProviderStateMixin {
  final AuthenticationManager authManager = Get.find();
  Codec _codec = Codec.aacMP4;
  late String _mPath;
  FlutterSoundPlayer? _mPlayer = FlutterSoundPlayer();
  FlutterSoundRecorder? _mRecorder = FlutterSoundRecorder();
  bool _mPlayerIsInited = false;
  bool _mRecorderIsInited = false;
  bool _mplaybackReady = false;
  late Animation<Color?> animation;
  late AnimationController animationcontroller;

  @override
  void initState() {
    _mPlayer!.openAudioSession().then((value) {
      setState(() {
        _mPlayerIsInited = true;
      });
    });

    openTheRecorder().then((value) {
      setState(() {
        _mRecorderIsInited = true;
      });
    });

    animationcontroller = AnimationController(
        vsync: this, duration: const Duration(microseconds: 1500));

    animationcontroller.repeat();

    animation = ColorTween(begin: Colors.red[800], end: Colors.red[400])
        .animate(animationcontroller);

    animation.addListener(() {
      setState(() {});
    });
    super.initState();
  }

  @override
  void dispose() {
    _mPlayer!.closeAudioSession();
    _mPlayer = null;

   // _mRecorder!.closeRecorder();
    _mRecorder = null;
    animationcontroller.dispose();

    super.dispose();
  }

  Future<void> openTheRecorder() async {
    await _mRecorder!.openAudioSession();

    final session = await AudioSession.instance;
    await session.configure(AudioSessionConfiguration(
      avAudioSessionCategory: AVAudioSessionCategory.playAndRecord,
      avAudioSessionCategoryOptions:
          AVAudioSessionCategoryOptions.allowBluetooth |
              AVAudioSessionCategoryOptions.defaultToSpeaker,
      avAudioSessionMode: AVAudioSessionMode.spokenAudio,
      avAudioSessionRouteSharingPolicy:
          AVAudioSessionRouteSharingPolicy.defaultPolicy,
      avAudioSessionSetActiveOptions: AVAudioSessionSetActiveOptions.none,
      androidAudioAttributes: const AndroidAudioAttributes(
        contentType: AndroidAudioContentType.speech,
        flags: AndroidAudioFlags.none,
        usage: AndroidAudioUsage.voiceCommunication,
      ),
      androidAudioFocusGainType: AndroidAudioFocusGainType.gain,
      androidWillPauseWhenDucked: true,
    ));

    _mRecorderIsInited = true;
  }

  void record() async {
    Directory appDocDir = await getApplicationDocumentsDirectory();
    _mPath = appDocDir.path + '/' + 'tau_file.mp4';
    await PermissionHandlerPermissionService()
        .handleMicrophonePermission(context);
    _mRecorder!
        .startRecorder(
      toFile: _mPath,
      codec: _codec,
      audioSource: theSource,
    )
        .then((value) {
      setState(() {});
    });
  }

  void stopRecorder() async {
    await _mRecorder!.stopRecorder().then((value) {
      setState(() {
        //var url = value;
        _mplaybackReady = true;
      });
    });
    List<Comment> list = await authManager.api
        .addVoiceComment(widget.commentFor, widget.relationId, File(_mPath));

    widget.addedFunction(list);
  }

  void play() {
    assert(_mPlayerIsInited &&
        _mplaybackReady &&
        _mRecorder!.isStopped &&
        _mPlayer!.isStopped);
    _mPlayer!
        .startPlayer(
            fromURI: _mPath,
            whenFinished: () {
              setState(() {});
            })
        .then((value) {
      setState(() {});
    });
  }

  void stopPlayer() {
    _mPlayer!.stopPlayer().then((value) {
      setState(() {});
    });
  }

// ----------------------------- UI --------------------------------------------

  fn? getRecorderFn() {
    return null;
  }

  fn? getPlaybackFn() {
    if (!_mPlayerIsInited || !_mplaybackReady || !_mRecorder!.isStopped) {
      return null;
    }
    return _mPlayer!.isStopped ? play : stopPlayer;
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      height: Get.width * 0.2,
      color: AppColors.white,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          _mRecorder!.isRecording
              ? Container(
                  margin: const EdgeInsets.symmetric(horizontal: 8.0),
                  width: Get.width * 0.045,
                  height: Get.width * 0.045,
                  decoration: BoxDecoration(
                      color: animation.value, shape: BoxShape.circle),
                )
              : const SizedBox(),
          CustomButton(
              background:
                  _mRecorder!.isRecording ? AppColors.primary : AppColors.red,
              borderRadius: BorderRadius.circular(8.0),
              padding: const EdgeInsets.all(8.0),
              text: Text(
                _mRecorder!.isRecording ? 'Send'.tr : 'record'.tr,
                style:
                    Get.textTheme.headline6!.copyWith(color: AppColors.white),
                textAlign: TextAlign.center,
              ),
              width: Get.width * 0.3,
              onTap: () {
                if (!_mRecorderIsInited || !_mPlayer!.isStopped) {}

                if (_mRecorder!.isStopped) {
                  record();
                } else {
                  stopRecorder();
                }
              }),
        ],
      ),
    );
  }
}
Editor is loading...