我有一个.wav文件,我想在我的游戏中使用它,目前我正在加载游戏中每项活动onCreate()
的声音。
soundCount = soundpool.load(this,R.raw.count, 1);
活动开始后将播放声音。
soundpool.play(soundCount, 0.9f, 0.9f, 1, -1, 1f);
问题有时我会遇到错误"sample x not ready"
。
是否可以在开始游戏时加载.wav文件并将其保存在内存中并在以后的游戏中使用它?或者是否可以等待1-2秒以使声音加载完成?
答案 0 :(得分:33)
您需要通过SoundPool.setOnLoadCompleteListener
添加一个监听器来等待它完成。
答案 1 :(得分:5)
由于我的项目与Android 1.5兼容,我无法使用setOnLoadCompleteListener,因此我解决了延迟播放声音的问题。 我的源代码如下:
playSound_Delayed(soundId, 100);
//(..)
private void playSound_Delayed (final int soundId, final long millisec) {
// TIMER
final Handler mHandler = new Handler();
final Runnable mDelayedTimeTask = new Runnable() {
int counter = 0;
public void run() {
counter++;
if (counter == 1) {
boolean ret = mHandler.postDelayed(this, millisec);
if (ret==false) Log.w("playSound_Delayed", "mHandler.postAtTime FAILED!");
} else {
playSound(soundId);
}
}
};
mDelayedTimeTask.run();
}
答案 2 :(得分:4)
如果可能的话,你应该使用setOnLoadCompleteListener ......如果没有,请在你的'play'调用周围打一个while循环。类似的东西:
int waitLimit = 1000;
int waitCounter = 0;
int throttle = 10;
while(soundPool.play(soundId, 1.f, 1.f, 1, 0, 1.f) == 0 && waitCounter < waitLimit)
{waitCounter++; SystemClock.sleep(throttle);}
这将以10毫秒的间隔重试“播放”1000次。这当然应该在非ui线程上运行,并且仍然不理想。但也许比等待任意时间并期望游泳池准备好一点强。
答案 3 :(得分:2)
SoundPool库使用MediaPlayer服务将音频解码为原始的16位PCM单声道或立体声流,我们可以简单地调用Stream的准备,这需要一些时间取决于声音文件的大小。如果我们在该过程结束之前尝试播放声音,我们会得到“sample x not ready”错误。
这个有两个解决方案
然后播放它 请注意,此条件没有例外,或者应用程序在没有任何try-catch
的情况下不会崩溃答案 4 :(得分:2)
private SoundPool soundPool;
private int my_sound;
boolean loaded = false;
//在构造函数
中soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
my_sound = soundPool.load(this, R.raw.blast_sound, 1);
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
public void onLoadComplete(SoundPool soundPool, int sampleId,int status) {
loaded = true;
}
});
//然后在哪里播放声音,输入
if (loaded) {
soundPool.play(my_sound, 0.9f, 0.9f, 1, 0, 1f);
}
答案 5 :(得分:2)
我用简单的do-while cicle解决了问题。方法play()如果成功则返回非零streamID,如果失败则返回零。因此,检查返回值就足够了。
int streamID = -1;
do {
streamID = soundPool.play(soundPoolMap.get(index), streamVolume, streamVolume, 1, 0, 1f);
} while(streamID==0);
答案 6 :(得分:2)
这绝对适用于您!
public void playWavFile() {
Thread streamThread = new Thread(new Runnable() {
@Override
public void run() {
SoundPool soundPool;
final int wav;
String path = "/mnt/sdcard/AudioRecorder/record.wav";
soundPool = new SoundPool(5,AudioManager.STREAM_MUSIC, 0);
wav = soundPool.load(path, 1);
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
// TODO Auto-generated method stub
soundPool.play(wav,100, 100, 0, 0, 1f);
}
});
}
});
streamThread.start();
}
答案 7 :(得分:1)
这听起来很疯狂,但不要马上播放声音。给你的应用程序几秒钟初始化SoundPool。在我的应用程序中,这正是问题所在;我添加了一个假的“加载”屏幕~3秒,然后一切正常。 (我甚至不需要预加载声音。)