2011-09-29 26 views
4

在我的iPhone應用程序中,我使用AVAudioPlayer播放音樂。當我的應用程序在後臺運行,當時還正在運行的THT我在AppDelegate中寫了這個代碼iPhone應用程序:在AVAudio播放器中不恢復音頻會話

上 - 應用程序didFinishLaunchingWithOptions

audioManager= [[AudioManager alloc] init]; 
    audioManager.delegate=self; 
    audioManager.soundFile=[[[NSBundle mainBundle] pathForResource:@"mysong" ofType:@"wav"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
    [audioManager setFileForPlay]; 
    [audioManager.player setNumberOfLoops:-1]; 
    [audioManager.player setVolume:.5]; 
    [audioManager play]; 



-(void) playerBeginInterruption:(AVAudioPlayer *)p{ 


[usdef setValue:@"START" forKey:@"LOCATIONMANAGER"]; 

[locationManager startUpdatingLocation]; 
[p pause]; 
// audioManager=nil; 

    } 

-(void) playerBeginInterruptionInBackground:(AVAudioPlayer *)p{ 

[usdef setValue:@"START" forKey:@"LOCATIONMANAGER"]; 
[locationManager startUpdatingLocation]; 
[p pause]; 
//audioManager=nil; 

} 

-(void) playerEndInterruption:(AVAudioPlayer *)p{ 
NSLog(@"Inteerpt END"); 

    [p prepareToPlay]; 
    [p play]; 
    [usdef setValue:@"STOP" forKey:@"LOCATIONMANAGER"]; 



} 

-(void) playerEndInterruptionInBackgroud:(AVAudioPlayer *)p{ 
    NSLog(@"Inteerpt END BG"); 
// [self performSelector:@selector(allocaudioManager)]; 
    [p prepareToPlay]; 
    [p play]; 

    [usdef setValue:@"STOP" forKey:@"LOCATIONMANAGER"]; 
    // [locationManager stopUpdatingLocation]; 

} 

現在我已經創造了saperate類音頻管理器,它HANDELS委託在.m文件方法

在.h文件中

#import <Foundation/Foundation.h> 
    #import <AudioToolbox/AudioToolbox.h> 
#import <AVFoundation/AVFoundation.h> 
@protocol AudioManagerDelegate; 
@interface AudioManager : NSObject <AVAudioPlayerDelegate> { 
AVAudioPlayer      *player; 

NSString       *soundFile; 
BOOL        inBackground; 
id<AudioManagerDelegate>   delegate; 

} 
@property (nonatomic, assign) id<AudioManagerDelegate>delegate; 
@property (nonatomic, retain) NSString  *soundFile; 

@property (nonatomic, assign) AVAudioPlayer *player; 
@property (nonatomic, assign) BOOL   inBackground; 
- (void)play; 
- (void)pause; 
- (void)stop; 
- (void)registerForBackgroundNotifications; 
-(void) setFileForPlay; 
    @end 
    @protocol AudioManagerDelegate <NSObject> 
    @optional 
    - (void)playerDidFinishPlayingInBackground:(AVAudioPlayer*)p; 
    - (void)playerDidFinishPlaying:(AVAudioPlayer*)p; 
    - (void)playerBeginInterruption:(AVAudioPlayer*)p; 
    - (void)playerBeginInterruptionInBackground:(AVAudioPlayer*)p; 
    - (void)playerEndInterruption:(AVAudioPlayer *)p; 
    - (void)playerEndInterruptionInBackgroud:(AVAudioPlayer *)p; 
@end 
@implementation AudioManager 
    @synthesize delegate; 
    @synthesize player; 
    @synthesize inBackground; 
    @synthesize soundFile; 

    void RouteChangeListener(void *inClientData, AudioSessionPropertyID inID,UInt32 inDataSize, const void *inData); 

-(id) init 
{ 
    if((self=[super init])) 
    { 

    OSStatus result = AudioSessionInitialize(NULL, NULL, NULL, NULL); 
    if (result) 
     NSLog(@"Error initializing audio session! %ld", result); 

    [[AVAudioSession sharedInstance] setDelegate: self]; 
    NSError *setCategoryError = nil; 
    [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError]; 
    if (setCategoryError) 
     NSLog(@"Error setting category! %@", setCategoryError); 

    result = AudioSessionAddPropertyListener (kAudioSessionProperty_AudioRouteChange, RouteChangeListener, self); 
    if (result) 
     NSLog(@"Could not add property listener! %ld", result); 

    return self; 
} 
return nil; 
} 


-(void) setFileForPlay{ 
    self.player=nil; 
     player = [[AVAudioPlayer alloc] initWithData:[NSData dataWithContentsOfFile:self.soundFile] error:nil];//initWithContentsOfURL:[NSURL URLWithString:self.soundFile] error:nil]; 

    if (self.player) 
    { 
      player.delegate = self; 
     } 

    } 


-(void) play{ 

    [self.player play]; 

    } 
    -(void)pause{ 
    [self.player pause]; 
    NSLog(@"in Pause"); 
    } 
-(void)stop{ 
    [self.player stop]; 
    NSLog(@"in stop"); 
    } 



       void RouteChangeListener(void *inClientData, AudioSessionPropertyID inID,UInt32 inDataSize, const void *inData){ 
     AudioManager* This = (AudioManager*)inClientData; 

     if (inID == kAudioSessionProperty_AudioRouteChange) { 

     CFDictionaryRef routeDict = (CFDictionaryRef)inData; 
    NSNumber* reasonValue = (NSNumber*)CFDictionaryGetValue(routeDict, CFSTR(kAudioSession_AudioRouteChangeKey_Reason)); 

    int reason = [reasonValue intValue]; 

    if (reason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) { 

     [This stop]; 
    } 
} 

    } 
    - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)p successfully:(BOOL)flag 
    { 
if (flag == NO) 
    NSLog(@"Playback finished unsuccessfully"); 

[p setCurrentTime:0.]; 
if (inBackground) 
{ 
    [delegate playerDidFinishPlayingInBackground:p]; 
} 
else 
{ 
    [delegate playerDidFinishPlaying:p]; 
} 
    } 
    - (void)playerDecodeErrorDidOccur:(AVAudioPlayer *)p error:(NSError *)error 
    { 
NSLog(@"ERROR IN DECODE: %@\n", error); 
    } 
    // we will only get these notifications if playback was interrupted 
    - (void)audioPlayerBeginInterruption:(AVAudioPlayer *)p 
    { 
NSLog(@"Interruption begin "); 
// the object has already been paused, we just need to update UI 
if (inBackground) 
{ 
    [delegate playerBeginInterruptionInBackground:p]; 
} 
else 
{ 
    [delegate playerBeginInterruption:p]; 
} 

    } 


    - (void)audioPlayerEndInterruption:(AVAudioPlayer *)p withFlags:(NSUInteger)flags 
    { 
    if(inBackground) 
     { 
     [delegate playerEndInterruptionInBackgroud:p]; 
    } 
     else 
    { 
    [delegate playerEndInterruption:p]; 
    } 
     NSLog(@"Interruption ended. Resuming playback"); 
    } 

    - (void)registerForBackgroundNotifications 
    { 
[[NSNotificationCenter defaultCenter] addObserver:self 
                selector:@selector(setInBackgroundFlag) 
                name:UIApplicationWillResignActiveNotification 
              object:nil]; 

     [[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(clearInBackgroundFlag) 
               name:UIApplicationWillEnterForegroundNotification 
              object:nil]; 
    } 

- (void)setInBackgroundFlag 
    { 
inBackground = true; 
    } 

- (void)clearInBackgroundFlag 
    { 
inBackground = false; 
    } 

    @end 

現在的問題是,如果我打任何歌曲形成的iPod圖書館和停止樂曲和關閉的iPod庫,我原來avaudioplayer這是開始的IPO庫之前打不恢復意味着它不會被再次playong歌

什麼可能是錯的?

是否有任何演示項目或示例代碼可以幫助我?

請幫助和建議。

+0

你是說,在你的應用程序,你有一個AVAudioPlayer玩一些音樂文件添加到您的項目。然後,當你離開應用程序並打開iPod播放器並播放歌曲,然後重新打開你的應用程序,它不會恢復原始歌曲,而是恢復到你的iPod庫? – Eric

+0

不,它不是從iPod庫它是音頻文件,我已經包含到我的項目 – ios

+0

在這種情況下,我總是使用方法applicationWillResignActive和applicationDidBecomeActive在您的應用程序委託來暫停並啓動您的AVAudioPlayer。 – Eric

回答

4

你不應該呼籲AVAudioPlayerpausep在你的代碼)在audioPlayerBeginInterruption:球員不應該在這個階段被打,因爲中斷。在audioPlayerEndInterruption:下面通常爲我工作:

[p prepareToPlay]; 
[p play]; 

Audio Session Cookbook在iOS的文檔對「處理與AVAudioPlayer類中斷」也應該幫助的部分。

相關問題