2008-08-25 38 views
153

Quiero ser capaz de reproducir archivos de sonido en mi programa. ¿Dónde debería mirar?¿Cómo puedo reproducir sonido en Java?

+1

Echa un vistazo a esta clase: https://github.com/dberm22/DBoard/blob/master/src/com/dberm22/utils/MediaPlayer.java Puedes llamarlo con (nuevo Thread (nuevo MediaPlayer (PATHTOFILE))). start(); – dberm22

Respuesta

116

me escribió el siguiente código que funciona bien. Pero creo que solo funciona con el formato .wav.

public static synchronized void playSound(final String url) { 
    new Thread(new Runnable() { 
    // The wrapper thread is unnecessary, unless it blocks on the 
    // Clip finishing; see comments. 
    public void run() { 
     try { 
     Clip clip = AudioSystem.getClip(); 
     AudioInputStream inputStream = AudioSystem.getAudioInputStream(
      Main.class.getResourceAsStream("/path/to/sounds/" + url)); 
     clip.open(inputStream); 
     clip.start(); 
     } catch (Exception e) { 
     System.err.println(e.getMessage()); 
     } 
    } 
    }).start(); 
} 
+7

Para evitar que el Clip se cierre al azar, se requiere un LineListener. Eche un vistazo: http://stackoverflow.com/questions/577724/trouble-playing-wav-in-java/577926#577926 – yanchenko

+3

+1 para una solución que usa la API pública. Sin embargo, ¿no es necesario crear un nuevo hilo (redundante)? – Jataro

+3

Gracias ... ¿Es redundante? Lo hice en un nuevo hilo para poder reproducir el sonido nuevamente antes de que termine el primer clip. – pek

19

Un mal ejemplo:

import sun.audio.*; //import the sun.audio package 
import java.io.*; 

//** add this into your application code as appropriate 
// Open an input stream to the audio file. 
InputStream in = new FileInputStream(Filename); 

// Create an AudioStream object from the input stream. 
AudioStream as = new AudioStream(in);   

// Use the static class member "player" from class AudioPlayer to play 
// clip. 
AudioPlayer.player.start(as);    

// Similarly, to stop the audio. 
AudioPlayer.player.stop(as); 
+13

http://java.sun.com/products/jdk/faq/faq-sun-packages.html Hay alternativas de API públicas para usar sun.audio. – McDowell

+4

@GregHurlman Is not sun. * paquete hecho para que no lo usen los desarrolladores de EE. UU .: –

+0

@Tom: podría ser; normalmente no me encuentro usando este tipo de código. –

21

El Sound Trail del Tutorial de Java es digno de ser el punto de partida.

+3

Consulte también [Información de JavaSound. página] (http://stackoverflow.com/tags/javasound/info) por ejemplo código y muchos enlaces útiles relacionados con JavaSound. –

4

Existe una alternativa a la importación de archivos de sonido que funciona en ambos applets y aplicaciones: convierta los archivos de audio en archivos .java y simplemente úselos en su código.

He desarrollado una herramienta que hace que este proceso sea mucho más fácil. Simplifica bastante la API de Java Sound.

http://stephengware.com/projects/soundtoclass/

+0

Utilicé su sistema para crear una clase a partir de un archivo wav, sin embargo, cuando hago my_wave.play(); no reproduce el audio ... ¿Hay un sistema de audio que necesito inicializar o algo así? ... –

+0

esto sería genial si realmente funcionara. Cuando se ejecuta play(), la línea de audio get falla (excepción "java.lang.IllegalArgumentException: sin interfaz de coincidencia de línea SourceDataLine compatible con formato PCM_UNSIGNED 44100.0 Hz, 16 bit, estéreo, 4 bytes/frame, little-endian es compatible." No es arrojado). Triste. – Blauhirn

2

que creaba un marco de juego hace algún tiempo para trabajar en Android y de escritorio, la parte de escritorio que se encargan de sonido tal vez puede utilizarse como fuente de inspiración a lo que necesita.

https://github.com/hamilton-lima/jaga/blob/master/jaga%20desktop/src-desktop/com/athanazio/jaga/desktop/sound/Sound.java

Aquí es el código de referencia.

package com.athanazio.jaga.desktop.sound; 

import java.io.BufferedInputStream; 
import java.io.IOException; 
import java.io.InputStream; 

import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioInputStream; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.DataLine; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.SourceDataLine; 
import javax.sound.sampled.UnsupportedAudioFileException; 

public class Sound { 

    AudioInputStream in; 

    AudioFormat decodedFormat; 

    AudioInputStream din; 

    AudioFormat baseFormat; 

    SourceDataLine line; 

    private boolean loop; 

    private BufferedInputStream stream; 

    // private ByteArrayInputStream stream; 

    /** 
    * recreate the stream 
    * 
    */ 
    public void reset() { 
     try { 
      stream.reset(); 
      in = AudioSystem.getAudioInputStream(stream); 
      din = AudioSystem.getAudioInputStream(decodedFormat, in); 
      line = getLine(decodedFormat); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public void close() { 
     try { 
      line.close(); 
      din.close(); 
      in.close(); 
     } catch (IOException e) { 
     } 
    } 

    Sound(String filename, boolean loop) { 
     this(filename); 
     this.loop = loop; 
    } 

    Sound(String filename) { 
     this.loop = false; 
     try { 
      InputStream raw = Object.class.getResourceAsStream(filename); 
      stream = new BufferedInputStream(raw); 

      // ByteArrayOutputStream out = new ByteArrayOutputStream(); 
      // byte[] buffer = new byte[1024]; 
      // int read = raw.read(buffer); 
      // while(read > 0) { 
      // out.write(buffer, 0, read); 
      // read = raw.read(buffer); 
      // } 
      // stream = new ByteArrayInputStream(out.toByteArray()); 

      in = AudioSystem.getAudioInputStream(stream); 
      din = null; 

      if (in != null) { 
       baseFormat = in.getFormat(); 

       decodedFormat = new AudioFormat(
         AudioFormat.Encoding.PCM_SIGNED, baseFormat 
           .getSampleRate(), 16, baseFormat.getChannels(), 
         baseFormat.getChannels() * 2, baseFormat 
           .getSampleRate(), false); 

       din = AudioSystem.getAudioInputStream(decodedFormat, in); 
       line = getLine(decodedFormat); 
      } 
     } catch (UnsupportedAudioFileException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (LineUnavailableException e) { 
      e.printStackTrace(); 
     } 
    } 

    private SourceDataLine getLine(AudioFormat audioFormat) 
      throws LineUnavailableException { 
     SourceDataLine res = null; 
     DataLine.Info info = new DataLine.Info(SourceDataLine.class, 
       audioFormat); 
     res = (SourceDataLine) AudioSystem.getLine(info); 
     res.open(audioFormat); 
     return res; 
    } 

    public void play() { 

     try { 
      boolean firstTime = true; 
      while (firstTime || loop) { 

       firstTime = false; 
       byte[] data = new byte[4096]; 

       if (line != null) { 

        line.start(); 
        int nBytesRead = 0; 

        while (nBytesRead != -1) { 
         nBytesRead = din.read(data, 0, data.length); 
         if (nBytesRead != -1) 
          line.write(data, 0, nBytesRead); 
        } 

        line.drain(); 
        line.stop(); 
        line.close(); 

        reset(); 
       } 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

} 
7

Para reproducir sonido en java, puede consultar el siguiente código.

import java.io.*; 
import java.net.URL; 
import javax.sound.sampled.*; 
import javax.swing.*; 

// To play sound using Clip, the process need to be alive. 
// Hence, we use a Swing application. 
public class SoundClipTest extends JFrame { 

    public SoundClipTest() { 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.setTitle("Test Sound Clip"); 
     this.setSize(300, 200); 
     this.setVisible(true); 

     try { 
     // Open an audio input stream. 
     URL url = this.getClass().getClassLoader().getResource("gameover.wav"); 
     AudioInputStream audioIn = AudioSystem.getAudioInputStream(url); 
     // Get a sound clip resource. 
     Clip clip = AudioSystem.getClip(); 
     // Open audio clip and load samples from the audio input stream. 
     clip.open(audioIn); 
     clip.start(); 
     } catch (UnsupportedAudioFileException e) { 
     e.printStackTrace(); 
     } catch (IOException e) { 
     e.printStackTrace(); 
     } catch (LineUnavailableException e) { 
     e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 
     new SoundClipTest(); 
    } 
} 
7

No quería tener tantas líneas de código solo para reproducir un simple sonido. Esto puede funcionar si tienes el paquete JavaFX (ya incluido en mi jdk 8).

private static void playSound(String sound){ 
    // cl is the ClassLoader for the current class, ie. CurrentClass.class.getClassLoader(); 
    URL file = cl.getResource(sound); 
    final Media media = new Media(file.toString()); 
    final MediaPlayer mediaPlayer = new MediaPlayer(media); 
    mediaPlayer.play(); 
} 

Aviso: Necesita initialize JavaFX. Una forma rápida de hacer eso, es llamar al constructor de JFXPanel() una vez en su aplicación:

static{ 
    JFXPanel fxPanel = new JFXPanel(); 
} 
3

Por alguna razón, la respuesta más común por wchargin me daba un error de puntero nulo cuando me estaba llamando a esto. getClass(). getResourceAsStream().

lo que funcionó para mí fue la siguiente:

void playSound(String soundFile) { 
    File f = new File("./" + soundFile); 
    audioIn = AudioSystem.getAudioInputStream(f.toURI().toURL()); 
    Clip clip = AudioSystem.getClip(); 
    clip.open(audioIn); 
    clip.start(); 
} 

Y me gustaría jugar con el sonido:

playSound("sounds/effects/sheep1.wav"); 

sonidos/efectos/sheep1.wav se encuentran en el directorio de base de mi proyecto en Eclipse (por lo tanto, no dentro de la carpeta src).

+0

hola Anrew, tu código funcionó para mí, pero noté que toma un poco más de tiempo en ejecución ... aproximadamente 1,5 segundos. –

-1

Este hilo es bastante antiguo pero he determinado una opción que podría ser útil.

En lugar de utilizar la biblioteca Java AudioStream, puede utilizar un programa externo como Windows Media Player o VLC y ejecutarlo con un comando de consola a través de Java.

String command = "\"C:/Program Files (x86)/Windows Media Player/wmplayer.exe\" \"C:/song.mp3\""; 
try { 
    Process p = Runtime.getRuntime().exec(command); 
catch (IOException e) { 
    e.printStackTrace(); 
} 

Esto también creará un proceso separado que puede ser controlado por el programa.

p.destroy(); 

Por supuesto, esto se necesitará más tiempo para ejecutar que el uso de una biblioteca interna pero puede haber programas que pueden iniciar más rápido y posiblemente sin una interfaz gráfica de usuario dado ciertos comandos de la consola.

Si el tiempo no es esencial, entonces esto es útil.

Cuestiones relacionadas