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
相关产品推荐
相关产品推荐

