Java clip not working

 ̄綄美尐妖づ 提交于 2019-12-02 13:37:36

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.

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

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...

For example...

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

Updated

There a few things wrong with the above example (IMHO), which can be fixed with a simple object monitor.

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();
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!