cocos creator 背景音乐设置循环后仍然在某些情况下会中断播放

图1


图2

图3

图4


如上图所示,图1为播放背景音乐代码,设置loop为true.图2为播放log日志。图3为释放日志。图4位释放是截图。
问题为:
1.既然设置了循环播放,为什么source为AL_STOPPED状态?这个状态是什么时候改变的?
2.为什么脚本层返回的audio为63,到c++层变为64了?但其_alSource都是2401?

补充一下:
大于1M就默认不循环,但是我们发现我们主菜单背景音乐大于1M,还是循环播放?


这块,update在主线程中执行,手动断点卡顿后就变为AL_STOPPED状态了。何解呢?

拜托,以后反馈问题,可以带上你的Creator版本号么?????????

这个问题,应该在1.5.1版本中修复了。
你对比一下:
https://github.com/cocos-creator/cocos2d-x-lite/pull/664
看看你的代码是否有这个patch的内容。

alSource id和返回给脚本层的id不是同一个的, alSource id是内部循环使用的底层ID,返回给上层的ID是不重复递增的。

版本号是1.5.1正式版。

你好,我之前发现你们CocosCreator_v1.5.2-beta.2版本修正了这个问题,我就对比了代码。发现修正跟https://github.com/cocos-creator/cocos2d-x-lite/pull/664这个是一样的。但是还是存在这个问题。

昨天晚上我debug发现貌似我play时候传的loop没有用,这里重新设置了。而且是根据_queBufferFrames这个值。能说明一下,既然_queBufferFrames在大于0的情况下,何时设置为循环的呢?


然后还发现在断点的情况下,这里的循环播放的背景音乐sourceState会变为AL_STOPPED。

如果是_queBufferFrames > 0的情况,说明当前的audio是被streaming的状态,即不全部预加载到内存中,streaming是边解码边播放的方式,不能调用alSourcei(_alSource, AL_LOOPING, AL_TRUE);的方式设置循环。

streaming设置循环的地方在:

void AudioPlayer::rotateBufferThread(int offsetFrame)
{
...
            if (sourceState == AL_PLAYING) {
                alGetSourcei(_alSource, AL_BUFFERS_PROCESSED, &bufferProcessed);
                while (bufferProcessed > 0) {
                    bufferProcessed--;
                    if (_timeDirty) {
                        _timeDirty = false;
                        offsetFrame = _currTime * decoder.getSampleRate(); 
                        decoder.seek(offsetFrame); // 由于_currTime被设置为0, 这里解码的时候,就seek到开始位置。
                    }
                    else {
                        _currTime += QUEUEBUFFER_TIME_STEP;
                        if (_currTime > _audioCache->_duration) {
                            if (_loop) { // 这里判断,如果是循环,则将_currTime设置为0
                                _currTime = 0.0f;
                            } else {
                                _currTime = _audioCache->_duration;
                            }
                        }
                    }
}

这块调试,还是不能手动断点,否则太久没有fill AL buffer,可能导致让AL认为状态为Stop了。