如何在jar(背景音乐)中播放长音频片段?

hrysbysz  于 2021-06-29  发布在  Java
关注(0)|答案(1)|浏览(428)

我在做一个宠物项目(一种游戏)。我遇到了一个问题:当用命令从控制台调用应用程序时:

C:\java -jar MyGame.jar

短音播放,长音不播放。所有声音都在jar的“/assets”文件夹中。
音频的路径如下所示:

C:\MyGame.jar\assets\background_music.wav

比如一次射门或一次跳跃。对于长音频数据,仅播放前0.5秒。
例如:如果加载长度为0.834秒的声音,那么它会循环播放(背景音乐),声音会循环播放(wav文件,0.843秒,48 kb)。但如果加载一个wav文件2秒,大小为115KB,则只播放0.5-1秒。如果加载wav背景音乐文件15秒(或7秒),大小为110-2000 kb或更大,将播放相同的0.5秒。每15(或7)秒(如果你说“循环播放”)。
也就是说,文件被加载,其长度被加载,标记被放置在开头和结尾,但我只听到前0.5秒的音频(每“x”-秒,其中“x”是剪辑的长度)。
音频上传方式:

public static InputStream uploadAudio (String path){
    InputStream sourceSound = null;
    try{

        final File jarFile = new File(ResourceLoader.class.getProtectionDomain().getCodeSource().getLocation().getPath());
        if(jarFile.isFile()) {  // Run with JAR file

            final JarFile jar = new JarFile(jarFile);

            InputStream fileInputStreamReader =(jar.getInputStream(jar.getEntry(path)));
            byte[] byteArray = new byte[fileInputStreamReader.available()];
            fileInputStreamReader.read(byteArray);

            InputStream newInputStreamFromArray =  new BufferedInputStream(new ByteArrayInputStream(byteArray));

            sourceSound = newInputStreamFromArray;
            jar.close();

        } else { // Run with IDE

            URL url = ResourceLoader.class.getResource( "../" + path);
            InputStream fileInputStreamReader = new BufferedInputStream(new FileInputStream(url.getPath()));
            sourceSound = fileInputStreamReader;
        }

    }catch (IOException e){
        e.printStackTrace();
    }
    return sourceSound;
}

音频播放类的一部分:

public class Sound implements AutoCloseable {
private boolean released = false;
private AudioInputStream stream = null;
private Clip clip = null;
private FloatControl volumeControl = null;
private boolean playing = false;

public Sound(InputStream inputStream) {
    try {
        stream = AudioSystem.getAudioInputStream(inputStream);
        clip = AudioSystem.getClip();
        clip.open(stream);
        clip.addLineListener(new Listener());
        volumeControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
        released = true;
    } catch (IOException | UnsupportedAudioFileException | LineUnavailableException exc) {
        exc.printStackTrace();
        released = false;

        close();
    }
}

public void playLoop(boolean breakOld){
    if (released) {
        if (breakOld) {
            clip.stop();
            clip.loop(Clip.LOOP_CONTINUOUSLY);
            playing = true;
        } else if (!isPlaying()) {
            clip.loop(Clip.LOOP_CONTINUOUSLY);
            playing = true;
        }
    }

}
public void playLoop(){
    playLoop(true);
}

没有错误。这个程序有效。背景声音以循环播放,但仅为剪辑的0.5秒。播放短音(射击或跳跃音)。一切都在ide中工作:简短的声音和完整的背景音乐。

m2xkgtsf

m2xkgtsf1#

问题解决了(可能不是最好的方法)。我的问题是我采取了这种方法

public static Image uploadImage (String path)

并重写了部分音频。在images方法中,有一个字符串用于解包jar。

InputStream fileInputStreamReader = (jar.getInputStream (jar.getEntry (path)));

接下来,我编写了音频代码。它并没有直接起作用:对我来说就不一样了

InputStream sourceSound = new BufferedInputStream (fileInputStreamReader);
 ... ...
return sourceSound;

下一步-我补充说:

InputStream fileInputStreamReader =(jar.getInputStream(jar.getEntry(path)));
            byte[] byteArray = new byte[fileInputStreamReader.available()];
            fileInputStreamReader.read(byteArray);

            InputStream newInputStreamFromArray =  new BufferedInputStream(
                                      new ByteArrayInputStream(byteArray));

            sourceSound = newInputStreamFromArray;

成功了(我想是的)。在这里发布了这个问题之后,我开始认为并非所有的inputstream都是用byte[]bytearray编写的。我复制了一个bytearray并将其写入一个文件“h:/1.wav”。
这是我在文件里看到的:

RIFFp[) WAVEfmt      D¬  ±   dataäZ) ÿ1VÿEÿR¾ÿVëÿH .
.....................................................................................
.....................................................................................

和etс. 数据被切断了。没有内容。
图像工作代码:

BufferedImage sourceImage = null;
                InputStream fileInputStreamReader = jar.getInputStream(jar.getJarEntry(path));
                sourceImage = ImageIO.read(fileInputStreamReader);//magic ImageIO.read () !!!!

同样不适用于音频:

InputStream fileInputStreamReader =(jar.getInputStream(jar.getEntry(path)));
            byte[] byteArray = new byte[fileInputStreamReader.available()];
            fileInputStreamReader.read(byteArray);

我想我没有学好java=),所以我现在就这样解决了这个问题:

InputStream fileInputStreamReader =(jar.getInputStream(jar.getEntry(path)));
        byte[] byteArray = new byte[fileInputStreamReader.available()];

        int i = 0;
        int byteRead;
        while ((byteRead = fileInputStreamReader.read()) != -1) {
            byteArray[i] = (byte) byteRead;
            i++;
        }

        InputStream newInputStreamFromArray =  new BufferedInputStream(new ByteArrayInputStream(byteArray));

现在可以正常地从jar中读取长音频和短音频。
如果有人知道如何做得更好-我会很高兴听到答案。

相关问题