You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决JavaFX音乐播放器切换歌曲后时长不显示的问题

问题根因
  • 切换歌曲时生成了新的MediaPlayer实例,原有currentTimeProperty的监听器仅绑定在第一首歌的MediaPlayer对象上,未同步绑定到新实例,因此无法响应新歌曲的播放进度更新
  • Media的元数据(包含歌曲总时长)为异步加载,仅监听播放进度无法覆盖新歌曲元数据未就绪时的总时长展示场景
  • 未对旧MediaPlayer实例绑定的监听器做解绑清理,可能出现内存泄漏、旧实例回调干扰新实例逻辑的问题
修复方案
  1. 切换歌曲前先执行旧播放器的清理操作,避免内存泄漏和逻辑冲突
if (currentMediaPlayer != null) {
    currentMediaPlayer.stop();
    // 移除旧实例绑定的进度监听器
    currentMediaPlayer.currentTimeProperty().removeListener(timeChangeListener);
    currentMediaPlayer.dispose();
}
  1. 每次创建新的Media实例时,先监听其durationProperty,元数据加载完成后立刻更新总时长展示
Media newMedia = new Media(newSongUri);
// 监听元数据加载完成事件,更新总时长
newMedia.durationProperty().addListener((obs, oldVal, newVal) -> {
    if (newVal != null && !newVal.isUnknown()) {
        totalDurationLabel.setText(formatDuration(newVal));
    }
});
  1. 初始化新的MediaPlayer实例后,重新绑定进度监听器,同时监听播放器就绪事件做兜底校验
currentMediaPlayer = new MediaPlayer(newMedia);
// 给新实例重新绑定进度监听器
currentMediaPlayer.currentTimeProperty().addListener(timeChangeListener);
// 播放器就绪后兜底校验总时长展示,避免元数据监听漏触发
currentMediaPlayer.setOnReady(() -> {
    Duration totalDur = newMedia.getDuration();
    if (!totalDur.isUnknown()) {
        totalDurationLabel.setText(formatDuration(totalDur));
    }
});
currentMediaPlayer.play();
注意事项
  • MediaPlayer需存为类成员变量,不要设为方法局部变量,避免被GC提前回收导致监听器失效
  • 时长格式化方法需先判断Duration是否为UNKNOWN,避免直接调用toMillis()抛出空指针异常

内容的提问来源于stack exchange,提问作者Devanshu Mahapatra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 03:24:03