有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在JAR(背景音乐)中播放长的音频剪辑?

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

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秒,大小为115 KB,则仅播放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中的所有功能都可以正常工作:简短的声音和完整的背景音乐


共 (1) 个答案

  1. # 1 楼答案

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

     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都是用字节[]byteArray编写的。 我制作了一份byteArray的副本,并将其写入一个文件“H:/1.wav”

    这是我在文件中看到的:

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

    和等等。数据被切断了。没有内容

    图像的工作代码:

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

    长和短音频现在可以正常地从罐子中读取

    如果有人知道如何做得更好,我会很高兴听到答案