Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
403 views
in Technique[技术] by (71.8m points)

java - Audio file plays in Eclipse IDE; but NOT as JAR file

The audio file that I am using is found here: http://www.orangefreesounds.com/loud-alarm-clock-sound/

This is what my file structure looks like in my Eclipse IDE: What my file structure looks like

The audio file plays perfectly fine when I run it in my IDE, but not when I export it as a JAR file. I have already checked and found that the audio file is inside the JAR file.

I am using the terminal command java -jar Sandbox.jar & to run the JAR file. The program seems to be able to find the file (since it is not throwing an IOException), but does not seem to be able to perform playback.

Why is this problem happening and how can I fix it?

Weird Update

Okay, so actually, the JAR file is able to play the audio file when run in cmd or PowerShell on Windows 8.1, but not in the terminal of Ubuntu 14.04 for some reason. This whole time, I have been trying to run the JAR file in Ubuntu 14.04.

Weird Update #2

I have confirmed the issue of the JAR files only working on a Windows 8.1 system. Both of the code snippets in this question DO NOT WORK, while both of MadProgrammer's solutions work.

Minimal, Complete, and Verifiable example (does NOT work on Windows or 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();
    }

}

Attempted Solution #1 (does NOT work on Windows or Ubuntu)

One attempted solution (as suggested by Andrew Thompson) was to write this.getClass().getResource( ... ) instead of 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, IOException, LineUnavailableException
    {
        new Sandbox();
    }

    public Sandbox() throws UnsupportedAudioFileException, IOException, 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();
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Adding clip.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();
        }
    }

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...