5

我有一個應用程序,它可以同時收聽和播放聲音。默認情況下,聲音輸出通過耳機。所以我用下面的代碼通過揚聲器路由它:路由iPhone音頻聲音

UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; 
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride); 

這工作正常。但現在,當連接耳機或外接揚聲器時,我希望通過耳機傳送聲音。我將如何實現這一目標?

理想情況下,所有其他聲音(即音樂等)應該靜音,當應用程序啓動。

謝謝!

回答

11

要做到這一點,你必須添加屬性監聽器,當你設置音頻會議:

AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, audioSessionPropertyListener, nil); 

void audioSessionPropertyListener(void* inClientData, AudioSessionPropertyID inID, 
              UInt32 inDataSize, const void* inData) { 
      UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; 

      if (!isHeadsetPluggedIn()) 
      AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride); 
     } 

BOOL isHeadsetPluggedIn() { 
    UInt32 routeSize = sizeof (CFStringRef); 
    CFStringRef route; 

    OSStatus error = AudioSessionGetProperty (kAudioSessionProperty_AudioRoute, 
              &routeSize, 
              &route 
              ); 



    if (!error && (route != NULL) && ([(NSString*)route rangeOfString:@"Head"].location != NSNotFound)) { 
     NSLog(@"HeadsetPluggedIn"); 
     return YES; 
     } 
     NSLog(@"Headset_NOT_PluggedIn"); 
     return NO; 
    } 

所以,當插入耳機或出你得到一個通知,並更改音頻輸出方向。

+0

這並不爲我工作。任何幫助? – 2011-03-12 16:39:24

1

這是一個快速和骯髒的方式,似乎爲我工作:

void sessionPropertyListener(void *     inClientData, 
          AudioSessionPropertyID inID, 
          UInt32     inDataSize, 
          const void *   inData){ 

    if (inID == kAudioSessionProperty_AudioRouteChange) 
    { 
    CFStringRef newRoute; 
    UInt32 size = sizeof(CFStringRef); 
    AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &size, &newRoute); 
    if (newRoute) 
    { 
     CFShow(newRoute); 
     if (CFStringCompare(newRoute, CFSTR("ReceiverAndMicrophone"), 
          (UInt32)NULL) == kCFCompareEqualTo)//if receiver, play through speakers 
     { 
     UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; 
     AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, 
           sizeof(audioRouteOverride), 
           &audioRouteOverride); 
     } 
     else if (CFStringCompare(newRoute, CFSTR("HeadsetInOut"), 
           (UInt32)NULL) == kCFCompareEqualTo)//headset 
     { 
     UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None; 
     AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, 
           sizeof(audioRouteOverride), 
           &audioRouteOverride); 
     } 
    } 
    } 
} 
0

隨着AudioSessionSetProperty廢棄了,因爲iOS的7,我們應該使用AVFoundation AVAudioSession。由於所需的操作是允許用戶操作覆蓋通過揚聲器的路線,因此您可以考慮AVAudioSessionPortOverrideSpeaker和AVAudioSessionCategoryOptionDefaultToSpeaker之間的區別。

根據技術公告Q &一個QA1754:「當使用AVAudioSessionCategoryOptionDefaultToSpeaker,用戶手勢將榮幸例如,在耳機插入會導致路線改變爲耳機麥克風/耳機拔掉耳機將導致路線更換爲內置麥克風/揚聲器「。

請注意,該技術公告解釋說,AVAudioSessionPortOverrideSpeaker比較適合用於揚聲器電話按鈕,例如,這不是原始帖子所要求的。

NSError *error; 
AVAudioSession* audioSession = [AVAudioSession sharedInstance]; 
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:&error]; 
// handle any error 
// initiate the player or recorder 
[_player play]; 

而且這個問題是類似於在不同但相關的郵遞方式寄往一個:之前我調用播放器如下

https://developer.apple.com/library/ios/qa/qa1754/_index.html

我自己的實現被調用。

根據相同的技術公告,在此提及「考慮使用overrideOutputAudioPort:根據您可能用於實現揚聲器電話按鈕的方式,您希望能夠在揚聲器(AVAudioSessionPortOverrideSpeaker)和正常輸出路徑(AVAudioSessionPortOverrideNone)「。

請參閱該職位,如果你正在尋找實現揚聲器覆蓋overrideOutputPort類別: How Do I Route Audio to Speaker without using AudioSessionSetProperty?