2011-04-03 28 views
52
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()); 
} 

Este código funciona bien cuando ejecuto la aplicación desde netbeans. El sonido se reproduce y no hay excepciones. Sin embargo, cuando lo ejecuto desde la carpeta dist, el sonido no se reproduce y obtengo el java.io.IOException: mark/reset not supported en el cuadro de diálogo de mi mensaje.java.io.IOException: mark/reset no compatible

¿Cómo puedo solucionar esto?

Respuesta

113

La documentación para AudioSystem.getAudioInputStream(InputStream) dice:

La aplicación de este método puede requerir múltiples programas de análisis para examinar la corriente para determinar si apoyan. Estos analizadores deben poder marcar la secuencia, leer suficientes datos para determinar si admiten la secuencia y, si no, restablecer el puntero de lectura de la secuencia a su posición original . Si el flujo de entrada no admite esta operación, este método puede fallar con una excepción IOException.

Por lo tanto, la secuencia que proporcione a este método debe ser compatible con la funcionalidad opcional mark/reset. Decora tu flujo de recursos con 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); 
+3

Ty, esto funcionó. Modifiqué el código de esta manera: 'BufferedInputStream myStream = new BufferedInputStream (getClass(). GetResourceAsStream (" mySound.au ")); AudioInputStream audio2 = AudioSystem.getAudioInputStream (myStream); ' Y ahora funciona =) P.S. si alguien pudiera formatear este comentario sería genial =/ – Crais

+0

¿Eso es lo que marca/reinicio significa? una corriente que se puede buscar? @McDowell, ¿podría mostrar el código decorado en su respuesta? –

+0

@Shurane - mark/reset permite que los datos "no leídos" de una secuencia vuelvan al punto de marca cuando se realiza el restablecimiento (normalmente almacenando en memoria RAM los datos en la RAM desde que se llama). – McDowell

0

El problema es que su flujo de entrada tiene que admitir la marca de métodos y restablecer. Al menos, si la marca es compatible, puede probar con: AudioInputStream#markSupported.

Así que tal vez debería usar un InputStream diferente.

5

Después de forcejeo alrededor por un tiempo y hacer referencia a esta página muchas veces, me encontré con this que me ayudó con mi problema. Inicialmente pude cargar un archivo wav, pero posteriormente solo pude reproducirlo una vez, porque no pudo rebobinarlo debido al error "marca/restablecimiento no compatible". Fue enloquecedor.

El código relacionado lee un AudioInputStream de un archivo, a continuación, pone el AudioInputStream en un BufferedInputStream, luego pone que de nuevo en el AudioInputStream así:

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

Y, finalmente, que convierte los datos de lectura a una codificación PCM:

audioInputStream = convertToPCM(audioInputStream); 

Con convertToPCM definido como:

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

Creo que lo hacen porque BufferedInputStream maneja la marca/reinicio mejor que audioInputStream. Espero que esto ayude a alguien por ahí.

+0

Las otras soluciones aquí no funcionaron para mi problema, ¡pero esta sí lo hizo! ¡Gracias! –

4

Acabo de encontrar esta pregunta de otra persona con el mismo problema que la hizo referencia.

base de datos de Oracle Bug, # 7095006

Utilice el siguiente código para evitar el paso de InputStream. Es el InputStream que está causando el error.

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

voila - sin InputStream

mark/reset exception during getAudioInputStream()

+1

¿Dónde puedo obtener AudioMixer? Probé un enlace que tenías en una publicación similar, pero se dirige a otro sitio. –

+2

@Potney Perdón por eso. AudioMixer parece que podría ser el nombre de una clase principal de Java, pero es solo una clase que escribí. Estoy usando su ubicación de directorio en el código fuente como punto de partida para ubicar el "nombre de archivo". http://docs.oracle.com/javase/tutorial/uiswing/components/icon.html Consulte la sección sobre "Cargando imágenes usando getResource" en el tutorial anterior si aún no está familiarizado con esto. –

Cuestiones relacionadas