Reputation: 6546
I have 8 mp3 files. And I have to play it simultaneously (not nearly. will for sure).
I'm using 'AudaCity' for control accuracy. But my code did't give me the desired results...
(asynchrony = 30~90 ms)
So, it's my code:
(for first start to play)
public void start() {
//songInfo.getMediaPlayer() - it's array of MediaPlayers, source already setted
for (MediaPlayer player : songInfo.getMediaPlayer()) {
try {
if (player != null) {
player.prepare();
player.seekTo(0);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
songInfo.getMediaPlayer()[0]
.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
//code for play next setlist
}
});
resume();
}
(for pause)
public void pause() {
for (MediaPlayer player : songInfo.getMediaPlayer()) {
if (player != null)
player.pause();
}
}
(for resume after pause, and for start play(used in first method))
public void resume() {
int pos = songInfo.getMediaPlayer()[0].getCurrentPosition();
long iTime = System.currentTimeMillis();
for (MediaPlayer player : songInfo.getMediaPlayer()) {
if (player != null) {
player.seekTo(pos + (int)(System.currentTimeMillis()-iTime));
player.start();
}
}
}
If I start play in the first time it gives me asynchrony ~ 30ms+
Then after pause/resume it plays perfect.
Upvotes: 4
Views: 3055
Reputation: 6546
After much research, problem was solved.
To play several tracks simultaneously you should use AsyncTask and execute it on THREAD_POOL_EXECUTOR.
How to do this:
Thread class:
class PlayThread extends AsyncTask<MediaPlayer, Void, Void>
{
@Override
protected Void doInBackground(MediaPlayer... player) {
player[0].start();
return null;
}
}
Media Players:
MediaPlayer[] players = new MediaPlayer[5];
//Then set source to each player...
//...
//Create objects of Thread class
PlayThread[] playThreads = new PlayThread[5];
for (int i = 0; i < 5; i++)
playThreads[i] = new PlayThread();
//Set Media Players there and start play
for (int i = 0; i < 5; i++)
playThreads[i].executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, players[i]);
AsyncTask can execute only 5 Threads simultaneously, other are going to queue.
SoundPool buffer limit is 1Mb, so it is not a solution at all.
It is very important:
To play simultaneously more audio tracks you should mix them into 1 buffer.
The way to do this: decode mp3 to pcm (to small buffers in stream mode), mix it into one byte buffer and put it to AudioTrack for playing.
Upvotes: 5