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?