Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]: Unreliable volume control #733

Closed
tamoyal opened this issue Jul 23, 2021 · 22 comments
Closed

[BUG]: Unreliable volume control #733

tamoyal opened this issue Jul 23, 2021 · 22 comments

Comments

@tamoyal
Copy link

tamoyal commented Jul 23, 2021

Flutter Sound Version :

» flutter pub deps | grep flutter_sound
|-- flutter_sound 8.2.0
|   |-- flutter_sound_platform_interface 8.2.0
|   |-- flutter_sound_web 8.2.0
|   |   |-- flutter_sound_platform_interface...

Severity

Pretty high! The plugin is not usable if we can't control the volume.


Platforms you faced the error

  • iOS 14.6 / Real device

Describe the bug
There are several situations where the volume lowers and cannot be controlled via setVolume back to normal. One seems to be when we setVolume to a lower number, like setVolume(0.5). If I do that, then set the volume back to 1.0 (setVolume(1.0)), the sound does not change.

Another situation that more reliably messes with the volume is if I use the mic. I am using this speech to text plugin and when I activate the mic, all further sounds from this plugin will be very low (almost inaudible), even if I reset the volume to 1.0. When I reinstatiate the player (like if I do that every single time I play an audio file), the issue does not occur. It is also worth noting that I have used 3 flutter audio plugins prior to this and none of them had this issue so I think something funky is going on and it's probably not an issue with the speech to text plugin. And probably worth noting that after looking through the code of the speech to text plugin, I can't find any area of code that messes with the play volume.

In my particular case, I am playing a local file. Like this:

import 'dart:typed_data';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:flutter/services.dart' show rootBundle;

play() async {
    final player = FlutterSoundPlayer();
    await player.openAudioSession();
    await player.setVolume(1.0);
    final data = await _dataForAssetPath('assets/sounds/correct.mp3');
    await player.startPlayer(
        fromDataBuffer: data, whenFinished: () => {player.closeAudioSession()});
}

Future<Uint8List> _dataForAssetPath(String path) async {
    var asset = await rootBundle.load(path);
    return asset.buffer.asUint8List();
}
@Larpoux
Copy link
Collaborator

Larpoux commented Jul 23, 2021

@tamoyal ,

I already saw a Problem Report (a long time ago) from someone else, having a problem with the volume setting.
I am pretty sure that there is something wrong inside Flutter Sound, because nobody have fixed anything in this area.

I would like to investigate your PR better. Unfortunately I am actually very busy and I have no much time.
If someone else can look to this Problem Report it would be great 👍

@Larpoux
Copy link
Collaborator

Larpoux commented Jul 23, 2021

@tamoyal :

Can you specify :

  • Do you use iOS, Android or you have the problem on both. Or Web App ?
  • Do you playback :
    • From a file ?
    • From a buffer ?
    • From a stream ?
    • From a track ?
    • From the mic ?

@Larpoux
Copy link
Collaborator

Larpoux commented Jul 23, 2021

Note for FS developers :
Another PR waiting to be solved, is from someone wanting to specify the Volume (and the pitch, and the seekTo, and the speed) before starting the playback, and not during the playback.
Maybe this PR can be fixed, too.

@tamoyal
Copy link
Author

tamoyal commented Jul 23, 2021

@Larpoux Added details! I have only tested on iOS / real device

@Larpoux
Copy link
Collaborator

Larpoux commented Jul 23, 2021

OK. I put your PR on top of the TODO stack.
I am actually developing a simple example setting the Volume Control.
You can expect to get some news from me in a few days.

What are you playing back from ?

  • From a file ?
  • From a buffer ?
  • From a stream ?
  • From a track ?
  • From the mic ?

@tamoyal
Copy link
Author

tamoyal commented Jul 23, 2021

@Larpoux Thank you! A buffer (see this line in the example above await player.startPlayer( fromDataBuffer: data, whenFinished: () => {player.closeAudioSession()});)

@Larpoux
Copy link
Collaborator

Larpoux commented Jul 23, 2021

Sorry, I did not see that you posted your code.
It seems that you set the volume BEFORE starting your playback and not DURING the playback.
It could be the reason of the problems.
I will post you soon something

@tamoyal
Copy link
Author

tamoyal commented Jul 23, 2021

@Larpoux I've tried both but either way, isn't it a bit strange? Maybe if setting volume doesn't actually work until the player is playing it should throw an exception (like setting volume would throw an exception if the player audio session wasn't is not open)

@Larpoux
Copy link
Collaborator

Larpoux commented Jul 23, 2021

Yes. I agree

@Larpoux
Copy link
Collaborator

Larpoux commented Jul 23, 2021

@tamoyal ,

I found where was the problem. I will publish a new release in a few days (I want to fix a few others things in this release and check that everything OK on Android and Web).
Patience 🙄

@tamoyal
Copy link
Author

tamoyal commented Jul 23, 2021

Oh amazing, let me know if I can help test @Larpoux

@tamoyal
Copy link
Author

tamoyal commented Jul 24, 2021

@Larpoux I have a question that is sorta related to this issue. One thing I'm noticing is there seems to be a conflict between this library and the speech to text plugin I mentioned above, on iOS. When the conflict occurs, that is one instance of this volume issue. I'm curious to see if your fix will handle that. Regardless, that led me to dig in deeper and I see that audio sessions on iOS are handled via a shared instance like AVAudioSession.sharedInstance(). However with this plugin, there is the claim that we can have multiple player instances with unique player IDs. How is it we can multiple players if the audio session can conflict with each other? Maybe you handle all the management for the "players" created in this library but if some other library does some stuff with audio, you can't handle that because you don't have the instance ....I could see that....

@Larpoux
Copy link
Collaborator

Larpoux commented Jul 24, 2021

@tamoyal ,
I am not sure to understand perfectly your questions but I am trying to answer.

  1. For each startPlayer(fromURL) and each startPlayer(fromBuffer) an AVAudioPlayer is created.
    This AVAudioPlayer is destroyed when the playback is finished or when the App does a stopPlayer().

  2. The App can instantiate, several FlutterSoundPlayer. So it can open and start several playback simultaneously.
    Each FlutterSoundPlayer will create its own AVAudioPlayer. There is no problem to playback all those sources to the same sink (speaker, etc...)

  3. Each FlutterSoundPlayer will manage its own Volume. This must be verified (I have never done that).
    When the App does a setVolume(), FlutterSound set this volume on the matching AVAudioPlayer .
    If the AVAudioPlayer is not yet created (i.e. before startPlayer()), the Volume requested is kept, and will be set during the next startPlayer()

  4. Actually there is no direct possibility to playback one source to several sink. If the App wants to do that, it must
    create several FlutterSoundPlayer and feed them with the same data.
    But I am not really sure that it works correctly. I must do some tests.

  5. I did a mess with the audio session concept. The problem is that iOS can manage several audio sessions simultaneously, one for each App running, but does not allow an App to open several audio-sessions at the same time.
    I will clean the API soon, in this area. It is possible that this has impact on points 3. and 4.

I suggest to release today or tomorrow, the fix for the setVolume() PR that you filled and test 3. and 4. after this release.
Maybe you can help me doing some test. iOS sucks 😢 : this is really bad that an App cannot open several audio-sessions simultaneously.

@Larpoux
Copy link
Collaborator

Larpoux commented Jul 24, 2021

@tamoyal

Flutter Sound 8.2.2 is released.
Can you check that your problem on iOS with setVolume() is fixed ?

@Larpoux
Copy link
Collaborator

Larpoux commented Jul 24, 2021

Sorry, 8.2.2 is bad
😞
Please wait tomorrow. I will build a good 8.2.3

@tamoyal
Copy link
Author

tamoyal commented Jul 24, 2021

@Larpoux No problem, I will test whenever you are ready. Thank you!

@Larpoux
Copy link
Collaborator

Larpoux commented Jul 24, 2021

OK.
v8.2.5 is released and seems better.
You can try it if you want. I will check tomorrow that everything is correct this time.

I coded a simple example that starts two Flutter Sound Players.
There is no problem to set the volumes of the two players independently.

@Larpoux
Copy link
Collaborator

Larpoux commented Jul 24, 2021

@Larpoux
Copy link
Collaborator

Larpoux commented Jul 26, 2021

Fixed in v8.2.5. Please re-open this issue if you have still problems with setVolume()

@Larpoux Larpoux closed this as completed Jul 26, 2021
@quickratio
Copy link

quickratio commented Jul 6, 2022

Hello Larpoux,

Hope you've been well my friend. Sorry to drag this old issue open, but i am having the exact same issue as described above!

Volume is almost inaudible on iOS, works perfectly fine on android, i even tried reinitialising each time i play a sound, with no luck as per OPs workaround. I also use flutter sound recorder, not sure if that is causing the issue.

flutter_sound: ^9.2.13
Device: iOS physical iPhone 8, 10max and 12max all have the same problem (works on iOS emulator)

I tried testing your volume example (https://github.com/Canardoux/flutter_sound/blob/master/flutter_sound/example/lib/volume_control/volume_control.dart)

And it seems a little louder, but still not as loud as when i try another app, e.g. Youtube; I also noticed that it is mono, i.e. only uses the phone speaker, and not the speakers at the bottom of the phone.

void play(Uint8List fileBuffer) async {
    FlutterSoundPlayer player = FlutterSoundPlayer(logLevel: Level.error);
    await player.openPlayer();
    await player.setVolume(1.0);
    await player.startPlayer(
        fromDataBuffer: fileBuffer,
        codec: Codec.mp3,
        whenFinished: () {
          player.stopPlayer();
        }
    );
  }

@quickratio
Copy link

@Larpoux never mind, i think i may have resolved it the same way you helped me resolve the play and record issue last time with setting audioSession config ha. Will do some further testing.

@quickratio
Copy link

quickratio commented Jul 9, 2022

Should anyone encounter my issue, i suspect that iOS physical devices were ducking all audio, running this once solved the issue for me, note, i only call this function on iOS and not android, as it caused issues for me on android:

import 'package:audio_session/audio_session.dart';

...

  Future<void> setAudioConfig() async {
    final session = await AudioSession.instance;
    await session.configure(AudioSessionConfiguration(
      avAudioSessionCategory: AVAudioSessionCategory.playAndRecord,
      avAudioSessionCategoryOptions: AVAudioSessionCategoryOptions.defaultToSpeaker,
      avAudioSessionMode: AVAudioSessionMode.defaultMode,
      avAudioSessionRouteSharingPolicy: AVAudioSessionRouteSharingPolicy.defaultPolicy,
      avAudioSessionSetActiveOptions: AVAudioSessionSetActiveOptions.none,
      androidAudioAttributes: const AndroidAudioAttributes(
        contentType: AndroidAudioContentType.speech,
        flags: AndroidAudioFlags.none,
        usage: AndroidAudioUsage.voiceCommunication,
      ),
      androidAudioFocusGainType: AndroidAudioFocusGainType.gain,
      androidWillPauseWhenDucked: true,
    ));
  }

Specifically this config fixed the issue:

avAudioSessionCategoryOptions: AVAudioSessionCategoryOptions.defaultToSpeaker,

Original credit to @Larpoux ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants