Search code examples
iosxamarinxamarin.iosavaudiosession

AVAudioSession App Volume Independent of System Volume


I'm writing an iOS app (using Xamarin) and it's a workout app. Pretty simple really. You start up iTunes, play some music in the background and this app has periodic voice prompts during different parts of the workout. It's a basic HIIT/Tabata timer.

I'm using AVAudioSession to duck the background audio when the voice prompts and it works as expected. But, I want the user to be able to set the volume level for the voice prompts via settings. I thought it would be as simple as setting the volume level on the AVAudioSession but soon found that it's read-only.

I don't want to change the system volume. I only want to set the volume of my app's audio, independent of the system volume level. This is possible. I know this because I have an app in front of me that does this very thing. My only problem is, I don't know how to set the volume for the audio in my app within my AVAudioSession.

So, does anyone know how to set the volume level for audio emitted by an app independently of the system volume level?

Below is the code I use to wrap my calls to activate and deactivate the AVAudioSession:

private void ActivateAudioSession()
{
    var session = AVAudioSession.SharedInstance();
    session.SetCategory(AVAudioSessionCategory.Playback, AVAudioSessionCategoryOptions.DuckOthers);
    session.SetActive(true);
}

private void DeactivateAudioSession()
{
    new System.Threading.Thread(new System.Threading.ThreadStart(() =>
    {
        var session = AVAudioSession.SharedInstance();
        session.SetActive(false);
    })).Start();
}

Solution

  • AVAudioSession as you said has a read only volume property but with:

    AudioPlayer you can set the volume from 0.0 silent to 1.0 max https://developer.xamarin.com/api/property/AVFoundation.AVAudioPlayer.Volume/ like so:

            string path = NSBundle.PathForResourceAbsolute ("audiofile", "mp3", NSBundle.MainBundle.ResourcePath);
            var url = NSUrl.FromFilename (path);
            var audioPlayer = AVAudioPlayer.FromUrl (url);
            audioPlayer.Volume = 0.5f;
            audioPlayer.Play ();
    

    Or you could use MPMusicPlayerController but I think it can only play music https://developer.xamarin.com/api/property/MonoTouch.MediaPlayer.MPMusicPlayerController.Volume/