簡體   English   中英

如何停止在新線程中播放的聲音?

[英]How to stop a sound played in a new thread?

我正在做一個簡單的坦克游戲,它有背景音樂。 每當播放器死亡時,我都需要停止播放音樂(播放器健康狀態為0)。 我該怎么做?

我試圖通過在play()函數之外釋放線程並使用t.stop()來停止線程來停止線程,但是它沒有用。

package com.company;

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.*;

public class Sound implements Runnable
{

    private String fileLocation;
    public String getFileLocation() {
        return fileLocation;
    }

    public Sound() {
    }



    public void play(String fileLocation)
    {
        Thread t = new Thread(this);
        this.fileLocation = fileLocation;
        t.start();
    }

    public void run ()
    {
        playSound(fileLocation);
    }



    public void playSound(String fileName)
    {
        File soundFile = new File(fileName);
        AudioInputStream audioInputStream = null;
        try
        {
            audioInputStream = AudioSystem.getAudioInputStream(soundFile);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        AudioFormat audioFormat = audioInputStream.getFormat();
        SourceDataLine line = null;
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
        try
        {
            line = (SourceDataLine) AudioSystem.getLine(info);
            line.open(audioFormat);
        }
        catch (LineUnavailableException e)
        {
            e.printStackTrace();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        line.start();
        int nBytesRead = 0;
        byte[] abData = new byte[128000];
        while (nBytesRead != -1)
        {
            try
            {
                nBytesRead = audioInputStream.read(abData, 0, abData.length);
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            if (nBytesRead >= 0)
            {
                int nBytesWritten = line.write(abData, 0, nBytesRead);
            }
        }
        line.drain();
        line.close();
    }
}

聲明一個易失的布爾值。 為什么易揮發? 因為它需要跨線程更新。

private volatile boolean playing;

在while子句中包含布爾值。

while(playing && nBytesRead != -1)

使布爾值可從播放線程外部訪問。

public void setPlaying(boolean) {
    this.playing = playing;
}

當您想要關閉聲音時,請調用setPlaying(false) 不要忘記在聲音開始之前將布爾值設為true。

唯一的缺點是聲音可能會發出喀噠聲,因為它會立即發出聲音。 添加淡入淡出涉及設置並調用javax.sound.sampled.Control對象(我對它們有好運),或擺弄PCM數據本身。

至少使用SourceDataLine ,我們可以訪問字節(在您的abData數組中)。 可以根據您的音頻格式將數據組合成PCM,然后將其乘以推子值(在諸如64幀之類的過程中,從1到0),逐漸將PCM值降低到0,然后取這些新PCM值並將其轉換回字節並寫入。 是的,要擺脫點擊會帶來很多麻煩。 但很值得。

暫無
暫無

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

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