为什么当我选择一首新歌时我的音乐不会停止?
Why is my music not stopping when I pick a new song?
我正在 Java 中制作一个程序,每当用户按下键盘上的一个按钮时,就会播放一首歌曲。但是,当我对此进行测试时,按下按键会使歌曲相互播放,而不是在播放另一首之前停止播放。
这是我在播放器中的代码:
import javax.swing.*;
import javax.sound.sampled.*;
import java.io.*;
public class Player
{
public void playmusic(String musicfile) {
File soundFile = new File(musicfile);
try {
Clip clip = AudioSystem.getClip();
if(musicfile.equals("stop")){
clip.stop();
}
else {
AudioInputStream inputStream= AudioSystem.getAudioInputStream(soundFile);
clip.open(inputStream);
//clip.loop(clip.LOOP_CONTINUOUSLY);
clip.start();
}
}
catch(Exception e)
{
System.out.println(e);
}
}
}
在我的游戏 class 中,我创建了一个名为 play 的播放器实例 class。这是class(与音乐相关的方法是keyPressed()):
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.*;
public class Game extends JPanel implements Runnable, KeyListener{
private BufferedImage back;
private int key;
private String[] song;
private Player play;
private ImageIcon menu, choose;
private String screen;
public Game() {
new Thread(this).start();
this.addKeyListener(this);
key =-1;
play = new Player();
song = new String[]{"the_greatest_show.wav","a_million_dreams.wav","a_million_dreams_reprise.wav","come_alive.wav","the_other_side.wav","never_enough.wav","this_is_me.wav","rewrite_the_star.wav","tightrope.wav", "never_enough_reprise.wav","from_now_on.wav"};
letter = 'Z';
menu = new ImageIcon("menu.png");
choose = new ImageIcon("select.png");
screen = "Menu";
}
public void run()
{
try
{
while(true)
{
Thread.currentThread().sleep(5);
repaint();
}
}
catch(Exception e)
{
}
}
public void paint(Graphics g){
Graphics2D twoDgraph = (Graphics2D) g;
if( back ==null)
back=(BufferedImage)( (createImage(getWidth(), getHeight())));
Graphics g2d = back.createGraphics();
g2d.clearRect(0,0,getSize().width, getSize().height);
switch(screen){
case("Menu"):
g2d.drawImage(menu.getImage(), 0, 0, 1000, 700, this);
break;
case("Choose"):
g2d.drawImage(choose.getImage(), 0, 0, 1000, 700, this);
}
twoDgraph.drawImage(back, null, 0, 0);
}
public void stopMusic(){
play.playmusic("stop");
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
key= e.getKeyCode();
char c = (char)(key);
switch(c){
case 'A':
stopMusic();
play.playmusic(song[0]);
break;
case 'S':
stopMusic();
play.playmusic(song[1]);
break;
case 'D':
stopMusic();
play.playmusic(song[2]);
break;
case 'F':
stopMusic();
play.playmusic(song[3]);
break;
case 'G':
stopMusic();
play.playmusic(song[4]);
break;
case 'H':
stopMusic();
play.playmusic(song[5]);
break;
case 'J':
stopMusic();
play.playmusic(song[6]);
break;
case 'K':
stopMusic();
play.playmusic(song[7]);
break;
case 'L':
stopMusic();
play.playmusic(song[8]);
break;
case 'V':
stopMusic();
play.playmusic(song[9]);
break;
case 'B':
stopMusic();
play.playmusic(song[10]);
break;
default:
stopMusic();
}
}
@Override
public void keyReleased(KeyEvent e) {
}
}
请帮我解决这个问题。提前谢谢你。
替换playmusic()方法并检查
public void playmusic(String musicfile) {
try {
Clip clip = AudioSystem.getClip();
if(musicfile.equals("stop")){
clip.stop();
}
else {
File soundFile = new File(musicfile);
AudioInputStream inputStream= AudioSystem.getAudioInputStream(soundFile);
clip.open(inputStream);
//clip.loop(clip.LOOP_CONTINUOUSLY);
clip.start();
}
}
catch(Exception e)
{
System.out.println(e);
}
}
如果您在该方法中调用 getClip()
,您将停止第二个剪辑,因为您丢失了对前一个剪辑的引用(并将继续播放在后台)。 AudioSystem.getClip()
returns 新 剪辑,不是当前剪辑。
当您播放下一首歌曲时,您同时播放了两个片段:第一个片段和当前片段,因为您停止的片段是全新片段。
Clip[0] Clip[1] Clip[2]
Song 1 (nosong-stopped) Song 2
为了解决这个问题,你可以让clip
成为一个全局变量,所以当stop()
和close()
被调用时,当前歌曲的clip
是选择的(您将只有一个剪辑)。
Clip clip = null;
//...
public void playmusic(String musicfile) {
File soundFile = new File(musicfile);
try
{
if(musicfile.equals("stop"))
{
if (clip!=null) //do not nest it to the previous condition ...
{
clip.stop();
clip.flush();
clip.close();
}
}
else //...so no song is played if you called stop and clip was null
{
AudioInputStream inputStream= AudioSystem.getAudioInputStream(soundFile);
if (clip == null || !clip.isOpen())
clip = AudioSystem.getClip();
clip.open(inputStream);
//clip.loop(clip.LOOP_CONTINUOUSLY);
clip.start();
}
}
catch(Exception e)
{
System.out.println(e);
}
}
我正在 Java 中制作一个程序,每当用户按下键盘上的一个按钮时,就会播放一首歌曲。但是,当我对此进行测试时,按下按键会使歌曲相互播放,而不是在播放另一首之前停止播放。 这是我在播放器中的代码:
import javax.swing.*;
import javax.sound.sampled.*;
import java.io.*;
public class Player
{
public void playmusic(String musicfile) {
File soundFile = new File(musicfile);
try {
Clip clip = AudioSystem.getClip();
if(musicfile.equals("stop")){
clip.stop();
}
else {
AudioInputStream inputStream= AudioSystem.getAudioInputStream(soundFile);
clip.open(inputStream);
//clip.loop(clip.LOOP_CONTINUOUSLY);
clip.start();
}
}
catch(Exception e)
{
System.out.println(e);
}
}
}
在我的游戏 class 中,我创建了一个名为 play 的播放器实例 class。这是class(与音乐相关的方法是keyPressed()):
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.*;
public class Game extends JPanel implements Runnable, KeyListener{
private BufferedImage back;
private int key;
private String[] song;
private Player play;
private ImageIcon menu, choose;
private String screen;
public Game() {
new Thread(this).start();
this.addKeyListener(this);
key =-1;
play = new Player();
song = new String[]{"the_greatest_show.wav","a_million_dreams.wav","a_million_dreams_reprise.wav","come_alive.wav","the_other_side.wav","never_enough.wav","this_is_me.wav","rewrite_the_star.wav","tightrope.wav", "never_enough_reprise.wav","from_now_on.wav"};
letter = 'Z';
menu = new ImageIcon("menu.png");
choose = new ImageIcon("select.png");
screen = "Menu";
}
public void run()
{
try
{
while(true)
{
Thread.currentThread().sleep(5);
repaint();
}
}
catch(Exception e)
{
}
}
public void paint(Graphics g){
Graphics2D twoDgraph = (Graphics2D) g;
if( back ==null)
back=(BufferedImage)( (createImage(getWidth(), getHeight())));
Graphics g2d = back.createGraphics();
g2d.clearRect(0,0,getSize().width, getSize().height);
switch(screen){
case("Menu"):
g2d.drawImage(menu.getImage(), 0, 0, 1000, 700, this);
break;
case("Choose"):
g2d.drawImage(choose.getImage(), 0, 0, 1000, 700, this);
}
twoDgraph.drawImage(back, null, 0, 0);
}
public void stopMusic(){
play.playmusic("stop");
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
key= e.getKeyCode();
char c = (char)(key);
switch(c){
case 'A':
stopMusic();
play.playmusic(song[0]);
break;
case 'S':
stopMusic();
play.playmusic(song[1]);
break;
case 'D':
stopMusic();
play.playmusic(song[2]);
break;
case 'F':
stopMusic();
play.playmusic(song[3]);
break;
case 'G':
stopMusic();
play.playmusic(song[4]);
break;
case 'H':
stopMusic();
play.playmusic(song[5]);
break;
case 'J':
stopMusic();
play.playmusic(song[6]);
break;
case 'K':
stopMusic();
play.playmusic(song[7]);
break;
case 'L':
stopMusic();
play.playmusic(song[8]);
break;
case 'V':
stopMusic();
play.playmusic(song[9]);
break;
case 'B':
stopMusic();
play.playmusic(song[10]);
break;
default:
stopMusic();
}
}
@Override
public void keyReleased(KeyEvent e) {
}
}
请帮我解决这个问题。提前谢谢你。
替换playmusic()方法并检查
public void playmusic(String musicfile) {
try {
Clip clip = AudioSystem.getClip();
if(musicfile.equals("stop")){
clip.stop();
}
else {
File soundFile = new File(musicfile);
AudioInputStream inputStream= AudioSystem.getAudioInputStream(soundFile);
clip.open(inputStream);
//clip.loop(clip.LOOP_CONTINUOUSLY);
clip.start();
}
}
catch(Exception e)
{
System.out.println(e);
}
}
如果您在该方法中调用 getClip()
,您将停止第二个剪辑,因为您丢失了对前一个剪辑的引用(并将继续播放在后台)。 AudioSystem.getClip()
returns 新 剪辑,不是当前剪辑。
当您播放下一首歌曲时,您同时播放了两个片段:第一个片段和当前片段,因为您停止的片段是全新片段。
Clip[0] Clip[1] Clip[2]
Song 1 (nosong-stopped) Song 2
为了解决这个问题,你可以让clip
成为一个全局变量,所以当stop()
和close()
被调用时,当前歌曲的clip
是选择的(您将只有一个剪辑)。
Clip clip = null;
//...
public void playmusic(String musicfile) {
File soundFile = new File(musicfile);
try
{
if(musicfile.equals("stop"))
{
if (clip!=null) //do not nest it to the previous condition ...
{
clip.stop();
clip.flush();
clip.close();
}
}
else //...so no song is played if you called stop and clip was null
{
AudioInputStream inputStream= AudioSystem.getAudioInputStream(soundFile);
if (clip == null || !clip.isOpen())
clip = AudioSystem.getClip();
clip.open(inputStream);
//clip.loop(clip.LOOP_CONTINUOUSLY);
clip.start();
}
}
catch(Exception e)
{
System.out.println(e);
}
}