はじめに
この記事は、SLP KBIT Advent Calendar 2019 の13日目の記事です。
(滑り込みセーフアウトでしたごめんなさい…)
やっと折返し地点まできましたね!
今回は、"BasicPlayer API"を使って、かねてから作ってみたかった音楽プレイヤーを作ってみようと思います。
Javaのアプリケーション開発といえばEclipseですが、今回はVSCodeの拡張機能"Java Extension Pack"を使用して開発を行います。
ソースコードは、一応GitHubで公開してますが、まだ単純な機能しかなく、途中段階なので今後も更新していきたいと思ってます。
https://github.com/kakukaku-15/media_player
開発環境
- macOS Big Sur
- Visual Studio Code 1.51.1
- 拡張機能:Java Extension Pack
- Java 15.0.1
使用したAPI
- BasicPlayer API 3.0
準備
Java環境構築
まずは、https://www.oracle.com/java/technologies/javase-jdk15-downloads.html よりJDKをダウンロードします。
※JDK…Javaでソフトウェア開発を行うのに必要なソフトウェアを一つにまとめたパッケージ
ダウンロードが完了したら、.dmgファイルを開いてインストーラを立ち上げ、インストーラの手順に沿ってインストールを完了させます。
次に、VSCodeでJavaアプリケーションを開発するために、VSCodeの拡張機能"Java Extension Pack"をインストールします。
BasicPlayer APIのダウンロード
BasicPlayerとは、JavaSoundAPIに基づいてスレッド化された、単純な機能を持つAPIです。MP3などのオーディアファイルを再生することができます。
http://www.javazoom.net/jlgui/api.html より、BasicPlayer APIをダウンロードします。
以下はダウンロードしたディレクトリの中身です。
プロジェクト作成
VSCodeを開いて、コマンドパレットよりJava: Create Java Project...
-> No build tools
の順に選択し、プロジェクト名を指定してプロジェクトを作成します。
すると、src
, lib
というディレクトリが自動的に生成されます。
上でダウンロードしたBasicPlayer3.0
直下にあるbasicplayer3.0.jar
とlib
ディレクトリにあるすべての.jarファイルを、作成したプロジェクトのlib
に置きます。
これで準備OKです。
src
ディレクトリの直下にソースコードを記述していきます。
ファイル構造
media_player
├── README.md
├── lib
│ ├── basicplayer3.0.jar
│ ├── commons-logging-api.jar
│ ├── jl1.0.jar
│ ├── jogg-0.0.7.jar
│ ├── jorbis-0.0.15.jar
│ ├── jspeex0.9.7.jar
│ ├── mp3spi1.9.4.jar
│ ├── tritonus_share.jar
│ └── vorbisspi1.0.2.jar
└── src
├── Player.java
└── SimplePlayer.java
開発
実際にできたものがこちらです。とてもシンプルですが、音楽プレイヤーと呼べる最低限の機能は持っているのではないかと思います。
機能としては、読み込みボタンを押すとダイアログが表示され、ファイルパスを指定することでオーディオファイル(.mp3)を読み込むことができます。読み込むと、写真のようにファイル名がウィンドウの真ん中に表示されます。再生ボタンを押すと、音楽が再生されます。一時停止、停止位置からの再開も可能です。
完成したソースコードは以下のとおりです。
package src;
import java.io.*;
import java.util.Map;
import javazoom.jlgui.basicplayer.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SimplePlayer extends JFrame implements ActionListener, BasicPlayerListener {
// オブジェクト生成
JFrame frame = new JFrame();
JFileChooser chooser = new JFileChooser();
BasicPlayer player = new BasicPlayer();
BasicController control = (BasicController) player;
File playFile;
JButton btnOpen, btnPlay;
JLabel label;
// コンストラクタ
SimplePlayer() {
frame.setTitle("MP3 Player"); // タイトル
frame.setLayout(new BorderLayout());
// display("" + player.getStatus());
// ボタンを生成
btnOpen = new JButton("読み込み"); // 開くボタン
btnOpen.setActionCommand("open");
btnOpen.addActionListener(this);
btnPlay = new JButton("再生"); // 再生ボタン
btnPlay.setActionCommand("play/pause");
btnPlay.addActionListener(this);
label = new JLabel("Set Music");
label.setHorizontalAlignment(JLabel.CENTER); // 中央に表示
// モジュール設置
frame.add(btnOpen, BorderLayout.NORTH); // 開くボタンをセットする
frame.add(btnPlay, BorderLayout.SOUTH); // 開くボタンをセットする
frame.add(label, BorderLayout.CENTER); // 文字列表示
// frame.pack(); // レイアウトの自動最適化
frame.setSize(200, 200); // ウインドウサイズの設定
frame.setVisible(true); // ウインドウの可視性を設定
// プレイヤーの設定を反映させる
player.addBasicPlayerListener(this);
// ウインドウを閉じるときの処理
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0); // 終了
}
});
}
// 再生
public void play() {
try {
// ファイルを再生、音量、パンなどを設定
control.play();
// display(control.toString());
control.setGain(0.50);
control.setPan(0.0);
} catch (BasicPlayerException e) {
e.printStackTrace();
}
}
// 一時停止
public void pause() {
try {
control.pause();
} catch (BasicPlayerException e) {
e.printStackTrace();
}
}
// 再開
public void resume() {
try {
control.resume(); // 一時停止したところから再生
} catch (BasicPlayerException e) {
e.printStackTrace();
}
}
// BasicPlayerをcontrollerを通じて制御する
public void setController(BasicController controller) {
display("Controll: " + controller.toString());
}
// 音量、パン、プレイヤーの再生などの現在の状況を取得
public void stateUpdated(BasicPlayerEvent event) {
display("stateUpdated: " + event.toString());
}
// サウンドの進捗状況を取得
public void progress(int read, long time, byte[] data, Map map) {
// display("progress :" + map.toString());
// display("" + player.getStatus());
}
// 開かれたサウンドファイルの詳細を取得
public void opened(Object object, Map map) {
display("opened :" + map.toString());
}
// コンソールに文字列を出力
public void display(String str) {
if (str != null)
System.out.println(str);
}
// ボタンアクション
public void actionPerformed(ActionEvent event) {
if (event.getActionCommand() == "open") { // open
int choice = chooser.showOpenDialog(this);
try {
if (choice == JFileChooser.APPROVE_OPTION) {
playFile = chooser.getSelectedFile(); // 選択されたファイルのパスを取得
FileReader fr = new FileReader(playFile); // ファイルパスから読み込み
// frame.setTitle(playFile.getName()); // タイトルを選ばれたファイルの名前に変更
label.setText(playFile.getName()); // 選ばれたファイルの名前を表示
fr.close(); // ファイルの解放
// 指定されたサウンドファイルを開く
control.open(playFile);
}
} catch (Exception e) {
display("ファイルダイアログの展開に失敗しました。");
}
} else if (event.getActionCommand() == "play/pause") {
switch (player.getStatus()) {
case BasicPlayer.OPENED: // 再生
play();
display("再生");
btnPlay.setText("一時停止");
break;
case BasicPlayer.PLAYING: // 一時停止
pause();
display("一時停止");
btnPlay.setText("再生");
break;
case BasicPlayer.PAUSED: // 再開
resume();
display("再開");
btnPlay.setText("一時停止");
break;
default:
break;
}
}
}
}
mainで、作成したSimplePlayerインスタンスを生成し、画面を表示させます。
package src;
//プレイヤーのメインクラス
public class Player {
public static void main(String[] args) {
new SimplePlayer();
}
}
まとめ
BasicPlayerを使った、シンプルな音楽プレイヤーの作成を行いました。
思ったよりお手軽に作れてよかったかなと思います。
とはいえ課題は山積みです。
MP3の再生しかできませんでしたが、他のオーディオファイル、最終的に動画も再生できるようにしたいと思ってます。他の機能としては、プレイリストの作成や、再生位置の調節なども実装したいです。UIももっと考える必要があると思います。
もっと計画性を持って、コツコツとやっていけるような人間になりたいです。
参考
-
Java環境構築(Mac版) JDKインストール
https://techfun.cc/java/mac-jdk-install.html -
VSCodeでJavaの開発環境を構築する
https://www.suzu6.net/posts/130-vscode-for-java/ -
SwingとjavazoomのBasicPlayer APIを使用した超簡易プレイヤー
http://yasshiemd.web.fc2.com/sub/appli/simpleplayer/simpleplayer.html