[英]Java play multiple Clips simultaneously
因此,每次單擊面板時,我的應用程序都應該播放 WAV 文件。 但現在的問題是,它在播放第二個之前等待第一個完成。 我希望能夠讓他們同時播放。
我把 Thread.sleep(500) 的原因是因為如果我不這樣做,那么它根本不會播放聲音:(
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JFrame;
@SuppressWarnings("serial")
public class SoundEffectPlayer extends JFrame {
/*
* Jframe stuff
*/
public SoundEffectPlayer() {
this.setSize(400, 400);
this.setTitle("Mouse Clicker");
this.addMouseListener(new Clicker());
this.setVisible(true);
}
private class Clicker extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
try {
playSound(1);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
/*
* Directory of your sound files
* format is WAV
*/
private static final String DIRECTORY = "file:///C:/Users/Jessica/Desktop/audio/effects/sound 1.wav";
/*
* The volume for sound effects
*/
public static float soundEffectsVolume = 0.00f;
/*
* Loads the sound effect files from cache
* into the soundEffects array.
*/
public void playSound(int ID) throws InterruptedException {
try {
System.out.println("playing");
Clip clip;
URL url = new URL(DIRECTORY);
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url);
clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.setFramePosition(0);
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
gainControl.setValue(soundEffectsVolume);
clip.start();
System.out.println("played");
Thread.sleep(3000);
System.out.println("closing");
} catch (MalformedURLException e) {
System.out.println("Sound effect not found: "+ID);
e.printStackTrace();
return;
} catch (UnsupportedAudioFileException e) {
System.out.println("Unsupported format for sound: "+ID);
return;
} catch (LineUnavailableException e) {
e.printStackTrace();
return;
} catch (IOException e) {
e.printStackTrace();
return;
}
}
public static void main(String[] args) throws InterruptedException {
new SoundEffectPlayer();
}
}
更新:好的,所以我讓它們同時播放,但是我想在 Clip 播放完畢后關閉線程,而不是讓線程等待 500 毫秒
我怎樣才能做到這一點?
我一直運行多個這樣的聲音。 我沒有生成新線程,因為我猜 javaSound 已經在另一個線程中運行了剪輯。 主要的“游戲循環”可能會繼續做自己的事情。 應用程序可以為回調注冊偵聽器或使用 getter 來查看剪輯正在做什么。
有時,如果我們要制作多媒體或游戲應用程序,只需使用 getter 就更容易了。 運行 gameloop 30-60fps 為大多數情況提供了足夠的粒度,我們可以完全控制發生的事情和時間。 這個小 testapp 播放兩個 wav 文件,第一個運行一次,第二個在 3 秒后啟動,第二個循環。
// java -cp ./classes SoundTest1 clip1=sound1.wav clip2=sound2.wav
import java.util.*;
import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;
public class SoundTest1 {
public Clip play(String filename, boolean autostart, float gain) throws Exception {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File(filename));
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.setFramePosition(0);
// values have min/max values, for now don't check for outOfBounds values
FloatControl gainControl = (FloatControl)clip.getControl(FloatControl.Type.MASTER_GAIN);
gainControl.setValue(gain);
if(autostart) clip.start();
return clip;
}
public static void main(String[] args) throws Exception {
Map<String,String> params = parseParams(args);
SoundTest1 test1 = new SoundTest1();
Clip clip1 = test1.play(params.get("clip1"), true, -5.0f);
Clip clip2 = test1.play(params.get("clip2"), false, 5.0f);
final long duration=Long.MAX_VALUE;
final int interval=500;
float clip2IncGain=0.4f;
for(long ts=0; ts<duration; ts+=interval) {
System.out.println(String.format("clip1=%d/%d(%.2f), clip2=%d/%d(%.2f)"
,clip1.getFramePosition(), clip1.getFrameLength()
,((FloatControl)clip1.getControl(FloatControl.Type.MASTER_GAIN)).getValue()
,clip2.getFramePosition(), clip2.getFrameLength()
,((FloatControl)clip2.getControl(FloatControl.Type.MASTER_GAIN)).getValue()
));
if (ts>6000 && !clip2.isRunning()) {
clip2.setFramePosition(0);
clip2.start();
}
if (!clip1.isRunning()) {
clip1.close();
}
if(ts % 2000 == 0) {
// values have min/max values, for now don't check for outOfBounds values
FloatControl gainControl = (FloatControl)clip2.getControl(FloatControl.Type.MASTER_GAIN);
float oldVal=gainControl.getValue();
clip2IncGain = oldVal>=5.5 ? clip2IncGain*-1
: oldVal<=-5.5 ? clip2IncGain*-1
: clip2IncGain;
gainControl.setValue(oldVal+clip2IncGain);
}
Thread.sleep(interval);
}
}
private static Map<String,String> parseParams(String[] args) {
Map<String,String> params = new HashMap<String,String>();
for(String arg : args) {
int delim = arg.indexOf('=');
if (delim<0) params.put("", arg.trim());
else if (delim==0) params.put("", arg.substring(1).trim());
else params.put(arg.substring(0, delim).trim(), arg.substring(delim+1).trim() );
}
return params;
}
}
有關更多信息,請參閱JavaSound 文檔。
嘗試檢查這個開源音板程序的源代碼: DBoard 。
您對使用MediaPlayer類特別感興趣。 你可以調用它使用
(new Thread(new MediaPlayer(PATHTOFILE)).start();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.