Java SourceDataLine 播放音频
package com.xu.music.player.player;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.text.CharSequenceUtil;
import javazoom.spi.mpeg.sampled.file.MpegAudioFileReader;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Deque;
import java.util.LinkedList;
import com.xu.music.player.system.Constant;
/**
* Java 音频播放
*
* @author hyacinth
* @date 2019年10月31日19:06:39
*/
public class XPlayer implements Player {
private static SourceDataLine data = null;
private static AudioInputStream audio = null;
public static final Deque<Double> deque = new LinkedList<>();
public void put(Double v) {
synchronized (deque) {
deque.add(v);
if (deque.size() > Constant.SPECTRUM_TOTAL_NUMBER) {
deque.removeFirst();
}
}
}
private XPlayer (){
}
public static XPlayer createPlayer() {
return XPlayer.SingletonHolder.player;
}
private static class SingletonHolder {
private static final XPlayer player = new XPlayer();
}
@Override
public void load(URL url) throws Exception {
load(AudioSystem.getAudioInputStream(url));
}
@Override
public void load(File file) throws Exception {
String name = file.getName();
if (CharSequenceUtil.endWithIgnoreCase(name, ".mp3")) {
AudioInputStream stream = new MpegAudioFileReader().getAudioInputStream(file);
AudioFormat format = stream.getFormat();
format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, format.getSampleRate(), 16, format.getChannels(),
format.getChannels() * 2, format.getSampleRate(), false);
stream = AudioSystem.getAudioInputStream(format, stream);
load(stream);
} else if (CharSequenceUtil.endWithIgnoreCase(name, ".flac")) {
AudioInputStream stream = AudioSystem.getAudioInputStream(file);
AudioFormat format = stream.getFormat();
format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, format.getSampleRate(), 16, format.getChannels(),
format.getChannels() * 2, format.getSampleRate(), false);
stream = AudioSystem.getAudioInputStream(format, stream);
load(stream);
} else {
load(AudioSystem.getAudioInputStream(file));
}
}
@Override
public void load(String path) throws Exception {
load(new File(path));
}
@Override
public void load(AudioInputStream stream) throws Exception {
DataLine.Info info = new DataLine.Info(SourceDataLine.class, stream.getFormat(), AudioSystem.NOT_SPECIFIED);
data = (SourceDataLine) AudioSystem.getLine(info);
data.open(stream.getFormat());
audio = stream;
}
@Override
public void load(AudioFormat.Encoding encoding, AudioInputStream stream) throws Exception {
load(AudioSystem.getAudioInputStream(encoding, stream));
}
@Override
public void load(AudioFormat format, AudioInputStream stream) throws Exception {
load(AudioSystem.getAudioInputStream(format, stream));
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void play() throws IOException {
if (null == audio || null == data) {
return;
}
data.start();
byte[] buf = new byte[4];
int channels = audio.getFormat().getChannels();
float rate = audio.getFormat().getSampleRate();
while (audio.read(buf) != -1) {
if (channels == 2) {//立体声
if (rate == 16) {
put((double) ((buf[1] << 8) | buf[0]));//左声道
//put((double) ((buf[3] << 8) | buf[2]));//右声道
} else {
put((double) buf[1]);//左声道
put((double) buf[3]);//左声道
//put((double) buf[2]);//右声道
//put((double) buf[4]);//右声道
}
} else {//单声道
if (rate == 16) {
put((double) ((buf[1] << 8) | buf[0]));
put((double) ((buf[3] << 8) | buf[2]));
} else {
put((double) buf[0]);
put((double) buf[1]);
put((double) buf[2]);
put((double) buf[3]);
}
}
data.write(buf, 0, 4);
}
}
@Override
public void stop() {
if (null == audio || null == data) {
return;
}
IoUtil.close(audio);
data.stop();
IoUtil.close(data);
}
}