+1 untuk solusi yang menggunakan API publik. Bukankah membuat utas baru tidak perlu (berlebihan)?
Jataro
4
Terima kasih .. Apakah itu berlebihan? Saya membuatnya menjadi utas baru sehingga saya bisa memainkan suara lagi sebelum klip pertama berakhir.
pek
4
Saya tahu clip.start () memunculkan thread baru, jadi saya cukup yakin itu tidak perlu.
Jataro
44
1) Tidak Threadperlu. 2) Untuk contoh penggunaan yang baik Clip, lihat info JavaSound. halaman . 3) Jika suatu metode membutuhkan URL(atau File) memberinya dang URL(atau File) daripada menerima Stringyang mewakili satu. (Hanya 'bee in my bonnet' pribadi.) 4) e.printStackTrace();memberikan lebih banyak informasi dengan lebih sedikit mengetik daripada System.err.println(e.getMessage());.
Andrew Thompson
18
Contoh buruk:
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 Bukankah matahari. * Paket dibuat agar tidak digunakan oleh kami pengembang?
Tom Brito
36
Contoh ini berasal dari artikel JavaWorld 1997. Jalan keluar dari tanggal, Anda TIDAK boleh menggunakan paket sun. *.
sproketboy
3
apakah Anda perlu menutup "dalam"?
rogerdpack
6
+1 untuk tidak menggunakan matahari. * Paket. Mereka memiliki bug aneh seperti tidak menangani file> 1MB dan tidak dapat memutar satu klip jika sebelumnya belum selesai, dll.
rogerdpack
10
Saya tidak ingin memiliki begitu banyak baris kode hanya untuk memainkan suara yang sederhana. Ini dapat bekerja jika Anda memiliki paket JavaFX (sudah termasuk dalam jdk 8 saya).
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();}
Perhatikan: Anda perlu menginisialisasi JavaFX . Cara cepat untuk melakukan itu, adalah memanggil konstruktor JFXPanel () sekali di aplikasi Anda:
Untuk memainkan suara dalam java, Anda dapat merujuk ke kode berikut.
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();}}
halo Anrew, kode Anda berfungsi untuk saya, tetapi saya perhatikan bahwa membutuhkan sedikit waktu ekstra dalam eksekusi ... sekitar 1,5 detik.
getResourceAsStream()akan kembali nulljika sumber daya tidak ditemukan, atau melempar pengecualian jika nameini null- bukan kesalahan dari jawaban atas jika jalan yang diberikan tidak valid
user85421
3
Saya membuat kerangka permainan beberapa waktu lalu untuk bekerja di Android dan Desktop, bagian desktop yang menangani suara mungkin dapat digunakan sebagai inspirasi untuk apa yang Anda butuhkan.
Saya benar-benar menyelesaikan ini dengan menggunakan raw.mark(raw.available()+1)setelah menginisialisasi rawdan kemudian di loop sementara, dan kemudian menggunakan raw.reset()bukan stream.reset(). Masalah saya sekarang adalah bahwa ketika datang untuk mengatur ulang, ada celah di antara permainan. Saya ingin mencapai lingkaran berkelanjutan seperti yang Anda dapatkan Clip. Saya tidak menggunakan Clipkarena memanipulasi kontrol seperti MASTER_GAIN mengalami keterlambatan ~ 500 ms. Ini mungkin pertanyaan tersendiri yang akan saya tanyakan nanti.
driima
Bukan do { ... } while?
Andreas
2
Ada alternatif untuk mengimpor file suara yang berfungsi baik di applet maupun aplikasi: konversikan file audio menjadi file .java dan cukup gunakan dalam kode Anda.
Saya telah mengembangkan alat yang membuat proses ini jauh lebih mudah. Ini menyederhanakan Java Sound API sedikit.
Saya menggunakan sistem Anda untuk membuat kelas dari file wav, Namun, Ketika saya melakukan my_wave.play (); itu tidak memutar audio .. Apakah ada sistem audio yang perlu saya inisialisasi atau sesuatu?
Nathan F.
ini akan sangat keren jika itu benar-benar berfungsi. Saat menjalankan play (), get Audio Line gagal (kecuali "java.lang.IllegalArgumentException: Tidak ada antarmuka pencocokan baris, format pendukung SourceDataLine, PCM_UNSIGNED 44100.0 Hz, 16 bit, stereo, 4 byte / bingkai, little-endian didukung." terlempar). Sedih.
phil294
2
Saya terkejut tidak ada yang menyarankan menggunakan Applet. GunakanApplet . Anda harus menyediakan file audio bip sebagai wavfile, tetapi itu berfungsi. Saya mencoba ini di 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
Utas ini agak lama tetapi saya telah menentukan opsi yang bisa berguna.
Alih-alih menggunakan AudioStreamperpustakaan Java Anda bisa menggunakan program eksternal seperti Windows Media Player atau VLC dan menjalankannya dengan perintah konsol melalui 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();}
Ini juga akan membuat proses terpisah yang bisa dikontrol programnya.
p.destroy();
Tentu saja ini akan memakan waktu lebih lama untuk dieksekusi daripada menggunakan perpustakaan internal tetapi mungkin ada program yang dapat memulai lebih cepat dan mungkin tanpa GUI yang diberikan perintah konsol tertentu.
Meskipun saya pikir ini adalah solusi yang buruk secara objektif (dalam hal keandalan, efisiensi, dan metrik lain semacam itu), itu setidaknya yang menarik yang tidak akan saya pikirkan sebelumnya!
Jawaban:
Saya menulis kode berikut yang berfungsi dengan baik. Tapi saya pikir ini hanya berfungsi dengan
.wav
format.sumber
Thread
perlu. 2) Untuk contoh penggunaan yang baikClip
, lihat info JavaSound. halaman . 3) Jika suatu metode membutuhkanURL
(atauFile
) memberinya dangURL
(atauFile
) daripada menerimaString
yang mewakili satu. (Hanya 'bee in my bonnet' pribadi.) 4)e.printStackTrace();
memberikan lebih banyak informasi dengan lebih sedikit mengetik daripadaSystem.err.println(e.getMessage());
.Contoh buruk:
sumber
Saya tidak ingin memiliki begitu banyak baris kode hanya untuk memainkan suara yang sederhana. Ini dapat bekerja jika Anda memiliki paket JavaFX (sudah termasuk dalam jdk 8 saya).
Perhatikan: Anda perlu menginisialisasi JavaFX . Cara cepat untuk melakukan itu, adalah memanggil konstruktor JFXPanel () sekali di aplikasi Anda:
sumber
Untuk memainkan suara dalam java, Anda dapat merujuk ke kode berikut.
sumber
Untuk alasan apa pun, jawaban teratas oleh wchargin memberi saya kesalahan pointer nol ketika saya memanggil this.getClass (). GetResourceAsStream ().
Apa yang berhasil bagi saya adalah sebagai berikut:
Dan saya akan memainkan suaranya dengan:
sounds / effects / sheep1.wav terletak di direktori dasar proyek saya di Eclipse (jadi tidak di dalam folder src).
sumber
getResourceAsStream()
akan kembalinull
jika sumber daya tidak ditemukan, atau melempar pengecualian jikaname
ininull
- bukan kesalahan dari jawaban atas jika jalan yang diberikan tidak validSaya membuat kerangka permainan beberapa waktu lalu untuk bekerja di Android dan Desktop, bagian desktop yang menangani suara mungkin dapat digunakan sebagai inspirasi untuk apa yang Anda butuhkan.
https://github.com/hamilton-lima/jaga/blob/master/jaga%20desktop/src-desktop/com/athanazio/jaga/desktop/sound/Sound.java
Ini adalah kode untuk referensi.
sumber
stream.reset();
mengarah keResetting to invalid mark
. Apa yang ingin Anda lakukan untuk memperbaikinya?raw.mark(raw.available()+1)
setelah menginisialisasiraw
dan kemudian di loop sementara, dan kemudian menggunakanraw.reset()
bukanstream.reset()
. Masalah saya sekarang adalah bahwa ketika datang untuk mengatur ulang, ada celah di antara permainan. Saya ingin mencapai lingkaran berkelanjutan seperti yang Anda dapatkanClip
. Saya tidak menggunakanClip
karena memanipulasi kontrol seperti MASTER_GAIN mengalami keterlambatan ~ 500 ms. Ini mungkin pertanyaan tersendiri yang akan saya tanyakan nanti.do { ... } while
?Ada alternatif untuk mengimpor file suara yang berfungsi baik di applet maupun aplikasi: konversikan file audio menjadi file .java dan cukup gunakan dalam kode Anda.
Saya telah mengembangkan alat yang membuat proses ini jauh lebih mudah. Ini menyederhanakan Java Sound API sedikit.
http://stephengware.com/projects/soundtoclass/
sumber
Saya terkejut tidak ada yang menyarankan menggunakan Applet. Gunakan
Applet
. Anda harus menyediakan file audio bip sebagaiwav
file, tetapi itu berfungsi. Saya mencoba ini di Ubuntu:sumber
Applet
sudah tidak digunakan lagi pada Java 9.Utas ini agak lama tetapi saya telah menentukan opsi yang bisa berguna.
Alih-alih menggunakan
AudioStream
perpustakaan Java Anda bisa menggunakan program eksternal seperti Windows Media Player atau VLC dan menjalankannya dengan perintah konsol melalui Java.Ini juga akan membuat proses terpisah yang bisa dikontrol programnya.
Tentu saja ini akan memakan waktu lebih lama untuk dieksekusi daripada menggunakan perpustakaan internal tetapi mungkin ada program yang dapat memulai lebih cepat dan mungkin tanpa GUI yang diberikan perintah konsol tertentu.
Jika waktu bukan dari esensi maka ini berguna.
sumber