audioplayers icon indicating copy to clipboard operation
audioplayers copied to clipboard

[1.0.1] iOS volume very low (sound is coming from earpiece)

Open lijinshanmx opened this issue 2 years ago • 14 comments

Android device is ok, but volume is very low on ios (xsmax os version: 15.5). I see some same issue, but close with 1.0.0-rc4 fix. now i am use 1.0.1.

lijinshanmx avatar Jun 25 '22 15:06 lijinshanmx

It's not the volume. I figured out that it's not playing out of the speaker properly like it's supposed to. Instead it's playing out of the earpiece. I tried setting the audio context like this

AudioContextAndroid androidContext = AudioContextAndroid( isSpeakerphoneOn: true, stayAwake: true, contentType: AndroidContentType.music, usageType: AndroidUsageType.media, audioFocus: AndroidAudioFocus.gain); AudioContextIOS iosContext = AudioContextIOS( category: AVAudioSessionCategory.ambient, defaultToSpeaker: true, options: [ AVAudioSessionOptions.defaultToSpeaker, AVAudioSessionOptions.allowBluetooth, AVAudioSessionOptions.allowBluetoothA2DP ] ); player.play(UrlSource(_currentSong!.downloadUrl),volume: 1.0,ctx: AudioContext(android: androidContext, iOS: iosContext),mode: PlayerMode.lowLatency);

But it did not work on iOS. Still playing out of the earpiece. Be careful bringing up the volume too much to compensate out of the earpiece and get a "speakerphone" effect as you may be overdriving the earpiece speaker. Any ideers?

AldanisVigo avatar Jun 25 '22 18:06 AldanisVigo

Yes, you're right,it's really not playing out of the speaker。I turned the volume all the way up and the sound is still very low on ios。

lijinshanmx avatar Jun 26 '22 12:06 lijinshanmx

Hi , here same bug. The sound play into Ear speaker and won’t play in Bluetooth airpods and sound very low.

poupouneroot avatar Jun 26 '22 22:06 poupouneroot

same issue on iOS 15.4.1.

sakatech-jp avatar Jun 27 '22 13:06 sakatech-jp

I ran into the same issue. This is what I did to solve. I created AudioContext for iOS with defaultToSpeaker: false and set it in AudioPlayer.global.setGlobalAudioContext(_getAudioContext()). That solved my audio super quiet issue on my iPhone Xs Max.

DSoe avatar Jun 27 '22 17:06 DSoe

I ran into the same issue. This is what I did to solve. I created AudioContext for iOS with defaultToSpeaker: false and set it in AudioPlayer.global.setGlobalAudioContext(_getAudioContext()). That solved my audio super quiet issue on my iPhone Xs Max.

I switched to just_audio already but this looks like the correct solution here.

AldanisVigo avatar Jun 27 '22 20:06 AldanisVigo

@DSoe it's unclear how defaultToSpeaker: false could help. Can you please add a code of _getAudioContext()?

@AldanisVigo can you please paste the working example of using just_audio? I found it even less friendly, and it plays from earpiece too.

agordeev avatar Jul 01 '22 07:07 agordeev

Ok, so this code worked for me:


      final AudioContext audioContext = AudioContext(
        iOS: AudioContextIOS(
          defaultToSpeaker: true,
          category: AVAudioSessionCategory.ambient,
          options: [
            AVAudioSessionOptions.defaultToSpeaker,
            AVAudioSessionOptions.mixWithOthers,
          ],
        ),
        android: AudioContextAndroid(
          isSpeakerphoneOn: true,
          stayAwake: true,
          contentType: AndroidContentType.sonification,
          usageType: AndroidUsageType.assistanceSonification,
          audioFocus: AndroidAudioFocus.none,
        ),
      );
      AudioPlayer.global.setGlobalAudioContext(audioContext);

agordeev avatar Jul 01 '22 07:07 agordeev

@DSoe it's unclear how defaultToSpeaker: false could help. Can you please add a code of _getAudioContext()?

@AldanisVigo can you please paste the working example of using just_audio? I found it even less friendly, and it plays from earpiece too.

import 'package:just_audio/just_audio.dart' show AudioPlayer, AudioSource;

Everything else is pretty much the same except for there's no Completion listener, but there is still a duration and position listener so whenerver position == duration it's the same thing as the completion listener if you need it. Hope that helps.

AldanisVigo avatar Jul 01 '22 10:07 AldanisVigo

@DSoe it's unclear how defaultToSpeaker: false could help. Can you please add a code of _getAudioContext()?

@AldanisVigo can you please paste the working example of using just_audio? I found it even less friendly, and it plays from earpiece too.

This is what_getAudioContext() has.

AudioContext _getAudioContext() {
    return AudioContext(
        android: AudioContextAndroid(
          isSpeakerphoneOn: false,
          stayAwake: true,
          contentType: AndroidContentType.music,
          usageType: AndroidUsageType.media,
          audioFocus: AndroidAudioFocus.gain,
        ),
        iOS: AudioContextIOS(
          defaultToSpeaker: false,
          category: AVAudioSessionCategory.playback,
          options: [AVAudioSessionOptions.mixWithOthers]
              + [AVAudioSessionOptions.allowAirPlay]
          + [AVAudioSessionOptions.allowBluetooth]
          + [AVAudioSessionOptions.allowBluetoothA2DP]
        )
    );
  }

Since setting defaultToSpeaker: true works for you, I am thinking setting globalAudioContext somehow fixes the audio volume too low issue on iOS. I am not sure though.

DSoe avatar Jul 05 '22 17:07 DSoe

I just had the same issue in a Flame Game (using FlameAudio) where on my iPhone I couldn't hear anything but it was working fine on my iPad. I was going crazy trying to figure this out. Thought maybe something was wrong with my phone. Tried it on my wife's phone same issue. Ended up needed to add the same info above and now both iPhone and iPad have volume. I tried both AVAudioSessionCategory.ambient and AVAudioSessionCategory.playback and either worked. Pretty sure like others have said the key is AVAudioSessionOptions.defaultToSpeaker

    if (!kIsWeb) {
      final AudioContext audioContext = AudioContext(
        iOS: AudioContextIOS(
          defaultToSpeaker: true,
          category: AVAudioSessionCategory.ambient,
          options: [
            AVAudioSessionOptions.defaultToSpeaker,
            AVAudioSessionOptions.mixWithOthers,
          ],
        ),
        android: AudioContextAndroid(
          isSpeakerphoneOn: true,
          stayAwake: true,
          contentType: AndroidContentType.sonification,
          usageType: AndroidUsageType.assistanceSonification,
          audioFocus: AndroidAudioFocus.none,
        ),
      );
          // NEEDED THIS audioContext or iPhone volume didn't work only BGM I could hardly hear
      AudioPlayer.global.setGlobalAudioContext(audioContext);
    }

TSurridge avatar Jul 24 '22 01:07 TSurridge

this code worked for me 😊

hgjinfan avatar Jul 24 '22 01:07 hgjinfan

I just had the same issue in a Flame Game (using FlameAudio) where on my iPhone I couldn't hear anything but it was working fine on my iPad. I was going crazy trying to figure this out. Thought maybe something was wrong with my phone. Tried it on my wife's phone same issue. Ended up needed to add the same info above and now both iPhone and iPad have volume. I tried both AVAudioSessionCategory.ambient and AVAudioSessionCategory.playback and either worked. Pretty sure like others have said the key is AVAudioSessionOptions.defaultToSpeaker

    if (!kIsWeb) {
      final AudioContext audioContext = AudioContext(
        iOS: AudioContextIOS(
          defaultToSpeaker: true,
          category: AVAudioSessionCategory.ambient,
          options: [
            AVAudioSessionOptions.defaultToSpeaker,
            AVAudioSessionOptions.mixWithOthers,
          ],
        ),
        android: AudioContextAndroid(
          isSpeakerphoneOn: true,
          stayAwake: true,
          contentType: AndroidContentType.sonification,
          usageType: AndroidUsageType.assistanceSonification,
          audioFocus: AndroidAudioFocus.none,
        ),
      );
          // NEEDED THIS audioContext or iPhone volume didn't work only BGM I could hardly hear
      AudioPlayer.global.setGlobalAudioContext(audioContext);
    }

Not working on all devices how to fix?

hatemragab avatar Aug 23 '22 14:08 hatemragab

If anyone wants to put up a PR for this it would be greatly appreciated (I don't have any Apple devices to properly test this with).

spydon avatar Sep 12 '22 07:09 spydon

Hi! I would be interested looking into fixing this issue :)

tozu avatar Oct 03 '22 14:10 tozu

Hi @tozu, you're welcome. Just start a Merge Request, if you feeling ready :)

Gustl22 avatar Oct 06 '22 08:10 Gustl22

Ok, so this code worked for me:

      final AudioContext audioContext = AudioContext(
        iOS: AudioContextIOS(
          defaultToSpeaker: true,
          category: AVAudioSessionCategory.ambient,
          options: [
            AVAudioSessionOptions.defaultToSpeaker,
            AVAudioSessionOptions.mixWithOthers,
          ],
        ),
        android: AudioContextAndroid(
          isSpeakerphoneOn: true,
          stayAwake: true,
          contentType: AndroidContentType.sonification,
          usageType: AndroidUsageType.assistanceSonification,
          audioFocus: AndroidAudioFocus.none,
        ),
      );
      AudioPlayer.global.setGlobalAudioContext(audioContext);

    final AudioContext audioContext = AudioContext(
      iOS: AudioContextIOS(
        defaultToSpeaker: true,
        category: AVAudioSessionCategory.ambient,
        options: [
          AVAudioSessionOptions.defaultToSpeaker,
          AVAudioSessionOptions.mixWithOthers,
        ],
      ),
      android: AudioContextAndroid(
        isSpeakerphoneOn: true,
        stayAwake: true,
        contentType: AndroidContentType.music,  // i change this
        usageType: AndroidUsageType.media,  // i change this
        audioFocus: AndroidAudioFocus.gain,  // i change this
      ),
    );
    AudioPlayer.global.setGlobalAudioContext(audioContext);

i change some android config, and work

yoer avatar Oct 08 '22 03:10 yoer

@agordeev thanks this save my day

adnanatif avatar Oct 20 '22 13:10 adnanatif

Worked for me with this config only on iOS:

iOS: AudioContextIOS(
  defaultToSpeaker: true,
  category: AVAudioSessionCategory.playAndRecord,
  options: [
    AVAudioSessionOptions.defaultToSpeaker,
    AVAudioSessionOptions.mixWithOthers,
  ],
)

iksent avatar Nov 10 '22 22:11 iksent

android has same issue

OHeroJ avatar Nov 16 '22 00:11 OHeroJ

android has same issue

As far as I know, Android does not have this issue, the sound is coming from the speaker and not from the earpiece by default on android.

spydon avatar Nov 16 '22 03:11 spydon

Set the phone volume to 0, still can play out the sound; set the phone volume to the maximum, but the sound played out is still the original size。Unable to adjust the volume level of playback

OHeroJ avatar Nov 17 '22 12:11 OHeroJ

Found this in the SwiftAudioplayersDarwinPlugin class definition. Hope this resolves any mystery around "why setAudioContext doesn't work but setGlobalAudioContext does".

I think it will be useful to update the documentation accordingly. Or let the Flutter wrapper also mention this in logs.

image

Consequently, a fix (if someone would like to work on it; I would have loved to but time doesn't permit :( ) for iOS could be to roll-over regular AudioContext to GlobalAudioContext, since it has been established that iOS does not allow player-specific audio contexts.

utkarsh1097 avatar Nov 27 '22 02:11 utkarsh1097

Good catch @utkarsh1097!

spydon avatar Nov 28 '22 16:11 spydon

Ok, so this code worked for me:

      final AudioContext audioContext = AudioContext(
        iOS: AudioContextIOS(
          defaultToSpeaker: true,
          category: AVAudioSessionCategory.ambient,
          options: [
            AVAudioSessionOptions.defaultToSpeaker,
            AVAudioSessionOptions.mixWithOthers,
          ],
        ),
        android: AudioContextAndroid(
          isSpeakerphoneOn: true,
          stayAwake: true,
          contentType: AndroidContentType.sonification,
          usageType: AndroidUsageType.assistanceSonification,
          audioFocus: AndroidAudioFocus.none,
        ),
      );
      AudioPlayer.global.setGlobalAudioContext(audioContext);

That works for me!

The only change for iOS is 'category: AVAudioSessionCategory.playAndRecord' instead of 'category: AVAudioSessionCategory.ambient'

wjeanvilma avatar Nov 30 '22 03:11 wjeanvilma

sorry, thank you for the answer, but I want to know Why before worked without that setting , I mean before I don't needed set all that is it for iOS update?

      final AudioContext audioContext = AudioContext(
        iOS: AudioContextIOS(
          defaultToSpeaker: true,
          category: AVAudioSessionCategory.ambient,
          options: [
            AVAudioSessionOptions.defaultToSpeaker,
            AVAudioSessionOptions.mixWithOthers,
          ],
        ),
        android: AudioContextAndroid(
          isSpeakerphoneOn: true,
          stayAwake: true,
          contentType: AndroidContentType.sonification,
          usageType: AndroidUsageType.assistanceSonification,
          audioFocus: AndroidAudioFocus.none,
        ),
      );
      AudioPlayer.global.setGlobalAudioContext(audioContext);

victormanuelfrancodev avatar Dec 01 '22 08:12 victormanuelfrancodev

sorry, thank you for the answer, but I want to know Why before worked without that setting , I mean before I don't needed set all that is it for iOS update?

Previously you probably used an earlier version of AudioPlayers where this bug doesn't exist. It shouldn't be that hard to fix within AudioPlayers, and we are very open to PRs for it. It should be a pretty easy fix, but we don't have any iOS devices to test with.

spydon avatar Dec 01 '22 09:12 spydon

Can you tell us what version was this bug introduced in, incase we want to revert back to a version where this didn't exist?

sameergoyal avatar Dec 07 '22 13:12 sameergoyal

@sameergoyal I think it was introduced in v1.0.0

spydon avatar Dec 07 '22 13:12 spydon

Sounds like this is a default configuration issue?

lukepighetti avatar Dec 18 '22 19:12 lukepighetti