Java剪辑不起作用 [英] Java clip not working

查看:140
本文介绍了Java剪辑不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以帮我理解为什么下面这段代码不起作用吗?

Can someone please help me understand why this code below doesn't work?

我通过调用方法 start()<启动剪辑/ code>。此方法为剪辑创建一个新线程以运行。但是,不,它似乎没有播放任何东西。

I start the clip by calling method start(). This method creates a new thread for the clip to run. However, no it doesn't seem to play anything.

代码编译没有任何错误...

The code is compiled without any error...

public class Audio
{
    private Clip clip;

    private Thread thread; 

    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 start()
    {
        Runnable r = new Runnable() {
            public void run()
            {
                loop();
            }
        };
        thread = new Thread(r);
        thread.start();
    }

    public void loop ()
    {       
        // Rewind the media to the beginning of the clip.
        this.clip.setFramePosition(0);

        // Continuously play the clip.
        this.clip.loop(Clip.LOOP_CONTINUOUSLY);

        try
        {
            Thread.sleep(5000);
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }

更新

我发现了问题!问题是因为音频文件。我使用了不同的音频文件,我可以用上面的代码听到声音。

I found the problem! The problem is because of the audio file. I used a different audio file and I can hear the sound with the code above.

编译的代码没有任何错误或警告真的很烦人。我通过获取音频格式检测到问题,然后将其传递给类DataLine.Info的对象。然后,从数据线中检索剪辑。

It is just really annoying that the code compiled without any error or warning. I detected the problem by getting the audio format, then pass it to an object of class DataLine.Info. Then, retrieve the clip from the Data Line.

因此,基本上不是通过以下方式获取剪辑:

So, basically instead of getting the clip by:

this.clip = AudioSystem.getClip();

我会得到以下剪辑:

AudioFormat format = audioStream.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, format);
this.clip = (Clip) AudioSystem.getLine(info);

当我用这个编译时,Java抛出以下错误:

When I compiled with this, Java threw below error:


没有行匹配接口Clip支持格式PCM_SIGNED 48000.0 Hz,24 bit

No line matching interface Clip supporting format PCM_SIGNED 48000.0 Hz, 24 bit

所以,我替换了音频文件,它有效!

So, I replaced the audio file, and it worked !

推荐答案

clip.loop 是一个非阻塞的电话。也就是说,一旦你调用它(并且它完成了它的工作),它将返回,这意味着你的线程将退出,除非有另一个非守护程序线程在运行,否则JVM将退出。

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.

我原本以为你可以使用 Clip#drain 来阻止它直到剪辑完成,但从技术上讲,这个剪辑赢了在正常意义上完成......

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

现在,这可能是一个问题,因为线程是一个非守护进程线程,永远不会结束......而不是而(true){你应该设置某种 volitle 你设置为 false 的标志并帮助终止循环......

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

例如......

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

已更新

上面的例子(恕我直言)有一些问题,可以用简单的对象监视器修复。

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

因此,我们可以使用 Clip#而不是 volatile 标志和循环。循环功能,只需使用 Object#wait Object#notify ,例如

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

这篇关于Java剪辑不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆