前言
最近一段時間,學校請了達内的老師給我們上Java初級實訓課。實訓上完後,分組選題,做小遊戲。我們小組選了 泡泡堂,小組将近5天的協作編碼,終于差不多做完了。之後我也會把一些收獲的東西抽離出來,總結到部落格上去。
期間我有負責遊戲音效、BGM的工作,經上網查詢資料,自己寫了一個簡單的音樂播放類,來滿足我們的遊戲的需求。該工具類,沒有調用其他第三方jar包,用的是JDK底層API。隻支援wav格式的音樂檔案。
代碼
MusicPlayer.java
package com.tedu.manager;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Control;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
/**
* 根據jdk底層API實作的音樂播放器
*
* @功能
* 1、隻支援wav,且隻能播放一首
* 2、可循環播放,随時停止(并非暫停)
* 3、支援一定範圍内的音量調節
*
* 參考部落格:
* https://blog.csdn.net/qq_21907023/article/details/96174077
* https://blog.csdn.net/fuckcdn/article/details/83725725
*
* @author passerbyYSQ
* @create 2020年7月20日 下午4:05:50
*/
public class MusicPlayer {
// private AudioInputStream audioIn;
// private SourceDataLine sourceDataLine;
// wav檔案的路徑
private File file;
// 是否循環播放
private boolean isLoop = false;
// 是否正在播放
private boolean isPlaying;
// FloatControl.Type.MASTER_GAIN的值(可用于調節音量)
private float newVolumn = 7;
private PlayThread playThread;
// public static void main(String[] args) {
// try {
MusicPlayer player = new MusicPlayer("F:\\初級軟體實訓\\音效\\爆炸.wav");放泡泡.mp3
MusicPlayer player = new MusicPlayer("F:\\初級軟體實訓\\音效\\放泡泡.mp3");
// MusicPlayer player = new MusicPlayer("F:\\初級軟體實訓\\CrazyArcade-master\\music\\bgm0.wav");
// player.setVolumn(6f).play();
// System.out.println("開始播放");
//
// System.out.println("是否暫停?");
// Scanner sc = new Scanner(System.in);
// int isOver = sc.nextInt();
// if (isOver == 1) {
// player.over();
// }
//
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
public MusicPlayer(String srcPath) {
file = new File(srcPath);
}
/**
* 播放音樂
*/
public void play() {
playThread = new PlayThread();
playThread.start();
}
/**
* 結束音樂(并非暫停)
*/
public void over() {
isPlaying = false;
if (playThread != null) {
playThread = null;
}
}
/**
* 設定循環播放
* @param isLoop
* @return 傳回目前對象
*/
public MusicPlayer setLoop(boolean isLoop) {
this.isLoop = isLoop;
return this;
}
/**
* -80.0~6.0206測試,越小音量越小
* @param newVolumn
* @return 傳回目前對象
*/
public MusicPlayer setVolumn(float newVolumn) {
this.newVolumn = newVolumn;
return this;
}
/**
* 異步播放線程
*/
private class PlayThread extends Thread {
@Override
public void run() {
isPlaying = true;
do {
// isPlaying = true;
SourceDataLine sourceDataLine = null;
BufferedInputStream bufIn = null;
AudioInputStream audioIn = null;
try {
bufIn = new BufferedInputStream(new FileInputStream(file));
audioIn = AudioSystem.getAudioInputStream(bufIn); // 可直接傳入file
AudioFormat format = audioIn.getFormat();
sourceDataLine = AudioSystem.getSourceDataLine(format);
sourceDataLine.open();
// 必須open之後
if (newVolumn != 7) {
FloatControl control = (FloatControl) sourceDataLine.getControl(FloatControl.Type.MASTER_GAIN);
// System.out.println(control.getMaximum());
// System.out.println(control.getMinimum());
control.setValue(newVolumn);
}
sourceDataLine.start();
byte[] buf = new byte[512];
// System.out.println(audioIn.available());
int len = -1;
while (isPlaying && (len = audioIn.read(buf)) != -1) {
sourceDataLine.write(buf, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (sourceDataLine != null) {
sourceDataLine.drain();
sourceDataLine.close();
}
try {
if (bufIn != null) {
bufIn.close();
}
if (audioIn != null) {
audioIn.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
} while (isPlaying && isLoop);
}
}
}