web-dev-qa-db-fra.com

java.io.IOException: marquage / réinitialisation non pris en charge

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

Ce code fonctionne correctement lorsque j'exécute l'application à partir de netbeans. Le son joue et il n'y a aucune exception. Cependant, lorsque je l'exécute à partir du dossier dist, le son n'est pas lu et j'obtiens le Java.io.IOException: mark/reset not supported dans ma boîte de dialogue de message.

Comment puis-je réparer cela?

62
Crais

La documentation pour AudioSystem.getAudioInputStream(InputStream) dit:

L'implémentation de cette méthode peut nécessiter que plusieurs analyseurs analysent le flux pour déterminer s'ils le prennent en charge. Ces analyseurs doivent être capables de marquer le flux, de lire suffisamment de données pour déterminer s'ils prennent en charge le flux et, sinon, de réinitialiser le pointeur de lecture du flux à sa position d'origine. Si le flux d'entrée ne prend pas en charge ces opérations, cette méthode peut échouer avec une IOException.

Par conséquent, le flux que vous fournissez à cette méthode doit prendre en charge la fonctionnalité facultative mark/reset . Décorez votre flux de ressources avec un 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

Après avoir pataugé pendant un certain temps et référencé cette page plusieurs fois, je suis tombé sur this qui m'a aidé avec mon problème. Au départ, j'ai pu charger un fichier wav, mais par la suite, je n'ai pu le lire qu'une seule fois, car il ne pouvait pas le rembobiner en raison de l'erreur "marquer/réinitialiser non pris en charge". C'était exaspérant.

Le code lié lit un AudioInputStream à partir d'un fichier, puis place l'AudioInputStream dans un BufferedInputStream, puis remet qui dans AudioInputStream comme ceci:

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

Et enfin, il convertit les données lues en un encodage PCM:

audioInputStream = convertToPCM(audioInputStream);

Avec convertToPCM défini comme:

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

Je crois qu'ils le font parce que BufferedInputStream gère mieux la marque/réinitialisation que l'audioInputStream. J'espère que cela aide quelqu'un là-bas.

5
AndyG

Je suis juste tombé sur cette question de quelqu'un d'autre avec le même problème qui l'a référencée.

Base de données Oracle Bug, # 7095006

Utilisez le code suivant pour éviter l'étape InputStream. C'est le InputStream qui cause l'erreur.

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

voila - pas InputStream

marquer/réinitialiser l'exception pendant getAudioInputStream ()

4
Phil Freihofner

Le problème est que votre flux d'entrée doit prendre en charge le marquage et la réinitialisation des méthodes. Au moins si la marque est prise en charge, vous pouvez tester avec: AudioInputStream # markSupported .

Vous devriez donc peut-être utiliser un InputStream différent.

0
anon