音频会话"躲避"在iOS 4中被破坏......?

lev*_*ker 8 core-audio avaudioplayer mpmusicplayercontroller ios4

我有一个使用MPAudioPlayerController访问iPod音乐库的应用程序,以及一个AVAudioPlayer,用于在音乐之上叠加音频.我已经使用这个文档作为指导.特别:

最后,您可以增强类别,以便在播放音频时自动降低其他音频的音量.例如,这可以用在锻炼应用中.当您的应用程序想要覆盖语音消息时,假设用户正在练习iPod - 例如,"您已经划了10分钟."为了确保应用程序中的消息可以理解,请将kAudioSessionProperty_OtherMixableAudioShouldDuck属性应用于音频会话.当发生躲避时,设备上的所有其他音频 - 除了电话音频 - 音量降低.

但我没有看到这种行为.实际上,我所看到的(或听到的)是,如果我将kAudioSessionProperty_OtherMixableAudioShouldDuck设置为true来设置AudioSession,则MPAudioPlayerController初始卷会减少,如果我然后在MPAudioPlayerController上调用pause(然后再次播放)音量级别增加到"正常"水平.播放AVAudioPlayer对音频级别没有任何影响......

所以我设置了一个简单的测试用例来重现这个.

在ViewController标头中:

#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>

@interface MusicPlayerVolumeTestViewController : UIViewController <AVAudioPlayerDelegate>
{
    UIButton *musicButton;
    UIButton *soundButton;
    AVAudioPlayer *audioPlayer;
    MPMusicPlayerController *musicPlayerController;
}
@property (nonatomic, retain) IBOutlet UIButton *musicButton;
@property (nonatomic, retain) IBOutlet UIButton *soundButton;
@property (nonatomic, retain) MPMusicPlayerController *musicPlayerController;

- (IBAction)musicAction;
- (IBAction)soundAction;

@end
Run Code Online (Sandbox Code Playgroud)

并在实施中:

- (void)viewDidLoad
{
    [super viewDidLoad];

    //Setup our Audio Session
    OSStatus status = AudioSessionInitialize(NULL, NULL, NULL, NULL);    
    //We want our audio to play if the screen is locked or the mute switch is on
    UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
    status = AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory);
    //We want our audio to mix with other app's audio
    UInt32 shouldMix = true;
    status = AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof (shouldMix), &shouldMix);
    //Enable "ducking" of the iPod volume level while our sounds are playing
    UInt32 shouldDuck = true;
    AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, sizeof(shouldDuck), &shouldDuck);
    //Activate our audio session
    AudioSessionSetActive(YES);

    //Setup the Music Player to access the iPod music library
    self.musicPlayerController = [MPMusicPlayerController applicationMusicPlayer];
    [self.musicPlayerController setShuffleMode: MPMusicShuffleModeSongs];
    [self.musicPlayerController setRepeatMode: MPMusicRepeatModeNone];
    [self.musicPlayerController setQueueWithQuery:[MPMediaQuery songsQuery]];

    //Setup a AVAudioPlayer sound to overlay against the Music Player audio
    NSURL *soundURL = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"overlay" ofType:@"mp3"]];
    NSError *error = nil;
    audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error: &error];
    if (!audioPlayer)
    {
        NSLog(@"Could not create audio effect player: %@", [error localizedDescription]);
    }
    [audioPlayer prepareToPlay];
}

- (IBAction)musicAction
{
    if (self.musicPlayerController.playbackState == MPMusicPlaybackStatePlaying)
    {
        [self.musicPlayerController pause];
    }
    else if (self.musicPlayerController.playbackState == MPMusicPlaybackStateStopped
          || self.musicPlayerController.playbackState == MPMusicPlaybackStatePaused)
    {
        [self.musicPlayerController play];
    }
}

- (IBAction)soundAction
{
    if (audioPlayer.playing)
    {
        [audioPlayer pause];
    }
    else
    {
        [audioPlayer play];
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经连接了几个UIButtons.一个用于musicAction(用于播放/暂停MPMusicPlayerController),另一个用于soundAction(用于播放/暂停AVAudioPlayer).

如上所述,如果我点击musicAction按钮,音乐会播放,但音量会降低,如果我点击soundAction按钮,叠加会播放,但不会影响MPMusicPlayerController的音量.而且,更像bug的是,当我暂停然后播放MPMusicPlayerController时,音乐音量增加到我没有设置AudioSession时的音量.

我很想知道是否有其他人有过这种经历,如果有的话,如果你找到了解决办法(或者可以告诉我,我做错了什么).否则,我猜我要去雷达了.

非常感谢,

列维

zap*_*dtx 9

当我遇到类似问题并且难以让它始终如一地工作时,我使用了这篇文章.它会工作一段时间,然后只是卡住"躲避".我花了很多时间研究和调试这个,最后只是打电话给Apple.他们告诉我要查看面包屑示例代码.我按照那个例子,一切正常.

这是Apple的示例代码:

http://developer.apple.com/library/ios/#samplecode/Breadcrumb/Introduction/Intro.html

Apple的支持/开发人员还说要观察他们设置会话属性的方式和时间顺序.这显然是诀窍.在这里和其他地方阅读了很多帖子后,我的设置相互冲突.从头开始并遵循面包屑的例子使其成功.我从那以后就没有问题了.

我在这里发布了相同的答案:

如何解开AVAudioSession

对我来说,这个答案是临界商业秘密,因为它很难开始工作并且市场上有应用程序.对我来说,看到一个工作的例子,这几乎只是声音的躲避和解开,值得它的重量金.

此外,我向Apple提到这是一个已知问题,他们不同意.他们在这里没有发现任何问题.果然,如果你遵循面包屑的例子,它可以解决任何奇怪的会话停用和被动等等.


luc*_*ius 2

该文档不清楚闪避的预期行为应该是什么,但我发现,如果您将音频会话设置为闪避,那么当您激活音频会话时,它会闪避,而当您停用音频会话时,它会闪避它,它解开。因此,您必须不断激活和停用音频会话,以避开音乐以获取声音提示。

我发现的一个错误是,如果您在audioPlayerDidFinishPlaying:successfully:的方法内停用音频会话AVAudioPlayerDelegate,则不会删除闪避,并且音量会保持在同一水平。我已经就此提交了雷达,但如果其他人也提交类似的雷达,也没有什么坏处。事实上,这可能会给他们带来一些修复问题的压力。

您要做的就是启动音频会话并保持打开状态,这样它就会立即闪避并保持闪避状态,这样当您播放声音时它就不会进一步闪避音乐。暂停和播放音乐后音乐音量恢复的问题听起来像是一个错误。