java - JavaFX 2 媒体播放器 - 搜索功能不准确或根本不起作用
问题描述
我正在使用 JavaFX8 和 Java 8 创建一个音乐播放器,我遇到了一个问题,类似于其他人之前提到的问题。我想创建一个代表歌曲时间线的滑块。用户可以拖动滑块来更改歌曲的当前播放时间。滑块的刻度与音频文件的秒数一样多。
我目前支持 .m4a 和 .mp3 文件。
根据文件格式,搜索功能可能会稍微不准确、极不准确或工作正常。(详细信息见下文)
正如有人在另一个问题上建议的那样,我已经将 seek 函数移到了 JavaFX 主线程中。没有改变任何东西。
我试图忽略滑块,如果媒体播放器达到某个时间戳,只需使用搜索功能。例如,当媒体播放器超过 10 秒时,我调用了 mediaplayer.seek(Duration.toSeconds(25))。
主 JavaFX Thread 中的函数,它应该跳转到与滑块值对应的时间戳(可拖动)。
public void seekToSecond(){
currentSongmediaPlayer.seek(Duration.seconds(uiController.getSliderValue()));
}
这是根据媒体播放器当前的时间戳更新滑块位置的代码。只要媒体播放器的状态等于“正在播放”,它就会在 JavaFX 后台服务中运行。但它不应该对音频文件的播放时间有任何影响。
if(uiController.getDragged()) {
uiController.setTimeLineDraggedFalse();
}
uiController.setSliderPosition((int)currentSongmediaPlayer.getCurrentTime().toSeconds());
sleep(100); //sleep for 1/10 of a second
当我使用 mediaplayer.seek(double time) 函数时,可能会出现四种不同的结果: 如果文件是 .mp3 文件:
1) 歌曲中的新播放点是例如 0:24s,但是 mediaplayer.getCurrentTime().toSeconds 函数给了我例如 0:26s 作为当前时间。0:26s 应该是正确的值,因为这也是我想要跳转到的值。因此在歌曲结束时,getCurrentTime() 函数返回时间戳,该时间戳高于 mediaplayer.getDuration() 值。
2) 情况与 1) 相同,但这次播放点始终是 0:00s 而不是 0:24s,只要不跳过约 50% 的歌曲即可。如果我跳过这个标记,那么它是一个随机点,仍然相差很多秒。
3)在少数情况下它有效
如果是 .m4a 文件:
1)它工作正常,正如预期的那样
在这一点上,我完全一无所知,看不出有什么问题,除了不知何故搜索功能有错误或不知何故我的大多数 mp3 文件都不起作用。
这是一个最小的代码示例:
对于路径,只需放置一个 mp3 文件并用非常接近歌曲结尾的内容替换 in seek 的持续时间,以便手动检测到歌曲播放的时间比应有的时间长。(例如1s)
主要类:
package sample;
import java.io.File;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Main extends Application {
static MediaPlayer player;
@Override
public void start(Stage primaryStage) throws Exception{
MediaView mv = new MediaView();
File file = new File("path/to/file.mp3");
Media media = new Media(file.toURI().toString());
player = new MediaPlayer(media);
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
Scene scene = new Scene(root, 600, 400);
((Group) scene.getRoot()).getChildren().add(mv);
primaryStage.setTitle("Hello World");
primaryStage.setScene(scene);
primaryStage.show();
player.seek(Duration.seconds(40));
player.play();
}
public static void seekTest(){
System.out.println("hi");
player.seek(Duration.seconds(/*time where it is manually detectable, that the second is not correct (e.g. 1s before end of song)*/));
}
public static void main(String[] args) {
launch(args);
}
}
fxml 控制器:
package sample;
import javafx.fxml.FXML;
public class Controller {
@FXML
public void buttonPressed(){
Main.seekTest();
}
}
我的 fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.Group?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<Group xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<children>
<AnchorPane layoutX="-7.0" layoutY="-7.0" prefHeight="200.0" prefWidth="200.0">
<children>
<Button layoutX="85.0" layoutY="88.0" mnemonicParsing="false" onAction="#buttonPressed" text="Button" />
</children>
</AnchorPane>
</children>
</Group>
希望可以有人帮帮我,
最好的问候,卢卡
解决方案
推荐阅读
- javascript - 关闭引导模式时 VideoJS 视频不会停止
- python - Python gspread - 请求在范围内写入,但尝试写入行 [x]
- reactjs - 'PromiseConstructor' 类型的值不可调用。您的意思是包括“新”吗?反应打字稿
- python - Psycopg2 copy_from 用于 csv 到 postgress
- javascript - Firebase 查询不返回任何内容
- excel - 如何从包含按行分组的数据的电子表格在 Excel 中创建表格
- html - 如何根据选定的无线电验证文本输入以及是否可见
- javascript - 您如何确定媒体录制的 bitsPerSecond?
- java - 包“javax.jms”在模块中声明,名称无效(“geronimo.jms.2.0.spec”)
- c - 按时间顺序组织数据集的问题