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

时间:2013-03-11 03:35:09

标签: iphone cocoa-touch core-audio audio-recording avaudiosession

好的,我的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?即使我需要为不同的用例单独定义它。例如,如果应用程序正在录制,音频将始终通过耳机,如果应用程序未录制,则音频输出耳机或扬声器(取决于用户是否插入了耳机) - 即正常行为)。

其他详细信息

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

  

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

然后我尝试用3种不同的方式设置这个属性(这些属性):

  • kAudioSessionProperty_OverrideAudioRoute与kAudioSessionOverrideAudioRoute_Speaker继续播放音频,但通过接收器将其切换出来,并将路线显示为ReceiverAndMicrophone
  • kAudioSessionProperty_OverrideCategoryDe​​faultToSpeaker与kAudioSessionOverrideAudioRoute_Speaker停止当前播放的音频,并将路线显示为SpeakerAndMicrophone
  • kAudioSessionProperty_OverrideCategoryDe​​faultToSpeaker的值为1与kAudioSessionOverrideAudioRoute_Speaker
  • 相同

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

1 个答案:

答案 0 :(得分: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);