在iOS7及以上版本中,如何在接收器和扬声器之间切换音频输出?

6

我有一个音频播放器,它有一个选项可以在接近传感器通知1时将音频输出从扬声器切换到接收器/耳机(无论是否连接了耳机)。以下是我实现该功能的代码。

- (void) switchAudioOutput:(NSString*)output{
    AVAudioSession* audioSession = [AVAudioSession sharedInstance];
    BOOL success;
    NSError* error;

    if([output isEqualToString:keAudioOutputReciever]){
        //Force current audio out through reciever
        //set the audioSession override
        success = [audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideNone
                                             error:&error];
        if (!success)
            NSLog(@"AVAudioSession error overrideOutputAudioPort:%@",error);

        //activate the audio session
        success = [audioSession setActive:YES error:&error];
        if (!success)
            NSLog(@"AVAudioSession error activating: %@",error);
        else
            NSLog(@"AVAudioSession active with override: AVAudioSessionPortOverrideNone");

    }else if([output isEqualToString:keAudioOutputSpeaker]){
        //set the audioSession override
        success = [audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker
                                                  error:&error];
        if (!success)
            NSLog(@"AVAudioSession error overrideOutputAudioPort:%@",error);

        //activate the audio session
        success = [audioSession setActive:YES error:&error];
        if (!success)
            NSLog(@"AVAudioSession error activating: %@",error);
        else
            NSLog(@"AVAudioSession active with override: AVAudioSessionPortOverrideSpeaker");

    }
 }

这是基于答案 切换按钮路由音频到扬声器和接收器输入链接说明。我注意到这只强制将音频路由到扬声器,但不能确保路由仅到达接收器。此外,在切换到扬声器时,我会遇到以下错误:

AVAudioSession error overrideOutputAudioPort:Error Domain=NSOSStatusErrorDomain Code=-50 "The operation couldn’t be completed. (OSStatus error -50.)"


1
我也遇到了完全相同的错误。有人解决了吗? - Josip B.
2个回答

9

通过避免对接收器的覆盖,我找到了答案。

- (void) setAudioSession:(NSString*)audioOutput{

        NSError* error;
        if([audioOutput isEqualToString:audioOutputSpeaker.lowercaseString]){

            //set the audioSession override
            if(![self setCategory:AVAudioSessionCategoryPlayAndRecord
                              withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker|AVAudioSessionCategoryOptionAllowBluetooth
                                    error:&error])
                NSLog(@"AVAudioSession error AVAudioSessionCategoryPlayAndRecord:%@",error);

            //activate the audio session
            if (![self setActive:YES error:&error])
                NSLog(@"AVAudioSession error activating: %@",error);
            else
                NSLog(@"AVAudioSession active with override: AVAudioSessionPortOverrideNone");
        }else if ([audioOutput isEqualToString:audioOutputReciever.lowercaseString]){
            //Force current audio out through reciever
            //set the audioSession override
            if(![self setCategory:AVAudioSessionCategoryPlayAndRecord
                              withOptions:AVAudioSessionCategoryOptionAllowBluetooth
                                    error:&error])
                NSLog(@"AVAudioSession error AVAudioSessionCategoryPlayAndRecord:%@",error);

            if (![self overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:&error])
                NSLog(@"AVAudioSession error overrideOutputAudioPort to Reciever:%@",error);

            //activate the audio session
            if (![self setActive:YES error:&error])
                NSLog(@"AVAudioSession error activating: %@",error);
            else
                NSLog(@"AVAudioSession active with override: AVAudioSessionPortOverrideNone");
        }
    }

1

我也曾经遇到过这个问题,尝试设置mode参数,以便选择适当的模式,例如:

try AVAudioSession.sharedInstance().setCategory(.playAndRecord,
                                                mode: .voicePrompt,
                                                options: .defaultToSpeaker)

这会使程序报错:

Error Domain=NSOSStatusErrorDomain Code=2003329396 "(null)"

音频在只使用category参数和mode时会路由到接收器而不是扬声器,但当我随机决定尝试不带mode参数而使用options参数时,它可以正常工作!所以如果你遇到问题,请尝试以下代码:
try AVAudioSession.sharedInstance().setCategory(.playAndRecord,
                                                options: .defaultToSpeaker)

很有趣。这是最新iOS的方式吗?我已经有一段时间没有接触这个主题了。 - Edwin Abraham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接