javafx MediaPlayer 的搜索方法无法正确搜索 1.5 小时以上的长音频文件
Seek method for javafx MediaPlayer does not seek correctly for 1.5 hr+ long audio files
我最近修复了一个错误,每当我断开蓝牙耳机时,javafx MediaPlayer 就会中断。我通过这样做解决了这个问题。
mediaPlayer.setOnError( () -> {
mediaPlayer = new MediaPlayer(media);
System.out.println(durationBackup.toMillis());
mediaPlayer.setOnPlaying(() ->{
mediaPlayer.seek(durationBackup);
mediaPlayer.setOnPlaying(null);
});
mediaPlayer.play();
});
durationBackup 只是 MediaPlayer 崩溃前持续时间的备份。上面的代码适用于一个短的 5 分钟长的 mp3 文件,新创建的 MediaPlayer 将正确地寻找 durationBackup。然而,我随后决定用一个 1.5 小时长的 mp3 文件测试这段代码,在测试时,新创建的 MediaPlayer 无法找到 durationBackup。相反,创建的 MediaPlayer 对象从头开始播放,而不是所需的 durationBackup。
经过进一步测试,seek 方法似乎失败了,因为当我尝试从 1.5 小时长的 mp3 文件开始寻找 7 秒时,MediaPlayer 反而从头开始播放。当我使用 seek 方法从 5 分钟长的文件开始寻找 7 秒时,MediaPlayer 从开始播放 7 秒开始播放。我怀疑这与 mp3 文件的大小有关,但我似乎找不到解决办法。 seek(Duration.seconds(7))
不仅不能处理 1.5 小时长的 mp3 文件,setStartTime(Duration.seconds(7))
也不能处理 1.5 小时长的 mp3 文件。
如果有人能帮我解决这个问题那就太好了。下面是一个可重现的迷你示例。
SevenSecondSeekClass
package apprunner;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;
import javafx.util.Duration;
public class SevenSecondSeekClass extends Application {
MediaPlayer mediaPlayer;
public static void main(String[] args) throws MalformedURLException, IOException {
launch(args);
}
public InvalidationListener il = new InvalidationListener() {
public void invalidated(Observable ov) {
//Here we just print the current time of the song
System.out.println(mediaPlayer.getCurrentTime().toSeconds() + " seconds");
}
};
@Override
public void start(Stage stage) throws Exception {
stage.setTitle("My");
Button button0 = new Button("Play 7 seconds from start of 5min Song");
Button button1 = new Button("Play 7 seconds from start of 1hr Song");
StackPane layout = new StackPane(new VBox(button0, button1));
Scene scene = new Scene(layout, 200, 100);
stage.setScene(scene);
stage.setWidth(400);
stage.show();
File file0 = new File("C:\Users\John Doe\OneDrive\Desktop\YourLieInAprilTest\5minsong.mp3");
String path0 = file0.toURI().toASCIIString();
Media media0 = new Media(path0);
mediaPlayer = new MediaPlayer(media0);
button0.setOnAction(new EventHandler() {
@Override
public void handle(Event arg0) {
createNewPlayer(media0);
}
});
File file1 = new File("C:\Users\John Doe\downloadedMusic\1andHalfHourSong.mp3");
String path1 = file1.toURI().toASCIIString();
Media media1 = new Media(path1);
mediaPlayer = new MediaPlayer(media1);
button1.setOnAction(new EventHandler() {
@Override
public void handle(Event arg0) {
createNewPlayer(media1);
}
});
}
public void createNewPlayer(Media media) {
mediaPlayer.stop();
mediaPlayer.currentTimeProperty().removeListener(il);
mediaPlayer = new MediaPlayer(media);
mediaPlayer.setOnPlaying(() -> {
mediaPlayer.seek(Duration.seconds(7));
System.out.println("Trying to seek to 7 seconds from start of song");
mediaPlayer.setOnPlaying(null);
});
mediaPlayer.currentTimeProperty().addListener(il);//This will help us print the current time of the song
mediaPlayer.play();
}
}
如果您想知道为什么我在 MediaPlayer 的开头使用 .seek 而不是仅使用 .setStartTime(),那是因为 .setStartTime() 会更改 .getTotalDuration 的值并且不允许转到小于开始时间设置的持续时间。我需要这些方面在我的程序中可用,以保持可用 UI。 .setStartTime() 也不适用于 1.5 小时长的 mp3 文件。
附加信息
Link to the 5 minute long Mp3 file I used to test. https://drive.google.com/file/d/1CvAafbMviQ7nvKyojnem9GK73LJsD6MJ/view?usp=sharing
Link to the 1.5 hour long mp3 file I used to test. https://drive.google.com/file/d/1KggQct1VnY18m0_4Wik5pfP4RN8-HbUT/view?usp=sharing
I am using JDK 11 and Javafx 17.0.2
System Type: 64-bit operating system, x64-based processor
JRE version: OpenJDK Runtime Environment (11.0.4+11) (build 11.0.4+11)
Java VM: OpenJDK 64-Bit Server VM (11.0.4+11, mixed mode, tiered, compressed oops, g1 gc, windows-amd64)
Windows Edition: Windows 10 Home
我发现我可以通过将我的 mp3 文件转换为 m4a 文件来解决我的问题。 m4a 文件不再出现搜索问题。
我最近修复了一个错误,每当我断开蓝牙耳机时,javafx MediaPlayer 就会中断。我通过这样做解决了这个问题。
mediaPlayer.setOnError( () -> {
mediaPlayer = new MediaPlayer(media);
System.out.println(durationBackup.toMillis());
mediaPlayer.setOnPlaying(() ->{
mediaPlayer.seek(durationBackup);
mediaPlayer.setOnPlaying(null);
});
mediaPlayer.play();
});
durationBackup 只是 MediaPlayer 崩溃前持续时间的备份。上面的代码适用于一个短的 5 分钟长的 mp3 文件,新创建的 MediaPlayer 将正确地寻找 durationBackup。然而,我随后决定用一个 1.5 小时长的 mp3 文件测试这段代码,在测试时,新创建的 MediaPlayer 无法找到 durationBackup。相反,创建的 MediaPlayer 对象从头开始播放,而不是所需的 durationBackup。
经过进一步测试,seek 方法似乎失败了,因为当我尝试从 1.5 小时长的 mp3 文件开始寻找 7 秒时,MediaPlayer 反而从头开始播放。当我使用 seek 方法从 5 分钟长的文件开始寻找 7 秒时,MediaPlayer 从开始播放 7 秒开始播放。我怀疑这与 mp3 文件的大小有关,但我似乎找不到解决办法。 seek(Duration.seconds(7))
不仅不能处理 1.5 小时长的 mp3 文件,setStartTime(Duration.seconds(7))
也不能处理 1.5 小时长的 mp3 文件。
如果有人能帮我解决这个问题那就太好了。下面是一个可重现的迷你示例。
SevenSecondSeekClass
package apprunner;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;
import javafx.util.Duration;
public class SevenSecondSeekClass extends Application {
MediaPlayer mediaPlayer;
public static void main(String[] args) throws MalformedURLException, IOException {
launch(args);
}
public InvalidationListener il = new InvalidationListener() {
public void invalidated(Observable ov) {
//Here we just print the current time of the song
System.out.println(mediaPlayer.getCurrentTime().toSeconds() + " seconds");
}
};
@Override
public void start(Stage stage) throws Exception {
stage.setTitle("My");
Button button0 = new Button("Play 7 seconds from start of 5min Song");
Button button1 = new Button("Play 7 seconds from start of 1hr Song");
StackPane layout = new StackPane(new VBox(button0, button1));
Scene scene = new Scene(layout, 200, 100);
stage.setScene(scene);
stage.setWidth(400);
stage.show();
File file0 = new File("C:\Users\John Doe\OneDrive\Desktop\YourLieInAprilTest\5minsong.mp3");
String path0 = file0.toURI().toASCIIString();
Media media0 = new Media(path0);
mediaPlayer = new MediaPlayer(media0);
button0.setOnAction(new EventHandler() {
@Override
public void handle(Event arg0) {
createNewPlayer(media0);
}
});
File file1 = new File("C:\Users\John Doe\downloadedMusic\1andHalfHourSong.mp3");
String path1 = file1.toURI().toASCIIString();
Media media1 = new Media(path1);
mediaPlayer = new MediaPlayer(media1);
button1.setOnAction(new EventHandler() {
@Override
public void handle(Event arg0) {
createNewPlayer(media1);
}
});
}
public void createNewPlayer(Media media) {
mediaPlayer.stop();
mediaPlayer.currentTimeProperty().removeListener(il);
mediaPlayer = new MediaPlayer(media);
mediaPlayer.setOnPlaying(() -> {
mediaPlayer.seek(Duration.seconds(7));
System.out.println("Trying to seek to 7 seconds from start of song");
mediaPlayer.setOnPlaying(null);
});
mediaPlayer.currentTimeProperty().addListener(il);//This will help us print the current time of the song
mediaPlayer.play();
}
}
如果您想知道为什么我在 MediaPlayer 的开头使用 .seek 而不是仅使用 .setStartTime(),那是因为 .setStartTime() 会更改 .getTotalDuration 的值并且不允许转到小于开始时间设置的持续时间。我需要这些方面在我的程序中可用,以保持可用 UI。 .setStartTime() 也不适用于 1.5 小时长的 mp3 文件。
附加信息
Link to the 5 minute long Mp3 file I used to test. https://drive.google.com/file/d/1CvAafbMviQ7nvKyojnem9GK73LJsD6MJ/view?usp=sharing
Link to the 1.5 hour long mp3 file I used to test. https://drive.google.com/file/d/1KggQct1VnY18m0_4Wik5pfP4RN8-HbUT/view?usp=sharing
I am using JDK 11 and Javafx 17.0.2
System Type: 64-bit operating system, x64-based processor
JRE version: OpenJDK Runtime Environment (11.0.4+11) (build 11.0.4+11)
Java VM: OpenJDK 64-Bit Server VM (11.0.4+11, mixed mode, tiered, compressed oops, g1 gc, windows-amd64)
Windows Edition: Windows 10 Home
我发现我可以通过将我的 mp3 文件转换为 m4a 文件来解决我的问题。 m4a 文件不再出现搜索问题。