2013-04-16 2 views
1

Я адаптировал класс musicplayer от Music Loop in Java для использования в моей собственной программе, но у меня возникла странная проблема. У меня есть кнопка, чтобы начать и остановить музыку, , и если я нажму один раз, музыка начнется правильно, и программа будет работать нормально. Если я снова нажму на него, музыка остановится, и программа останется в порядке. Проблема возникает, когда я нажимаю кнопку в третий раз. Музыка начнет играть так, как должна, но остальная часть программы перестает отвечать. Вот что я имею в классе MusicPlayer.Неисправность перезагрузки музыки

import java.io.*; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import sun.audio.AudioPlayer; 
import sun.audio.AudioStream; 

public class MusicPlayer extends Thread { 
private AudioStream as; 
private AudioPlayer player; 
private boolean playback; 
private String fileLoc = MusicPlayer.class.getClassLoader().getResource("resources/Yamaha-TG-77-Acoustic-Bass-C4.wav").toString(); 
private String edittedLoc = fileLoc.substring(6); 

public void run() { 
    try 
    { 
     startPlayback(); 
    } catch (FileNotFoundException ex) 
    { 
     Logger.getLogger(MusicPlayer.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (IOException ex) 
    { 
     Logger.getLogger(MusicPlayer.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 
public void startPlayback() throws FileNotFoundException, IOException 
{ 
    playback = true; 
    System.out.println(edittedLoc); 
    as = new AudioStream(new FileInputStream(edittedLoc)); 
    AudioPlayer.player.start(as); 
    try { 
     do { 
     } while (as.available() > 0 && playback); 
     if (playback) { 
      startPlayback(); 
     } 
    } catch (IOException ex) { 
     Logger.getLogger(MusicPlayer.class.getName()).log(Level.SEVERE, null, ex); 
    } 

} 

public void stopPlayback() throws IOException 
{ 
    playback = false; 
    AudioPlayer.player.stop(as); 
} 
} 

и вот кнопка, которая управляет музыкой

class MusicClick implements ActionListener 
{ 
    @Override 
    public void actionPerformed(ActionEvent e) 
    { 
     Game tempGame = getGame(); 
     if (tempGame.getMusicInitialized() == false) 
     { 
      tempGame.getMusicPlayer().start(); 
      tempGame.setMusicInitialized(true); 
      tempGame.setMusicPlaying(true); 
     } 
     else if (tempGame.getMusicInitialized() == true) 
     { 
      if (tempGame.getMusicPlaying() == false) 
      { 
       try 
       { 
        tempGame.getMusicPlayer().startPlayback(); 
       } catch (FileNotFoundException ex) 
       { 
        Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); 
       } catch (IOException ex) 
       { 
        Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); 
       } 
       tempGame.setMusicPlaying(true); 
      } 
      else if (tempGame.getMusicPlaying() == true) 
      { 
       try 
       { 
        tempGame.getMusicPlayer().stopPlayback(); 
       } catch (IOException ex) 
       { 
        Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); 
       } 
       tempGame.setMusicPlaying(false); 
      } 
     } 
    } 
} 

Ok, я пытался использовать клип вместо, как это было предложено. Теперь у меня есть это

import java.io.File; 
import java.net.URL; 
import javax.swing.*; 
import javax.sound.sampled.*; 

public class BackgroundMusic extends Thread 
{ 
private static Clip clip; 
private static String fileLoc = MusicPlayer.class.getClassLoader().getResource("resources/Yamaha-TG-77-Acoustic-Bass-C4.wav").toString(); 

public static synchronized void playSound() 
{ 
    new Thread(new Runnable() { 
     public void run() 
     { 
      try 
      { 
       clip = AudioSystem.getClip(); 
       String edittedLoc = fileLoc.substring(6); 
       System.out.println(edittedLoc); 
       AudioInputStream inputStream = AudioSystem.getAudioInputStream(new File(edittedLoc)); 
       clip.open(inputStream); 
       clip.loop(Clip.LOOP_CONTINUOUSLY); 
       clip.start(); 
      } catch(Exception e) 
      { 
       System.err.println(e.getMessage()); 
      } 
     } 
    }).start(); 
} 

public static void resumePlay() 
{ 
    playSound(); 
} 

public static void pausePlay() 
{ 
    clip.stop(); 
} 
} 

Это работает именно так, как я хочу, но у меня был только один вопрос. Для метода resumePlay() я попытался просто сделать clip.start(), но по какой-то причине это не возобновит клип, поэтому вместо этого я снова вызвал функцию playSound(), которая работает. Есть ли причина, по которой clip.start не будет работать в этом методе? Или есть способ, которым я могу закончить поток при остановке музыки, потому что я заметил в отладчике, что каждый вызов playSound запускает новый поток, который, как я думаю, может привести к проблемам.

+0

Используйте 'Clip' вместо того, чтобы погружаться в пакеты' sun.audio'. 'Clip' является частью JSE и документирован, если эти' sun' не являются. См. [Информация о звуке Java. страница] (http://stackoverflow.com/tags/javasound/info) для примера использования. –

ответ

0

Если программа перестает отвечать, первая мысль, которая приходит мне на ум, заключается в том, что у вас бесконечный цикл. Debug или положить System.out.println() заявления внутри ваших петель, чтобы убедиться, что зацикливания переменные фактически меняется ...

+0

Вся программа не перестает отвечать. Музыка будет продолжать играть, но больше ничего не ответит. Я знаю, что сама игра отлично работает, если я никогда не начинаю музыку, или если я ее однажды остановлю. Я думаю, возможно, это потому, что музыкальный поток каким-то образом блокирует основной поток? –

1

В классе MusicClick используется

tempGame.getMusicPlayer().startPlayback(); 

Это не создает новый поток и блокирует ваше приложение.

+0

Вот почему у меня есть tempGame.getMusicPlayer(). Start(); если музыка не была инициализирована, хотя –

+0

Ваша нить 'MusicPlayer' умирает при вызове 'stopPlayback();'. Если вы пытаетесь перезагрузить музыку, основной поток отвечает за воспроизведение музыки (из-за того, что не создается новый поток (метод .start()) – user1595178

+0

Хорошо, это имеет смысл, что главный становится ответственным за воспроизведение музыки, но если я измените его туда, где он делает .start(), я получаю исключение из нелегального состояния. –