#java #eclipse #audio
#java #eclipse #Аудио
Вопрос:
Я работаю с несколькими одноклассниками над игрой, до сих пор мы программировали практически все, кроме музыки. The music.java класс размещен ниже.
У нас проблема с остановкой звука, поэтому мне нужен способ остановить воспроизведение этого клипа, чтобы мы могли запустить другой клип, таким образом, мы могли переключать музыку во время нашей игры (например, когда вы запускаете игру, песня должна отличаться от главного меню).
Даже если я могу просто уничтожить объект, чтобы создать новый, если это возможно, я готов это сделать, но я понятия не имею, как это сделать. Я бы предпочел иметь возможность остановить текущий файл клипа и заменить его новым.
package sound;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
public class Music implements LineListener, Runnable
{
private File soundFile;
private Thread thread;
private static Music player;
private Music audio;
private Clip clip;
private boolean stoppen = false;
/**
* Private because of the singleton
*/
public Music()
{
}
/**
* Play a siren sound
*/
public void playSiren(String musicFileName)
{
audio = getPlayer();
audio.playSirenFile(musicFileName);
}
/**
* Play the siren file
*/
private void playSirenFile(String musicFileName)
{
this.soundFile = new File("Music/" musicFileName ".wav");
thread = new Thread(this);
thread.setName("SoundPlayer");
thread.start();
}
/**
* Invoked when the thread kicks off
*/
public void run()
{
try
{
AudioInputStream stream = AudioSystem.getAudioInputStream(this.soundFile);
AudioFormat format = stream.getFormat();
/**
* we can't yet open the device for ALAW/ULAW playback, convert
* ALAW/ULAW to PCM
*/
if ((format.getEncoding() == AudioFormat.Encoding.ULAW) || (format.getEncoding() == AudioFormat.Encoding.ALAW))
{
AudioFormat tmp = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
format.getSampleRate(),
format.getSampleSizeInBits() * 2, format.getChannels(),
format.getFrameSize() * 2, format.getFrameRate(), true);
stream = AudioSystem.getAudioInputStream(tmp, stream);
format = tmp;
}
DataLine.Info info = new DataLine.Info(Clip.class, stream
.getFormat(), ((int) stream.getFrameLength() * format
.getFrameSize()));
this.clip = (Clip) AudioSystem.getLine(info);
this.clip.addLineListener(this);
this.clip.open(stream);
this.clip.start();
try
{
thread.sleep(99);
}
catch (Exception e)
{
}
while (clip.isActive() amp;amp; thread != null)
{
try
{
thread.sleep(99);
}
catch (Exception e)
{
break;
}
}
clip.loop(999999999);
clip.drain();
}
catch (UnsupportedAudioFileException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (LineUnavailableException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static Music getPlayer()
{
if (player == null)
{
player = new Music();
}
return player;
}
public void update(LineEvent event)
{
}
public void stopClip()
{
//TODO NEED HELP HERE
}
public void startClip()
{
//TODO need help here
}
public void volume(float volume)
{
//TODO NEED HELP HERE
/*
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
gainControl.setValue(-50.0f); // Reduce volume IN DECIBELS
clip.start();
*/
}
}
В моем GuiController я создаю новый музыкальный объект, с помощью метода playSiren я даю название моей песни, а затем он автоматически запускается.
Ответ №1:
Ознакомьтесь с DataLine.stop()
методом. Clip
реализует DataLine
.
Например, ClipControl.java
import java.awt.event.*;
import javax.swing.*;
import javax.sound.sampled.*;
import java.net.URL;
class ClipControl {
public static void main(String[] args) throws Exception {
URL url = new URL("http://pscode.org/media/leftright.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
final Clip clip = AudioSystem.getClip();
clip.open( ais );
Runnable r = new Runnable() {
public void run() {
final JToggleButton startStop = new JToggleButton("Stop");
startStop.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (startStop.isSelected()) {
clip.stop();
startStop.setText("Start");
} else {
clip.loop(-1);
clip.start();
startStop.setText("Stop");
}
}
} );
clip.loop(-1);
JOptionPane.showMessageDialog(null, startStop);
}
};
SwingUtilities.invokeLater(r);
}
}
Комментарии:
1. @Andrew извините, что снова беспокою вас, я вижу, как вы остановили свой клип в том же классе, но не могли бы вы сделать это и в другом?
2. @Andrew извините, что снова беспокою вас, я вижу, как вы остановили свой клип в том же классе, но не могли бы вы сделать это и в другом? потому что я не знаю, как мне это сделать, когда панель становится видимой;
3. @Jonathan: «вы остановили свой клип в том же классе» На самом деле это не так. При компиляции этого исходного кода создаются 3 класса. Первый — это
ClipControl.class
, гдеClip
создается. 2-й и 3-й — это анонимные внутренние классы с именамиClipControl$1.class
дляRunnable
иClipControl$1$1.class
дляActionListener
. Именно вActionListener
этомClip
переключается на запуск / остановку. В конечном счете, на самом деле речь идет не о звуковых клипах, а о видимости элементов и дизайне кода. Возможно, вам следует задать новый вопрос по этому поводу.4. @andrew большое спасибо за вашу помощь в этом вопросе, я думаю, мы поступили намного мудрее, все еще задаваясь вопросом, как это сделать, потому что нам не нужна кнопка для переключения музыки, поэтому мы не можем реально поместить ActionListener в этот клип, но большое спасибо ^^ мы что-нибудь придумаем