Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
路由iPhone音频_Iphone_Objective C_Avaudioplayer_Avaudiorecorder_Audiosession - Fatal编程技术网

路由iPhone音频

路由iPhone音频,iphone,objective-c,avaudioplayer,avaudiorecorder,audiosession,Iphone,Objective C,Avaudioplayer,Avaudiorecorder,Audiosession,我有一个应用程序,它可以同时收听和播放声音。默认情况下,声音输出通过耳机。因此,我使用以下代码将其发送到扬声器: UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride); 这个

我有一个应用程序,它可以同时收听和播放声音。默认情况下,声音输出通过耳机。因此,我使用以下代码将其发送到扬声器:

UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
这个很好用。但是现在,我想在连接耳机或外置扬声器时通过耳机传递声音。我将如何实现这一点

理想情况下,当应用程序启动时,所有其他声音(如音乐等)都应静音


谢谢

要执行此操作,您必须在设置音频会话时添加属性侦听器:

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

因此,当您插入或拔出耳机时,您会收到通知并更改音频输出方向。

这是一种快速而肮脏的方式,似乎对我很有效:


由于AudioSessionSetProperty自iOS 7以来已被弃用,我们应该使用AVFoundation AVAudioSession。由于期望的动作是允许用户动作通过扬声器重写路由,所以您可能会考虑AVOODISOSSION PORTORTVRIDESPEACK和AVAODISOSSIESTORYYOPTION DEVAUTHORTOPEKER。 根据技术公告Q&A 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];
同样,这个问题类似于另一篇相关文章中提到的问题

根据这里提到的同一份技术公告,“考虑使用overrideOutputAudioPort:您可以使用什么来实现扬声器按钮,您希望在扬声器(AVAudioSessionPortOverrideSpeaker)和正常输出路径(AvaudioSessionPortOverrideOne)之间切换。”

如果您希望实现扬声器覆盖覆盖输出类别,请参阅该帖子:

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