我在Android上播放Ogg Vorbis声音时遇到了一个奇怪的问题,我很难纠正。我正在使用SoundPool类播放声音。除了暂停后播放的第一个声音外,它的效果很好。
这是我遇到的问题:我有一个菜单上有几个按钮。如果我按下按钮,我会发出嘀嗒声。但是,我第一次尝试播放它时,它不会发出声音。然后,如果我再次点击相同的菜单按钮,它会起作用。如果我然后延迟下一次按下几秒钟,问题就会重新出现。具体来说,我看到以下行为:
我在几个不同的设备上看到过这种行为:HTC Incredible,rooted Nook Color和HTC Thunderbolt,所以我不相信它是特定于设备的。
我是GUESSING这是AudioHardwareQSD进入待机状态的功能。一旦它处于待机状态,滑槽外的第一个声音将被忽略,而随后的声音将一直有效,直到它再次进入待机状态。 “写入阻止”消息和HTC Incredible上的AudioHardwareQSD消息之间大约有3秒的延迟。
这里有一个关于StackOverflow的答案,讨论使用WakeLock来防止这种情况发生。我尝试了这个解决方案,并没有解决我的问题。
为什么会这样?有没有办法防止AudioHardwareQSD进入待机状态?有没有人对此进行故障排除提示?
谢谢!
更新:我已经能够实施一个相当粗略的解决方法来纠正这个问题。在我的应用程序(游戏)中,我有一个更健全的渲染类。我添加了一个新方法present(),它由游戏逻辑定期执行。该方法使用1.5秒超时计时器。当计时器触底时,声音渲染器播放包含50ms静音的音频文件,然后重置计时器。
这已经纠正了我的问题......远非最佳状态,但它确实有效。
答案 0 :(得分:1)
Android SoundPool真的很糟糕。我必须
int streamid = soundPool.play(sid, soundVolume, soundVolume, 0, loopVal, 1.0f);
if (streamid == 0) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} while(streamid == 0 && retry++<3);
但这并不理想,它确实会降低帧速率。
答案 1 :(得分:0)
您可以在后台线程中初始化SoundPool并设置SoundPool.OnLoadCompleteListener以在准备好时获得通知。
答案 2 :(得分:0)
原帖发表四年,我也有同样的问题!在我的情况下,它使用Android API 19在三星Galaxy S3上。但我找到了一个不同的解决方案,不需要以定时间隔播放静音。
相反,我发现它只是第一次没有播放的音频文件的第一部分(50-100ms)。因此,编辑我的声音文件,以便生成的mp3在开始时有大约100毫秒的静音,然后正确播放。点击按钮几乎感觉不到100毫秒的延迟。
答案 3 :(得分:0)
问题在 2021 年仍然存在。
真正摆脱初始延迟的唯一解决方案是使用一个线程,每 5 秒左右连续播放音量为 0 的声音。
科特林代码:
class SoundThread(soundPool: SoundPool) : Thread() {
private var soundPool: SoundPool = soundPool;
var sounds: BlockingQueue<SoundEntity> = LinkedBlockingQueue<SoundEntity>();
override fun run() {
var sound: SoundEntity;
var prevTime = System.currentTimeMillis();
while(true){
var now = System.currentTimeMillis();
if(now - prevTime > 5000){
this.soundPool.play(1, 0.0f, 0.0f, 1, 0, 1.0f);
prevTime = now;
}
if(!sounds.isEmpty()) {
sound = sounds.take();
this.soundPool.play(sound.soundId, sound.volume, sound.volume, 1, 0, 1.0f);
}
}
}
}
修改了来自 here 的 Andreas Linden 的回答。
(我为那些忽略问题中解决方法部分的人写了这个答案,就像我一样。)