Java SourceDataLine 播放音频

时间:2024-02-23 07:25:56
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); } }