问题
So for an app I'm developing I have a bunch of audio files that, depending on the state of some variables, may or may not play (and the order in which they play can change as well).
I understand the basics of the setOnCompletionListener
, but I can't figure out the best way to use it. As of right now, if I want to play audio1, audio2, then audio3, my code is set up as follows:
clipSetup(1);
aP.setOnCompleteListener(new MediaPlayer.OnCompletionListener(){
@Override
public void onCompletion(MediaPlayer mp){
clipSetup(2);
aP.setOnCompleteListener(new MediaPlayer.OnCompletionListener(){
@Override
public void onCompletion(MediaPlayer mp){
clipSetup(3);
}
});
}
});
private MediaPlayer clipSetup(int i){
switch (i){
case 1:
aP = MediaPlayer.create(this, R.raw.audio1);
aP.start();
break;
case 2:
aP = MediaPlayer.create(this, R.raw.audio2);
aP.start();
break;
case 3:
aP = MediaPlayer.create(this, R.raw.audio3);
aP.start();
break;
}
return aP;
}
This works, but its ugly as all hell, especially when I have to play upwards of 15 files for some purposes. Is there a better way of accomplishing what I've got above?
回答1:
I have not worked with audio files before, but here is my best shot
It is a good starting idea. This only allows you to add files to a buffer that will play one after another. Call addInitFile() to start an audio file, and then call addFile() to add more files to keep playing after the first one. It is just a start and code that was thrown together without testing
It could be much better code, but its just a start. at least better than a case switch
I would make this an inner class for accessibility purposes
public class CustomMediaBuffer{
public static ArrayList<Integer> buffer = new ArrayList<Integer>();
public static void addInitFile(final int res){
buffer.add(res);
ap = MediaPlayer.create(this, res);
ap.start();
ap.setOnCompleteListener(new MediaPlayer.OnCompletionListener(){
public void onCompletion(MediaPlayer mp){
int indx = buffer.indexOf(res);
if(buffer.size()-1>index){
ap = MediaPlayer.create(this, buffer.get(indx+1));
ap.start();
}
}
});
}
public static void addFile(int res){
buffer.add(res);
}
}
Here is the better, updated code:
public class CustomMediaBuffer{
public static ArrayList<MediaPlayer> buffer = new ArrayList<MediaPlayer>();
public static void addInitFile(final int res){
final MediaPlayer mp= MediaPlayer.create(this, res );
buffer.add(mp);
ap = buffer.get(0);
ap.start();
ap.setOnCompleteListener(new MediaPlayer.OnCompletionListener(){
public void onCompletion(MediaPlayer media){
int indx = buffer.indexOf(mp);
if(buffer.size()-1>index){
ap = buffer.get(indx+1));
ap.start();
}
}
});
}
public static void addFile(final int res){
final MediaPlayer mp= MediaPlayer.create(this, res );
mp.setOnCompleteListener(new MediaPlayer.OnCompletionListener(){
public void onCompletion(MediaPlayer media){
int indx = buffer.indexOf(mp);
if(buffer.size()-1>index){
ap = buffer.get(indx+1));
ap.start();
}
}
});
buffer.add(mp);
}
}
回答2:
Try to use setDetaSource(). It will looks something like that:
@Override
public void onCompletion(MediaPlayer mp) {
if (currentPosition < sourceArray.size()) {
mediaPlayer.reset();
currentResId=currentResId==RESIDS.length-1?0:currentResId+1;
AssetFileDescriptor afd = context.getResources().openRawResourceFd(RESIDS[currentResId]);
if (afd == null) {
return;
}
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
mediaPlayer.start();
} else {
mediaPlayer.release();
}
}
But you should create the RESIDS
array first.
You can create it from your raw resources:
int[] RESIDS = {R.raw.audio1,R.raw.audio2,R.raw.audio3}
int currentResId=0;
You may need to add try-catch. Hope this helps.
回答3:
You can try this recursive approach
MediaPlayer aP;
int i;
R[] rid = {R.raw.audio0,R.raw.audio1,R.raw.audio2,R.raw.audio3,R.raw.audio4};
private void clipSetup(final int end) {
aP = MediaPlayer.create(this, rid[i]);
aP.start();
if(i<end){
aP.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
@Override
public void onCompletion(MediaPlayer mp){
clipSetup(end);
}
});
}
i++;
}
Just call clipSetup(5) in the place where you want to call it. Where 5 is the last number in the sequence
来源:https://stackoverflow.com/questions/27881684/how-do-you-play-audio-file-sequentially-in-java