Flash Player播放音频导致的极其隐秘的线上Bug

Posted on April 10, 2012

这几天遇到一个纠结的问题。游戏上线后,大家都可以正常访问,唯独公司有几台机器总是无法进入游戏。以为是个别测试人员的数据配置问题导致的,一开始没有关注。到后来客服说用户也出现了这个情况,而且还不少的时候,这个事引起大家的重视。我们一堆人在一台100%不能访问游戏的电脑上调试了半天,也没发现有什么问题。只能查出一件事:这台电脑上,无论谁的账号,任何浏览器下,都无法进入我们游戏。而同样的账号,在其他人的电脑上都能正常登陆。这就太诡异了。Web的应用居然还电脑环境相关的。 而且我们公司的电脑全部都是同一个配置一个型号的。更让人摸不着头脑了。

于是我继续测试。写了一个线上的日志打印调试工具。把版本发到内网环境测试。在那台有问题的电脑上调试。通过日志看游戏初始化到哪一步了。通过日志发现了在那台电脑上游戏的模块间通讯机制全部失灵了,所以数据虽然准备好了,但是无法发送出去完成实例化。于是跑去找写框架的老大问问可能的原因。也没问出个所以然来。最后没招了,就把老大拖过来看看。不愧是老大啊。抓包查看了一会数据就发现了可能的问题。有一个mp3的文件加载卡住了。然后不知他怎么会想到插上个耳机去试试的。居然游戏就进去了!再把耳机拔出来,游戏果然又进不去了。居然是没有音频输出设备导致的问题。。。公司的电脑虽然都是一样的硬件,但是有的是32位的有的是64位的系统,声卡驱动安装的可能也不太一样。可能碰巧有少数电脑的驱动在没有任何音频输出设备的时候会屏蔽掉声卡吧。游戏中又是有音效的。导致播放声音的时候FP内部报错了,影响了通讯模块。

既然知道了问题出在没有音频设备上,那就在代码里找出这台机器不插耳机和插耳机的标志,然后临时关闭音频播放就可以了。先测试了Capabilities.hasAudio,Capabilities.hasMP3,Capabilities.hasStreamingAudio这几个标志,全都始终为true。不可用。幸好出问题的电脑在公司,我可以直接上去调试。花了一个多小时在那台机器上部署了一套开发环境。不多久就查出报错的问题了。有几行代码如下,

if(_bgSound==null)
{
_bgSound = new Sound;
_bgSound.load(new URLRequest(model.OutFolder+model.BACKGROUND_SELF));
}
_bgSoundChanel = _bgSound.play();
_bgSoundChanel.soundTransform.volume = SOUND_LEVEL_MEDIUM;

    最后一行报_bgSoundChanel为空对象的错误。查看了play()方法的注释才发现最后有这一句:

“返回: SoundChannel 对象,用于控制声音。如果没有声卡或用完了可用的声道,此方法将返回 null。”

    原来是这样。加上是否是null的判断就可以了。

    这个bug在本地还真不容易被发现。一般人的电脑即使没有音频设备,声卡也是可以用的。记录一下吧。如果有人有遇到类似情况,可以给个参考。