[Java(FX)] Audio-Datei abspielen?
Fehlermeldung:
...build\resources\main\sounds\welcome.wav (Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch)
Ich habe schon ausprobiert, ob es am Ordnernamen liegt und sounds und audio als Verzeichnis für die Audio-Datei genommen. .mp3 funktioniert wie .wav genauso wenig.
Der Code:
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new File(String.valueOf(getClass().getResource("/sounds/welcome.wav").toURI().toString()))));
clip.start();
Ich habe bei clip.open() alles reingepackt, weil es so Zeilen spart, aber es macht eigentlich genau das Gleiche.
Im Internet finde ich immer was mit MediaPlayer und Media, aber das bringt mich nicht wirklich weiter.
1 Antwort
Ich finde es seltsam, dass du Swing-Klassen den Klassen von JavaFX an der Stelle vorziehst. Das Java Audiosystem unterstützt zudem nur bestimmte Formate (aiff, au, wav). JavaFX ist da breiter aufgestellt.
Nimm für deinen einfachen Fall also besser ein AudioClip-Objekt.
var soundUrl = getClass().getResource("/sounds/welcome.wav").toExternalForm();
var clip = new AudioClip(soundUrl);
clip.play();
Prüfe zudem, ob die Pfadangabe tatsächlich stimmt. Für einen kurzen Test kann man auch einen absoluten Pfad angeben. Wenn es danach noch immer Problem mit der Wiedergabe gibt, liegt es womöglich an der Datei (Kodierung o.ä.).
Die AudioClip-Klasse liegt wie gesagt in JavaFX, nicht in der Java SE.
import javafx.scene.media.AudioClip;
Ah okay, ich habs jetzt auch in den Imports verbessert. In build.gradle und module-info.java eingetragen.
Wenn ich das Programm dann aber über Build Artifacts exportiere und die .jar-Datei (über cmd) ausführe, kommt diese Fehlermeldung. Irgendeine Klasse soll nicht vorhanden sein ...
'resources' directory contents ist in Project Structure > Artifacts ja vorhanden. Die Sound-Datei befindet sich auch definitiv in diesem Ordner, wo auch alle FXML-, .properties- und .css-Dateien liegen. Alle anderen Dateien werden ja geladen 🤔
Die Sounds nochmal extra bei Artifacts anzugeben hats auch nicht gebracht, außerdem ist die fertige .jar-Datei dann über 1 MB größer.
Main.java:
...
welcomeClip = new AudioClip(Objects.requireNonNull(getClass().getResource("/sounds/welcome.wav")).toExternalForm());
welcomeClip.play();
...
module-info.java:
...
requires javafx.media;
...
build.gradle:
...
javafx {
modules = ["javafx.controls", "javafx.fxml", "javafx.media"]
version = "15"
}
...
Welche Klasse nicht gefunden werden kann, steht in der Fehlermeldung:
Caused by: java.lang.ClassNotFoundException: javafx.scene.media.AudioClip
Der Fehler hat also damit zutun, dass beim Build das javafx.media-Modul doch nicht eingebunden wurde. Würde die Sounddatei fehlen, bekämst du eine NullPointer- oder IOException.
Du kannst die JAR ja einmal mit einer ZIP-Extraktor wie 7zip öffnen. Wenn du die Klasse unter javafx/scene/media/AudioClip.class nicht findest (wovon ich ausgehe), war der Build nicht erfolgreich.
Deine Angaben in build.gradle und module-info.java sind richtig. Mehr braucht es an sich auch nicht. Ich habe es kurz einmal getestet, das Modul findet bei mir seinen Weg in die JAR.
Nimm den Eintrag in der build.gradle vielleicht noch einmal raus, aktualisiere, füge den Eintrag wieder hinzu und lass Gradle das Projekt nochmals aktualisieren. Im External Libraries-Knoten (Projekt Explorer) solltest du daraufhin einen entsprechenden Gradle-Eintrag finden (org.openjfx:javafx-media:win:15). Die bisher gebaute JAR würde ich anschließend aus dem build/libs-Ordner löschen und anschließend via build/build oder build/jar-Task ein neues Produkt generieren lassen.
Ich habe die von Dir erwähnten Methoden ausprobiert und sogar Extracted 'javafx-media-15-sources.jar/' in Artifacts mit reingepackt, da es dort nicht vorhanden war. Das hat aber nichts gebracht. Derselbe Fehler tritt erneut auf :/
Zwar gibt es jetzt den Ordner javafx\scene\media, aber er sagt immer noch, dass Zeile
welcomeClip = new AudioClip(Objects.requireNonNull(getClass().getResource("/sounds/welcome.wav")).toExternalForm());
nicht mitmacht.
Zwar gibt es jetzt den Ordner javafx\scene\media, (...)
Ist die AudioClip.class enthalten oder nicht?
Demzufolge werden die Dateien nur statisch in die JAR kopiert, aber nicht in den Compile Classpath aufgenommen und somit auch nicht gebaut. Warum das bei dir so ist, kann ich allerdings nicht sagen. Vielleicht hast du etwas Falsches in der build.gradle stehen oder manuell etwas an der Projektkonfiguration verändert (die einzigen Arbeitsbereiche sollten eigener Java-Code, module-info-Dateien, Ressourcen wie Bilder/... und die build.gradle sein).
Das einzige, was mir gerade noch spontan als Versuch einfällt, wäre ein Clean Build.
Ich habe einmal das Gesamte hochgeladen, denn ich kann einfach nichts Auffälliges finden. Nicht dass es wieder so ein Minifehler ist und ich hinterher 'nen Facepalm machen muss.
- Der Inhalt von der exportierten .jar-Datei (javafx\scene\media) und in Project Structure > Libraries & Artifacts
- build.gradle
- module-info.java (Programm.main)
Main.java: (Wie gehabt)
welcomeClip = new AudioClip(Objects.requireNonNull(getClass().getResource("/sounds/welcome.wav")).toExternalForm());
welcomeClip.play();
Ich habe Pseudonyme/Namen mit Programm und x ersetzt.
In deiner build.gradle steht in Zeile 51 ein x, welches dort nicht hingehört (hinter der Klammer sollte in dieser Zeile gar nichts stehen).
Ich schaue gleich mal nach, ob das auch so im Code steht und nicht aus Versehen durch das Teilen passiert ist.
Okay ... ich weiß, dass das jetzt über 2 Monate her ist, aber ich habe jetzt mal das "x" da aus der build.gradle entfernt und es ... hatte keinen Einfluss darauf. Der Fehler bleibt also bestehen. Ich hoffe, du weiß noch ungefähr, was hier los war 😅
Es lag wohl daran, dass ich Gradle 7.1 verwendet habe. Ich habe jetzt auf 7.4 aufgerüstet und benutze jetzt anstelle von SDK 15 SDK 17. Ich kanns mir nicht erklären ...
Ja, mit neuen Gradle-Versionen sind auch neue Features hinzugekommen. Du hast wohl eines dieser benutzt, obwohl es in deinem installierten Tool noch nicht unterstützt wurde.
Deinen Code habe ich ausprobiert, aber ich soll dann 3 Methoden (play(), loop(), stop()) implementieren lassen, wobei ich damit nicht weiter weiß. Auch im Internet sah ich bis jetzt nie diese Methoden, die implementiert werden.
Ich habe zum Spaß auch mal
ausprobiert, aber da stoppt die Audio unberechenbar mittendrin. Jamoin. Käse mit Brot ...