Yanıtlar:
İyi çalışan aşağıdaki kodu yazdım. Ama bence sadece .wav
formatla çalışıyor .
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
Gereksizdir. 2) Kullanmaya iyi bir örnek Clip
için JavaSound bilgilerine bakın. sayfası . 3) Bir yöntem bir URL
(veya File
) gerektiriyorsa, bunu temsil eden bir tanesini kabul etmek yerine bir dang URL
(veya File
) verin String
. (Sadece kişisel 'kaputumdaki arı'.) 4) e.printStackTrace();
daha az yazarak daha fazla bilgi sağlar System.err.println(e.getMessage());
.
Kötü bir örnek:
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);
Sadece basit bir lanet ses çalmak için çok fazla kod satırına sahip olmak istemedim. JavaFX paketiniz (jdk 8'de zaten var) varsa bu işe yarayabilir.
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();
}
Uyarı: JavaFX'i başlatmanız gerekir . Bunu yapmanın hızlı bir yolu, uygulamanızda bir kez JFXPanel () yapıcısını çağırmaktır:
static{
JFXPanel fxPanel = new JFXPanel();
}
Java'da ses çalmak için aşağıdaki koda başvurabilirsiniz.
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();
}
}
Her ne sebeple olursa olsun, wchargin tarafından üst yanıt bana this.getClass (). GetResourceAsStream () çağırırken boş bir işaretçi hatası veriyordu.
Benim için işe yarayan şuydu:
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();
}
Ve sesi şu şekilde çalarım:
playSound("sounds/effects/sheep1.wav");
sesler / efektler / sheep1.wav Eclipse projemin temel dizininde yer aldı (src klasörü içinde değil).
getResourceAsStream()
dönecektir null
kaynak bulunmazsa, ya eğer istisna name
olduğunu null
- üst cevabın bir arıza verilen yolun geçerli değilse
Bir süre önce Android ve Masaüstünde çalışmak için bir oyun çerçevesi oluşturdum, sesi işleyen masaüstü kısmı, ihtiyacınız olan şey için ilham kaynağı olarak kullanılabilir.
İşte referans kodu.
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();
adresine yönlendirirken hata verebilir Resetting to invalid mark
. Bunu düzeltmek için ne yapmayı öneriyorsun?
raw.mark(raw.available()+1)
başladıktan sonra raw
ve sonra while döngüsünde kullanarak ve sonra raw.reset()
yerine kullanarak çözdü stream.reset()
. Benim sorunum, sıfırlama söz konusu olduğunda, oyunlar arasında bir boşluk olması. Senin gibi sürekli bir döngü elde etmek istiyorum Clip
. Ben kullanmıyorum Clip
böyle MASTER_GAIN olarak manipüle kontrolleri ~ 500ms bir fark gecikmeye sahip olduğu için. Bu muhtemelen daha sonra soracağım kendi sorusu olmalı.
do { ... } while
mi?
Hem uygulamalarda hem de uygulamalarda çalışan ses dosyalarını içe aktarmanın bir alternatifi vardır: ses dosyalarını .java dosyalarına dönüştürün ve kodunuzda kullanın.
Bu süreci çok daha kolaylaştıran bir araç geliştirdim. Java Sound API'sını biraz basitleştirir.
Kimsenin Applet kullanmayı önermediğine şaşırdım. Kullanın Applet
. Bip ses dosyasını bir wav
dosya olarak sağlamanız gerekir , ancak çalışır. Ben Ubuntu üzerinde denedim:
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
Java 9'dan itibaren kullanımdan kaldırılmıştır.
Bu iş parçacığı oldukça eskidir, ancak yararlı olabilecek bir seçenek belirledim.
Java AudioStream
kitaplığını kullanmak yerine Windows Media Player veya VLC gibi harici bir program kullanabilir ve Java üzerinden bir konsol komutuyla çalıştırabilirsiniz.
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();
}
Bu aynı zamanda program tarafından kontrol edilebilen ayrı bir süreç yaratacaktır.
p.destroy();
Tabii ki bu, dahili bir kütüphane kullanmaktan daha uzun sürecektir, ancak belirli konsol komutları verildiğinde bir GUI olmadan daha hızlı ve muhtemelen başlayabilen programlar olabilir.
Zamanın özü değilse, bu yararlıdır.