确定何时在Java中关闭声音播放线程

时间:2009-05-08 02:21:57

标签: java multithreading audio

我正在使用Java播放声音文件,并且正在寻找一种简单的方法来确定声音文件何时播放完毕,这样我就可以杀死该主题。有没有一种简单的方法来实现这一目标?

4 个答案:

答案 0 :(得分:4)

对不起,这有点晚了,但我今天遇到了一个问题,听起来对这个问题非常熟悉。在一些游戏代码中,我使用javax.sound.sampled.Clip来播放各种声音,我发现如果我完成后没有显式调用line.close(),那么探查器中的本机线程数将只是天空-rocket直到我收到OutOfMemory错误。

// this just opens a line to play the sample
Clip clip = AudioSystem.getClip();
clip.open( audioFormat, sounddata, 0, sounddata.length);
clip.start();

// at this point, there is a native thread created 'behind the scenes'
// unless I added this, it never goes away:
clip.addLineListener( new LineListener() {
  public void update(LineEvent evt) {
    if (evt.getType() == LineEvent.Type.STOP) {
      evt.getLine().close();
    }
  }
});

我的假设是剪辑创建一个线程来将样本字节计量到行中,但是在此之后线程会挂起以防再次重新使用剪辑。我的第二个假设是,我的代码中的某些内容必须引用剪辑,反之亦然,但无论如何,上面的代码片段都会将问题录下来。

希望这对某人有用。

答案 1 :(得分:1)

评论

您可以同步或异步播放声音。

如果您同步播放(阻止调用线程),您就知道声音何时结束播放 - 然后您的代码获得控制权。

如果您异步播放(允许创建不同的线程),辅助线程将在完成播放后立即自行终止。

P.S。

请分享您对内存泄漏的观察以及问题背后的原因。

答案 2 :(得分:0)

你为什么要杀死这个帖子?一旦它终止,它就会自行消失。

如果你坚持,设置一个同步方法,你可以调用设置“立即死”标志;定期检查那个标志。

答案 3 :(得分:0)

我不使用剪辑,根据您正在阅读的文件的大小,在内存中加载需要更多时间。 我首选阅读字节,并使用我创建的方法:

public void play(File file) throws UnsupportedAudioFileException, IOException, LineUnavailableException, InterruptedException
{

    AudioInputStream encoded = AudioSystem.getAudioInputStream(file);
    AudioFormat encodedFormat = encoded.getFormat();
    AudioFormat decodedFormat = this.getDecodedFormat(encodedFormat);

    line = AudioSystem.getSourceDataLine(decodedFormat);
    currentDecoded = AudioSystem.getAudioInputStream(decodedFormat, encoded);
    line.open(decodedFormat);
    line.start();
    byte[] b = new byte[this.bufferSize];
    int i = 0;
    synchronized(lock){
        while(true)
        {
            i = currentDecoded.read(b, 0, b.length);
            if(i == -1)
                break;

            line.write(b, 0, i);
            if(paused == true)
            {
                line.stop();
                lock.wait();
                line.start();
            }
        }
    }
    line.drain();
    line.stop();
    line.close();
    currentDecoded.close();
    encoded.close();
}

它使用这种方法:

protected AudioFormat getDecodedFormat(AudioFormat format)
{
    AudioFormat decodedFormat = new AudioFormat(
            AudioFormat.Encoding.PCM_SIGNED,  // Encoding to use
            format.getSampleRate(),           // sample rate (same as base format)
            16,               // sample size in bits (thx to Javazoom)
            format.getChannels(),             // # of Channels
            format.getChannels()*2,           // Frame Size
            format.getSampleRate(),           // Frame Rate
            false                 // Big Endian
    );
    return decodedFormat;    
}