首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AudioSessionActive为NO时,无法通过硬件按钮控制AVAudioPlayer音量

AudioSessionActive为NO时,无法通过硬件按钮控制AVAudioPlayer音量
EN

Stack Overflow用户
提问于 2013-05-10 11:34:30
回答 1查看 2.3K关注 0票数 3

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

苹果在29:20分钟的“WWDC2010 session 412 iPhone OS第一部分音频开发”视频中详细讨论了逐个转弯的用例。实现效果很好,但有一个问题-当应用程序运行时,按下硬件音量控制来调整振铃器音量,而不是应用程序音量。如果要更改应用程序音量,必须在播放提示时按音量按键。

苹果在视频中非常明确地说,你不应该让AVAudioSession处于活动状态,但如果AVAudioSession处于非活动状态,音量按钮将无法控制我的应用程序的音量。

下面是我用来设置的代码:

代码语言:javascript
复制
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建议的那样:

代码语言:javascript
复制
OSStatus activationResult = AudioSessionSetActive(false);
NSAssert(activationResult == kAudioSessionNoError, @"Error deactivating audio session");

我是不是遗漏了什么,或者我必须违背他们在视频中的建议?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-23 10:41:07

在您的情况下,您不希望将音频会话设置为非活动状态。您需要做的是使用两种方法,一种是将会话设置为播放声音,另一种是将会话设置为空闲。第一种方法设置mix+duck音频模式,第二种方法使用环境音频友好模式。

如下所示:

代码语言:javascript
复制
- (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];
}

那就叫它:

代码语言:javascript
复制
[self setActive];
[self _playAudio:nil];

要在播放后清理,请执行以下操作:

代码语言:javascript
复制
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer*)player
                   successfully:(BOOL)flag {
[self setIdle];

}

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

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16474771

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档