Um zu vermeiden, dass der Clip zufällig heruntergefahren wird, ist ein LineListener erforderlich. Schauen Sie mal
rein
3
+1 für eine Lösung, die die öffentliche API verwendet. Ist das Erstellen eines neuen Threads nicht unnötig (redundant)?
Jataro
4
Danke .. Ist es überflüssig? Ich habe es zu einem neuen Thread gemacht, damit ich den Sound wieder abspielen kann, bevor der erste Clip endet.
Pek
4
Ich weiß, dass clip.start () einen neuen Thread erzeugt, daher bin ich mir ziemlich sicher, dass dies nicht erforderlich ist.
Jataro
44
1) Das Threadist unnötig. 2) Ein gutes Beispiel für die Verwendung Clipfinden Sie in den JavaSound-Informationen. Seite . 3) Wenn eine Methode ein URL(oder File) erfordert, geben Sie ihr einen Dang URL(oder File), anstatt einen zu akzeptieren String, der einen darstellt. (Nur eine persönliche 'Biene in meiner Haube'.) 4) e.printStackTrace();liefert mehr Informationen mit weniger Eingabe als System.err.println(e.getMessage());.
Andrew Thompson
18
Ein schlechtes Beispiel:
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 Ist nicht sun. * Paket gemacht, um nicht von uns Entwicklern verwendet zu werden?
Tom Brito
36
Dieses Beispiel stammt aus einem JavaWorld-Artikel von 1997. Veraltet, Sie sollten KEINE sun. * -Pakete verwenden.
Sproketboy
3
Müssen Sie jemals "in" schließen?
Rogerdpack
6
+1 für nicht mit Hilfe der Sonne. * Pakete. Sie haben seltsame Fehler wie das Nicht-Behandeln von Dateien> 1 MB und das Nicht-Abspielen eines Clips, wenn der vorherige noch nicht fertig ist usw.
Rogerdpack
10
Ich wollte nicht so viele Codezeilen haben, nur um einen einfachen verdammten Sound zu spielen. Dies kann funktionieren, wenn Sie das JavaFX-Paket haben (das bereits in meinem JDK 8 enthalten ist).
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();}
Hinweis: Sie müssen JavaFX initialisieren . Eine schnelle Möglichkeit, dies zu tun, besteht darin, den Konstruktor von JFXPanel () einmal in Ihrer App aufzurufen:
Informationen zum Abspielen von Sound in Java finden Sie im folgenden Code.
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();}}
Hallo Anrew, dein Code hat bei mir funktioniert, aber mir ist aufgefallen, dass die Ausführung etwas länger dauert ... ungefähr 1,5 Sekunden.
getResourceAsStream()kehrt , nullwenn die Ressource nicht gefunden wird, oder die Ausnahme auslösen , wenn nameist null- kein Fehler der Top - Antwort , wenn der angegebene Pfad ist nicht gültig
user85421
3
Ich habe vor einiger Zeit ein Spiel-Framework für Android und Desktop erstellt. Der Desktop-Teil, der den Sound verarbeitet, kann möglicherweise als Inspiration für Ihre Anforderungen verwendet werden.
Ich habe dies tatsächlich behoben, indem ich raw.mark(raw.available()+1)nach der Initialisierung rawund dann in der while-Schleife und dann raw.reset()anstelle von verwendet habe stream.reset(). Mein Problem ist jetzt, dass es beim Zurücksetzen eine Lücke zwischen den Spielen gibt. Ich möchte eine Endlosschleife erreichen, wie Sie sie erhalten Clip. Ich benutze es nicht, Clipweil das Manipulieren von Steuerelementen wie MASTER_GAIN eine merkliche Verzögerung von ~ 500 ms hat. Dies sollte wahrscheinlich eine eigene Frage sein, die ich später stellen werde.
Driima
Nicht ein do { ... } while?
Andreas
2
Es gibt eine Alternative zum Importieren der Audiodateien, die sowohl in Applets als auch in Anwendungen funktioniert: Konvertieren Sie die Audiodateien in Java-Dateien und verwenden Sie sie einfach in Ihrem Code.
Ich habe ein Tool entwickelt, das diesen Prozess erheblich vereinfacht. Dies vereinfacht die Java Sound API erheblich.
Ich habe Ihr System verwendet, um eine Klasse aus einer WAV-Datei zu erstellen. Wenn ich jedoch my_wave.play () mache; Es wird kein Audio abgespielt. Gibt es ein Audiosystem, das ich initialisieren muss oder so? ..
Nathan F.
Das wäre wirklich cool, wenn es tatsächlich funktionieren würde. Beim Ausführen von play () schlägt die get Audio Line fehl (Ausnahme "java.lang.IllegalArgumentException: Keine Line Matching-Schnittstelle SourceDataLine unterstützt das Format PCM_UNSIGNED 44100.0 Hz, 16 Bit, Stereo, 4 Byte / Frame, Little Endian wird nicht unterstützt." Wird nicht unterstützt geworfen). Traurig.
Phil294
2
Ich bin überrascht, dass niemand Applet vorgeschlagen hat. Verwenden SieApplet . Sie müssen die Signalton-Audiodatei als wavDatei angeben, aber es funktioniert. Ich habe das unter Ubuntu versucht:
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
Dieser Thread ist ziemlich alt, aber ich habe eine Option festgelegt, die sich als nützlich erweisen könnte.
Anstatt die Java- AudioStreamBibliothek zu verwenden, können Sie ein externes Programm wie Windows Media Player oder VLC verwenden und es mit einem Konsolenbefehl über Java ausführen.
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();}
Dadurch wird auch ein separater Prozess erstellt, der vom Programm gesteuert werden kann.
p.destroy();
Die Ausführung dauert natürlich länger als die Verwendung einer internen Bibliothek, aber es kann Programme geben, die bei bestimmten Konsolenbefehlen schneller und möglicherweise ohne GUI gestartet werden können.
Wenn die Zeit nicht entscheidend ist, ist dies nützlich.
Obwohl ich denke, dass dies eine objektiv schlechte Lösung ist (in Bezug auf Zuverlässigkeit, Effizienz und andere solche Metriken), ist es zumindest eine interessante, an die ich sonst nicht gedacht hätte!
Antworten:
Ich habe den folgenden Code geschrieben, der gut funktioniert. Aber ich denke, es funktioniert nur mit
.wav
Format.quelle
Thread
ist unnötig. 2) Ein gutes Beispiel für die VerwendungClip
finden Sie in den JavaSound-Informationen. Seite . 3) Wenn eine Methode einURL
(oderFile
) erfordert, geben Sie ihr einen DangURL
(oderFile
), anstatt einen zu akzeptierenString
, der einen darstellt. (Nur eine persönliche 'Biene in meiner Haube'.) 4)e.printStackTrace();
liefert mehr Informationen mit weniger Eingabe alsSystem.err.println(e.getMessage());
.Ein schlechtes Beispiel:
quelle
Ich wollte nicht so viele Codezeilen haben, nur um einen einfachen verdammten Sound zu spielen. Dies kann funktionieren, wenn Sie das JavaFX-Paket haben (das bereits in meinem JDK 8 enthalten ist).
Hinweis: Sie müssen JavaFX initialisieren . Eine schnelle Möglichkeit, dies zu tun, besteht darin, den Konstruktor von JFXPanel () einmal in Ihrer App aufzurufen:
quelle
Informationen zum Abspielen von Sound in Java finden Sie im folgenden Code.
quelle
Aus irgendeinem Grund gab mir die Top-Antwort von wchargin einen Nullzeigerfehler, als ich this.getClass (). GetResourceAsStream () aufrief.
Was für mich funktioniert hat, war Folgendes:
Und ich würde den Sound spielen mit:
Sounds / Effects / Schaf1.wav befand sich im Basisverzeichnis meines Projekts in Eclipse (also nicht im Ordner src).
quelle
getResourceAsStream()
kehrt ,null
wenn die Ressource nicht gefunden wird, oder die Ausnahme auslösen , wennname
istnull
- kein Fehler der Top - Antwort , wenn der angegebene Pfad ist nicht gültigIch habe vor einiger Zeit ein Spiel-Framework für Android und Desktop erstellt. Der Desktop-Teil, der den Sound verarbeitet, kann möglicherweise als Inspiration für Ihre Anforderungen verwendet werden.
https://github.com/hamilton-lima/jaga/blob/master/jaga%20desktop/src-desktop/com/athanazio/jaga/desktop/sound/Sound.java
Hier ist der Code als Referenz.
quelle
stream.reset();
Führen zu fehlerhaft seinResetting to invalid mark
. Was schlagen Sie vor, um dies zu beheben?raw.mark(raw.available()+1)
nach der Initialisierungraw
und dann in der while-Schleife und dannraw.reset()
anstelle von verwendet habestream.reset()
. Mein Problem ist jetzt, dass es beim Zurücksetzen eine Lücke zwischen den Spielen gibt. Ich möchte eine Endlosschleife erreichen, wie Sie sie erhaltenClip
. Ich benutze es nicht,Clip
weil das Manipulieren von Steuerelementen wie MASTER_GAIN eine merkliche Verzögerung von ~ 500 ms hat. Dies sollte wahrscheinlich eine eigene Frage sein, die ich später stellen werde.do { ... } while
?Es gibt eine Alternative zum Importieren der Audiodateien, die sowohl in Applets als auch in Anwendungen funktioniert: Konvertieren Sie die Audiodateien in Java-Dateien und verwenden Sie sie einfach in Ihrem Code.
Ich habe ein Tool entwickelt, das diesen Prozess erheblich vereinfacht. Dies vereinfacht die Java Sound API erheblich.
http://stephengware.com/projects/soundtoclass/
quelle
Ich bin überrascht, dass niemand Applet vorgeschlagen hat. Verwenden Sie
Applet
. Sie müssen die Signalton-Audiodatei alswav
Datei angeben, aber es funktioniert. Ich habe das unter Ubuntu versucht:quelle
Applet
ist ab Java 9 veraltet.Dieser Thread ist ziemlich alt, aber ich habe eine Option festgelegt, die sich als nützlich erweisen könnte.
Anstatt die Java-
AudioStream
Bibliothek zu verwenden, können Sie ein externes Programm wie Windows Media Player oder VLC verwenden und es mit einem Konsolenbefehl über Java ausführen.Dadurch wird auch ein separater Prozess erstellt, der vom Programm gesteuert werden kann.
Die Ausführung dauert natürlich länger als die Verwendung einer internen Bibliothek, aber es kann Programme geben, die bei bestimmten Konsolenbefehlen schneller und möglicherweise ohne GUI gestartet werden können.
Wenn die Zeit nicht entscheidend ist, ist dies nützlich.
quelle