+1 para una solución que utiliza la API pública. Sin embargo, ¿no es innecesario crear un nuevo hilo (redundante)?
Jataro
44
Gracias ... ¿Es redundante? Lo convertí en un nuevo hilo para poder reproducir el sonido nuevamente antes de que termine el primer clip.
pek
44
Sé que clip.start () genera un nuevo hilo, así que estoy bastante seguro de que es innecesario.
Jataro
44
1) El Threades innecesario. 2) Para ver un buen ejemplo de uso Clip, consulte la información de JavaSound. la página . 3) Si un método requiere un URL(o File) dele un dang URL(o File) en lugar de aceptar un Stringque representa uno. (Solo una 'abeja en mi capó' personal). 4) e.printStackTrace();proporciona más información con menos tipeo que System.err.println(e.getMessage());.
Andrew Thompson
18
Un mal ejemplo:
import sun.audio.*;//import the sun.audio packageimport java.io.*;//** add this into your application code as appropriate// Open an input stream to the audio file.InputStream in =newFileInputStream(Filename);// Create an AudioStream object from the input stream.AudioStream as =newAudioStream(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);
@GregHurlman ¿No está hecho el paquete sun. * Para que los desarrolladores no lo usemos?
Tom Brito
36
Este ejemplo proviene de un artículo de JavaWorld de 1997. Muy desactualizado, NO debe usar paquetes sun. *.
sproketboy
3
¿alguna vez necesitas cerrar "en"?
rogerdpack
66
+1 por no usar el sol. * Paquetes. Tienen bichos raros como no manejar archivos> 1 MB y no ser capaz de reproducir un clip si el anterior no ha terminado todavía, etc
rogerdpack
10
No quería tener tantas líneas de código solo para reproducir un simple sonido. Esto puede funcionar si tiene el paquete JavaFX (ya incluido en mi jdk 8).
privatestaticvoid playSound(String sound){// cl is the ClassLoader for the current class, ie. CurrentClass.class.getClassLoader();
URL file = cl.getResource(sound);finalMedia media =newMedia(file.toString());finalMediaPlayer mediaPlayer =newMediaPlayer(media);
mediaPlayer.play();}
Aviso: debe inicializar JavaFX . Una forma rápida de hacerlo es llamar al constructor de JFXPanel () una vez en su aplicación:
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.publicclassSoundClipTestextendsJFrame{publicSoundClipTest(){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();}}publicstaticvoid main(String[] args){newSoundClipTest();}}
Por alguna razón, la respuesta principal de wchargin me estaba dando un error de puntero nulo cuando estaba llamando this.getClass (). GetResourceAsStream ().
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.
getResourceAsStream()regresará nullsi no se encuentra el recurso, o arrojará la excepción si namees null- no es un error de respuesta superior si la ruta dada no es válida
user85421
3
Creé un marco de juego hace algún tiempo para trabajar en Android y escritorio, la parte de escritorio que maneja el sonido puede usarse como inspiración para lo que necesitas.
De hecho, resolví esto usando raw.mark(raw.available()+1)después de inicializar rawy luego en el ciclo while, y luego usando en raw.reset()lugar de stream.reset(). Mi problema ahora es que cuando se trata de reiniciar, hay una brecha entre las jugadas. Quiero lograr un ciclo continuo como el que tienes Clip. No estoy usando Clipporque manipular controles como MASTER_GAIN tiene un retraso notable de ~ 500ms. Probablemente esta debería ser su propia pregunta que voy a preguntar más tarde.
driima
No es un do { ... } while?
Andreas
2
Existe una alternativa a la importación de archivos de sonido que funciona tanto en applets como en aplicaciones: convierta los archivos de audio en archivos .java y simplemente utilícelos 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.
Usé 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í? ..
Nathan F.
Esto sería realmente genial si realmente funcionara. Al ejecutar play (), la línea de audio get falla (excepción "java.lang.IllegalArgumentException: no hay interfaz de coincidencia de línea. Formato de soporte SourceDataLine PCM_UNSIGNED 44100.0 Hz, 16 bit, estéreo, 4 bytes / frame, little-endian es compatible". arrojado). Triste.
phil294
2
Me sorprende que nadie sugirió usar Applet. UsoApplet . Tendrá que proporcionar el archivo de audio de pitido como un wavarchivo, pero funciona. Intenté esto en Ubuntu:
package javaapplication2;import java.applet.Applet;import java.applet.AudioClip;import java.io.File;import java.net.MalformedURLException;import java.net.URL;publicclassJavaApplication2{publicstaticvoid main(String[] args)throwsMalformedURLException{File file =newFile("/path/to/your/sounds/beep3.wav");
URL url =null;if(file.canRead()){url = file.toURI().toURL();}System.out.println(url);AudioClip clip =Applet.newAudioClip(url);
clip.play();System.out.println("should've played by now");}}//beep3.wav was available from: http://www.pacdv.com/sounds/interface_sound_effects/beep-3.wav
Este hilo es bastante antiguo, pero he determinado una opción que podría resultar útil.
En lugar de usar la AudioStreambiblioteca Java , puede usar 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 controlarse en el programa.
p.destroy();
Por supuesto, esto llevará más tiempo de ejecución que el uso de una biblioteca interna, pero puede haber programas que puedan iniciarse más rápido y posiblemente sin una GUI dada ciertos comandos de consola.
Si el tiempo no es esencial, entonces esto es útil.
Aunque creo que esta es una solución objetivamente mala (en términos de confiabilidad, eficiencia y otras métricas similares), ¡es al menos una solución interesante en la que de otra manera no habría pensado!
Respuestas:
Escribí el siguiente código que funciona bien. Pero creo que solo funciona con
.wav
formato.fuente
Thread
es innecesario. 2) Para ver un buen ejemplo de usoClip
, consulte la información de JavaSound. la página . 3) Si un método requiere unURL
(oFile
) dele un dangURL
(oFile
) en lugar de aceptar unString
que representa uno. (Solo una 'abeja en mi capó' personal). 4)e.printStackTrace();
proporciona más información con menos tipeo queSystem.err.println(e.getMessage());
.Un mal ejemplo:
fuente
No quería tener tantas líneas de código solo para reproducir un simple sonido. Esto puede funcionar si tiene el paquete JavaFX (ya incluido en mi jdk 8).
Aviso: debe inicializar JavaFX . Una forma rápida de hacerlo es llamar al constructor de JFXPanel () una vez en su aplicación:
fuente
Para reproducir sonido en java, puede consultar el siguiente código.
fuente
Por alguna razón, la respuesta principal de wchargin me estaba dando un error de puntero nulo cuando estaba llamando this.getClass (). GetResourceAsStream ().
Lo que funcionó para mí fue lo siguiente:
Y tocaría el sonido con:
sounds / effects / sheep1.wav estaba ubicado en el directorio base de mi proyecto en Eclipse (no dentro de la carpeta src).
fuente
getResourceAsStream()
regresaránull
si no se encuentra el recurso, o arrojará la excepción siname
esnull
- no es un error de respuesta superior si la ruta dada no es válidaCreé un marco de juego hace algún tiempo para trabajar en Android y escritorio, la parte de escritorio que maneja el sonido puede usarse como inspiración para lo que necesitas.
https://github.com/hamilton-lima/jaga/blob/master/jaga%20desktop/src-desktop/com/athanazio/jaga/desktop/sound/Sound.java
Aquí está el código de referencia.
fuente
stream.reset();
conducir aResetting to invalid mark
. ¿Qué propones hacer para solucionar esto?raw.mark(raw.available()+1)
después de inicializarraw
y luego en el ciclo while, y luego usando enraw.reset()
lugar destream.reset()
. Mi problema ahora es que cuando se trata de reiniciar, hay una brecha entre las jugadas. Quiero lograr un ciclo continuo como el que tienesClip
. No estoy usandoClip
porque manipular controles como MASTER_GAIN tiene un retraso notable de ~ 500ms. Probablemente esta debería ser su propia pregunta que voy a preguntar más tarde.do { ... } while
?Existe una alternativa a la importación de archivos de sonido que funciona tanto en applets como en aplicaciones: convierta los archivos de audio en archivos .java y simplemente utilícelos 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/
fuente
Me sorprende que nadie sugirió usar Applet. Uso
Applet
. Tendrá que proporcionar el archivo de audio de pitido como unwav
archivo, pero funciona. Intenté esto en Ubuntu:fuente
Applet
está en desuso desde Java 9.Este hilo es bastante antiguo, pero he determinado una opción que podría resultar útil.
En lugar de usar la
AudioStream
biblioteca Java , puede usar un programa externo como Windows Media Player o VLC y ejecutarlo con un comando de consola a través de Java.Esto también creará un proceso separado que puede controlarse en el programa.
Por supuesto, esto llevará más tiempo de ejecución que el uso de una biblioteca interna, pero puede haber programas que puedan iniciarse más rápido y posiblemente sin una GUI dada ciertos comandos de consola.
Si el tiempo no es esencial, entonces esto es útil.
fuente