问题
I have a small app that basically sets up a timer and plays sets of 2 sounds one after another.
I've tried 2 timers, because I wanted both sounds to start exactly at the same time each time. I gave the app 500ms for setting both timers before they start
Calendar cal = Calendar.getInstance();
Date start = new Date(cal.getTime().getTime() + 500);
timerTask1 = new TimerTask() { //1st timer
@Override
public void run() {
soundManager.playSound(1);
}
};
timer1 = new Timer();
timer1.schedule(timerTask1, start, 550);
timerTask2 = new TimerTask() { //2nd timer
@Override
public void run() {
soundManager.playSound(2);
}
};
timer2 = new Timer();
timer2.schedule(timerTask2, start, 550);
}
soundManager is a SoundManager object which is based on this tutorial. Thew only change I've made was decreasing number of avalible streams from 20 to 2 since I play only 2 sounds at the same time.
Now the problem. It's not playing at the equal rate neither on my Motorola RAZR or the emulator. The app slows sometimes, making a longer brake than desired. I can't let that happen. What could be wrong here?
I'm using very short sounds in OGG format
EDIT: I've made some research. Used 2 aproaches. I was measuring milisecond distances between sound was fired. Refresh rate was 500 ms.
- 1st aproach was TimerTask - it is a big fail. It started at 300ms, then was constantly growing, and after some time (2 mins) stabilized at 497ms which would be just fine if it started as that.
- 2nd aproach was while loop on AsyncTask - it was giving me outputs from 475 to 500ms which is better than TimerTask but still inaccurate
At the end none of aproach was playing smoothly. There were always lags
回答1:
I know it may be a little too much, but you could try a different implementation of SoundPool:
public class Sound {
SoundPool soundPool;
int soundID;
public Sound(SoundPool soundPool, int soundID) {
this.soundPool = soundPool;
this.soundID = soundID;
}
public void play(float volume) {
soundPool.play(soundID, volume, volume, 0, 0, 1);
}
public void dispose() {
soundPool.unload(soundID);
}
}
To use it you can do something like this:
SoundPool soundPool = new SoundPool(20, AudioManager.STREAM_MUSIC, 0);
AssetFileDescriptor assetFileDescriptor = activity.getAssets().openFd(fileName);
int soundID = soundPool.load(assetFileDescriptor, 0);
Sound sound = new Sound(soundPool, soundID);
And then play:
sound.play(volume);
P.S. If the problem persists even with this code, post a comment and I'll get back to you.
回答2:
Are you using SoundPool? It is quicker than MediaPlayer. The best chance of getting the two sounds together is when playing them on the same thread.
来源:https://stackoverflow.com/questions/12012933/lags-while-playing-2-sounds-on-the-same-time-in-timer