首页 文章

AVAudioSession /音频会话服务切换输出

提问于
浏览
10

好吧,我的AVAudioSession定义如下(是的,混合了c和obj-c调用)还要注意应用程序有背景模式音频,因为如果录制它必须在应用程序在后台时继续这样做:

[(AVAudioSession *)[AVAudioSession sharedInstance] setDelegate: self];
// Allow the app sound to continue to play when the screen is locked.
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
//Turn off automatic gain on the microphone
[[AVAudioSession sharedInstance] setMode:AVAudioSessionModeMeasurement error:nil];
//Turn on the ability to mix with others
UInt32 doSetProperty = 1;
AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(doSetProperty), &doSetProperty);

//Activate the audio session
[[AVAudioSession sharedInstance] setActive:YES error:nil];

该应用程序有几个不同的音频选项(只有前两个已编程):

  • 正常:没有来自应用程序的音频,所以不要乱用外部音频

  • 仅录制耳机麦克风:必须没有增益调整,不要弄乱外部音频(将通过耳机播放)

  • 在应用程序中播放音乐,无需录制:停止外部音频,并通过当前输出播放(扬声器或耳机)

  • 从应用程序播放音乐并录制耳机麦克风:停止外部音频,仅通过耳机录制和播放

录制在前台和后台运行良好,我稍后会添加播放 . 然而,我今晚才注意到,如果音频已经在扬声器上播放(Pandora)并且我进入我的应用程序并激活录音模式,那么它将Pandora切换到通过电话扬声器播放,甚至在音频消息停用后应用程序背景(但不强制关闭)音频继续通过手机扬声器播放,直到我强行关闭应用程序 .

//Deactivate the audio session
[[AVAudioSession sharedInstance] setActive:NO error:nil];

另一方面,如果耳机进入并且当应用程序开始进入录制模式时音乐正在通过耳机播放,那么只有短暂停顿并且音乐继续以相同音量播放(正确,没有闪避) .

当我在没有耳机的情况下激活音频会话时,我没有看到为什么路线应该改变的原因,以及为什么在会话停用时它不会改变 . 特别是换到手机扬声器!有什么东西我做错了,或者我只需要根据用户想要做什么(而不是毯子播放记录和模式测量)来定义AVAudioSession?即使我需要为不同的用例单独定义它 . 例如,如果应用程序正在录制,音频将始终通过耳机,如果应用程序未录制,则音频输出耳机或扬声器(取决于用户是否插入了耳机) - 即正常行为) .

Additional Details

好的,我尝试切换所有代码c并注意到有关kAudioSessionProperty_OverrideAudioRoute的文档中的一个注释

kAudioSessionOverrideAudioRoute_None为kAudioSessionCategory_PlayAndRecord类别指定输出音频应该发送到接收器 . 这是此类别的默认输出音频路由 .

那么我尝试以3种不同的方式设置这个属性(这些属性):

  • kAudioSessionProperty_OverrideAudioRoute与kAudioSessionOverrideAudioRoute_Speaker继续播放音频,但通过接收器将其切换出来,并将路线显示为ReceiverAndMicrophone

  • kAudioSessionProperty_OverrideCategoryDefaultToSpeaker与kAudioSessionOverrideAudioRoute_Speaker停止当前播放的音频,并将路线显示为SpeakerAndMicrophone

  • kAudioSessionProperty_OverrideCategoryDefaultToSpeaker的值为1与kAudioSessionOverrideAudioRoute_Speaker的作用相同

所以基本上文档说默认是切换到接收器 . 但是,无论我做什么,我似乎都无法保持扬声器输出并保持外部音频播放 .

1 回答

  • 9

    显然,设置属性的顺序很重要,尽管在文档中没有提到这一点 . 对于那些最终发现这一点的人来说,这是有效的:

    //Init and set the interrupt listener.  last parameter is passed to interruptlistener
    AudioSessionInitialize(NULL, NULL, interruptlistener, NULL);
    
    //Allow the app sound to continue to play when the screen is locked.
    UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord;
    AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory);
    
    //Force current audio out through speaker
    UInt32 routeSpeaker = kAudioSessionOverrideAudioRoute_Speaker;
    AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(routeSpeaker), &routeSpeaker);
    
    //Turn on the ability to mix with others
    UInt32 doSetProperty = 1;
    AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(doSetProperty), &doSetProperty);
    

相关问题