Java剪辑不起作用 [英] Java clip not working
问题描述
有人可以帮我理解为什么下面这段代码不起作用吗?
Can someone please help me understand why this code below doesn't work?
我通过调用方法 start()<启动剪辑/ code>。此方法为剪辑创建一个新线程以运行。但是,不,它似乎没有播放任何东西。
I start the clip by calling method start()
. This method creates a new thread for the clip to run. However, no it doesn't seem to play anything.
代码编译没有任何错误...
The code is compiled without any error...
public class Audio
{
private Clip clip;
private Thread thread;
public Audio (String audioFile)
{
AudioInputStream audioStream = null;
URL audioURL = this.getClass().getClassLoader().getResource(audioFile);
// Obtain audio input stream from the audio file and load the information
// into main memory using the URL path retrieved from above.
try { audioStream = AudioSystem.getAudioInputStream(audioURL); }
catch (Exception e)
{
e.printStackTrace();
System.exit(1);
}
try
{
// Retrieve the object of class Clip from the Data Line.
this.clip = AudioSystem.getClip();
// Load the audio input stream into memory for future play-back.
this.clip.open(audioStream);
}
catch (LineUnavailableException e)
{
e.printStackTrace();
System.exit(1);
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
}
public void start()
{
Runnable r = new Runnable() {
public void run()
{
loop();
}
};
thread = new Thread(r);
thread.start();
}
public void loop ()
{
// Rewind the media to the beginning of the clip.
this.clip.setFramePosition(0);
// Continuously play the clip.
this.clip.loop(Clip.LOOP_CONTINUOUSLY);
try
{
Thread.sleep(5000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
更新
我发现了问题!问题是因为音频文件。我使用了不同的音频文件,我可以用上面的代码听到声音。
I found the problem! The problem is because of the audio file. I used a different audio file and I can hear the sound with the code above.
编译的代码没有任何错误或警告真的很烦人。我通过获取音频格式检测到问题,然后将其传递给类DataLine.Info的对象。然后,从数据线中检索剪辑。
It is just really annoying that the code compiled without any error or warning. I detected the problem by getting the audio format, then pass it to an object of class DataLine.Info. Then, retrieve the clip from the Data Line.
因此,基本上不是通过以下方式获取剪辑:
So, basically instead of getting the clip by:
this.clip = AudioSystem.getClip();
我会得到以下剪辑:
AudioFormat format = audioStream.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, format);
this.clip = (Clip) AudioSystem.getLine(info);
当我用这个编译时,Java抛出以下错误:
When I compiled with this, Java threw below error:
没有行匹配接口Clip支持格式PCM_SIGNED 48000.0 Hz,24 bit
No line matching interface Clip supporting format PCM_SIGNED 48000.0 Hz, 24 bit
所以,我替换了音频文件,它有效!
So, I replaced the audio file, and it worked !
推荐答案
clip.loop
是一个非阻塞的电话。也就是说,一旦你调用它(并且它完成了它的工作),它将返回,这意味着你的线程将退出,除非有另一个非守护程序线程在运行,否则JVM将退出。
clip.loop
is a non-blocking call. That is, once you call it (and it does what it does), it will return, this means your thread will exit and, unless there is another non-daemon thread running, the JVM will exit.
我原本以为你可以使用 Clip#drain
来阻止它直到剪辑完成,但从技术上讲,这个剪辑赢了在正常意义上完成......
I had thought you might be able to use Clip#drain
to cause it to block until the clip had completed, but technically, the clip won't complete...in the normal sense.
相反,我设置了自己的循环......
Instead, I set up my own loop...
public void start() {
Runnable r = new Runnable() {
public void run() {
while (true) {
clip.setFramePosition(0);
clip.start();
clip.drain();
}
}
};
thread = new Thread(r);
thread.start();
}
现在,这可能是一个问题,因为线程
是一个非守护进程线程,永远不会结束......而不是而(true){
你应该设置某种 volitle
你设置为 false
的标志并帮助终止循环......
Now, this could be an issue, because the Thread
is a non-daemon thread and will never end...Instead of while (true) {
you should setup some kind volitle
flag which you set to false
and help terminate the loop...
例如......
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
public class Audio {
private Clip clip;
private Thread thread;
private volatile boolean keepPlaying = true;
public static void main(String[] args) {
Audio audio = new Audio("Kalimba.wav");
audio.start();
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
}
audio.stop();
}
public Audio(String audioFile) {
AudioInputStream audioStream = null;
URL audioURL = this.getClass().getClassLoader().getResource(audioFile);
// Obtain audio input stream from the audio file and load the information
// into main memory using the URL path retrieved from above.
try {
audioStream = AudioSystem.getAudioInputStream(audioURL);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
try {
// Retrieve the object of class Clip from the Data Line.
this.clip = AudioSystem.getClip();
// Load the audio input stream into memory for future play-back.
this.clip.open(audioStream);
} catch (LineUnavailableException e) {
e.printStackTrace();
System.exit(1);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
public void stop() {
if (thread != null) {
keepPlaying = false;
clip.stop();
thread.interrupt();
}
}
public void start() {
Runnable r = new Runnable() {
public void run() {
while (keepPlaying) {
clip.setFramePosition(0);
clip.start();
clip.drain();
}
}
};
thread = new Thread(r);
thread.start();
}
}
已更新
上面的例子(恕我直言)有一些问题,可以用简单的对象监视器修复。
There a few things wrong with the above example (IMHO), which can be fixed with a simple object monitor.
因此,我们可以使用 Clip#而不是
功能,只需使用 volatile
标志和而
循环。循环 Object#wait
和 Object#notify
,例如
So, instead of a volatile
flag and a while
loop, we can use the Clip#loop
functionality and simply use Object#wait
and Object#notify
instead, for example
import java.io.IOException;
import java.net.URL;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
public class Audio {
private Clip clip;
private Thread thread;
private final Object loopLock = new Object();
public static void main(String[] args) {
Audio audio = new Audio("Music.wav");
audio.start();
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
}
audio.stop();
}
public Audio(String audioFile) {
AudioInputStream audioStream = null;
URL audioURL = this.getClass().getClassLoader().getResource(audioFile);
// Obtain audio input stream from the audio file and load the information
// into main memory using the URL path retrieved from above.
try {
audioStream = AudioSystem.getAudioInputStream(audioURL);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
try {
// Retrieve the object of class Clip from the Data Line.
this.clip = AudioSystem.getClip();
// Load the audio input stream into memory for future play-back.
this.clip.open(audioStream);
} catch (LineUnavailableException e) {
e.printStackTrace();
System.exit(1);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
public void stop() {
synchronized (loopLock) {
loopLock.notifyAll();
}
}
public void start() {
Runnable r = new Runnable() {
public void run() {
clip.setFramePosition(0);
clip.loop(Clip.LOOP_CONTINUOUSLY);
synchronized (loopLock) {
try {
loopLock.wait();
} catch (InterruptedException ex) {
}
}
clip.stop();
}
};
thread = new Thread(r);
thread.start();
}
}
这篇关于Java剪辑不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!