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

JavaFX 16播放前调用seek/setStartTime导致视频无画面仅播声问题求解

问题原因

你的代码本身不存在逻辑错误,该问题是OpenJFX 16及更早版本在Linux平台下的已知缺陷:其底层依赖的GStreamer媒体处理管线,在视频未启动播放时调用seek()或setStartTime()会触发渲染异常,最终表现为音频正常播放但视频画面静止。


可行解决方案

方案1:升级OpenJFX版本

该bug已在OpenJFX 17及后续版本中修复,你只需修改pom.xml中JavaFX相关依赖的版本号即可,业务代码无需改动:

<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-controls</artifactId>
    <version>17</version>
</dependency>
<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-media</artifactId>
    <version>17</version>
</dependency>

方案2:兼容现有版本的规避实现

如果暂时无法升级OpenJFX,可调整调用逻辑:先启动播放,等首帧渲染完成后再执行跳转,跳转完成后可根据需求选择继续播放或暂停。
修改你的onReadyStateListener代码如下即可:

import javafx.beans.InvalidationListener;
import javafx.beans.value.Observable;

// 省略其他代码
private final Runnable onReadyStateListener = new Runnable() {
    @Override
    public void run() {
        registerMinimalKeyEventHandling();
        Duration startTime = new Duration(6000L);
        // 先启动播放
        mediaPlayer.play();
        // 加一次性监听器,等待首帧渲染完成后跳转
        InvalidationListener seekListener = new InvalidationListener() {
            @Override
            public void invalidated(Observable observable) {
                if (mediaPlayer.getCurrentTime().greaterThan(Duration.ZERO)) {
                    mediaPlayer.seek(startTime);
                    // 移除监听器避免重复触发
                    mediaPlayer.currentTimeProperty().removeListener(this);
                    // 如果需要跳转后暂停可取消注释下面的代码
                    // mediaPlayer.pause();
                }
            }
        };
        mediaPlayer.currentTimeProperty().addListener(seekListener);
    }
};

注意你原来的代码里同时调用了seek()和setStartTime(),实际上setStartTime()本身就会自动触发跳转,二者选其一即可,同时调用反而可能增加冲突概率。


内容的提问来源于stack exchange,提问作者Thomas Piekarski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 06:18:03