Android平台PJSIP与其他VOIP通话共存时音频异常问题求助
Android PJSIP与其他VOIP通话共存时的音频异常问题
问题现象
在Android平台使用PJSIP时,与Microsoft Teams通话并行会触发以下音频异常:
- 即使将PJSIP应用切换至前台,通话双方仍无法双向收音/发声
- 结束Teams通话后,设备扬声器自动切换至后置听筒模式,且无法通过常规代码切换回扬声器模式
无其他VOIP通话并行时,PJSIP应用运行完全正常。
复现步骤
- 在两台Android设备上发起Microsoft Teams通话
- 在其中一台设备上发起PJSIP VOIP通话
- 观察到PJSIP通话双方均无法听到对方声音,也无法发声
- 结束Microsoft Teams通话
- PJSIP通话恢复正常,但扬声器模式异常锁定为听筒模式
现有扬声器切换代码
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); audioManager.setSpeakerphoneOn(true);
解决方案
针对问题1:PJSIP与其他VOIP通话共存时的音频抢占问题
Android音频焦点机制是核心原因——Teams作为系统级VOIP应用会抢占音频焦点并锁定音频会话。PJSIP需正确处理音频焦点的申请与回调:
- 注册
AudioManager.OnAudioFocusChangeListener,监听音频焦点变化 - 发起PJSIP通话前,主动申请带有
AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE标记的音频焦点,明确告知系统当前需要独占音频资源:int result = audioManager.requestAudioFocus( audioFocusChangeListener, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE ); if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { // 初始化PJSIP音频会话 } - 在焦点丢失回调中暂停PJSIP音频流,重新获取焦点后恢复音频流
- 确保PJSIP的音频配置中启用
pjmedia_aud_dev_set_lock(),防止其他应用抢占音频设备
针对问题2:Teams结束后扬声器无法切换的问题
Teams结束通话时可能未正确释放音频会话或重置音频模式,导致系统音频状态异常。需强制重置音频状态并重新绑定PJSIP音频设备:
- 结束Teams通话后,先重置音频模式为
MODE_IN_COMMUNICATION(VOIP通话标准模式):audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); - 先关闭扬声器再重新开启,触发系统音频状态刷新:
audioManager.setSpeakerphoneOn(false); audioManager.setSpeakerphoneOn(true); - 调用PJSIP的音频设备重新初始化接口,强制刷新音频设备绑定:
pjmedia_aud_dev_refresh(); // PJSIP原生API,需在JNI层调用 - 确保切换扬声器前,当前应用持有音频焦点,否则
setSpeakerphoneOn会被系统忽略
额外注意事项
- Android 10及以上版本需申请
ACCESS_NOTIFICATION_POLICY权限,以获取更严格的音频焦点控制 - 避免在未获取音频焦点时初始化PJSIP音频会话,否则会被系统直接抢占
- 测试时需覆盖多品牌设备(部分厂商对音频焦点的处理有定制逻辑)
内容的提问来源于stack exchange,提问作者Mudassir Zulfiqar
相关产品推荐
相关产品推荐

