2013-04-05 184 views
4

我正在使用AUGraph和AUSampler將MIDI信號轉換爲音頻。該應用程序正常運行良好,但如果應用程序被打斷,例如通過電話或計時器出現問題。中斷後,AUGraph停止運行,沒有任何聲音。再次獲得聲音的唯一方法是重新啓動應用程序。我使用的是標準的方法來處理中斷:AUGraph在iOS中的電話中斷後停止運行

[[NSNotificationCenter defaultCenter] addObserver: self 
             selector: @selector(handleInterruption:) 
              name: AVAudioSessionInterruptionNotification 
              object: [AVAudioSession sharedInstance]]; 

當有中斷的handleInterruption方法被稱爲:

// If the system interrupts the audio session - kill the volume 
-(void) handleInterruption: (NSNotification *) notification { 
    NSDictionary *interuptionDict = notification.userInfo; 
    NSInteger interuptionType = [[interuptionDict valueForKey:AVAudioSessionInterruptionTypeKey] intValue]; 

    if (interuptionType == AVAudioSessionInterruptionTypeBegan) { 
     [self setAudioSessionActive: NO]; 
     [self stopAUGraph]; 
    } 
    else if (interuptionType == AVAudioSessionInterruptionTypeEnded) { 
     [self setAudioSessionActive: YES]; 
     [self startAUGraph]; 
    } 
} 

以下是啓動和停止AUGraph

-(void) startAUGraph { 
    CheckError(AUGraphStart(_audioGraph), "Failed to start Audio Graph"); 
} 

-(void) stopAUGraph { 
    Boolean isRunning = false; 

    // Check to see if the graph is running. 
    CheckError(AUGraphIsRunning(_audioGraph, &isRunning), "Error trying querying whether graph is running"); 
    // If the graph is running, stop it. 
    if (isRunning) { 
     CheckError(AUGraphStop(_audioGraph), "Failed to stop Audio Graph"); 
    } 
} 
方法

這裏是setAudioSessionActive方法:

-(void) setAudioSessionActive: (BOOL) active { 
    NSError *audioSessionError = nil; 
    BOOL success = [_audioSession setActive:active error:&audioSessionError]; 
    if (!success) { 
     NSLog (@"Error activating audio session!"); 
    } 
} 

我已經在渲染回調中放置了一個斷點,所以我可以確認AUGraph沒有運行。有沒有人遇到過這個問題?還有什麼我必須做的,讓AUGraph再次運行?提前致謝!

+0

如果你在handleInterruption中放置一個斷點:它會被打到嗎?值得注意的是,中斷通知系統是iOS6的新功能,因此可能無法在iOS5設備上運行。另外一種快速測試中斷的方法是激活Siri(按住home鍵)。 – 2013-04-06 09:42:04

回答

1

我不確定您可以通過當前的iOS6版本來實現。 看到這個錯誤報告 - http://openradar.appspot.com/12412685

你可能想聽聽UIApplicationWillResignActiveNotificationUIApplicationDidBecomeActiveNotification通知其如一個電話中斷期間發射,並停止/通知處理程序啓動音頻會話。

3

我也一直有這個bug的可怕的麻煩。我想我已經找到了一個解決方法:

由於NSNotifications不會在觸發中斷時返回,因此在我的AppDelegate的-applicationWillEnterForeground:方法中,我檢查是否有中斷導致它進入後臺我定當AVAudioSessionInterruptionNotification被貼有AVAudioSessionInterruptionTypeBegan的中斷類型鍵的標誌),如果是我調用對象的方法來控制AUGraph運行如下:

Boolean isRun = FALSE; 
    AUGraphIsRunning(myAUGraph, &isRun); 
    if (isRun) { 
     NSLog(@"END INTERRUPTION BUT AUGRAPH IS RUNNING"); 
     AUGraphStop(myAUGraph);// Kick start the AUGraph! 
     AUGraphStart(myAUGraph); //Restart immediately 
     Boolean isInit = FALSE; 
     AUGraphIsInitialized(processingGraph, &isInit); 
     if (!isInit) { 
      NSLog(@"augraph not initd'"); 
      OSStatus result = AUGraphInitialize(processingGraph); 
      if (result != noErr) { 
       NSLog(@">>can't init graph"); 
      } 
     } 
    } 
    else 
    { 
     NSLog(@"END INTERRUPTION BUT AUGRAPH IS NOT RUNNING"); 
    } 

的關鍵似乎是停止,然後立即重新啓動AUGraph。到目前爲止,當來電或其他應用程序接管揚聲器/麥克風時,它可以正常運行,我可以在應用程序中停止播放。

AUGraph的重新初始化似乎從未被執行過,也不是isRun,而是TRUE,但是我已經把它留下了。希望能夠幫助你解決這個問題,花了我好幾天的時間來解決這個問題,我希望它能夠繼續工作,而不僅僅是一個巧合! 4小時,並計數到目前爲止!

1

在iOS 7中,它適用於我。

//Interruption handler 
-(void) interruption: (NSNotification*) aNotification 
{ 

    NSDictionary *interuptionDict = aNotification.userInfo; 

    NSNumber* interuptionType = (NSNumber*)[interuptionDict valueForKey:AVAudioSessionInterruptionTypeKey]; 

    if([interuptionType intValue] == AVAudioSessionInterruptionTypeBegan) 

     [self stopAUGraph]; 

    else if ([interuptionType intValue] == AVAudioSessionInterruptionTypeEnded) 

     [self startAUGraph]; 

}