iPhone应用程序:在AVAudio Player中不恢复音频会话



在我的iPhone应用程序中,我使用AVAudioPlayer播放音乐。当我的应用程序在后台运行的时候它也在运行我写了这段代码

在AppDelegate上

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

现在我已经为audio manager创建了单独的类来处理委托方法。

in .h file

  #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

in .m file

    @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库之前播放的,不恢复意味着它不再播放歌曲。

怎么了?

是否有任何演示项目或示例代码可以帮助?

你不应该在audioPlayerBeginInterruption:AVAudioPlayer (p在你的代码)上调用pause,因为中断,玩家不应该在那个阶段玩。在audioPlayerEndInterruption:中,以下通常适用于我:

[p prepareToPlay];
[p play];

iOS文档中的Audio Session Cookbook中有一节是关于"处理AVAudioPlayer类的中断"的,应该也会有所帮助。

最新更新