【问题标题】:How to let my app audio to nicely interrupt iPhone audio while speaking如何让我的应用程序音频在说话时很好地中断 iPhone 音频
【发布时间】:2014-01-29 14:38:26
【问题描述】:

我的 iOS 7 应用会在必要时发声。

我想做的是让用户在我的运行时能够收听他的音乐或播客(或任何其他使用音频的应用程序)。

预期的行为是,当我的应用说话时,其他音频会混合或闪避,然后其他音频会立即恢复到初始音量。

我尝试了很多方法来实现这个目标,但没有什么是足够好的,因为我在代码之后列出了我面临的问题。

我当前的实现是基于在播放或文本转语音之前创建一个会话,如下所示:

+ (void)setAudioActive {

    [[self class] setSessionActiveWithMixing:YES];
}

在播放/演讲之后,我将 i 设置为空闲,如下所示:

+ (void)setAudioIdle {
    [[self class] setSessionActiveWithMixing:NO];
}

根据active参数处理会话建立的核心函数,如下:

+ (void)setSessionActiveWithMixing:(BOOL)active
{
    NSError *error = NULL;
    BOOL     success;

    AVAudioSession *session = [AVAudioSession sharedInstance];

    static NSInteger counter = 0;

    success = [session setActive:NO error:&error];
    if (error) {
        DDLogError(@"startAudioMixAndBackground: session setActive:NO, %@", error.description);
    }
    else {
        counter--; if (counter<0) counter = 0;
    }

    if (active) {
        AVAudioSessionCategoryOptions options = AVAudioSessionCategoryOptionAllowBluetooth
            //|AVAudioSessionCategoryOptionDefaultToSpeaker
            |AVAudioSessionCategoryOptionDuckOthers
        ;


        success = [session setCategory://AVAudioSessionCategoryPlayback
                   AVAudioSessionCategoryPlayAndRecord
                           withOptions: options
                                 error: &error];
        if (error) {
            // Do some error handling
            DDLogError(@"startAudioMixAndBackground: setCategory:AVAudioSessionCategoryPlayback, %@", error.description);
        }
        else {
            //activate the audio session
            success = [session setActive:YES error:&error];
            if (error) {
                DDLogError(@"startAudioMixAndBackground: session setActive:YES, %@", error.description);
            }
            else {
                counter++;
            }
        }
    }

    DDLogInfo(@"Audio session counter is: %ld",counter);
}

我目前的问题是:

1) 当我的应用程序开始说话时,我听到声音中出现了一些故障,这使得它不太好听;

2) 当我将路由连接到蓝牙时,底层音频(比如 Podcast 或 ipod 音乐)会变得非常低并且听起来很嘈杂,这使得我的解决方案无法使用,我的用户会拒绝这个级别的质量差。

3) 当其他蓝牙连接的设备尝试发出声音时(比如汽车或实例中的 GPS),我的 App 没有收到任何中断(或者我处理错误),请参见我的代码如下:

- (void)startAudioMixAndBackground {

    // initialize our AudioSession -
    // this function has to be called once before calling any other AudioSession functions
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioSessionDidChangeInterruptionType:)
                                                 name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];

    // set our default audio session state
    [[self class] setAudioIdle];

    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

    if ([self canBecomeFirstResponder]) {
        [self becomeFirstResponder];
    }

    @synchronized(self) {
        self.okToPlaySound = YES;
    }

    //MPVolumeSettingsAlertShow();
}
//  want remote control events (via Control Center, headphones, bluetooth, AirPlay, etc.)
- (void)remoteControlReceivedWithEvent:(UIEvent *)event
{
    if (event.type == UIEventTypeRemoteControl)
    {
        switch(event.subtype)
        {
            case UIEventSubtypeRemoteControlPause:
            case UIEventSubtypeRemoteControlStop:
                [[self class] setAudioIdle];
                break;
            case UIEventSubtypeRemoteControlPlay:
                [[self class] setAudioActive];
                break;
            default:
                break;
        }
    }
}

#pragma mark - Audio Support

- (void)audioSessionDidChangeInterruptionType:(NSNotification *)notification
{
    AVAudioSessionInterruptionType interruptionType = [[[notification userInfo]
                                                        objectForKey:AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];

    if (AVAudioSessionInterruptionTypeBegan == interruptionType)
    {
       DDLogVerbose(@"Session interrupted: --- Begin Interruption ---");
    }
    else if (AVAudioSessionInterruptionTypeEnded == interruptionType)
    {
        DDLogVerbose(@"Session interrupted: --- End Interruption ---");
    }
}

【问题讨论】:

  • 您找到解决问题的方法了吗?我的问题是 2 号
  • 唉,不。听起来没有人知道如何做这些事情。你有没有跑过什么特别的东西可以帮助你? (提出问题以引起注意)@Jan
  • 看来这篇文章有很多问题。只是为了澄清问题,您是否无法将您的应用程序的音频与用户的音乐混合使用?由于您的解决方法,外部和蓝牙音频出现故障
  • @sam 真实。我相信代码 sn-p 不言自明。更一般地说,需要哪些代码才能实现与计划相同的无缝结果?

标签: ios bluetooth avaudiosession


【解决方案1】:

您的问题很可能是由于您设置的类别:AVAudioSessionCategoryPlayAndRecord。 PlayAndRecord 类别不允许您的应用与其他应用混合/隐藏音频。您应该在此处再次参考有关音频会话类别的文档:https://developer.apple.com/library/ios/documentation/avfoundation/reference/AVAudioSession_ClassReference/Reference/Reference.html。看起来 AVAudioSessionCategoryAmbient 可能更符合您的要求。

【讨论】:

  • PlayAndRecord 类别允许使用鸭子音频选项。
猜你喜欢
  • 1970-01-01
  • 2012-01-06
  • 2022-12-18
  • 1970-01-01
  • 1970-01-01
  • 2020-07-31
  • 2011-08-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多