从Java的资源文件中作为资源播放.wav文件

9
我想使用Java代码播放一个在JAR文件中作为资源的.wav文件。我的代码如下 -
try {
     URL defaultSound = getClass().getResource("/images/ads/WindowsNavigationStart.wav");
     // getClass().getSy.getResource("/images/ads/WindowsNavigationStart.wav");
     File soundFile = new File(defaultSound.toURI());
     AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundFile);
     Clip clip = AudioSystem.getClip();
     clip.open(audioInputStream);
     clip.start( );
} catch (Exception ex) {
     ex.printStackTrace();
}

我的一个jar文件中存在文件WindowsNavigationStart.wav。但是出现了以下异常 -

java.lang.IllegalArgumentException: URI is not hierarchical
at java.io.File.<init>(File.java:363)
at au.com.webscan.wwwizard.app.admin.customfile.UpOneLevelFolder.btnUpFolderActionPerformed(Unknown Source)
at au.com.webscan.wwwizard.app.admin.customfile.UpOneLevelFolder.access$000(Unknown Source)
at au.com.webscan.wwwizard.app.admin.customfile.UpOneLevelFolder$1.actionPerformed(Unknown Source)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:272)
at java.awt.Component.processMouseEvent(Component.java:6288)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6053)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4651)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2478)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:643)
at java.awt.EventQueue.access$000(EventQueue.java:84)
at java.awt.EventQueue$1.run(EventQueue.java:602)
at java.awt.EventQueue$1.run(EventQueue.java:600)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$2.run(EventQueue.java:616)
at java.awt.EventQueue$2.run(EventQueue.java:614)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:613)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

请给我一个解决方案。非常感谢大家。


你的wav文件在哪里?如果它与你的java文件一起压缩了,你就不能使用URI创建File对象。但是,使用InputStream是可能的。 - qrtt1
它是由Ant构建创建的一个JAR文件。 - Pritom
9个回答

9

你尝试过以下方法吗:

InputStream is= getClass().getResourceAsStream("/images/ads/WindowsNavigationStart.wav");
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(is);

基本上,我认为你不能从jar文件中的URI创建文件。但是你可以直接传递输入流。

1
我得到了以下异常java.io.IOException: mark/reset不支持 - Pritom
2
@Pritorn,为了解决那个IOException异常,将InputStream包装在BufferedInputStream中。完整的解决方案如下:InputStream is= getClass().getResourceAsStream("/images/ads/WindowsNavigationStart.wav"); AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new BufferedInputStream(is)); - Sean
谢谢你提供的BufferedInputStream提示,对我帮助很大。 - Frans Lundberg

7

更改:

AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundFile);

致:

System.out.println("defaultSound " + defaultSound);  // check the URL!
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(defaultSound);

我得到了以下错误信息:defaultSound jar:file:/E:/console2012/console2012/lib/pics-webcommerce.jar!/images/ads/WindowsNavigationStart.wav javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input URL,这是我的wav文件出错了吗? - Pritom
1
Wav 是一种“容器格式”。它可能具有许多不同类型的编码。Java 只理解其中的一些编码。请尝试使用此示例媒体页面上提供的左/右 Wav 进行操作。 - Andrew Thompson
2
你好,这对我有效。 尝试{ URL defaultSound = this.getClass().getResource(thePathToFile); AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(defaultSound); Clip clip = AudioSystem.getClip(); clip.open(audioInputStream); clip.start(); } catch (Exception ex) { ex.printStackTrace(); } - Hermandroid

3

使用 Class.getResourceAsStream() 方法。

获取 inputStream 句柄之后,获取 audioInputStream 并完成其余操作。

InputStream is = getClass().getResourceAsStream("......");
AudioInputStream ais = AudioSystem.getAudioInputStream(is);
Clip clip = AudioSystem.getClip();
clip.open(ais);

我得到了以下异常 java.io.IOException: mark/reset不支持 - Pritom

2

完美的解决方案......

URL url = this.getClass().getResource("sounds/beep.au");

String urls=url.toString(); 
urls=urls.replaceFirst("file:/", "file:///");

AudioClip ac=Applet.newAudioClip(new URL(urls));

ac.play();

1
请参考我之前的回答制作单一JAR Java应用程序。标题有些误导,但发帖人试图做的事情与您几乎相同。一些最好的细节在聊天记录的链接中。

0

就像Kal所写的:

  1. InputStream is = getClass().getResourceAsStream("......");
  2. AudioInputStream ais = AudioSystem.getAudioInputStream(is);...

我也尝试了这种方法,一开始并没有成功,但是出现"java.io.IOException"的问题是因为我使用了File.separator,而某些原因导致win 8.1无法处理"\\"...

public AudioInputStream getSound(String fileName){
    InputStream inputSound;
    AudioInputStream audioInStr;
    String fs = File.separator;

    try {
       absolutePath = fs +packageName+ fs +folderName+ fs +fileName;
       inputSound = getClass().getResourceAsStream(absolutePath);

       //if null pointer exception try unix, for some reason \\ doesn't work on win 8.1
       if(inputSound == null) {
           absolutePath = "/" + packageName + "/" + folderName + "/" + fileName;
           inputSound = getClass().getResourceAsStream(absolutePath);
       }

       audioInStr = AudioSystem.getAudioInputStream(new BufferedInputStream(inputSound));
       return audioInStr;
    }

0
以下代码允许我在Eclipse项目和导出的jar文件中播放声音:
- 注意使用了BufferedInputStream
- 注意,使用inputStream而不是file。

在我的main()函数中:

playAlarmSound();

在我的类中:

public static void playAlarmSound() {
ClassLoader classLoader = App.class.getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("alarmsound.wav");
try {
  Clip clip = AudioSystem.getClip();
  AudioInputStream ais = AudioSystem.getAudioInputStream(new BufferedInputStream(inputStream));
  clip.open(ais);
  clip.start();
} catch (IOException | LineUnavailableException | UnsupportedAudioFileException e) {
  System.err.println("ERROR: Playing sound has failed");
  e.printStackTrace();
}
}

0

这对我来说很好用:

public void playSound() {
        InputStream in;
        try {
            in = new BufferedInputStream(new FileInputStream(new File(
                    getClass().getClassLoader()
                            .getResource("com/kaito/resources/sound.wav").getPath())));
            AudioStream audioStream = new AudioStream(in);
            AudioPlayer.player.start(audioStream);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

0
     try {
        AudioPlayer.player.start(new AudioStream(getClass().getResourceAsStream("/sound/SystemNotification.wav")));
    } catch (Exception e) {
        e.printStackTrace();
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接