Réponses:
J'ai écrit le code suivant qui fonctionne très bien. Mais je pense que cela ne fonctionne qu'avec le .wav
format.
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
n'est pas nécessaire. 2) Pour un bon exemple d'utilisation Clip
, consultez les informations JavaSound. page . 3) Si une méthode nécessite un URL
(ou File
), donnez-lui un dang URL
(ou File
) plutôt que d'accepter un String
qui en représente un. (Juste une «abeille personnelle dans mon bonnet».) 4) e.printStackTrace();
fournit plus d'informations avec moins de frappe que System.err.println(e.getMessage());
.
Un mauvais exemple:
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);
Je ne voulais pas avoir autant de lignes de code juste pour jouer un simple son. Cela peut fonctionner si vous avez le package JavaFX (déjà inclus dans mon 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();
}
Remarque: vous devez initialiser JavaFX . Un moyen rapide de le faire est d'appeler le constructeur de JFXPanel () une fois dans votre application:
static{
JFXPanel fxPanel = new JFXPanel();
}
Pour jouer du son en java, vous pouvez vous référer au code suivant.
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();
}
}
Pour une raison quelconque, la réponse principale de wchargin me donnait une erreur de pointeur nul lorsque j'appelais this.getClass (). GetResourceAsStream ().
Ce qui a fonctionné pour moi était le suivant:
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();
}
Et je jouerais le son avec:
playSound("sounds/effects/sheep1.wav");
sons / effets / mouton1.wav se trouvait dans le répertoire de base de mon projet dans Eclipse (donc pas dans le dossier src).
getResourceAsStream()
sera de retour null
si la ressource ne se trouve pas, ou jeter l'exception si name
est null
- pas un défaut de réponse supérieure si le chemin donné est pas valide
J'ai créé il y a quelque temps un framework de jeu pour travailler sur Android et Desktop, la partie bureau qui gère le son peut peut-être être utilisée comme source d'inspiration pour ce dont vous avez besoin.
Voici le code pour référence.
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();
entraîner une erreur en menant à Resetting to invalid mark
. Que proposez-vous de faire pour résoudre ce problème?
raw.mark(raw.available()+1)
après l'initialisation raw
, puis dans la boucle while, puis en utilisant à la raw.reset()
place de stream.reset()
. Mon problème maintenant est que lorsqu'il s'agit de réinitialiser, il y a un écart entre les jeux. Je veux réaliser une boucle continue comme vous le faites Clip
. Je ne l'utilise pas Clip
car la manipulation de contrôles tels que MASTER_GAIN a un retard notable d'environ 500 ms. Cela devrait probablement être sa propre question que je poserai plus tard.
do { ... } while
?
Il existe une alternative à l'importation des fichiers audio qui fonctionne à la fois dans les applets et les applications: convertissez les fichiers audio en fichiers .java et utilisez-les simplement dans votre code.
J'ai développé un outil qui rend ce processus beaucoup plus facile. Cela simplifie un peu l'API Java Sound.
Je suis surpris que personne n'ait suggéré d'utiliser Applet. Utilisez Applet
. Vous devrez fournir le fichier audio du bip sous forme de wav
fichier, mais cela fonctionne. J'ai essayé ceci sur 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 obsolète à partir de Java 9.
Ce fil est assez ancien mais j'ai déterminé une option qui pourrait s'avérer utile.
Au lieu d'utiliser la AudioStream
bibliothèque Java , vous pouvez utiliser un programme externe comme Windows Media Player ou VLC et l'exécuter avec une commande de console via 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();
}
Cela créera également un processus distinct qui peut être contrôlé par le programme.
p.destroy();
Bien sûr, cela prendra plus de temps à s'exécuter que d'utiliser une bibliothèque interne, mais il peut y avoir des programmes qui peuvent démarrer plus rapidement et éventuellement sans interface graphique étant donné certaines commandes de la console.
Si le temps presse, c'est utile.