flutter_sound icon indicating copy to clipboard operation
flutter_sound copied to clipboard

[BUG]: Recorder to StreamFloat32 not emit event again after resume in background.

Open duongvanthai opened this issue 9 months ago • 11 comments

Flutter Sound Version :

├── flutter_sound 9.25.9 │ ├── flutter_sound_platform_interface 9.25.9 │ ├── flutter_sound_web 9.25.9 │ │ ├── flutter_sound_platform_interface...


Severity

  • Result is not what expected ? stream.listen not running again after pause and resume recorder when app in background.

Platforms you faced the error

  • iOS

Describe the bug I'm using flutter_sound to record audio to StreamFloat32 to handle data realtime. When app running in foreground. I can pause and resume recorder normal & get StreamController emit data. But if app running on background. When resume, StreamController is not emit event again. I try restart StreamController & start recorder again. But it's not working.

To Reproduce

FlutterSoundRecorder? _recorder = FlutterSoundRecorder();
StreamSubscription? _recordingDataSubscriptionF32;

@override
initState() {
     await _recorder?.openRecorder();
}

Future<void> startRecording() async {
var recordingDataControllerF32 = StreamController<List<Float32List>>();
_recordingDataSubscriptionF32 = recordingDataControllerF32.stream.listen((data) {
// handle data emit here
}
await _recorder?.startRecorder(
      codec: Codec.pcmFloat32,
      sampleRate: 44100,
      numChannels: 1,
      audioSource: AudioSource.defaultSource,
      bufferSize: 5000,
      toStreamFloat32: recordingDataControllerF32.sink,
    );
}

Future<void> pauseRecording() async {
      await _recorder?.stopRecorder();

      if (_recordingDataSubscriptionF32 != null) {
        await _recordingDataSubscriptionF32!.cancel();
        _recordingDataSubscriptionF32 = null;
      }
}

Future<void> resumeRecording() async {
      startRecording()
}

duongvanthai avatar Mar 24 '25 10:03 duongvanthai

Sorry for the bug. I’m going to look to it.

Larpoux avatar Mar 24 '25 10:03 Larpoux

How do you pause/resume in background state?

Larpoux avatar Mar 24 '25 10:03 Larpoux

I'm using audio_session package to detect if app have interrupt when recording

final session = await AudioSession.instance;
    await session.configure(const AudioSessionConfiguration(
        avAudioSessionCategory: AVAudioSessionCategory.playAndRecord));

    session.interruptionEventStream.listen((event) {
      if (event.begin) {
        // Handle audio interruption began (e.g., phone call)
        LoggerUtils.info('AudioSession: interruption began');
        pauseRecording();
      } else {
        // Handle audio interruption ended (e.g., phone call ended)
        LoggerUtils.info('AudioSession: interruption ended');
        resumeRecording();
      }
    });

duongvanthai avatar Mar 24 '25 10:03 duongvanthai

I don't reproduce your issue with the Demo example. When I have a phone call during recording, after the com finished, the recorder is in pause state, but pause/resume and stop/start work correctly.

Larpoux avatar Mar 24 '25 14:03 Larpoux

@duongvanthai : yes, you are right. There is a problem somewhere. I am going to work on that.

Larpoux avatar Mar 24 '25 15:03 Larpoux

@duongvanthai , my problem was something else (I didn't call audio_session correctly).

I did some test with the dev. sources (not exactly your configuration) but I haven't see any problem.

  • I startRecorder() to stream
  • I do a phone call during the recording
  • When the com. is finished, Flutter Sound is in pause state
  • I do pause()/resume()
  • The recorder works correctly.
  • I do a startPlayer() to check that everything before and after the phone call is correctly recorded

Have you any idea why it works for me but not for you ?

Larpoux avatar Mar 25 '25 13:03 Larpoux

If app running on foreground when incoming call, no problem. When you start record, go to home screen -> make a phone call. Problem will happen.

I try with flutter_sound example still have this issue.

I have a function

Future<void> configAudioSession() async {
    final session = await AudioSession.instance;
    await session.configure(const AudioSessionConfiguration(
        avAudioSessionCategory: AVAudioSessionCategory.playAndRecord));

    session.interruptionEventStream.listen((event) {
      if (event.begin) {
        // Handle audio interruption began (e.g., phone call)
        print('AudioSession: interruption began');
        stopRecorder();
      } else {
        // Handle audio interruption ended (e.g., phone call ended)
        print('AudioSession: interruption ended');
        record();
      }
    });
  }

@override
  void initState() {
    super.initState();
    setCodec(Codec.pcmFloat32);
    // Do not access your FlutterSoundPlayer or FlutterSoundRecorder before the completion of the Future
    _mPlayer!.openPlayer().then((value) {
      setState(() {
        _mPlayerIsInited = true;
      });
    });
    _openRecorder();
    configAudioSession();
  }
'''

'''
_mRecordingDataSubscription =
        recordingDataController.stream.listen((buffer) {
      print('recordingDataController.stream.listen');
      sink!.add(buffer);
    });
'''

After phone call end recordingDataController.stream.listen not emit event again, although startRecord log still success start again.

duongvanthai avatar Mar 26 '25 03:03 duongvanthai

Thanks. I am going to look to that

Larpoux avatar Mar 26 '25 03:03 Larpoux

@duongvanthai , I did a test with an outgoing call on taudio 10.2.0 and everything seems to work fine. But I have not included your call to session.interruptionEventStream.listen(). Perhaps your problem is caused by this call. Perhaps the issue is fixed in 10.2.0.

If you want to do a test with 10.2.0 it is very simple (just 5 minutes) : here is a guide to migrate to 10.2.0

Larpoux avatar Mar 26 '25 18:03 Larpoux

Tks @Larpoux, I also trying with taudio. Still have this issue. As I said, it only happen when you recording in background and have phone call, or user play youtube. FlutterSoundRecorder can resume normal after phone call end or user exit youtube. Recorder can comeback & emit event again in onProgress.listen. But can not emit event again on stream.

duongvanthai avatar Mar 27 '25 07:03 duongvanthai

@Larpoux on Android platform,you should move "recording" logic to a service,and running as a FOREGROUND_SERVICE.

ditingvh avatar Aug 11 '25 07:08 ditingvh