gpt4 book ai didi

objective-c - 当 AudioSessionActive 为 NO 时,无法通过硬件按钮控制 AVAudioPlayer 的音量

转载 作者:搜寻专家 更新时间:2023-10-30 19:57:52 25 4
gpt4 key购买 nike

我正在构建一个逐步导航应用程序,它会播放周期性的短声音片段。无论屏幕是否锁定,声音都应该播放,应该与其他音乐播放混合,并且应该在播放此音频时让其他音乐闪避。

Apple 在“WWDC 2010 session 412 Audio Development for iPhone OS part 1”视频 29:20 中详细讨论了 turn-by-turn 用例。实现效果很好,但存在一个问题 - 当应用程序运行时,按下硬件音量控件会调整铃声音量,而不是应用程序音量。如果您想更改应用音量,您必须在播放提示时按音量按钮。

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];

最后我将 session 事件设置为 NO,正如 Apple 所建议的:

OSStatus activationResult = AudioSessionSetActive(false);
NSAssert(activationResult == kAudioSessionNoError, @"Error deactivating audio session");

我是否遗漏了什么,或者我是否必须违背他们在视频中推荐的内容?

最佳答案

在您的情况下,您不想将 Audio Session 设置为非事件状态。您需要做的是使用两种方法,一种将 session 设置为播放声音,另一种将其设置为空闲。第一种方法设置了 mix+duck 音频模式,第二种方法使用背景音频友好模式,如环境。

像这样:

- (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];

要成为一个好公民,您的应用应该在不导航(即执行其主要功能)时将 Audio Session 设置为非事件状态,但是当它处于事件状态时,保持 Audio Session 处于事件状态绝对没有错,使用模式与其他应用程序和平共存。您可以使用上面的代码复制 Apple 的导航应用程序功能。

关于objective-c - 当 AudioSessionActive 为 NO 时,无法通过硬件按钮控制 AVAudioPlayer 的音量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16474771/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com