1

我正在尝试在我的 java 应用程序中播放 mp3。用户可以单击按钮并更改声音。

声音和切换工作......但是,当用户尝试切换声音时,新歌开始在旧歌上播放大约一秒钟,然后旧歌停止播放。我正在尝试使用线程来处理所有事情。

我的 MP3 课:

import java.applet.*;
import javazoom.jl.player.Player;
import java.io.*;
import java.io.FileInputStream;
import java.net.*;

public class mp3 extends Thread implements Runnable{

    private Player sound;
    private InputStream path;  
    public mp3(String file_name) {
        path = mp3.class.getClassLoader().getResourceAsStream(file_name);  
    }
    public void run(){
        try {
            Player sound=new Player(path);
            sound.play();
        } catch(Exception e) {System.out.println(e);}
    }
}

这就是我尝试在主游戏中运行代码的方式。MP3 对象称为歌曲。

当应用程序初始化时,将运行以下代码:

song = new mp3("default.mp3");
song.start();

有人试图更改它,运行以下代码:

song.stop();
song = new mp3(t+".mp3");
song.start();

其中 t 是文件名的参数。

我很确定问题出在 MP3 对象的运行函数中。我对线程完全陌生,所以我会很感激一些帮助。

同样,从调用“stop”到它实际停止播放的时间大约有 1 秒的延迟。所以也许在某个地方等待?

谢谢!

编辑: 我现在使用基于这里的代码:

http://introcs.cs.princeton.edu/java/faq/mp3/MP3.java.html

我创建了一个播放和关闭函数,定义如下:

    public void close() { if (player != null) player.close(); }

    // play the MP3 file to the sound card
    public void play() {
        try {
            FileInputStream fis     = new FileInputStream(filename);
            BufferedInputStream bis = new BufferedInputStream(fis);
            player = new Player(bis);
        } catch (Exception e) {
            System.out.println("Problem playing file " + filename);
            System.out.println(e);
        }

        // run in new thread to play in background
        new Thread() {
            public void run() {
                try { player.play(); }
                catch (Exception e) { System.out.println(e); }
            }
        }.start();

我的问题是关闭函数……播放器对象始终为空,关闭函数不执行……即使播放函数对其进行了初始化。为什么它是空的?

4

1 回答 1

1

编辑:

在您的编辑中,如果多个线程正在访问该player字段,则应该进行volatile. 如果不了解如何player定义,则很难猜测其他问题。


我认为您需要确保Player在开始下一个之前已经完成了上一个 mp3。寻找javadocsPlayer我看到:

`player.isComplete()`

去引用:

如果所有可用的 MPEG 音频帧都已解码,则返回 true,否则返回 false

如果您想在新声音开始时停止以前的音频,您应该close()在旧播放器上使用。

关闭此播放器。当前播放的任何音频都会立即停止

在我看来,您需要关闭当前正在运行的Player对象(如果有)并启动一个新Player对象来播放新声音。如果您在多个线程中执行此操作,那么您将需要执行以下操作:

  1. 锁定某个final Object lock对象
  2. 如果您希望当前声音完成,请检查当前Player对象(如果有)是否已在循环中完成sleep
  3. close()如果你想杀死当前的声音,则Player创建一个新的对象Player
  4. 调用play()下一个mp3,
  5. 解锁锁定对象。

据我所知,该play()方法不会等待声音播放,而是在将声音加载到音频缓冲区后立即返回。我不确定如果音频文件很大会发生什么。

于 2012-04-17T05:14:10.393 回答