在开发WebRTC的Android端时遇到一个奇怪的问题,Android端与PC端视频时听不到PC端的声音,其他一切都正常。通过分析,之前音视频工作都很正常,最近测试声音引擎时出现了该问题,本次测试增加了声音引擎的一些限制,如下:
audioConstraints.mandatory.add(new MediaConstraints.KeyValuePair(AUDIO_ECHO_CANCELLATION_CONSTRAINT, "false")); audioConstraints.mandatory.add(new MediaConstraints.KeyValuePair(AUDIO_AUTO_GAIN_CONTROL_CONSTRAINT, "false")); audioConstraints.mandatory.add(new MediaConstraints.KeyValuePair(AUDIO_HIGH_PASS_FILTER_CONSTRAINT, "false")); audioConstraints.mandatory.add(new MediaConstraints.KeyValuePair(AUDIO_NOISE_SUPPRESSION_CONSTRAINT, "false"));从代码没有发现有什么不妥的地方,只能先还原,屏蔽了上述代码再测试,一切又正常了。这下有的玩了,难道是WebRTC的声音引擎有bug?检查下视频连接的日志,发现一个显眼的红色error日志:“ Platform AEC state can't be modified while recording”
这个错误发生在交换SDP过程中,从错误的语义中可以大致判断出是声音引擎抛出来的。
在Android Studio中通过全局搜索的方式将问题定位到WebRtcAudioEffects类,该类是WebRTC处理音频效果的,而问题是下面这个方法抛出来的:
// Call this method to enable or disable the platform AEC. It modifies // |shouldEnableAec| which is used in enable() where the actual state // of the AEC effect is modified. Returns true if HW AEC is supported and // false otherwise. public boolean setAEC(boolean enable) { Logging.d(TAG, "setAEC(" + enable + ")"); if (!canUseAcousticEchoCanceler()) { Logging.w(TAG, "Platform AEC is not supported"); shouldEnableAec = false; return false; } if (aec != null && (enable != shouldEnableAec)) { Logging.e(TAG, "Platform AEC state can't be modified while recording"); return false; } shouldEnableAec = enable; return true; }
通过debug发现抛出该异常时由于shouldEnableAec 一直为false,而enable=ture,aec!=null。
思来想去还是去maven检查下libjingle的最新版本:http://mvnrepository.com/artifact/io.pristine/libjingle
发现最新版本为11139,而我们的项目采用的自己编译的,版本可能有差异,还不确定是否是版本差异导致的,那就先采用远程依赖的方式引入最新的版本测试下吧
compile 'io.pristine:libjingle:11139@aar'
将代码稍微调整了一下,经过测试发下一切正常,问题原因浮出水面,下面我们看下最新版本是怎样的:
扫描二维码关注公众号,回复:
1520572 查看本文章
public boolean setAEC(boolean enable) { Logging.d("WebRtcAudioEffects", "setAEC(" + enable + ")"); if(!canUseAcousticEchoCanceler()) { Logging.w("WebRtcAudioEffects", "Platform AEC is not supported"); this.shouldEnableAec = false; return false; } else if(this.aec != null && enable != this.shouldEnableAec) { Logging.e("WebRtcAudioEffects", "Platform AEC state can\'t be modified while recording"); return false; } else { this.shouldEnableAec = enable; return true; } }
细心看下肯定能发现判断语句在这里是闭环的,看来google的确已经发现问题并处理过了,好吧,看来又有工作要做了:编译最新版的libjingle了。