提问者:小点点

每当您断开蓝牙耳机时,Javafx MediaPlayer都会出错


我有一个高中顶点,我必须创建一个播放音乐的音乐播放器。但是,每当我连接蓝牙耳机(airpods或musicozy)然后断开它们时,媒体播放器都会停止并产生错误。我在互联网上搜索了答案,但找不到。如果有人能帮助我,那就太好了!我正在使用Javafx 17.0.2和JDK 11。

下面是一个可重现的迷你示例。

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.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;

public class JavaFxMediaPlayer extends Application {

    public static void main(String[] args) throws MalformedURLException, IOException {
        launch(args);

    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setTitle("My");
        Button button = new Button("Play Song");
        Scene scene = new Scene(button, 200, 100);
        stage.setScene(scene);
        stage.show();
        File file = new File("C:\\Users\\John Doe\\OneDrive\\Desktop\\YourLieInAprilTest\\Mp3Test.mp3");
        String path = file.toURI().toASCIIString();
        Media media = new Media(path);
        MediaPlayer mediaPlayer = new MediaPlayer(media);
        button.setOnAction(new EventHandler() {
            @Override
            public void handle(Event arg0) {
                mediaPlayer.stop();
                mediaPlayer.play();
            }
        });
        Runnable printStackTrace = new Runnable() {
            public void run() {
                mediaPlayer.getError().getMessage();
                mediaPlayer.getError().printStackTrace();
            }
        };
        mediaPlayer.setOnError(printStackTrace);

    }
}
module MotisHarmony {
    requires javafx.swt;
    requires javafx.base;
    requires javafx.controls;
    requires javafx.fxml;
    requires javafx.graphics;
    requires javafx.media;
    requires javafx.swing;
    requires javafx.web;
    exports mediaplayerjavafx;
    opens mediaplayerjavafx to javafx.graphics;
}
MediaException: PLAYBACK_HALTED : IDirectSoundBuffer_GetStatus The operation completed successfully.
, IDirectSoundBuffer_GetCurrentPosition: The operation completed successfully.
, dwStatus: 0
    at javafx.media/javafx.scene.media.MediaException.haltException(MediaException.java:150)
    at javafx.media/javafx.scene.media.MediaPlayer$_PlayerStateListener.lambda$onHalt$7(MediaPlayer.java:2566)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
    at java.base/java.lang.Thread.run(Thread.java:834)
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.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;
import javafx.util.Duration;

public class AppRunner extends Application {

    public Duration durationBackup = null;

    MediaPlayer mediaPlayer;

    public static void main(String[] args) throws MalformedURLException, IOException {
        launch(args);

    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setTitle("My");
        Button button = new Button("Play Song");
        Scene scene = new Scene(button, 200, 100);
        stage.setScene(scene);
        stage.show();
        File file = new File("C:\\Users\\John Doe\\OneDrive\\Desktop\\YourLieInAprilTest\\Mp3Test.mp3");
        String path = file.toURI().toASCIIString();
        Media media = new Media(path);
        mediaPlayer = new MediaPlayer(media);
        button.setOnAction(new EventHandler() {
            @Override
            public void handle(Event arg0) {
                mediaPlayer.stop();
                mediaPlayer.play();
            }
        });
        mediaPlayer.currentTimeProperty().addListener(new InvalidationListener() {
            public void invalidated(Observable ov) {
                //Here we keep a backup of the current duration of the song just incase the mediaPlayer crashes, which it does everytime you disconnect a bluetooth headset for some reason
                durationBackup = mediaPlayer.getCurrentTime();
            }
        });
        //Here I try to create a new MediaPlayer and go to the last position we were at before the mediaPlayer halted
        Runnable attemptToResetMediaPlayer = new Runnable() {
            public void run() {
                mediaPlayer = new MediaPlayer(media);
                mediaPlayer.play();
                System.out.println(durationBackup.toMillis());
                mediaPlayer.seek(durationBackup);
            }
        };
        mediaPlayer.setOnError(attemptToResetMediaPlayer);
    }
}
  • 首先,您必须将蓝牙耳机连接到笔记本电脑/计算机
  • 然后,您必须运行上面的迷你可重现示例
  • 然后,您必须单击出现的“播放歌曲”按钮
  • 然后在播放歌曲时,断开蓝牙耳机的连接
  • 媒体播放器将停止,错误消息及其堆栈跟踪将被打印

链接到我用来测试的Mp3文件。https://drive . Google . com/file/d/1c vaafbmviq 7 nvkyojnem 9 GK 73 ljsd 6 mj/view?usp =共享

我正在使用JDK 11和Javafx 17.0.2

系统类型:64位操作系统,x64处理器

处理器:Intel(R)Core(TM)i7-7700HQ CPU@2.80GHz 2.81 GHz

Windows版:Windows 10 Home


共1个答案

匿名用户

你恢复的问题是你寻求得太快了。seek的文档声明,当媒体播放器停止时,它什么也不做,但是在调用play()之后,您没有等待状态改变。

试试这个:

    mediaPlayer.setOnError( () -> {
            mediaPlayer = new MediaPlayer(media);
            System.out.println(durationBackup.toMillis());
            mediaPlayer.setOnPlaying(() ->{
                mediaPlayer.seek(durationBackup);
                mediaPlayer.setOnPlaying(null);
            });
            mediaPlayer.play();
    });