为什么尝试获取 Clip 会抛出异常?

Why does attempting to get a Clip throw exception?

我一直在关注 this tutorial for Java 1.7,我确信我的代码是正确的。但是,Java 在运行时抛出一个 IllegalArgumentException

我尝试使用 Java 稍新的 multi-catch 在现有的 catch 块中捕获它。但是,它只是抛出异常。

这是我的代码的开头。

        Mixer.Info[] mixInfos = AudioSystem.getMixerInfo();
        /*
        for (Mixer.Info info : mixInfos)
        {
            System.out.println(info.getName() + " - " + info.getDescription());
        }
        */
        mixer = AudioSystem.getMixer(mixInfos[0]);

        DataLine.Info dataInfo = new DataLine.Info(Clip.class, null);
        try
        {
            clip = (Clip) mixer.getLine(dataInfo);
        }

我希望代码会继续 运行 并播放 Clip 但我收到此异常:

Exception in thread "main" java.lang.IllegalArgumentException: Line unsupported: interface Clip
    at java.desktop/com.sun.media.sound.PortMixer.getLine(PortMixer.java:131)
    at main.Driver.main(Driver.java:35)

注意:如果这不向前兼容,请解释。

我认为你应该检查你的导入。 AFAIK,声音库都在 javax.sound.sampled 中。 PortMixer 在 com.sun.media.sound.

本教程的作者会比必要的麻烦更多。您可以让系统选择默认值,而不是对特定的混音器进行硬编码。这可能是最好的策略,因为世界上的 PC 将具有不同的硬件配置。

以下示例可能会有所帮助。请注意,我们甚至懒得声明一个 Mixer。

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.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

public class BasicClipExample {

    public static void main(String[] args) {

        BasicClipExample bc = new BasicClipExample();

        try {
            bc.run();
        } catch (UnsupportedAudioFileException | IOException 
                | LineUnavailableException | InterruptedException e) {
            e.printStackTrace();
        }

    }

    private void run() throws UnsupportedAudioFileException, 
            IOException, LineUnavailableException, InterruptedException
    {
        String filename = "a3.wav";

        URL url = this.getClass().getResource("audio/" + filename);
        System.out.println(url);

        AudioInputStream ais = AudioSystem.getAudioInputStream(url);
        DataLine.Info info = new DataLine.Info(Clip.class, ais.getFormat());
        Clip clip = (Clip) AudioSystem.getLine(info);
        clip.open(ais);
        clip.start();
        Thread.sleep(6000);
        clip.close();
    }       
}

此示例假定您的音频文件位于名为“/audio”的子目录中。 它还具有睡眠命令,可在剪辑播放时保持程序 运行ning。在自己的线程下剪辑 运行,但线程是 "daemon" 类型,不会阻止 Java 程序关闭。我的 a3.wav 是一段恰好持续约 5 秒的钟声录音。

最后,上面的代码没有以理想的方式使用 Clip。 Clip 的概念是它是为了重复使用。每次播放之前重新加载剪辑变量是低效的。剪辑变量应该只加载一次,然后按需播放。如果您有 clip.open() 和 clip.start() 作为连续的代码行,您可能应该使用 SourceDataLine 而不是 Clip,或者您应该重新编码并将这两个命令放入单独的方法中。