SimformSolutionsPvtLtd/audio_waveforms

E/AudioWaveforms( 5594): Failed to stop initialize recorder

Opened this issue · 3 comments

Describe the bug
Recorder controller failed to initialize, it was working before but now it fails to initialize and i can't figure out why

i use following widget to use audio recorder

class AudioRecorder extends StatefulWidget {
  final AudioModel audioModel;
  final double height;
  final Duration? maxDuration;
  final void Function(Duration)? onRecordEnd;

  const AudioRecorder({
    super.key,
    required this.audioModel,
    required this.height,
    this.maxDuration,
    this.onRecordEnd,
  });

  @override
  State<AudioRecorder> createState() => _AudioRecorderState();
}

class _AudioRecorderState extends State<AudioRecorder> {
  late RecorderController recorder;
  late StreamSubscription<RecorderState> recordSub;
  late StreamSubscription<Duration> durationSub;
  late StreamSubscription<Duration> recordEndSub;

  final recorderWaveStyle =
  const WaveStyle(showDurationLabel: true, durationLinesColor: Colors.red);

  @override
  void initState() {
    super.initState();
    recorder = RecorderController();

    recordSub = recorder.onRecorderStateChanged.listen((_) {
      setState(() {});
    });
    durationSub = recorder.onCurrentDuration.listen((dur) {
      if (widget.maxDuration != null && widget.maxDuration! >= dur) {
        recorder.stop();
        setState(() {});
      }
    });
    recordEndSub = recorder.onRecordingEnded.listen((dur) {
      if (widget.onRecordEnd != null) {
        widget.onRecordEnd!(dur);
      }
    });
  }

  @override
  void dispose() {
    recordSub.cancel();
    durationSub.cancel();
    recordEndSub.cancel();
    recorder.dispose();
    super.dispose();
  }

  Future<bool> _hasPermission() {
    final status = Permission.microphone.request();
    final storage = Permission.storage.request();

    return status.isGranted;
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        AudioWaveforms(
          size: Size(MediaQuery.of(context).size.width, widget.height),
          recorderController: recorder,
          waveStyle: recorderWaveStyle,
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            if (!recorder.recorderState.isInitialized)
              IconButton(
                icon: const Icon(Icons.mic),
                onPressed: () async {
                  if (await _hasPermission()) {
                    await recorder.record(path: widget.audioModel.path);
                  } else {
                    throw CustomException(
                        "microphone permission not granted");
                  }
                },
              ),
            if (!recorder.recorderState.isStopped)
              IconButton(
                onPressed: () async {
                  recorder.recorderState.isRecording
                      ? await recorder.pause()
                      : await recorder.record();
                },
                icon: Icon(
                  recorder.recorderState.isRecording ? Icons.stop : Icons.play_arrow,
                ),
              ),

            if (!recorder.recorderState.isStopped)
              IconButton(onPressed: recorder.stop, icon: const Icon(Icons.stop))
          ],
        )
      ],
    );
  }
}

and its used here

class Media extends StatefulWidget {
  final String _applicationID;

  const Media(this._applicationID, {super.key});

  @override
  State<Media> createState() => _MediaState();
}

class _MediaState extends State<Media> {
  bool _showPlayer = false;

  void _setShowPlayer(bool val) {
    setState(() {
      _showPlayer = val;
    });
  }

  Widget _buildAudioCard(MediaProvider media) {
    if (media.audio == null) {
      // Audio is not initialized yet
      return const CircularProgressIndicator();
    }

    return Card(
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: !_showPlayer
            ? AudioRecorder(audioModel: media.audio!, height: 200)
            : AudioPlayer(audioModel: media.audio!, height: 200),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    MediaProvider media = Provider.of<MediaProvider>(context, listen: false);

    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          children: [
            _buildAudioCard(media),
            // AudioCard(),
            const SizedBox(height: 20),
            // ImageCard(),
          ],
        ),
      ),
    );
  }
}

although i tired using it in other ways too it didn't work

To Reproduce
try init RecorderController or use AudioRecorder

Expected behavior
RecorderController initialises

Smartphone (please complete the following information):

  • Device: Pixel 5
  • OS: Android
  • Version 13

Additional context
it worked before but it suddenly stopped working, i have tried different ways but it just seems to stop at initialization phase with "E/AudioWaveforms( 5594): Failed to stop initialize recorder" as error log when try to record

i also tried it in different emulators and device it still didn't work

Same for me

Same here did you find any fix?

@Illia-Dulebov @tentamens @gautam8404
I also have the same problem. My solution is to pass a path to it:
await recorderController.record(path: soundFilePath);