AVAudioSession's OutputVolume never changes

2019-01-28 01:45发布

问题:

There are plenty of questions and answers on SO that say [AVAudioSession sharedInstance].outputVolume is the only way to detect a device's volume. But it doesn't seem to work quite right. outputVolume never changes, though it is correct when it is first set (at application launch).

Am I doing it wrong? I don't know what else to do besides reading the value of outputVolume. My instincts would tell me this was a bug, if it wasn't for the fact that other people seem to be doing it just fine. I also tested it on iOS 7 and 8, so it's not an iOS 8 bug. I reproduced the same thing in a small test project, so nothing in my project is interfering with it.

Also: I am well aware of the difference between ringer-volume and sound-volume. I changed both, and the reported volume still did not change.

Here's the function I used in my test project:

- (void)checkVolume
{
    float volume = [AVAudioSession sharedInstance].outputVolume;

    NSLog(@"Volume: %f", volume);

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
    {
        [self checkVolume];
    });
}

回答1:

Use KVO, and make sure to activate the sharedInstance:

[[AVAudioSession sharedInstance] setActive:YES error:nil];
[[AVAudioSession sharedInstance] addObserver:self forKeyPath:@"outputVolume" options:NSKeyValueObservingOptionNew context:nil];


回答2:

I checked in iOS 12:

[[AVAudioSession sharedInstance] setActive:YES error:nil];
float vol = [[AVAudioSession sharedInstance] outputVolume];
NSLog(@"outputVolume: %f", vol);


回答3:

I am finding I need to actually output sound in order for [AVAudioSession sharedInstance].outputVolume to be accurate.

In other words - [AVAudioSession sharedInstance].outputVolume is a little flakey - you need to play audio for it to return the correct volume.