java.io.IOException: пометка / сброс не поддерживается - PullRequest
61 голосов
/ 03 апреля 2011
try {
    //String location = dir1.getCanonicalPath()+"\\app_yamb_test1\\mySound.au";
    //displayMessage(location);
    AudioInputStream audio2 = AudioSystem.getAudioInputStream(getClass().getResourceAsStream("mySound.au"));
    Clip clip2 = AudioSystem.getClip();
    clip2.open(audio2);
    clip2.start();
} catch (UnsupportedAudioFileException uae) {
    System.out.println(uae);
    JOptionPane.showMessageDialog(null, uae.toString());
} catch (IOException ioe) {
    System.out.println("Couldn't find it");
    JOptionPane.showMessageDialog(null, ioe.toString());
} catch (LineUnavailableException lua) {
    System.out.println(lua);
    JOptionPane.showMessageDialog(null, lua.toString());
}

Этот код отлично работает, когда я запускаю приложение из netbeans.Звук играет и нет никаких исключений.Однако, когда я запускаю его из папки dist, звук не воспроизводится, и я получаю java.io.IOException: mark/reset not supported в своем диалоговом окне сообщения.

Как это исправить?

Ответы [ 4 ]

127 голосов
/ 03 апреля 2011

Документация для AudioSystem.getAudioInputStream(InputStream) гласит:

Реализация этого метода может требуется несколько парсеров для изучения поток, чтобы определить, являются ли они поддержать это. Эти парсеры должны быть в состоянии чтобы пометить поток, прочитайте достаточно данных чтобы определить, поддерживают ли они поток, и, если нет, сбросьте указатель чтения потока на его оригинал позиция. Если входной поток не поддержать эти операции, этот метод может произойти сбой с IOException.

Следовательно, поток, который вы предоставляете этому методу, должен поддерживать дополнительную функциональность mark / reset . Украсьте свой поток ресурсов с помощью BufferedInputStream.

//read audio data from whatever source (file/classloader/etc.)
InputStream audioSrc = getClass().getResourceAsStream("mySound.au");
//add buffer for mark/reset support
InputStream bufferedIn = new BufferedInputStream(audioSrc);
AudioInputStream audioStream = AudioSystem.getAudioInputStream(bufferedIn);
5 голосов
/ 28 ноября 2011

Поработав некоторое время и многократно обращаясь к этой странице, я наткнулся на на , что помогло мне решить мою проблему. Сначала я мог загрузить файл wav, но впоследствии мог воспроизвести его только один раз, потому что он не мог перемотать его из-за ошибки «пометка / сброс не поддерживается». Это было невыносимо.

Связанный код считывает AudioInputStream из файла, затем помещает AudioInputStream в BufferedInputStream, затем помещает , что , обратно в AudioInputStream следующим образом:

audioInputStream = AudioSystem.getAudioInputStream(new File(filename));
BufferedInputStream bufferedInputStream = new BufferedInputStream(audioInputStream);
audioInputStream = new AudioInputStream(bufferedInputStream, audioInputStream.getFormat(), audioInputStream.getFrameLength());

И, наконец, он преобразует прочитанные данные в кодировку PCM:

audioInputStream = convertToPCM(audioInputStream);

С convertToPCM, определенной как:

private static AudioInputStream convertToPCM(AudioInputStream audioInputStream)
    {
        AudioFormat m_format = audioInputStream.getFormat();

        if ((m_format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) &&
            (m_format.getEncoding() != AudioFormat.Encoding.PCM_UNSIGNED))
        {
            AudioFormat targetFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
                m_format.getSampleRate(), 16,
                m_format.getChannels(), m_format.getChannels() * 2,
                m_format.getSampleRate(), m_format.isBigEndian());
            audioInputStream = AudioSystem.getAudioInputStream(targetFormat, audioInputStream);
    }

    return audioInputStream;
}

Я полагаю, что они делают это, потому что BufferedInputStream обрабатывает метку / сброс лучше, чем audioInputStream. Надеюсь, это кому-нибудь поможет.

4 голосов
/ 17 февраля 2012

Только что натолкнулся на этот вопрос от кого-то с той же проблемой, который ссылался на него.

База данных ошибок Oracle, # 7095006

Используйте следующий код, чтобы избежать шага InputStream. Именно InputStream вызывает ошибку.

URL url = AudioMixer.class.getResource(fileName); 
AudioInputStream ais =  AudioSystem.getAudioInputStream(url); 

вуаля - без InputStream

пометка / сброс исключения во время getAudioInputStream ()

0 голосов
/ 03 апреля 2011

Проблема в том, что ваш входной поток должен поддерживать методы mark и reset.По крайней мере, если поддерживается метка, вы можете проверить с помощью: AudioInputStream # markSupported .

Так что вам следует использовать другой InputStream.

...