Jawaban:
Saya menulis kode berikut yang berfungsi dengan baik. Tapi saya pikir ini hanya berfungsi dengan .wav
format.
public static synchronized void playSound(final String url) {
new Thread(new Runnable() {
// The wrapper thread is unnecessary, unless it blocks on the
// Clip finishing; see comments.
public void run() {
try {
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(
Main.class.getResourceAsStream("/path/to/sounds/" + url));
clip.open(inputStream);
clip.start();
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}).start();
}
Thread
perlu. 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 String
yang 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());
.
Contoh buruk:
import sun.audio.*; //import the sun.audio package
import java.io.*;
//** add this into your application code as appropriate
// Open an input stream to the audio file.
InputStream in = new FileInputStream(Filename);
// Create an AudioStream object from the input stream.
AudioStream as = new AudioStream(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);
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).
private static void playSound(String sound){
// cl is the ClassLoader for the current class, ie. CurrentClass.class.getClassLoader();
URL file = cl.getResource(sound);
final Media media = new Media(file.toString());
final MediaPlayer mediaPlayer = new MediaPlayer(media);
mediaPlayer.play();
}
Perhatikan: Anda perlu menginisialisasi JavaFX . Cara cepat untuk melakukan itu, adalah memanggil konstruktor JFXPanel () sekali di aplikasi Anda:
static{
JFXPanel fxPanel = new JFXPanel();
}
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.
public class SoundClipTest extends JFrame {
public SoundClipTest() {
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();
}
}
public static void main(String[] args) {
new SoundClipTest();
}
}
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:
void playSound(String soundFile) {
File f = new File("./" + soundFile);
AudioInputStream audioIn = AudioSystem.getAudioInputStream(f.toURI().toURL());
Clip clip = AudioSystem.getClip();
clip.open(audioIn);
clip.start();
}
Dan saya akan memainkan suaranya dengan:
playSound("sounds/effects/sheep1.wav");
sounds / effects / sheep1.wav terletak di direktori dasar proyek saya di Eclipse (jadi tidak di dalam folder src).
getResourceAsStream()
akan kembali null
jika sumber daya tidak ditemukan, atau melempar pengecualian jika name
ini null
- bukan kesalahan dari jawaban atas jika jalan yang diberikan tidak valid
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.
Ini adalah kode untuk referensi.
package com.athanazio.jaga.desktop.sound;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
public class Sound {
AudioInputStream in;
AudioFormat decodedFormat;
AudioInputStream din;
AudioFormat baseFormat;
SourceDataLine line;
private boolean loop;
private BufferedInputStream stream;
// private ByteArrayInputStream stream;
/**
* recreate the stream
*
*/
public void reset() {
try {
stream.reset();
in = AudioSystem.getAudioInputStream(stream);
din = AudioSystem.getAudioInputStream(decodedFormat, in);
line = getLine(decodedFormat);
} catch (Exception e) {
e.printStackTrace();
}
}
public void close() {
try {
line.close();
din.close();
in.close();
} catch (IOException e) {
}
}
Sound(String filename, boolean loop) {
this(filename);
this.loop = loop;
}
Sound(String filename) {
this.loop = false;
try {
InputStream raw = Object.class.getResourceAsStream(filename);
stream = new BufferedInputStream(raw);
// ByteArrayOutputStream out = new ByteArrayOutputStream();
// byte[] buffer = new byte[1024];
// int read = raw.read(buffer);
// while( read > 0 ) {
// out.write(buffer, 0, read);
// read = raw.read(buffer);
// }
// stream = new ByteArrayInputStream(out.toByteArray());
in = AudioSystem.getAudioInputStream(stream);
din = null;
if (in != null) {
baseFormat = in.getFormat();
decodedFormat = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED, baseFormat
.getSampleRate(), 16, baseFormat.getChannels(),
baseFormat.getChannels() * 2, baseFormat
.getSampleRate(), false);
din = AudioSystem.getAudioInputStream(decodedFormat, in);
line = getLine(decodedFormat);
}
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
private SourceDataLine getLine(AudioFormat audioFormat)
throws LineUnavailableException {
SourceDataLine res = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class,
audioFormat);
res = (SourceDataLine) AudioSystem.getLine(info);
res.open(audioFormat);
return res;
}
public void play() {
try {
boolean firstTime = true;
while (firstTime || loop) {
firstTime = false;
byte[] data = new byte[4096];
if (line != null) {
line.start();
int nBytesRead = 0;
while (nBytesRead != -1) {
nBytesRead = din.read(data, 0, data.length);
if (nBytesRead != -1)
line.write(data, 0, nBytesRead);
}
line.drain();
line.stop();
line.close();
reset();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
stream.reset();
mengarah ke Resetting to invalid mark
. Apa yang ingin Anda lakukan untuk memperbaikinya?
raw.mark(raw.available()+1)
setelah menginisialisasi raw
dan 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 Clip
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.
Saya terkejut tidak ada yang menyarankan menggunakan Applet. Gunakan Applet
. Anda harus menyediakan file audio bip sebagai wav
file, 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;
public class JavaApplication2 {
public static void main(String[] args) throws MalformedURLException {
File file = new File("/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
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.
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.
Jika waktu bukan dari esensi maka ini berguna.