我正在使用JavaFX8和Java 8创建音乐播放器,但遇到了一个问题,类似于之前提到的其他问题。我想创建一个代表歌曲时间轴的滑块。用户可以向周围拖动滑块以更改歌曲的当前播放时间。滑块的滴答声与音频文件的秒数一样多。
我目前支持.m4a和.mp3文件。
取决于文件格式,seek函数要么稍微不准确,要么非常不准确,要么可以正常工作。 (有关详细信息,请参见下文)
我已经将seek函数移至JavaFX主线程中,正如有人在另一个问题上建议的那样。没有任何改变。
我试图忽略滑块,如果媒体播放器达到一定的时间戳,则只使用搜索功能。例如。当Mediaplayer超过第二秒10时,我调用了mediaplayer.seek(Duration.toSeconds(25))。
JavaFX主线程中的函数,应跳至与滑块值相对应的时间戳(可拖动)。
public void seekToSecond(){
currentSongmediaPlayer.seek(Duration.seconds(uiController.getSliderValue()));
}
这是代码,它根据媒体播放器当前所在的当前时间戳更新滑块位置。只要mediaplayer的状态等于“正在播放”,它就会在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的持续时间,以便可以手动检测到该歌曲的播放时间。 (例如1秒)
主要类别:
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>
希望有人可以帮助我
最好的问候, 路卡