Canardoux / flutter_sound

Flutter plugin for sound. Audio recorder and player.
Mozilla Public License 2.0
877 stars 573 forks source link

[HELP]: Unable to use bluetooth devices for playback or recording Flutter Sound 9.1.2 #852

Closed RishiKar closed 2 years ago

RishiKar commented 2 years ago

Hi,

Thank you for your package and extensive support. Since using the new Flutter Sound 9.1.2 package, I am not able to specify anyway to record or playback using bluetooth connected devices for recording or playback.

My code is working correctly. The only issue is I can not get it to detect bluetooth headphones as a source of input or output.

Research I went through old issues and there it was mentioned that one can mention device as a property in the openAudioSession method. But with the new API, there is only openPlayer method available.

Any help would be really appreciated as I have got every thing else set up. Thank you!

Tested On Iphone 12, iOS 15.3.1

RishiKar commented 2 years ago

I tried changing the AudioSource value but I still could not get it to use the microphone of AirPods. final theSource = AudioSource.bluetoothHFP;

Also, I used audio_session 0.1.6+1 package as shown in the example. Using different version of configurations could still not get it to use the microphone or speakers of AirPods.

AudioSessionConfiguration( avAudioSessionCategory: AVAudioSessionCategory.record, avAudioSessionCategoryOptions: AVAudioSessionCategoryOptions.allowBluetooth, avAudioSessionMode: AVAudioSessionMode.spokenAudio, avAudioSessionRouteSharingPolicy: AVAudioSessionRouteSharingPolicy.defaultPolicy, avAudioSessionSetActiveOptions: AVAudioSessionSetActiveOptions.none, )

If I could just know that bluetooth headphones are not supported or if I could know a way to overwrite session configuration, I ll be very grateful. Thank you very much @Larpoux

RishiKar commented 2 years ago

Leaving this here in case it helps someone. Since I was developing exclusively for iOS, I did not bother putting in android permissions. Once I put in the permissions for android, it did work! I really don't understand how.

However, there is a problem with switching between device microphone and bluetooth microphone. There is a need to force disconnect and reconnect. If @Larpoux thinks this is a known or unsupported issue, I ll close this.

Larpoux commented 2 years ago

Bluetooth are bit flags in the audio session. In Flutter Sound 8.x, we tried to manage the audio sessions ourself. This was convenient most of the time. But we had compatibility problems when the App wanted to use at the same time another library like JustAudio because on ios there is only one session per app. The only good way to fix those compatibility issues was to remove from Flutter Sound everything related to Audio Sessions. Now, the App must use a flutter plugin like audio_session that federate this when it wants to manage its sessions.

RishiKar commented 2 years ago

@Larpoux thank you for elaborating. As mentioned in my earlier ticket, I could not get (audio_session) to manage it. I will try again and close the ticket with suggestions for others if it works out. As an update, on pushing the build and testing after, unfortunately its not working with bluetooth. It works perfectly with the device speaker and mic.

Zrzzzz commented 2 years ago

Leaving this here in case it helps someone. Since I was developing exclusively for iOS, I did not bother putting in android permissions. Once I put in the permissions for android, it did work! I really don't understand how.

However, there is a problem with switching between device microphone and bluetooth microphone. There is a need to force disconnect and reconnect. If @Larpoux thinks this is a known or unsupported issue, I ll close this.

Hey, I wonder what your code is before starting recorder, I came across the same bug.

RishiKar commented 2 years ago

Thank you @Larpoux I made one small tweak after reading the documentation of audio_session package.

The tweak is to open audio session to manage sessions after opening flutter_sound recorder or player. Once this was done, I was able to manage the audio session and use bluetooth mic and earphones for recording and playback.

@Zrzzzz Please try the approach mentioned above. On Android I am still running into issues but I guess some of these are device specific. I am trying to use an AirPods Pro device with OnePlus 5T running Android version 10, Oxygen OS 10.0.1 I will close this issue now.

Larpoux commented 2 years ago

Thank you @RishiKar to share your experience with us. 👍

ericadu commented 2 years ago

@RishiKar Would you mind sharing a code snippet? I think I'm running into similar issues, though I use Bluetooth to play, but not record. I have been managing the audio session after opening the sound recorder and player as you mentioned, but it doesn't seem to make a difference.

I'm recording PCM16 to a stream, if that makes a difference.

When I print to console, it looks like there is no FoodData being written to the stream when I try to record with Bluetooth. Everything works perfectly with speaker.

#### Open recorder, then manage audio session
      _mRecorder!.openRecorder().then((value) {
        if (mounted)
          setState(() {
            _mRecorderIsInited = true;
          });
        _initAudio();
      });

#### initAudio method
Future<void> _initAudio() async {
    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,
    ));
}
RishiKar commented 2 years ago

@ericadu your code looks pretty similar to mine and since it works with the speaker , it is doing its intended job.

However, from my experience, switching input modes after initialisation of audio session creates issues. To elaborate a bit more: you start a session and in the same session, switch from phone mic to bluetooth headphones (or vice versa), then it does not record. I have also had my app crash when connected to bluetooth speaker with no mic input. One suggestion: Could you try testing by first connecting with bluetooth, then opening up the session and check if it works?

Sorry I don't have anything concrete to suggest in terms of code changes. Or maybe I am missing something in your workflow.

ericadu commented 2 years ago

We figured it out here: https://github.com/Canardoux/flutter_sound/issues/885 -- ended up being device specific and how it affected the way flutter_sound was looking at buffer statuses. Thank you for the thoughtful response @RishiKar, and apologies for the delay in update!