audio_waveforms icon indicating copy to clipboard operation
audio_waveforms copied to clipboard

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

Open gautam8404 opened this issue 1 year ago • 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

gautam8404 avatar Jun 11 '24 08:06 gautam8404

Same for me

Illia-Dulebov avatar Jul 12 '24 08:07 Illia-Dulebov

Same here did you find any fix?

tentamens avatar Aug 29 '24 21:08 tentamens

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

JWAutumn avatar Sep 26 '24 18:09 JWAutumn

Same for me....

abellee avatar Nov 13 '24 17:11 abellee

Hi @gautam8404,

Could you please check if the sound path is available or not during recording? Additionally, try using a static path to verify if your code behaves as expected.

Additionally, please check what is the audio file extension.

If this issue persists please provide your flutter version or flutter doctor output.

jay-simformsolutions avatar Nov 22 '24 05:11 jay-simformsolutions

@gautam8404, Currently we are closing this issue as we don't have sufficient information. Feel free to open this issue or a new one.

jay-simformsolutions avatar Dec 04 '24 13:12 jay-simformsolutions

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

Yes it's a problem of path

final dir = await getTemporaryDirectory(); audioPath = "${dir.path}/$getTimestamp().m4a";

ibrahimkelly avatar Aug 03 '25 13:08 ibrahimkelly