Boa noite, eu estou com um problema utilizando um Sequencer.
Classe MusicPlayer
private static final MusicPlayer MUSIC_PLAYER = new MusicPlayer();
private Thread player;
private String currentMusic;
private Sequencer sequencer;
private MusicPlayer() {
player = new Thread(this);
try {
sequencer = MidiSystem.getSequencer();
player.start();
} catch (MidiUnavailableException e) {
// TODO
}
}
public static MusicPlayer getInstance() {
return MUSIC_PLAYER;
}
public void playMusic() throws Exception {
sequencer.open();
InputStream is = new BufferedInputStream(new FileInputStream(new File(
currentMusic)));
sequencer.setSequence(is);
sequencer.start();
}
public void changeMusic(String newMusic) throws Exception {
currentMusic = newMusic;
if (sequencer.isRunning()) {
sequencer.stop();
}
}
Main:
public static void main(String[] args) throws Exception {
MUSIC_PLAYER.changeMusic("midi1.mid");
Thread.sleep(2500);
MUSIC_PLAYER.changeMusic("midi2.mid");
Thread.sleep(2500);
MUSIC_PLAYER.changeMusic("midi1.mid");
}
Metodo run (a classe implements Runnable):
@Override
public void run() {
while (true) {
if (currentMusic != null && !sequencer.isRunning()) {
try {
playMusic();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Basicamente, eu instancio o MusicPlayer, no construtor eu instancio a Thread aponto o sequencer para o MidiSystem e começo a Thread. Na(s) primeira(s) vez(es) dentro do run() currentMusic será null até que MUSIC_PLAYER.changeMusic(“midi1.mid”) seja chamado.
A partir dai a String currentMusic será “midi1.mid” e ambas as condições do bloco if dentro do método run() válidas para chamar o metodo playMusic(). O !sequencer.isRunning() é necessário para evitar que a mesma música seja tocada milhares de vezes por segundo. Até ai tudo bem, a música toca sem problema até MUSIC_PLAYER.changeMusic(“midi2.mid”).
O método é chamado, interrompe a música que está tocando o que é o suficiente para satisfazer o if, já que sequencer.isRunning() retorna false e currentMusic não é null.
Ele simplesmente não entra mas a parte mais estranha é se eu chamo o método sequencer.isRunning() a partir de dentro de um System.out.println(); ele entra no if. Se eu invocar esse método sem o System.out.println() nada acontece.
Ou seja, se eu alterar o método run para:
@Override
public void run() {
while (true) {
System.out.println(sequencer.isRunning());
if (currentMusic != null && !sequencer.isRunning()) {
try {
playMusic();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Ele reinicia a música assim que ela se encerra (que é o que eu quero). Qual a minha falha nesse código?