Невозможно управлять громкостью AVAudioPlayer через аппаратные кнопки, когда AudioSessionActive НЕТ
Я создаю пошаговое навигационное приложение, которое воспроизводит периодические короткие клипы. Звук должен воспроизводиться независимо от того, заблокирован ли экран, должен смешиваться с другой воспроизводимой музыкой и должен вызывать утечку музыки при воспроизведении этого звука.
Apple подробно обсуждает вариант использования по очереди в видео "Сессия WWDC 412 Audio Development для iPhone OS часть 1" в минуту 29:20. Реализация работает отлично, но есть одна проблема - когда приложение работает, нажатие на аппаратные регуляторы громкости регулирует громкость звонка, а не громкость приложения. Если вы хотите изменить громкость приложения, вы должны нажимать кнопки громкости во время воспроизведения подсказки.
Apple очень четко описывает видео, что нельзя оставлять AVAudioSession активным, но если AVAudioSession неактивен, кнопки громкости не будут контролировать громкость моего приложения.
Вот код, который я использую для настройки:
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
propertySetError = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
UInt32 allowMixing = true;
propertySetError = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(allowMixing), &allowMixing);
UInt32 shouldDuck = true;
propertySetError = AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, sizeof(shouldDuck), &shouldDuck);
OSStatus activationResult = AudioSessionSetActive(true);
NSError* err = nil;
_player = [[AVAudioPlayer alloc] initWithData:audioData error:&err];
_player.delegate = self;
[_player play];
И в конце я установил активную сессию NO, как Apple рекомендует:
OSStatus activationResult = AudioSessionSetActive(false);
NSAssert(activationResult == kAudioSessionNoError, @"Error deactivating audio session");
Я что-то упускаю, или я должен идти против того, что они рекомендовали в видео?
1 ответ
В вашем случае вы не хотите отключать аудио сеанс. Что вам нужно сделать, это использовать два метода: один для настройки сеанса для воспроизведения звука, а другой для настройки его для бездействия. Первый метод устанавливает режим аудио mix+duck, а второй использует режим, дружественный к фоновому аудио, например, ambient.
Что-то вроде этого:
- (void)setActive {
UInt32 mix = 1;
UInt32 duck = 1;
NSError* errRet;
AVAudioSession* session = [AVAudioSession sharedInstance];
[session setActive:NO error:&errRet];
[session setCategory:AVAudioSessionCategoryPlayback error:&errRet];
NSAssert(errRet == nil, @"setCategory!");
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(mix), &mix);
AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, sizeof(duck), &duck);
[session setActive:YES error:&errRet];
}
- (void)setIdle {
NSError* errRet;
AVAudioSession* session = [AVAudioSession sharedInstance];
[session setActive:NO error:&errRet];
[session setCategory:AVAudioSessionCategoryAmbient error:&errRet];
NSAssert(errRet == nil, @"setCategory!");
[session setActive:YES error:&errRet];
}
Тогда назвать это:
[self setActive];
[self _playAudio:nil];
Чтобы очистить после игры:
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer*)player
successfully:(BOOL)flag {
[self setIdle];
}
Чтобы быть хорошим гражданином, ваше приложение должно отключить аудио сеанс, когда он не перемещается (то есть выполняет свою основную функцию), но когда это так, нет ничего плохого в том, чтобы поддерживать аудио сеанс активным и использовать режимы для мирно сосуществовать с другими приложениями. Вы можете дублировать функциональность приложения Apple, используя приведенный выше код.