2013-11-02 49 views
3

在iOS 7中,在我的音頻中斷監聽器被調用後,任何恢復音頻會話的嘗試似乎都會自動失敗。如何在iOS 7中音頻中斷後恢復音頻會話?

我中斷偵聽器調用

NSError *activationError = nil; 
[[AVAudioSession sharedInstance] setActive:YES error:&activationError]; 

,但應用程序的音頻會話只要鬧鐘響起時已經死了。監聽者被調用適當的開始和結束狀態。

這工作就好在iOS 6

我聽說,這是iOS的7 bug,並有一種變通方法,但無法找到它。

有沒有人知道蘋果的解決方法或技術說明的鏈接?

編輯:我發現我HAVE使用AVAudioSessionCategoryPlayback,而不是kAudioSessionCategory_AmbientSound。現在它可以工作。但這不是我想要的類別。

回答

0

根據Apple的音頻會話編程指南,您應該傾聽並對您的中斷處理程序中的更改做出反應。這意味着您的代碼可以/應該根據收到的參數interruptionState處理中斷的結束。此鏈接

退房「音頻中斷處理技術」,我認爲這將幫助你很多:https://developer.apple.com/library/ios/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/HandlingAudioInterruptions/HandlingAudioInterruptions.html

祝你好運, Z.

+2

編程指南沒有提供太多的幫助:零示例代碼。在使用音頻單元的情況下,它只會說「重新激活音頻會話」,而我正是這樣做的(沒有任何錯誤),但聲音保持靜音。 –

0

你可以在下面看到我的代碼。但首先,

您應該選擇此位目標|背景模式|音頻,Airplay和功能圖片。

// ViewController.m 
// AVAudioPlayer 

#import "ViewController.h" 

@import AVFoundation; 
@import MediaPlayer; 

@interface ViewController() 

@property (strong, nonatomic) AVAudioPlayer *audioPlayer; 
@property (weak, nonatomic) IBOutlet UISlider *volumeSlider; 
@property (weak, nonatomic) IBOutlet UISlider *rateSlider; 

@end 

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
    [self setupAudio]; 
} 

- (void) setupAudio { 
    NSError *error; 
    [[AVAudioSession sharedInstance] setActive:YES error:&error]; 
    if (error != nil) { 
     NSAssert(error == nil, @""); 
    } 

    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error]; 
    if (error != nil) { 
     NSAssert(error == nil, @""); 
    } 

    NSURL *soundURL = [[NSBundle mainBundle] URLForResource:@"SoManyTimes" withExtension:@"mp3"]; 
    self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:&error]; 
    if (error != nil) { 
     NSAssert(error == nil, @""); 
    } 

    //[self.audioPlayer setVolume:0.8]; 
    self.audioPlayer.enableRate = YES; 
    [self.audioPlayer prepareToPlay]; 
    [self.audioPlayer setVolume:self.volumeSlider.value]; 

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioInterrupt:) name:AVAudioSessionInterruptionNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChanged:) name:AVAudioSessionRouteChangeNotification object:nil]; 

    MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter]; 
    [commandCenter.playCommand addTarget:self action:@selector(playButtonPressed:)]; 
    [commandCenter.stopCommand addTarget:self action:@selector(stopButtonPressed:)]; 
    [commandCenter.pauseCommand addTarget:self action:@selector(stopButtonPressed:)]; 

} 

- (void) audioRouteChanged:(NSNotification*)notification { 
    NSNumber *reason = (NSNumber*)[notification.userInfo valueForKey:AVAudioSessionRouteChangeReasonKey]; 
    switch ([reason integerValue]) { 
     case AVAudioSessionRouteChangeReasonOldDeviceUnavailable: 
     case AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory: 
      [self stopButtonPressed:nil]; 
      break; 

     default: 
      break; 
    } 
} 

- (void) audioInterrupt:(NSNotification*)notification { 
    NSNumber *interruptionType = (NSNumber*)[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey]; 
    switch ([interruptionType integerValue]) { 
     case AVAudioSessionInterruptionTypeBegan: 
      [self stopButtonPressed:nil]; 
      break; 
     case AVAudioSessionInterruptionTypeEnded: 
     { 
      if ([(NSNumber*)[notification.userInfo valueForKey:AVAudioSessionInterruptionOptionKey] intValue] == AVAudioSessionInterruptionOptionShouldResume) { 
       [self playButtonPressed:nil]; 
      } 
      break; 
     } 
     default: 
      break; 
    } 
} 

- (IBAction)playButtonPressed:(id)sender { 
    BOOL played = [self.audioPlayer play]; 
    if (!played) { 
     NSLog(@"Error"); 
    } 

    MPMediaItemArtwork *albumArt = [[MPMediaItemArtwork alloc] initWithImage:[UIImage imageNamed:@"CoverArt"]]; 

    NSDictionary *songInfo = @{ 

           MPMediaItemPropertyTitle:@"So Many Times", 
           MPMediaItemPropertyArtist:@"The Jellybricks", 
           MPMediaItemPropertyAlbumTitle:@"Soap Opera", 
           MPMediaItemPropertyArtwork:albumArt, 
           MPMediaItemPropertyPlaybackDuration:@(self.audioPlayer.duration), 
           MPNowPlayingInfoPropertyElapsedPlaybackTime:@(self.audioPlayer.currentTime), 

           }; 

    [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:songInfo]; 

} 

- (IBAction)stopButtonPressed:(id)sender { 
    [self.audioPlayer stop]; 
} 

- (IBAction)volumeSliderChanged:(UISlider*)sender { 
    [self.audioPlayer setVolume:sender.value]; 
} 

- (IBAction)rateSliderChanged:(UISlider*)sender { 
    [self.audioPlayer setRate:sender.value]; 
} 

- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

- (void) dealloc { 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

@end