question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItΒ collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[BUG]: Recording does not work when using non-Airpod Pro Bluetooth Headphones with iOS 15.4.x device

See original GitHub issue

Flutter Sound Version :

  • FULL or LITE flavor ? Full

  • Important: Result of the command : flutter pub deps | grep flutter_sound |-- flutter_sound 9.2.9 | |-- flutter_sound_platform_interface 9.2.9 | |-- flutter_sound_web 9.2.9 | | |-- flutter_sound_platform_interface…


Severity

  • Crash ?

  • Result is not what expected ? X

  • Cannot build my App ?

  • Minor issue ?


Platforms you faced the error

  • iOS ? XX

  • Android ?

  • Flutter Web ?

  • Emulator ?

  • Real device ?


Describe the bug A clear and concise description of what the bug is.

Recording to stream does not capture any audio when using bluetooth audio devices that are not Airpod Pros. Tested using real iOS devices 15.4.x.

Tested using the following bluetooth headphones:

  • Airpod Pros: Records perfectly
  • Airpod Gen 1: Does not record
  • Airpod Gen 2: Does not record
  • Logitech bluetooth headphones: Does not record

To Reproduce Steps to reproduce the behavior:

  1. Pair bluetooth headphones (that are not Airpod Pros) to iOS device
  2. Try recording to stream

Observation: No FoodData is being captured.

Error Domain=NSCocoaErrorDomain Code=3840 "Unable to parse empty data." UserInfo={NSDebugDescription=Unable to parse empty data.}

Logs!!!

(This is very important. Most of the time we cannot do anything if we do not have information on your bug). To activate the logs, you must instantiate your modules with the Log Level set to Level.debug :

FlutterSoundPlayer myPlayer = FlutterSoundPlayer(logLevel: Level.debug);
FlutterSoundRecorder myRecorder = FlutterSoundRecorder(logLevel: Level.debug);

See this

Some potentially helpful code snippets.

I created a helper service to manage audio sessions and to print out the current routes. initSession gets called in my initState component of my recorder widget

import 'package:audio_session/audio_session.dart';

class AudioSessionService {
  Future<void> initSession() async {
    final session = await AudioSession.instance;
    await session.configure(AudioSessionConfiguration(
      avAudioSessionCategory: AVAudioSessionCategory.playAndRecord,
      avAudioSessionCategoryOptions:
          AVAudioSessionCategoryOptions.allowBluetooth |
              AVAudioSessionCategoryOptions.allowBluetoothA2dp |
              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,
    ));
    print('setup');
    AVAudioSession().availableInputs.then((res) {
      res.forEach((element) {
        print(element.portName);
        print(element.portType);
        print(element.channels);
        print(element.dataSources);
        print(element.selectedDataSource);
        if (element.selectedDataSource != null) {
          print(element.selectedDataSource!.name);
        }
      });
    });

    AVAudioSession().currentRoute.then((res) {
      res.inputs.forEach((element) async {
        print('inputs');
        print(element.portName);
        print(element.portType);
      });
      res.outputs.forEach((element) {
        print('outputs');
        print(element.portName);
        print(element.portType);
      });
    });
  }
}

Recorder Widget


// ** Full code redacted for clarity, only including relevant parts
  @override
  void initState() {
    recordingDataController.stream.listen((FoodData data) {
      print("DATA");
    });
    _initAudio();
    super.initState();
  }

  void _initAudio() async {
    if (_mRecorder != null) {
      await _mRecorder!.openRecorder();
      await getIt<AudioSessionService>().initSession();
      if (mounted) {
        setState(() {
          _mRecorderIsInited = true;
        });
      }
    }
  }

  Future<void> _record() async {
    print('recording');
    AVAudioSession().currentRoute.then((res) {
      res.inputs.forEach((element) async {
        print('inputs');
        print(element.portName);
        print(element.portType);
      });
      res.outputs.forEach((element) {
        print('outputs');
        print(element.portName);
        print(element.portType);
      });
    });
}

LOGS OUTPUT

flutter: setup
flutter: PLAYING
flutter: iPhone Microphone
flutter: AVAudioSessionPort.builtInMic
flutter: []
flutter: [Instance of 'AVAudioSessionDataSourceDescription', Instance of 'AVAudioSessionDataSourceDescription', Instance of 'AVAudioSessionDataSourceDescription']
flutter: Instance of 'AVAudioSessionDataSourceDescription'
flutter: Front
flutter: Airpods ED
flutter: AVAudioSessionPort.bluetoothHfp
flutter: []
flutter: []
flutter: null
flutter: inputs
flutter: iPhone Microphone
flutter: AVAudioSessionPort.builtInMic
flutter: outputs
flutter: Airpods ED
flutter: AVAudioSessionPort.bluetoothA2dp
flutter: recording
flutter: β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
flutter: β”‚ #0   FlutterSoundRecorder.startRecorder (package:flutter_sound/public/flutter_sound_recorder.dart:590:13)
flutter: β”‚ #1   _RecordButtonBarRealtimeState._record (package:app/screens/chat_detail/record/record_button_realtime.dart:293:12)
flutter: β”œβ”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„
flutter: β”‚ πŸ› FS:---> startRecorder
flutter: └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
flutter: β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
flutter: β”‚ #0   FlutterSoundRecorder._startRecorder (package:flutter_sound/public/flutter_sound_recorder.dart:614:13)
flutter: β”‚ #1   FlutterSoundRecorder.startRecorder.<anonymous closure> (package:flutter_sound/public/flutter_sound_recorder.dart:592:13)
flutter: β”œβ”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„
flutter: β”‚ πŸ› FS:---> _startRecorder.
flutter: └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
flutter: inputs
flutter: Airpods ED
flutter: AVAudioSessionPort.bluetoothHfp
flutter: outputs
flutter: Airpods ED
flutter: AVAudioSessionPort.bluetoothHfp
flutter: β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
flutter: β”‚ #0   FlutterSoundRecorder.startRecorderCompleted (package:flutter_sound/public/flutter_sound_recorder.dart:234:13)
flutter: β”‚ #1   MethodChannelFlutterSoundRecorder.channelMethodCallHandler (package:flutter_sound_platform_interface/method_channel_flutter_sound_recorder.dart:74:22)
flutter: β”œβ”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„
flutter: β”‚ πŸ› ---> startRecorderCompleted: true
flutter: └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
flutter: β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
flutter: β”‚ #0   FlutterSoundRecorder.startRecorderCompleted (package:flutter_sound/public/flutter_sound_recorder.dart:243:13)
flutter: β”‚ #1   MethodChannelFlutterSoundRecorder.channelMethodCallHandler (package:flutter_sound_platform_interface/method_channel_flutter_sound_recorder.dart:74:22)
flutter: β”œβ”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„
flutter: β”‚ πŸ› <--- startRecorderCompleted: true
flutter: └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
flutter: β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
flutter: β”‚ #0   FlutterSoundRecorder._startRecorder (package:flutter_sound/public/flutter_sound_recorder.dart:689:13)
flutter: β”‚ #1   <asynchronous suspension>
flutter: β”œβ”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„
flutter: β”‚ πŸ› FS:<--- _startRecorder.
flutter: └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
flutter: β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
flutter: β”‚ #0   FlutterSoundRecorder.startRecorder (package:flutter_sound/public/flutter_sound_recorder.dart:602:13)
flutter: β”‚ #1   <asynchronous suspension>
flutter: β”œβ”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„
flutter: β”‚ πŸ› FS:<--- startRecorder
flutter: └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
[tcp] tcp_input [C206.1:3] flags=[R] seq=2968491827, ack=0, win=0 state=LAST_ACK rcv_nxt=2968491827, snd_una=1392928498
[tcp] tcp_input [C206.1:3] flags=[R] seq=2968491827, ack=0, win=0 state=CLOSED rcv_nxt=2968491827, snd_una=1392928498
[tcp] tcp_input [C206.1:3] flags=[R] seq=2968491827, ack=0, win=0 state=CLOSED rcv_nxt=2968491827, snd_una=1392928498
[tcp] tcp_input [C206.1:3] flags=[R] seq=2968491827, ack=0, win=0 state=CLOSED rcv_nxt=2968491827, snd_una=1392928498

and then my backend service throws an error because I’m sending it empty bytes.


Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:8

github_iconTop GitHub Comments

4reactions
fallenpanda1commented, May 4, 2022

Update on this issue (which I’m working with @ericadu on):

  1. Seems like this affects all 16Khz recording devices. I believe this generally means lower end mics, or bluetooth mics when poor signal quality is detected.
  2. Here’s a PR with a fix: https://github.com/Canardoux/flutter_sound_core/pull/5
2reactions
Larpouxcommented, May 5, 2022

@ericadu , @fallenpanda1

Allen : your Pull Request is now integrated inside Flutter Sound release 9.2.12 I am impressed that you was able to debug FlutterSoundCore without any help from me. If you had told me before, I would had help you to setup a development environment. Well done, Allen

Erica : can you try Flutter Sound release 9.2.12 and tell us if your issue is fixed ?

Read more comments on GitHub >

github_iconTop Results From Across the Web

If you can't connect a Bluetooth accessory to your iPhone or iPad
If your Bluetooth accessory won't pair or connect to your iOS or iPadOS device, learn what to do. Try these steps first. To...
Read more >
Sound is playing through the ear speaker if using "Force iOS ...
In the iOS device connect Bluetooth headphones 4. Deploy the app to the device 5. Open the app and listen. Expected result: Sound...
Read more >
AirPods Not Connecting to Your iPhone or iPad? Here's How ...
If your AirPods are not connecting to your iPhone, Mac, PC, or Android devices, here are the tested and proven solutions you can...
Read more >
Use Airpods + iPhone X as a Secret Listening ... - YouTube
Use Live Listen to spy on people WITHOUT Airpods !: https://youtu.be/3EDbdhi2DhMIf you have an iPhone X or any iPhone running iOS 12,Β ...
Read more >
Why can't I answer calls through a Bluetooth device after ...
After connecting a Bluetooth device to an iOS or Android device, you may encounter the following issues: Failure to answer calls through a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found