読者です 読者をやめる 読者になる 読者になる

くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

JavaFXで動画・音声を再生&時間表示&スライダー付

JavaFX java

JavaFXでメディアを操作する部分を触ったので、その時の備忘録。

基本Listenerを追加する口があるので、いい感じにリスナーを追加する

サンプルソース

全体的にはこんな感じ。

はまった点は、以下の2つ! 1. MediaPlayer#getStopTime()はReadyの状態にならないと、使い物にならない 1. Durationのformatは自前でがんばらないといけない

特にフォーマット変換がないのは、つらいなぁ。。。

public class SampleController {
    @FXML private Slider timeSlider;
    @FXML private Label timeLabel;
    private MediaPlayer player;

    public void initPlayer(MediaPlayer player) {
        this.player = player;
        
        //MediaPlayerがReadyになったら、時間ラベルとスライダーを設定して、再生を開始
        player.setOnReady(() -> {
            //ラベルの設定はOnReadyのイベント後にやらないと、
            //player.getStopTime()がNaNになってしまうので注意
            setTimeLabel();
            setTimeSlider();
            player.play();
        });

        //現在の時間が変わるごとに発火するイベントにリスナーを追加
        player.currentTimeProperty()
            .addListener((Observable observable) -> setTimeLabel());
        player.currentTimeProperty()
            .addListener((Observable observable) -> timeSlider.setValue(
                player.getCurrentTime().toSeconds()));
    }

    //時間ラベルの設定。'現在の時間  : 全体の時間"に設定する
    private void setTimeLabel() {
        Duration curTime = player.getCurrentTime();
        setTimeLabel(curTime);
    }
    
    //時間ラベルの設定。'指定した時間  : 全体の時間"に設定する
    private void setTimeLabel(Duration curTime) {
        Duration totalTime = player.getStopTime();
        String str = toStringMinSec(curTime) + " / " + toStringMinSec(totalTime);
        timeLabel.setText(str);
    }

    //Durationのフォーマッター。"MM:ss"形式
    private String toStringMinSec(Duration dur) {
        int min = (int) Math.floor(dur.toMinutes());
        int sec = (int) (Math.ceil(dur.toSeconds() % 60));
        return String.format("%1$d:%2$02d", min, sec);
    }

    //スライダーの設定
    private void setTimeSlider() {
        timeSlider.setMin(player.getStartTime().toSeconds());
        timeSlider.setMax(player.getStopTime().toSeconds());

        //スライダーからマウスをはなしたら、その時間から再生するようにリスナーを追加
        timeSlider.addEventFilter(MouseEvent.MOUSE_RELEASED, (e) -> {
            player.seek(Duration.seconds(timeSlider.getValue()));
        });
        //スライダーをドラッグ中は、現在の時間がスライダーの一になるようにリスナーを追加
        timeSlider.addEventFilter(MouseEvent.MOUSE_DRAGGED, (e) -> {
            setTimeLabel(Duration.seconds(timeSlider.getValue()));
        });
    }
}

以上!!

参考にしたサイト様