+1 pour une solution utilisant l'API publique. La création d'un nouveau thread n'est-elle pas inutile (redondante) cependant?
Jataro
4
Merci .. Est-ce redondant? J'en ai fait un nouveau fil pour pouvoir jouer à nouveau le son avant la fin du premier clip.
pek le
4
Je sais que clip.start () génère un nouveau thread, donc je suis presque sûr que ce n'est pas nécessaire.
Jataro
44
1) Le Threadn'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 Stringqui 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());.
Andrew Thompson
18
Un mauvais exemple:
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 Le paquet sun. * N'est-il pas fait pour ne pas être utilisé par les développeurs?
Tom Brito
36
Cet exemple provient d'un article de 1997 sur JavaWorld. Très obsolète, vous ne devez PAS utiliser les packages sun. *.
sproketboy
3
avez-vous déjà besoin de fermer "in"?
rogerdpack
6
+1 pour ne pas utiliser le soleil. * Packages. Ils ont des bugs étranges comme ne pas gérer les fichiers> 1 Mo et ne pas pouvoir lire un clip si le précédent n'est pas encore terminé, etc.
rogerdpack
10
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).
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();}
Remarque: vous devez initialiser JavaFX . Un moyen rapide de le faire est d'appeler le constructeur de JFXPanel () une fois dans votre application:
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.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();}}
Pour une raison quelconque, la réponse principale de wchargin me donnait une erreur de pointeur nul lorsque j'appelais this.getClass (). GetResourceAsStream ().
bonjour Anrew, votre code a fonctionné pour moi, mais j'ai remarqué que l'exécution prend un peu plus de temps ... environ 1,5 sec.
getResourceAsStream()sera de retour nullsi la ressource ne se trouve pas, ou jeter l'exception si nameest null- pas un défaut de réponse supérieure si le chemin donné est pas valide
user85421
3
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.
En fait, j'ai résolu ce problème en utilisant 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 Clipcar 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.
driima
Pas un do { ... } while?
Andreas le
2
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.
J'ai utilisé votre système pour créer une classe à partir d'un fichier wav, cependant, quand je fais my_wave.play (); il ne lit pas l'audio .. Y a-t-il un système audio que j'ai besoin d'initialiser ou quelque chose? ..
Nathan F.
ce serait vraiment cool si cela fonctionnait réellement. Lors de l'exécution de play (), l'obtention de la ligne audio échoue (exception "java.lang.IllegalArgumentException: Aucune interface de correspondance de ligne SourceDataLine prenant en charge le format PCM_UNSIGNED 44100,0 Hz, 16 bits, stéréo, 4 octets / image, petit-boutiste est pris en charge." N'est pas jeté). Triste.
phil294
2
Je suis surpris que personne n'ait suggéré d'utiliser Applet. UtilisezApplet . Vous devrez fournir le fichier audio du bip sous forme de wavfichier, 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;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
Ce fil est assez ancien mais j'ai déterminé une option qui pourrait s'avérer utile.
Au lieu d'utiliser la AudioStreambibliothè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.
Bien que je pense que c'est une solution objectivement mauvaise (en termes de fiabilité, d'efficacité et d'autres mesures similaires), c'est au moins une solution intéressante à laquelle je n'aurais pas pensé autrement!
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.la source
Thread
n'est pas nécessaire. 2) Pour un bon exemple d'utilisationClip
, consultez les informations JavaSound. page . 3) Si une méthode nécessite unURL
(ouFile
), donnez-lui un dangURL
(ouFile
) plutôt que d'accepter unString
qui en représente un. (Juste une «abeille personnelle dans mon bonnet».) 4)e.printStackTrace();
fournit plus d'informations avec moins de frappe queSystem.err.println(e.getMessage());
.Un mauvais exemple:
la source
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).
Remarque: vous devez initialiser JavaFX . Un moyen rapide de le faire est d'appeler le constructeur de JFXPanel () une fois dans votre application:
la source
Pour jouer du son en java, vous pouvez vous référer au code suivant.
la source
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:
Et je jouerais le son avec:
sons / effets / mouton1.wav se trouvait dans le répertoire de base de mon projet dans Eclipse (donc pas dans le dossier src).
la source
getResourceAsStream()
sera de retournull
si la ressource ne se trouve pas, ou jeter l'exception siname
estnull
- pas un défaut de réponse supérieure si le chemin donné est pas valideJ'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.
https://github.com/hamilton-lima/jaga/blob/master/jaga%20desktop/src-desktop/com/athanazio/jaga/desktop/sound/Sound.java
Voici le code pour référence.
la source
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'initialisationraw
, puis dans la boucle while, puis en utilisant à laraw.reset()
place destream.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 faitesClip
. Je ne l'utilise pasClip
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.
http://stephengware.com/projects/soundtoclass/
la source
Je suis surpris que personne n'ait suggéré d'utiliser Applet. Utilisez
Applet
. Vous devrez fournir le fichier audio du bip sous forme dewav
fichier, mais cela fonctionne. J'ai essayé ceci sur Ubuntu:la source
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.Cela créera également un processus distinct qui peut être contrôlé par le programme.
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.
la source