【JavaFX】動画や音声を再生するMediaPlayer

2018年2月17日

本稿は、動画や音声を再生できるMediaPlayerについて紹介したいと思います。

JavaFXには音声を再生することができるAudioClipも存在しますが、アプリケーション自体をJavaFXアプリケーションで作成するのならば、音声再生する用途にもMediaPlayerの使用をお勧めします。

こちらはAudioClipとは違い、メモリに全展開する再生方式ではない為、メモリにやさしい処理となります。

対応ファイル形式に関してはこちらの公式ドキュメントに記述されています。

音声を再生

まずはmp3ファイルの再生から見ていきましょう。

音声の再生はmediaクラスとMediaPlayerクラスを使用します。

JavaFXアプリケーションが終了している状態だと再生されないので注意が必要です。

new Media(ファイルのURI文字列)でインスタンスを作成し

new MediaPlayer(Mediaオブジェクト)と指定しましょう。

使用するサンプルのmp3ファイルは下記
sample2.mp3

import java.io.File;

import javafx.application.Application;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;

public class Test extends Application{

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

	@Override
	public void start(Stage primaryStage) {
		primaryStage.show();

		//ファイルを読み込み
		Media m = new Media(new File("sample2.mp3").toURI().toString());

		//音声の再生等の操作を実行できるオブジェクト
		MediaPlayer mp = new MediaPlayer(m);

		//再生開始
		mp.play();
	}

}
実行結果

ウィンドウをあえて表示しているのは、Java9の時点ではJavaFXアプリケーションを実行中の時でなければ再生されないからです。

ゲーム制作においてはどちらにしても表示することになるので問題にはならないでしょう。

動画を再生

動画を再生するにはMediaPlayerをMediaViewに組み込むことで表示できます。

new MediaView(MediaPlayerオブジェクト)と指定しましょう。

動画の再生に使うサンプルは下記です。

※2018/02/17時点でなぜかchrome環境では再生時間が2倍になっています。本当は13秒程度の再生時間です。IE、safari、firefoxでは問題ないようです。chromeのバグか?

import java.io.File;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.Stage;

public class Test extends Application{

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

	@Override
	public void start(Stage primaryStage) {
		BorderPane p = new BorderPane();
		Scene scene = new Scene(p, 800, 600);
		primaryStage.setScene(scene);
		primaryStage.show();

		//ファイルを読み込み
		Media m = new Media(new File("sample2.mp4").toURI().toString());

		//動画の再生等の操作を実行できるオブジェクト
		MediaPlayer mp = new MediaPlayer(m);

		//動画パネルの挿入
		MediaView view = new MediaView(mp);
		p.setCenter(view);

		//再生開始
		mp.play();
	}

}
実行結果

自動的に再生する時間を指定するsetStartTimeメソッドや準備ができたら即再生するsetAutoPlayメソッドなどの便利なメソッドも存在します。

ループ再生

動画や音声をループ再生させたい場合は

setCycleCount(ループ回数)と指定しましょう。

setCycleCount(MediaPlayer.INDEFINITE)と指定することで無限ループとなります。

import java.io.File;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.Stage;

public class Test extends Application{

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

	@Override
	public void start(Stage primaryStage) {
		BorderPane p = new BorderPane();
		Scene scene = new Scene(p, 800, 600);
		primaryStage.setScene(scene);
		primaryStage.show();

		//ファイルを読み込み
		Media m = new Media(new File("sample2.mp4").toURI().toString());

		//動画の再生等の操作を実行できるオブジェクト
		MediaPlayer mp = new MediaPlayer(m);

		//動画パネルの挿入
		MediaView view = new MediaView(mp);
		p.setCenter(view);

		//ループ回数を指定
		mp.setCycleCount(2);

		//自動再生開始命令
		mp.setAutoPlay(true);
	}

}
実行結果

サンプルでは2回に設定したので再生終了後もう一度だけ再生されると思います。

停止

再生中の動画や音声を停止したい場合はstopメソッドを使用します。

import java.io.File;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.Stage;

public class Test extends Application{

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

	@Override
	public void start(Stage primaryStage) {
		BorderPane p = new BorderPane();
		Scene scene = new Scene(p, 800, 600);
		primaryStage.setScene(scene);
		primaryStage.show();

		//ファイルを読み込み
		Media m = new Media(new File("sample2.mp4").toURI().toString());

		//動画の再生等の操作を実行できるオブジェクト
		MediaPlayer mp = new MediaPlayer(m);

		//動画パネルの挿入
		MediaView view = new MediaView(mp);
		p.setCenter(view);

		//自動再生開始命令
		mp.setAutoPlay(true);

		//3秒後に停止命令
		new Thread(()->{
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			//停止
			mp.stop();


			try {
				Thread.sleep(3000);

				//再び最初から再生
				mp.play();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}).start();
	}

}
実行結果

今回のような3秒後に停止したい場合などはsetStopTime(new Duration(ミリ秒))で何秒後に停止するかなどを指定したほうが簡単です。

ここではstopメソッドを試したかったのであえてこのようなサンプルとしています。

用途によって使い分けましょう。

まあゲーム用途ならstopメソッドだけ覚えれば問題ないです。

一時停止

pauseメソッドで一時停止ができます。

一時停止後playメソッドを呼ぶと再開できます。

import java.io.File;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.Stage;

public class Test extends Application{

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

	@Override
	public void start(Stage primaryStage) {
		BorderPane p = new BorderPane();
		Scene scene = new Scene(p, 800, 600);
		primaryStage.setScene(scene);
		primaryStage.show();

		//ファイルを読み込み
		Media m = new Media(new File("sample2.mp4").toURI().toString());

		//動画の再生等の操作を実行できるオブジェクト
		MediaPlayer mp = new MediaPlayer(m);

		//動画パネルの挿入
		MediaView view = new MediaView(mp);
		p.setCenter(view);

		//自動再生開始命令
		mp.setAutoPlay(true);

		//3秒後に一時停止命令
		new Thread(()->{
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			//一時停止
			mp.pause();


			try {
				Thread.sleep(3000);

				//再開
				mp.play();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}).start();
	}

}
実行結果

再生位置の指定

seekメソッドを利用します。

seek(new Duration(ミリ秒))で再生位置の指定ができます。

import java.io.File;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Test extends Application{

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

	@Override
	public void start(Stage primaryStage) {
		BorderPane p = new BorderPane();
		Scene scene = new Scene(p, 800, 600);
		primaryStage.setScene(scene);
		primaryStage.show();

		//ファイルを読み込み
		Media m = new Media(new File("sample2.mp4").toURI().toString());

		//動画の再生等の操作を実行できるオブジェクト
		MediaPlayer mp = new MediaPlayer(m);

		//動画パネルの挿入
		MediaView view = new MediaView(mp);
		p.setCenter(view);

		//再生準備完了コールバック
		mp.setOnReady(()->{

			//5秒後から再生開始
			mp.seek(new Duration(15000));

			//再生開始命令
			mp.play();
		});
	}

}
実行結果

音量の変更

setVolumeメソッドを利用すると音量を変更できます。

AudioClipとは違い、再生中に音量変更が可能となっています。

import java.io.File;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.Stage;

public class Test extends Application{

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

	@Override
	public void start(Stage primaryStage) {
		BorderPane p = new BorderPane();
		Scene scene = new Scene(p, 800, 600);
		primaryStage.setScene(scene);
		primaryStage.show();

		//ファイルを読み込み
		Media m = new Media(new File("sample2.mp4").toURI().toString());

		//動画の再生等の操作を実行できるオブジェクト
		MediaPlayer mp = new MediaPlayer(m);

		//動画パネルの挿入
		MediaView view = new MediaView(mp);
		p.setCenter(view);

		//音量のフェードアウト
		new Thread(()->{
				for ( int i = 100;i >= 0;i-- ) {
					mp.setVolume((double)i / 100);
					try {
						Thread.sleep(100);
					} catch ( Exception e ) {
						e.printStackTrace();
					}
				}

		}).start();

		//自動再生開始命令
		mp.setAutoPlay(true);
	}

}
実行結果

再生速度の変更

setRate(速度倍率)メソッドを利用すると再生の速度を変更できます。

音声に関してはピッチも変更されます。

import java.io.File;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.Stage;

public class Test extends Application{

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

	@Override
	public void start(Stage primaryStage) {
		BorderPane p = new BorderPane();
		Scene scene = new Scene(p, 800, 600);
		primaryStage.setScene(scene);
		primaryStage.show();

		//ファイルを読み込み
		Media m = new Media(new File("sample2.mp4").toURI().toString());

		//動画の再生等の操作を実行できるオブジェクト
		MediaPlayer mp = new MediaPlayer(m);

		//動画パネルの挿入
		MediaView view = new MediaView(mp);
		p.setCenter(view);

		//再生速度変更
		mp.setRate(2);

		//自動再生開始命令
		mp.setAutoPlay(true);
	}

}
実行結果

JavaJavaFX

Posted by nompor