JavaFX MediaPlayer的搜索非常不准确

时间:2015-09-05 08:48:26

标签: java audio javafx mp3

我使用320 kbps大约1小时的MP3文件。我正在研究的项目将寻找MP3文件中的音乐集合,以便它可以随机播放歌曲。我会把时间戳给程序,它会寻找这首歌。如果JavaFX的搜索方法不是非常不准确的话,它会起作用。

使用MediaPlayer.seek(duration)The MediaPlayer.getCurrentTime()返回我们按预期查找的持续时间。然而,如果我们听mp3文件(无论是在寻求还是在外部MP3播放器中),我们都会意识到报告的时间和现实是非常不同的,有时甚至是秒。

例如MediaPlayer.seek(Duration.millis(2000))结果寻求0秒。 2秒的故障率是不可接受的。

使用WAV似乎有效。虽然它没有MP3。

我认为到目前为止有两种解决方法是可能的:

  • 编写没有错误的MP3解码器和播放器
  • 使用未压缩的WAV文件

有没有人知道更好的事情?

如果有人需要源代码,那么其中没有更多内容:

public static void main(String[] args) {
        MediaPlayer player = null;
        JFXPanel fxPanel = new JFXPanel(); //To initialize JavaFX
        try {
            String url = new File("E:\\Music\\test.mp3").toURI().toURL().toExternalForm();
            player = new MediaPlayer(new Media(url));
            System.out.println("File loaded!");
        } catch (MalformedURLException e) {
            //e.printStackTrace();
            System.out.println("Error with filename!");
            System.exit(0);
        }

        player.play();

        System.out.println("Playing!");

        while (true)
        {
            Scanner reader = new Scanner(System.in);
            String string = reader.nextLine();
            if (string.equals("Exit")) System.exit(0);
            else if (string.equals("Seek"))
            {
                player.seek(Duration.millis(2000)); //this seeks to the beggining of the file
                player.pause();
                try {
                    Thread.sleep(100); //player.getCurrentTime() doesn't update immediately
                } catch (InterruptedException e) { }
                System.out.println("Time: " + player.getCurrentTime().toMillis() + " / " + player.getTotalDuration().toMillis());
                player.play();
            }
        }
    }

2 个答案:

答案 0 :(得分:1)

我建议使用javazoom库。它是一个开源的java库,已经编写了这些东西没有错误(至少没有我发现)。

来源 http://www.javazoom.net/index.shtml

答案 1 :(得分:0)

将对seek方法的调用置于UI线程之外,否则UI会挂起。

@Override
  @Bean
  public UserDetailsService userDetailsService() {
    return new UserDetailServiceImpl();
  }