+1 dla rozwiązania korzystającego z publicznego interfejsu API. Czy tworzenie nowego wątku nie jest jednak niepotrzebne (zbędne)?
Jataro
4
Dzięki… Czy to jest zbędne? Stworzyłem nowy wątek, więc mogę ponownie odtworzyć dźwięk przed zakończeniem pierwszego klipu.
pek
4
Wiem, że clip.start () tworzy nowy wątek, więc jestem prawie pewien, że jest to niepotrzebne.
Jataro
44
1) Nie Threadjest konieczne. 2) Aby Clipzapoznać się z dobrym przykładem użycia , zobacz informacje o JavaSound. stronę . 3) Jeśli metoda wymaga URL(lub File) daj jej dang URL(lub File) zamiast akceptować to, Stringco reprezentuje jeden. (Tylko osobista „pszczoła w mojej masce”.) 4) e.printStackTrace();dostarcza więcej informacji przy mniejszym wpisywaniu niż System.err.println(e.getMessage());.
Andrew Thompson,
18
Zły przykład:
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 Czy pakiet sun. * Nie jest przeznaczony do użytku przez nas, programistów?
Tom Brito
36
Ten przykład pochodzi z artykułu JavaWorld z 1997 roku. Wydaje się, że NIE WOLNO używać opakowań sun. *.
sproketboy
3
czy kiedykolwiek potrzebujesz zamknąć „w”?
rogerdpack
6
+1 za nie korzystanie z pakietów sun. *. Mają dziwne błędy, takie jak brak obsługi plików> 1 MB i niemożność odtworzenia jednego klipu, jeśli poprzedni jeszcze się nie skończył itp.
rogerdpack
10
Nie chciałem mieć tylu linijek kodu tylko po to, by odtworzyć prosty, cholerny dźwięk. To może zadziałać, jeśli masz pakiet JavaFX (już zawarty w moim 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();}
Uwaga: Musisz zainicjować JavaFX . Szybkim sposobem na to jest wywołanie konstruktora JFXPanel () raz w aplikacji:
Aby odtworzyć dźwięk w Javie, możesz skorzystać z następującego kodu.
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();}}
witaj Anrew, Twój kod działał dla mnie, ale zauważyłem, że wykonanie zajmuje trochę więcej czasu ... około 1,5 sekundy.
getResourceAsStream()zwróci, nulljeśli zasób nie zostanie znaleziony, lub wyrzuci wyjątek, jeśli tak namejest null- nie jest to błąd pierwszej odpowiedzi, jeśli podana ścieżka jest nieprawidłowa
user85421
3
Jakiś czas temu stworzyłem platformę do gier, aby pracować na urządzeniach z systemem Android i komputerach stacjonarnych. Część komputerowa obsługująca dźwięk może posłużyć jako inspiracja do tego, czego potrzebujesz.
Naprawdę rozwiązałem to, używając raw.mark(raw.available()+1)po inicjalizacji, rawa następnie w pętli while, a następnie używając raw.reset()zamiast stream.reset(). Mój problem polega teraz na tym, że jeśli chodzi o resetowanie, między kolejnymi grami jest luka. Chcę uzyskać ciągłą pętlę, taką jak ty Clip. Nie używam, Clipponieważ manipulowanie kontrolkami, takimi jak MASTER_GAIN, ma zauważalne opóźnienie ~ 500 ms. Prawdopodobnie powinno to być własne pytanie, które zadam później.
driima
Nie do { ... } while?
Andreas
2
Istnieje alternatywa dla importowania plików dźwiękowych, która działa zarówno w apletach, jak i aplikacjach: przekonwertuj pliki audio na pliki .java i po prostu użyj ich w swoim kodzie.
Opracowałem narzędzie, które znacznie ułatwia ten proces. Znacznie upraszcza Java Sound API.
Użyłem twojego systemu do stworzenia klasy z pliku wav, jednak kiedy robię my_wave.play (); nie odtwarza dźwięku .. Czy jest jakiś system audio, który muszę zainicjować, czy coś? ..
Nathan F.
byłoby to naprawdę fajne, gdyby faktycznie działało. Podczas uruchamiania funkcji play () funkcja get Audio Line kończy się niepowodzeniem (wyjątek „java.lang.IllegalArgumentException: Brak dopasowania linii interfejsu SourceDataLine obsługującego format PCM_UNSIGNED 44100,0 Hz, 16 bitów, stereo, 4 bajty / ramkę, obsługa little-endian” nie jest rzucony). Smutny.
phil294,
2
Jestem zaskoczony, że nikt nie zasugerował używania Appleta. UżyjApplet . Będziesz musiał dostarczyć plik dźwiękowy jako wavplik, ale to działa. Próbowałem tego na 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
Ten wątek jest dość stary, ale wybrałem opcję, która może się okazać przydatna.
Zamiast korzystać z AudioStreambiblioteki Java, możesz użyć zewnętrznego programu, takiego jak Windows Media Player lub VLC, i uruchomić go za pomocą polecenia konsoli za pośrednictwem języka 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();}
Stworzy to również oddzielny proces, którym można sterować w programie.
p.destroy();
Oczywiście wykonanie tego zajmie więcej czasu niż użycie wewnętrznej biblioteki, ale mogą istnieć programy, które mogą uruchamiać się szybciej i być może bez GUI przy pewnych poleceniach konsoli.
Jeśli czas nie jest najważniejszy, jest to przydatne.
Chociaż uważam, że jest to obiektywnie złe rozwiązanie (pod względem niezawodności, wydajności i innych tego typu wskaźników), jest przynajmniej interesujące, o którym inaczej bym nie pomyślał!
Odpowiedzi:
Napisałem następujący kod, który działa dobrze. Ale myślę, że działa tylko z
.wav
formatem.źródło
Thread
jest konieczne. 2) AbyClip
zapoznać się z dobrym przykładem użycia , zobacz informacje o JavaSound. stronę . 3) Jeśli metoda wymagaURL
(lubFile
) daj jej dangURL
(lubFile
) zamiast akceptować to,String
co reprezentuje jeden. (Tylko osobista „pszczoła w mojej masce”.) 4)e.printStackTrace();
dostarcza więcej informacji przy mniejszym wpisywaniu niżSystem.err.println(e.getMessage());
.Zły przykład:
źródło
Nie chciałem mieć tylu linijek kodu tylko po to, by odtworzyć prosty, cholerny dźwięk. To może zadziałać, jeśli masz pakiet JavaFX (już zawarty w moim jdk 8).
Uwaga: Musisz zainicjować JavaFX . Szybkim sposobem na to jest wywołanie konstruktora JFXPanel () raz w aplikacji:
źródło
Aby odtworzyć dźwięk w Javie, możesz skorzystać z następującego kodu.
źródło
Z jakiegoś powodu górna odpowiedź wchargin dawała mi błąd wskaźnika zerowego, kiedy wywoływałem this.getClass (). GetResourceAsStream ().
U mnie zadziałało:
I grałbym dźwięk z:
sound / effects / sheep1.wav znajdował się w katalogu podstawowym mojego projektu w Eclipse (a więc nie w folderze src).
źródło
getResourceAsStream()
zwróci,null
jeśli zasób nie zostanie znaleziony, lub wyrzuci wyjątek, jeśli takname
jestnull
- nie jest to błąd pierwszej odpowiedzi, jeśli podana ścieżka jest nieprawidłowaJakiś czas temu stworzyłem platformę do gier, aby pracować na urządzeniach z systemem Android i komputerach stacjonarnych. Część komputerowa obsługująca dźwięk może posłużyć jako inspiracja do tego, czego potrzebujesz.
https://github.com/hamilton-lima/jaga/blob/master/jaga%20desktop/src-desktop/com/athanazio/jaga/desktop/sound/Sound.java
Oto kod w celach informacyjnych.
źródło
stream.reset();
prowadzeniu doResetting to invalid mark
. Co proponujesz zrobić, aby to naprawić?raw.mark(raw.available()+1)
po inicjalizacji,raw
a następnie w pętli while, a następnie używającraw.reset()
zamiaststream.reset()
. Mój problem polega teraz na tym, że jeśli chodzi o resetowanie, między kolejnymi grami jest luka. Chcę uzyskać ciągłą pętlę, taką jak tyClip
. Nie używam,Clip
ponieważ manipulowanie kontrolkami, takimi jak MASTER_GAIN, ma zauważalne opóźnienie ~ 500 ms. Prawdopodobnie powinno to być własne pytanie, które zadam później.do { ... } while
?Istnieje alternatywa dla importowania plików dźwiękowych, która działa zarówno w apletach, jak i aplikacjach: przekonwertuj pliki audio na pliki .java i po prostu użyj ich w swoim kodzie.
Opracowałem narzędzie, które znacznie ułatwia ten proces. Znacznie upraszcza Java Sound API.
http://stephengware.com/projects/soundtoclass/
źródło
Jestem zaskoczony, że nikt nie zasugerował używania Appleta. Użyj
Applet
. Będziesz musiał dostarczyć plik dźwiękowy jakowav
plik, ale to działa. Próbowałem tego na Ubuntu:źródło
Applet
jest przestarzałe od wersji Java 9Ten wątek jest dość stary, ale wybrałem opcję, która może się okazać przydatna.
Zamiast korzystać z
AudioStream
biblioteki Java, możesz użyć zewnętrznego programu, takiego jak Windows Media Player lub VLC, i uruchomić go za pomocą polecenia konsoli za pośrednictwem języka Java.Stworzy to również oddzielny proces, którym można sterować w programie.
Oczywiście wykonanie tego zajmie więcej czasu niż użycie wewnętrznej biblioteki, ale mogą istnieć programy, które mogą uruchamiać się szybciej i być może bez GUI przy pewnych poleceniach konsoli.
Jeśli czas nie jest najważniejszy, jest to przydatne.
źródło