Respuestas:
Escribí el siguiente código que funciona bien. Pero creo que solo funciona con .wav
formato.
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();
}
Thread
es 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 String
que 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());
.
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);
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).
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: debe inicializar JavaFX . Una forma rápida de hacerlo es llamar al constructor de JFXPanel () una vez en su aplicación:
static{
JFXPanel fxPanel = new JFXPanel();
}
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();
}
}
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:
void playSound(String soundFile) {
File f = new File("./" + soundFile);
AudioInputStream audioIn = AudioSystem.getAudioInputStream(f.toURI().toURL());
Clip clip = AudioSystem.getClip();
clip.open(audioIn);
clip.start();
}
Y tocaría el sonido con:
playSound("sounds/effects/sheep1.wav");
sounds / effects / sheep1.wav estaba ubicado en el directorio base de mi proyecto en Eclipse (no dentro de la carpeta src).
getResourceAsStream()
regresará null
si no se encuentra el recurso, o arrojará la excepción si name
es null
- no es un error de respuesta superior si la ruta dada no es válida
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.
Aquí está 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();
}
}
}
stream.reset();
conducir a Resetting to invalid mark
. ¿Qué propones hacer para solucionar esto?
raw.mark(raw.available()+1)
después de inicializar raw
y 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 Clip
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.
Me sorprende que nadie sugirió usar Applet. Uso Applet
. Tendrá que proporcionar el archivo de audio de pitido como un wav
archivo, 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;
public class JavaApplication2 {
public static void main(String[] args) throws MalformedURLException {
File file = new File("/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
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.
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.