How to play java?

I am developing a simple timer app, but I have some problems playing audio.

Here is my code

public class Timer {

    private static int time = 0;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("Type the values");
        System.out.print("Hours   :  ");
        int hours = scanner.nextInt();
        System.out.print("Minutes :  ");
        int minutes = scanner.nextInt();
        System.out.print("Seconds :  ");
        int seconds = scanner.nextInt();

        time = hours * 3600 + minutes * 60 + seconds;

        new Thread() {
            @Override
            public void run() {
                try {
                    while (time != 0) {
                        time--;
                        sleep(1000);
                    }
                    System.out.println("Time elapsed");
                    URL url = Timer.class.getResource("Timer.wav");
                    AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
                    Clip clip = AudioSystem.getClip();
                    clip.open(audioIn);
                    clip.start();
                } catch (InterruptedException | UnsupportedAudioFileException | IOException | LineUnavailableException e) {
                    e.printStackTrace();
                }
            }
        }.start();

        System.out.println("Timer started");

    }
}

      

And here is my project structure. enter image description here Now the problem is that the app is not giving me any exceptions even though it doesn't play audio. What's wrong?

+3


source to share


4 answers


This is a multithreading problem.

The problem is that you start the clip, but then terminate your program, preventing it from playing with it. The method is Clip.start()

not a blocking operation, which means that it does not wait, but starts a new daemon thread to play sound - a daemon thread that is killed when the program exits the method main

.



Here is a sample code from my other answer , to play an audio file using Clip

. Notice how I calculate the duration of the sound and then sleep()

so that it plays.

import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

public class PlaySound {
    private static boolean tryToInterruptSound = false;
    private static long mainTimeOut = 3000;
    private static long startTime = System.currentTimeMillis();

    public static synchronized Thread playSound(final File file) {

        Thread soundThread = new Thread() {
            @Override
            public void run() {
                try{
                    Clip clip = null;
                    AudioInputStream inputStream = null;
                    clip = AudioSystem.getClip();
                    inputStream = AudioSystem.getAudioInputStream(file);
                    AudioFormat format = inputStream.getFormat();
                    long audioFileLength = file.length();
                    int frameSize = format.getFrameSize();
                    float frameRate = format.getFrameRate();
                    long durationInMiliSeconds = 
                            (long) (((float)audioFileLength / (frameSize * frameRate)) * 1000);

                    clip.open(inputStream);
                    clip.start();
                    System.out.println("" + (System.currentTimeMillis() - startTime) + ": sound started playing!");
                    Thread.sleep(durationInMiliSeconds);
                    while (true) {
                        if (!clip.isActive()) {
                            System.out.println("" + (System.currentTimeMillis() - startTime) + ": sound got to it end!");
                            break;
                        }
                        long fPos = (long)(clip.getMicrosecondPosition() / 1000);
                        long left = durationInMiliSeconds - fPos;
                        System.out.println("" + (System.currentTimeMillis() - startTime) + ": time left: " + left);
                        if (left > 0) Thread.sleep(left);
                    }
                    clip.stop();  
                    System.out.println("" + (System.currentTimeMillis() - startTime) + ": sound stoped");
                    clip.close();
                    inputStream.close();
                } catch (LineUnavailableException e) {
                    e.printStackTrace();
                } catch (UnsupportedAudioFileException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    System.out.println("" + (System.currentTimeMillis() - startTime) + ": sound interrupted while playing.");
                }
            }
        };
        soundThread.setDaemon(true);
        soundThread.start();
        return soundThread;
    }

    public static void main(String[] args) {
        Thread soundThread = playSound(new File("C:\\Booboo.wav"));
        System.out.println("" + (System.currentTimeMillis() - startTime) + ": playSound returned, keep running the code");
        try {   
            Thread.sleep(mainTimeOut );
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (tryToInterruptSound) {
            try {   
                soundThread.interrupt();
                Thread.sleep(1); 
                // Sleep in order to let the interruption handling end before
                // exiting the program (else the interruption could be handled
                // after the main thread ends!).
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println("" + (System.currentTimeMillis() - startTime) + ": End of main thread; exiting program " + 
                (soundThread.isAlive() ? "killing the sound deamon thread" : ""));
    }
}

      

+3


source


The problem was that the app exited before the clip started playing. So I replaced my game block with this new one.

                URL url = Timer.class.getResource("Timer.wav");
                AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
                AudioFormat format = audioIn.getFormat();
                Clip clip = AudioSystem.getClip();
                clip.open(audioIn);
                clip.start();
                long frames = audioIn.getFrameLength();
                double durationInSeconds = (frames + 0.0) / format.getFrameRate();
                sleep((long) durationInSeconds * 1000);

      



Now he waits until the clip plays and ends, and only then the application will terminate his work

+1


source


Edit: It might help if I read all the code before posting the lol response. So your class.getResource ("Timer.wav") should be class.getResource ("resources / Timer.wav"). I am assuming resources are a folder in your class structure. Also if you are using getResourceAsStream instead of getResource you can skip the url.

0


source


You have to check if the resource was actually restored successfully:

URL url = Timer.class.getResource("Timer.wav");
if (url == null)
{
    System.out.println("wav file resource not found!");
    return;
}
// continue on

      

Also add an exception handler to your program to check if any exceptions have gone all the way to the top of your program:

Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler()
{
    public void uncaughtException(Thread t, Throwable e)
    {
        String msg = "DefaultUncaughtExceptionHandler thread[" + t.getName() + "]";
        System.out.println(msg);
        e.printStackTrace(System.out);
        System.err.println(msg);
        e.printStackTrace(System.err);
    }
});

      

0


source







All Articles