JavaFX MediaPlayerを使った音楽ファイルの再生/停止/シーク

この記事は約8分で読めます。
スポンサーリンク

MediaPlayer

こんにちは、鈴木俊吾です。

現在、私はとある音楽プレーヤーアプリの制作をしています。

その流れで、Java(JavaFX)で音楽ファイル再生停止をどのように実装するのかについて少し調査。
MediaPlayerというクラスを使うと良いということが分かりました。
ところで、やり方が分かれば簡単なのですが…。
実際に、音楽プレーヤーアプリを作っている途中でハマったことがいくつかありましたね。

私と同じように、JavaやJavaFXを使って音楽系のアプリを開発する人の参考になればと思いまして…。
この記事に、MediaPlayerを使った音楽ファイルの再生・停止方法についてまとめておきます。

MediaPlayerクラスとAudioClipクラスの使い分け

Java(JavaFX)で、音楽ファイルを扱うのによく使われるのは…。
MediaPlayerクラスとAudioClipクラスの2つです。
ただ、それぞれに得意・不得意があるようですね。

MediaPlayerクラスを用いた方法では、主にBGMや楽曲の再生に向いています。
すなわち、比較的長時間再生する音楽ファイルを対象にした時に使うと良いです。

AudioClipクラスを用いた方法では、主にSEの再生に向いています。
すなわち、比較的短時間の再生時間で、効果音を出すためのファイルを対象にした時に使います。

今回の場合、音楽ファイルを再生したいということですので…。
用いるのはMediaPlayerクラスということになりますね。

MediaPlayerクラスの使い方

初期化

MediaPlayerクラスの使い方なのですが…。
まず、インスタンスの生成時にMediaを指定します。
このMediaには、音楽ファイルのパスを渡す必要があります。

MediaPlayer player = new MediaPlayer(new Media("sample.mp3"));

実際には、Fileから取得するケースが多いような気がします。
ファイル選択ダイアログやファイル選択用のGUIを用意しておいて、そこからFileを取得します。
そして、そのFileに対してfile.toURI().toURL().toString()を呼び出し、その結果をMediaに渡してやります。
この時、MalformedURLExceptionという例外が発生することがありますので適切に対処しましょう。

File file = ...;
MediaPlayer player = new MediaPlayer(new Media(file.toURI().toURL().toString()));

音楽ファイルの再生

読み込みが終わった音楽ファイルの再生には、play()メソッドを使います。

player.play();

音楽ファイルの停止

再生中の音楽ファイルを停止するには、stop()またはpause()メソッドを使います。

stop()を使うと、音楽ファイルの再生位置が最初に戻ります。
pause()を使うと、音楽ファイルの再生位置はそのままとなります。

player.stop();
player.pause();

音楽プレーヤーでよく使う再生と停止の処理では、play()とpause()を使うと良いです。
私は停止処理をstop()でしばらくの間実装していたため…。
思っていたのと異なる動作をしてしまい非常に苦戦しました。

音楽ファイルのシーク

音楽ファイルの再生位置をシークしたい時にはseek()メソッドを使います。
このメソッドは引数にDurationをとります。
new Duration()でインスタンスを作成すると、引数に渡すのはミリ秒になりますのでご注意を。
秒単位で渡したい場合には、Duration.seconds()を使うと良いです。

player.seek(Duration.seconds(30)); // 30秒の位置にシーク

サンプルプログラム

これらのクラスやメソッドを使って、簡単な音楽再生テストプログラムを組んでみました。
適当な音楽ファイルを3つ用意して、それぞれ「sample01.mp3」「sample02.mp3」「sample03.mp3」として、Mainクラスと同じディレクトリに配置。
GUIの作成は、プログラムから直接生成しています。

package com.suzushinlab.mediaplayer;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.VBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;

public class Main extends Application {
    private MediaPlayer mediaPlayer;
    private String file = "";

    @Override
    public void start(Stage stage) throws Exception {
        stage.setTitle("MediaPlayer");

        VBox panel = new VBox(10);
        panel.setPadding(new Insets(20, 20, 20, 20));
        panel.setAlignment(Pos.CENTER);

        ComboBox<String> combo = new ComboBox<>();
        String[] list = {"sample01.mp3", "sample02.mp3", "sample03.mp3"};
        combo.getItems().addAll(list);
        combo.setValue(list[0]);
        panel.getChildren().add(combo);

        Button playButton = new Button("Play");
        playButton.setMinSize(120, 30);
        playButton.setOnMouseClicked(e -> {
            playMusic(combo.getValue());
        });
        panel.getChildren().add(playButton);

        Button stopButton = new Button("Stop");
        stopButton.setMinSize(120, 30);
        stopButton.setOnMouseClicked(e -> {
            stopMusic();
        });
        panel.getChildren().add(stopButton);

        stage.setScene(new Scene(panel));
        stage.show();
    }

    private void playMusic(String file) {
        if(mediaPlayer != null) {
            if(!this.file.equals(file)) {
                mediaPlayer.stop();
                mediaPlayer.dispose();
            }
        } else {
            this.file = file;
            mediaPlayer = new MediaPlayer(new Media(getClass().getResource(file).toString()));
        }

        if(!this.file.equals(file)) {
            this.file = file;
            mediaPlayer = new MediaPlayer(new Media(getClass().getResource(file).toString()));
        }
        mediaPlayer.play();
    }

    private void stopMusic() {
        if(mediaPlayer != null) {
            mediaPlayer.stop();
        }
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}

プログラムの実行結果は、以下のようになります。
適当に再生したい音楽ファイルをコンボボックスから選び、「Play」ボタンを押します。
すると、選ばれたファイルの再生が行われます。
「Stop」ボタンを押すと、音楽ファイルの再生が停止されます。

MediaPlayer

ひとこと

JavaやJavaFXを使って、音楽系のアプリを開発したいと考える人はきっといるでしょう。
そんな時には、MediaPlayerクラスを使えば基本的には大丈夫。

ハマりどころとしては、stop()とpause()の使い分けですね。
基本的には、音楽の一時停止という意味合いで使うことが多いpause()を使っておくのが無難。

この記事を読んでいるということは、あなたもおそらく音楽系のJavaアプリを開発しているのでしょうね。
良い音楽アプリが作れるように、お互い頑張っていきましょう!

コメント

タイトルとURLをコピーしました