java.io.IOException:不支持标记/重置

use*_*089 2 java audio export

我知道这个问题已经被问过很多次了,但在某些情况下有所不同,所以我无法弄清楚。当我在 Eclipse 中运行游戏时,一切都很顺利,游戏运行完美,但在导出后,它崩溃了。我可以打开游戏并在菜单中移动,但没有播放任何声音,并且在我点击播放后,游戏就冻结了,并且它用 cmd 给了我这个错误(我可以粘贴任何必要的类,但希望只有 Audio 类是必要的) :

java.io.IOException: mark/reset not supported
    at java.util.zip.InflaterInputStream.reset(Unknown Source)
    at java.io.FilterInputStream.reset(Unknown Source)
    at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(Unknown Source)
    at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
    at com.neet.Audio.JukeBox.load(JukeBox.java:26)
    at com.neet.GameState.IntroState.<init>(IntroState.java:28)
    at com.neet.GameState.GameStateManager.loadState(GameStateManager.java:48)
    at com.neet.GameState.GameStateManager.setState(GameStateManager.java:72)
    at com.neet.GameState.GameStateManager.<init>(GameStateManager.java:31)
    at com.neet.Main.GamePanel.init(GamePanel.java:70)
    at com.neet.Main.GamePanel.run(GamePanel.java:75)
    at java.lang.Thread.run(Unknown Source)
Run Code Online (Sandbox Code Playgroud)

这是音频类:`

package com.neet.Audio;

import java.util.HashMap;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;

public class JukeBox {

    private static HashMap<String, Clip> clips;
    private static int gap;
    private static boolean mute = false;

    public static void init() {
        clips = new HashMap<String, Clip>();
        gap = 0;
    }

    public static void load(String s, String n) {
        if(clips.get(n) != null) return;
        Clip clip;
        try {           
            AudioInputStream ais =
                AudioSystem.getAudioInputStream(
                    JukeBox.class.getResourceAsStream(s)
                );
            AudioFormat baseFormat = ais.getFormat();
            AudioFormat decodeFormat = new AudioFormat(
                AudioFormat.Encoding.PCM_SIGNED,
                baseFormat.getSampleRate(),
                16,
                baseFormat.getChannels(),
                baseFormat.getChannels() * 2,
                baseFormat.getSampleRate(),
                false
            );
            AudioInputStream dais = AudioSystem.getAudioInputStream(decodeFormat, ais);
            clip = AudioSystem.getClip();
            clip.open(dais);
            clips.put(n, clip);
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void play(String s) {
        play(s, gap);
    }

    public static void play(String s, int i) {
        if(mute) return;
        Clip c = clips.get(s);
        if(c == null) return;
        if(c.isRunning()) c.stop();
        c.setFramePosition(i);
        while(!c.isRunning()) c.start();
    }

    public static void stop(String s) {
        if(clips.get(s) == null) return;
        if(clips.get(s).isRunning()) clips.get(s).stop();
    }

    public static void resume(String s) {
        if(mute) return;
        if(clips.get(s).isRunning()) return;
        clips.get(s).start();
    }

    public static void loop(String s) {
        loop(s, gap, gap, clips.get(s).getFrameLength() - 1);
    }

    public static void loop(String s, int frame) {
        loop(s, frame, gap, clips.get(s).getFrameLength() - 1);
    }

    public static void loop(String s, int start, int end) {
        loop(s, gap, start, end);
    }

    public static void loop(String s, int frame, int start, int end) {
        stop(s);
        if(mute) return;
        clips.get(s).setLoopPoints(start, end);
        clips.get(s).setFramePosition(frame);
        clips.get(s).loop(Clip.LOOP_CONTINUOUSLY);
    }

    public static void setPosition(String s, int frame) {
        clips.get(s).setFramePosition(frame);
    }

    public static int getFrames(String s) { return clips.get(s).getFrameLength(); }
    public static int getPosition(String s) { return clips.get(s).getFramePosition(); }

    public static void close(String s) {
        stop(s);
        clips.get(s).close();
    }

}`
Run Code Online (Sandbox Code Playgroud)

Jim*_*son 5

来自 Javadoc(我的重点):

public static AudioInputStream getAudioInputStream(InputStream stream)
                                        throws UnsupportedAudioFileException,
                                               IOException
Run Code Online (Sandbox Code Playgroud)

从提供的输入流获取音频输入流。该流必须指向有效的音频文件数据。此方法的实现可能需要多个解析器来检查流以确定它们是否支持它。这些解析器必须能够标记流,读取足够的数据以确定它们是否支持该流,如果不支持,则将流的读取指针重置为其原始位置。如果输入流不支持这些操作,则此方法可能会失败并出现 IOException。

您似乎正在从包含代码和声音文件的 jar 文件运行。返回InputStream的 fromgetResourceAsStream()将不起作用,因为它将由 a 支持(或实现)ZipInputStream,该 a 被视为mark()无操作,并抛出IOExceptionfor reset()

要解决该问题,您只需要将输入流包装在BufferedInputStream.

AudioInputStream ais =
    AudioSystem.getAudioInputStream(
        new BufferedInputStream(
            JukeBox.class.getResourceAsStream(s)
        )
    };
Run Code Online (Sandbox Code Playgroud)