Hello I am currently trying to add music to my application and right now I am having the program get the file names from a file and play them. Due to a flaw in the application that I have tried mediating by putting the Thread to sleep the music player plays both pieces at the same time which while it sounds nice doesn't help me. Below is my code:
public static class MusicPlayerService extends Service<Void>
{
public static File[] musicArray = new File[2];
public static int fileNumber = 0;
@Override
protected Task<Void> createTask(){
Scanner musicListReader;
try {
musicListReader = new Scanner(new File("Music_PlayList.txt"));
while(musicListReader.hasNext())
{
musicArray[fileNumber] = new File(musicListReader.next());
String uriString = musicArray[fileNumber].toURI().toString();
Media media = new Media(uriString);
MediaPlayer player = new MediaPlayer(media);
player.play();
Thread.sleep((long) media.getDuration().toMillis());
fileNumber++;
}
} catch (FileNotFoundException | InterruptedException e1) {
e1.printStackTrace();
}
return null;
}
}
Instead of the looping-and-sleeping approach, consider using an event-driven approach instead. You can register an onStopped
handler with the media player, and start the next song (if there is a next song) from there. This way, you don't need to use a background thread either.
Something like:
Queue<File> musicList = new LinkedList<File>();
try (Scanner musicListReader = new Scanner(new File("Music_PlayList.txt"))) {
while (musicListReader.hasNext()) {
musicList.add(new File(musicListReader.next()));
}
} catch (Exception e) {
e.printStackTrace();
}
playNextMusicFile(musicList);
// ...
private void playNextMusicFile(Queue<File> musicList) {
if (musicList.isEmpty()) {
return ;
}
Media media = new Media(musicList.remove().toURI().toString());
MediaPlayer player = new MediaPlayer(media);
player.setOnEndOfMedia(() -> {
player.dispose();
playNextMusicFile(musicList);
});
player.play();
}