2008-10-13 64 views
7

Dado un InputStream llamado que contiene datos de audio en un formato comprimido (como MP3 u OGG), deseo crear una matriz byte que contenga una conversión WAV de la entrada datos. Por desgracia, si intenta hacer esto, JavaSound le da el siguiente error:Convertir flujo de audio a matriz de bytes WAV en Java sin archivo temporal

java.io.IOException: stream length not specified 

me las arreglé para conseguir que funcione escribiendo el wav en un archivo temporal, y luego leerlo de nuevo, como se muestra a continuación:

AudioInputStream source = AudioSystem.getAudioInputStream(new BufferedInputStream(in, 1024)); 
AudioInputStream pcm = AudioSystem.getAudioInputStream(AudioFormat.Encoding.PCM_SIGNED, source); 
AudioInputStream ulaw = AudioSystem.getAudioInputStream(AudioFormat.Encoding.ULAW, pcm); 
File tempFile = File.createTempFile("wav", "tmp"); 
AudioSystem.write(ulaw, AudioFileFormat.Type.WAVE, tempFile); 
// The fileToByteArray() method reads the file 
// into a byte array; omitted for brevity 
byte[] bytes = fileToByteArray(tempFile); 
tempFile.delete(); 
return bytes; 

Esto es obviamente menos deseable. ¿Hay una mejor manera?

Respuesta

6

El problema es que la mayoría de los AudioFileWriters necesitan saber el tamaño del archivo por adelantado si escriben en un OutputStream. Como no puedes proporcionar esto, siempre falla. Desafortunadamente, la implementación API de sonido Java predeterminada no tiene ninguna alternativa.

Pero se puede tratar de usar la arquitectura AudioOutputStream de los plugins Tritonus (Tritonus es una implementación de código abierto de la API de sonido de Java): http://tritonus.org/plugins.html

+1

Tendré que intentarlo. Puede ser un poco antes de que pueda probarlo, por lo que no puedo aceptar la respuesta en este momento. Sin embargo, lo votaré mejor. –

-2

Esto es muy simple ...

File f = new File(exportFileName+".tmp"); 
File f2 = new File(exportFileName); 
long l = f.length(); 
FileInputStream fi = new FileInputStream(f); 
AudioInputStream ai = new AudioInputStream(fi,mainFormat,l/4); 
AudioSystem.write(ai, Type.WAVE, f2); 
fi.close(); 
f.delete(); 

El El archivo .tmp es un archivo de audio RAW, el resultado es un archivo WAV con encabezado.

+1

La pregunta pregunta si se puede hacer * sin * un archivo temporal. –

1

Me di cuenta de que esto se le preguntó hace mucho tiempo. En caso de que una persona nueva (utilizando Java 7 y superior) encuentre este hilo, tenga en cuenta que hay una mejor manera de hacerlo a través de la API Files.readAllBytes. Ver: How to convert .wav file into byte array?

1

Demasiado tarde, lo sé, pero me necesitaban esto, así que este es mi granito de arena sobre el tema.

public void UploadFiles(String fileName, byte[] bFile) 
{ 
    String uploadedFileLocation = "c:\\"; 

    AudioInputStream source; 
    AudioInputStream pcm; 
    InputStream b_in = new ByteArrayInputStream(bFile); 
    source = AudioSystem.getAudioInputStream(new BufferedInputStream(b_in)); 
    pcm = AudioSystem.getAudioInputStream(AudioFormat.Encoding.PCM_SIGNED, source); 
    File newFile = new File(uploadedFileLocation + fileName); 
    AudioSystem.write(pcm, Type.WAVE, newFile); 

    source.close(); 
    pcm.close(); 
} 
-1

El problema es fácil de resolver si prepara la clase que creará el encabezado correcto para usted. En mi ejemplo Example how to read audio input in wav buffer los datos van en algún búfer, después de eso creo un encabezado y tengo un archivo wav en el búfer. No es necesario en bibliotecas adicionales. Solo copie el código de mi ejemplo.

ejemplo de cómo utilizar la clase que crea cabecera correcta en la matriz de memoria intermedia:

public void run() {  
    try {  
     writer = new NewWaveWriter(44100); 

     byte[]buffer = new byte[256]; 
     int res = 0; 
     while((res = m_audioInputStream.read(buffer)) > 0) { 
      writer.write(buffer, 0, res); 
     } 
    } catch (IOException e) { 
     System.out.println("Error: " + e.getMessage()); 
    }  
}  

public byte[]getResult() throws IOException { 
    return writer.getByteBuffer(); 
} 

y Clase NewWaveWriter se pueden encontrar bajo mi enlace.

Cuestiones relacionadas