我有一点问题。我正在使用Java声音采样播放mp3,我想在单击按钮时停止播放。所以我想出了类似的东西:
package sk.umb.osadnici.Client.Core.getterImages;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine.Info;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.sound.sampled.FloatControl;
import javazoom.jl.player.advanced.AdvancedPlayer;
import static javax.sound.sampled.AudioSystem.getAudioInputStream;
import static javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED;
public class GetterForBGMusic {
private SourceDataLine line;
private URL url;
public URL bgUrl, bgUUUrl;
private boolean canPlay = true;
public void runMusic() {
final GetterForBGMusic player = new GetterForBGMusic();
player.play();
}
public void play() {
URL inTTT = getClass().getResource("../sounds/bgMusic.mp3");
try (AudioInputStream in = getAudioInputStream(inTTT)) {
AudioFormat outFormat = getOutFormat(in.getFormat());
Info info = new Info(SourceDataLine.class, outFormat);
try (SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info)) {
if (line != null) {
System.out.println(canPlay);
line.open(outFormat);
line.start();
stream(getAudioInputStream(outFormat, in), line);
line.drain();
line.stop();
}
}
} catch (UnsupportedAudioFileException
| LineUnavailableException
| IOException e) {
throw new IllegalStateException(e);
}
}
private AudioFormat getOutFormat(AudioFormat inFormat) {
final int ch = inFormat.getChannels();
final float rate = inFormat.getSampleRate();
return new AudioFormat(PCM_SIGNED, rate, 16, ch, ch * 2, rate, false);
}
private void stream(AudioInputStream in, SourceDataLine line)
throws IOException {
while (true) {
System.out.println(this.getCanPlay());
}
}
public void setCanPlay(boolean play) {
this.canPlay = play;
}
public boolean getCanPlay() {
return canPlay;
}
private void booleanValue() {
while (true)
System.out.println(canPlay);
}
}
我使用这段代码,如果我在构造函数中调用booleanValue方法,一切都很好。但如果在流内部调用此方法,则值更改后不会发生更改。
或者有人可以告诉我如何制止这种情况:http://odoepner.wordpress.com/2013/07/19/play-mp3-or-ogg-using-javax-sound-sampled-mp3spi-vorbisspi/
答案 0 :(得分:1)
你的程序是单线程的,这意味着它执行你从上到下编程的“命令”序列。
例如,在此示例中
setCanPlay(true);
play(); //your for loop
setCanPlay(false);
setCanPlay(false)指令仅在for循环执行完毕后执行。
您需要的是让for循环在后台运行,并且能够在for循环运行时修改 canPlay 。这称为多线程,您应该在java api doc中查找Runnable,Task和Service类,以了解如何实现它。
你最终会得到这样的东西:
setCanPlay(true);
play(); //your for loop, launched in another thread.
setCanPlay(false); // Executed while the for loop is running
这会立即开始和结束比赛。
多线程是唯一方式来停止执行程序(从外部)。