问题描述
Addingclip.drain()
after clip.start()
seems to have worked okay for me (IDE and command line
both with and without &
)
import java.io.IOException;
import java.net.URL;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
public class SandBox {
public static void main(String[] args) {
try {
URL url = SandBox.class.getResource("/sound-effects/Loud-alarm-clock-sound.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
AudioFormat af = ais.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, af);
Clip clip = (Clip) AudioSystem.getLine(info);
clip.open(ais);
clip.start();
System.out.println("Drain...");
clip.drain();
System.out.println("...Drained");
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException exp) {
exp.printstacktrace();
}
}
}
Now, having said that, I have found drain
a little unreliable in the past,
especially when there are multiple sounds playing in which case I tend to use
a LineListener
For example…
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
public class SandBox {
protected static final Object LOCK = new Object();
public static void main(String[] args) {
try {
URL url = SandBox.class.getResource("/sound-effects/Loud-alarm-clock-sound.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
AudioFormat af = ais.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, af);
Clip clip = (Clip) AudioSystem.getLine(info);
clip.open(ais);
clip.addLineListener(new LineListener() {
@Override
public void update(LineEvent event) {
System.out.println(event.getType());
if (event.getType() == LineEvent.Type.STOP) {
synchronized (LOCK) {
LOCK.notify();
}
}
}
});
clip.start();
synchronized (LOCK) {
LOCK.wait();
}
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException | InterruptedException exp) {
exp.printstacktrace();
}
}
}
解决方法
我正在使用的音频文件位于以下位置:http :
//www.orangefreesounds.com/loud-alarm-clock-sound/
这是我在Eclipse IDE中的文件结构: 我的文件结构是什么样的
当我在IDE中运行该音频文件时,它的播放效果非常好,但是当
将其导出为JAR文件时,该文件却不能正常播放。我已经检查并发现音频文件
在JAR文件中。
我正在使用终端命令java -jar Sandbox.jar &来运行JAR文件。
该程序似乎能够找到该文件(因为它没有抛出
IOException),但是似乎无法执行播放。
为什么会发生此问题,我该如何解决?
奇怪的更新
好的,实际上,在Windows 8.1
cmd或PowerShellWindows 8.1上运行时,JAR文件能够播放音频文件,但
由于某些原因,无法在Ubuntu 14.04终端中运行。一直以来,我一直在尝试在
Ubuntu 14.04中运行JAR文件。
奇怪的更新#2
我已经确认JAR文件仅在Windows 8.1
系统上起作用的问题。这个问题中的两个代码段都
不起作用,而MadProgrammer的两个解决方案都可以工作。
最小,完整和可验证的示例(不适用于Windows或
Ubuntu)
import java.io.IOException;
import java.net.URL;
import javax.sound.sampled.*;
public class Sandbox
{
public static void main(String[] args) throws UnsupportedAudioFileException,IOException,LineUnavailableException
{
URL url = Sandbox.class.getResource("/sound-effects/alarmSoundClip.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
AudioFormat af = ais.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class,af);
Clip clip = (Clip) AudioSystem.getLine(info);
clip.open(ais);
clip.start();
}
}
尝试的解决方案1(在Windows或Ubuntu上不起作用)
一种尝试的解决方案(如Andrew Thompson所建议)是
this.getClass().getResource( ... )代替Sandbox.class.getResource(…)
:
import java.io.IOException;
import java.net.URL;
import javax.sound.sampled.*;
public class Sandbox
{
public static void main(String[] args) throws UnsupportedAudioFileException,LineUnavailableException
{
new Sandbox();
}
public Sandbox() throws UnsupportedAudioFileException,LineUnavailableException
{
URL url = this.getClass().getResource("/sound-effects/alarmSoundClip.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
AudioFormat af = ais.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class,af);
Clip clip = (Clip) AudioSystem.getLine(info);
clip.open(ais);
clip.start();
}
}