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