簡體   English   中英

確定何時關閉Java中的聲音播放線程

[英]Determine when to close a sound-playing thread in Java

我正在用Java播放聲音文件,並且正在尋找一種簡單的方法來確定聲音文件何時完成播放,以便殺死線程。 有沒有簡單的方法可以做到這一點?

抱歉,這有點晚了,但是我今天遇到了一個聽起來可疑的問題。 在一些游戲代碼中,Im使用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();
    }
  }
});

我的推測是,該剪輯創建了一個線程以將樣本字節計量到該行中,但是此后該線程會掛起,以防您要再次使用該剪輯。 我的第二個假設是,我代碼中的某些地方必須引用該剪輯,反之亦然,但是無論如何,上面的代碼片段可以解決問題。

希望這對某人有用。

評論

您可以同步或異步播放聲音。

如果您同步播放(阻塞調用線程),則您知道聲音何時結束播放-然后您的代碼獲得控制權。

如果您以異步方式播放它(允許創建其他線程),則輔助線程將在播放完成后立即終止。

PS

請分享您對內存泄漏及其原因的看法。

我不使用剪輯,它需要更多時間加載到內存中,具體取決於您正在讀取的文件的大小。 我更喜歡讀取字節,並使用我創建的這種方法:

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

為什么要殺死線程? 一旦終止,它將自行消失。

如果您堅持要設置同步方法,則可以調用該方法來設置“立即死亡”標志。 定期檢查該標志。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM