简体   繁体   English

在 Java 中的单独线程上循环音频

[英]Looping audio on separate thread in Java

I am making a 2d RPG game and i was wanting to get background music working.我正在制作一个 2d RPG 游戏,我想让背景音乐发挥作用。 I wrote a sound class that plays the music on a separate thread but i cannot figure out how to make it loop.我写了一个声音类,在一个单独的线程上播放音乐,但我不知道如何让它循环。 My Sound class is as follows:我的声音类如下:

package tileRPG.gfx;

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

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;


public class Sound implements Runnable 
{

    private String fileLocation = "res/bgMusic.wav";

    public Sound() { }

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

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

    private 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();
    }
}
public void run ()
{
    while(true)
    {
        playSound(fileLocation);
    }
}

This creates an infinite loop.这将创建一个无限循环。 Adjust accordingly.相应调整。

When you start a thread, it will execute any code that is in the run() method and then exit.当您启动一个线程时,它将执行run()方法中的任何代码,然后退出。 So this is where the loop would go in order to repeatedly play the sound (without blocking your other threads/code).所以这是循环将要重复播放声音的地方(不阻塞其他线程/代码)。

This solution has no way of stopping this thread (and therefore stopping playback) with your current code, but I assume you are writing this in stages.此解决方案无法使用您当前的代码停止此线程(并因此停止播放),但我假设您是分阶段编写的。 The thread will stop playback and exit when the application does currently.当应用程序当前执行时,线程将停止播放并退出。

Use recursion使用递归

Sample code:示例代码:

private void playSound(String fileName) 
{
   ...
   line.drain();
   line.close();

   //recursive call to same method
   playSound(fileName);
}

You can make it more better by moving static part of the method playSound() in run() method.您可以通过在run()方法中移动playSound()方法的静态部分来使其更好。 In that case you don't need to read the file again.在这种情况下,您不需要再次读取文件。

Hint: pass SourceDataLine in playSound() method instead of fileName .提示:在playSound()方法中传递SourceDataLine而不是fileName

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM