web-dev-qa-db-ja.com

java.io.IOException:マーク/リセットはサポートされていません

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私のメッセージダイアログで。

どうすれば修正できますか?

62
Crais

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

しばらく迷い込んでこのページを何度も参照した後、私は this に出くわしました。これは問題の解決に役立ちました。最初はwavファイルを読み込むことができましたが、「マーク/リセットがサポートされていない」というエラーのため巻き戻せなかったため、その後は一度しか再生できませんでした。それは気が狂っていた。

リンクされたコードは、ファイルからAudioInputStreamを読み取り、AudioInputStreamをBufferedInputStreamに入れ、次にthatを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よりも優れたマーク/リセットを処理するため、彼らはこれを行うと信じています。これが誰かの助けになることを願っています。

5
AndyG

ちょうどそれを参照した同じ問題を持つ他の誰かからこの質問に出会いました。

Oracle Bugデータベース、#7095006

InputStreamステップを回避するには、次のコードを使用します。エラーを引き起こしているのはInputStreamです。

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

出来上がり-InputStreamなし

getAudioInputStream()中の例外をマーク/リセット

4
Phil Freihofner

問題は、入力ストリームがメソッドmarkおよびresetをサポートする必要があることです。少なくともマークがサポートされている場合は、 AudioInputStream#markSupported でテストできます。

したがって、別のInputStreamを使用する必要があります。

0
anon