当前位置: 首页 > 知识库问答 >
问题:

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

冯卜鹰
2023-03-14

我有一个高中顶点,我必须创建一个播放音乐的音乐播放器。但是,每当我连接蓝牙耳机(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个答案

邓翼
2023-03-14

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

试试这个:

    mediaPlayer.setOnError( () -> {
            mediaPlayer = new MediaPlayer(media);
            System.out.println(durationBackup.toMillis());
            mediaPlayer.setOnPlaying(() ->{
                mediaPlayer.seek(durationBackup);
                mediaPlayer.setOnPlaying(null);
            });
            mediaPlayer.play();
    });
 类似资料:
  • 我正在尝试构建一个应用程序,以获取当前连接的蓝牙耳机的电池电量。此应用程序可以在没有内置此功能的手机上使用 在stackoverflow上搜索时,我发现如何在android中获取蓝牙耳机电池状态这个问题。我使用BluetoothProfile获得了当前连接的蓝牙耳机。耳机情景模式 但是在BluetoothDevice类型的device对象中,我看不到任何获取蓝牙耳机电池电量的方法或属性 我可以获取

  • 我使用以下代码在Android中启动语音识别: 这很好用。但是,它似乎不接受使用“电话音频”模式配对和连接的蓝牙耳机的语音输入。 我可以使用一个名为SoundAbout的应用程序将“媒体音频”强制设置为“蓝牙(mono)(SCO)”。有了这个应用程序集,我的语音识别现在可以从耳机中提取语音输入。 如何使用RecognizerIntent并从蓝牙耳机获取语音输入? 我看到在API级别16中有一个新的

  • 我最近试图让WatchKit应用程序播放苹果手表扬声器的背景声音效果。据我所知(如果我错了,请纠正我!)这是不可能的,因为我需要连接蓝牙耳机才能使用WKAudioFilePlayer,或者使用额外的界面元素来播放声音(WKInterfaceMovie或PresMediaPlayerControlllerWithURL:选项:完成)。 现在,相反,我想使用WKAudioFilePlayer仅在连接蓝

  • 我听一个热门单词,并使用MediaPlayer播放一些音乐。 在播放音乐的同时继续收听下一个命令,并做出相应的反应。 该应用程序运行良好,音乐可以通过蓝牙耳机播放,语音也可以同时识别,但它总是使用手机的麦克风。即使蓝牙耳机连接或没有连接,它仍然使用手机的麦克风。 我试着用: 这让我觉得这是可能的但我不知道怎么做。 请帮帮我。提前谢了。

  • 我必须为Android平板电脑开发一个应用程序,要求将文件打印到蓝牙打印机上。 通过蓝牙打印是我应用程序最重要的功能之一。 我尝试了这个项目和这个项目。 它不工作,也不报告任何错误-不要打印。 蓝牙打印机有什么建议吗?

  • 获取手机蓝牙开启状态, 未授权时先授权再check 示例代码 Swift: RokidMobileSDK.binder.enableBLE() Objc: [RokidMobileSDK.binder enableBLE]; 在 SDKBinderObserver 实现类中的 onBLEEnabled() 函数 获取蓝牙开启状态。 Swift: // 手机蓝牙状态变更,用户是开起来了蓝牙功能