Java SourceDataLine 播放音频
- [1 依赖](#1 依赖)
- [2 接口](#2 接口)
- [3 实现](#3 实现)
- [4 测试](#4 测试)
项目 | Value |
---|---|
音频格式 添加依赖 | |
*.wav | (JDK 原生支持) |
*.pcm | (JDK 原生支持) |
*.au | (JDK 原生支持) |
*.aiff | (JDK 原生支持) |
*.mp3 | mp3spi.jar |
*.flac | jflac-codec.jar |
1 依赖
xml
<dependency>
<groupId>com.googlecode.soundlibs</groupId>
<artifactId>mp3spi</artifactId>
<version>1.9.5.4</version>
</dependency>
<!-- 如果需要解码播放flac文件则引入这个jar包 -->
<dependency>
<groupId>org.jflac</groupId>
<artifactId>jflac-codec</artifactId>
<version>1.5.2</version>
</dependency>
2 接口
java
package com.xu.music.player.player;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioFormat.Encoding;
import javax.sound.sampled.AudioInputStream;
import java.io.File;
import java.net.URL;
/**
* Java 音频播放
*
* @author hyacinth
* @date 2019年10月31日19:06:39
*/
public interface Player {
/**
* Java Music 加载音频
*
* @param url 音频文件url
* @throws Exception 异常
* @date 2019年10月31日19:06:39
*/
void load(URL url) throws Exception;
/**
* Java Music 加载音频
*
* @param file 音频文件
* @throws Exception 异常
* @date 2019年10月31日19:06:39
*/
void load(File file) throws Exception;
/**
* Java Music 加载音频
*
* @param path 文件路径
* @throws Exception 异常
* @date 2019年10月31日19:06:39
*/
void load(String path) throws Exception;
/**
* Java Music 加载音频
*
* @param stream 音频文件输入流
* @throws Exception 异常
* @date 2019年10月31日19:06:39
*/
void load(AudioInputStream stream) throws Exception;
/**
* Java Music 加载音频
*
* @param encoding Encoding
* @param stream AudioInputStream
* @throws Exception 异常
* @date 2019年10月31日19:06:39
*/
void load(Encoding encoding, AudioInputStream stream) throws Exception;
/**
* Java Music 加载音频
*
* @param format AudioFormat
* @param stream AudioInputStream
* @throws Exception 异常
* @date 2019年10月31日19:06:39
*/
void load(AudioFormat format, AudioInputStream stream) throws Exception;
/**
* Java Music 暂停播放
*
* @date 2019年10月31日19:06:39
*/
void pause();
/**
* Java Music 继续播放
*
* @date 2019年10月31日19:06:39
*/
void resume();
/**
* Java Music 开始播放
*
* @throws Exception 异常
* @date 2019年10月31日19:06:39
*/
void play() throws Exception;
/**
* Java Music 结束播放
*
* @description: Java Music 结束播放
* @date 2019年10月31日19:06:39
*/
void stop();
}
3 实现
java
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);
}
}
4 测试
java
package com.xu.music.player.player;
import java.io.File;
/**
* Java 音频播放
*
* @author hyacinth
* @date 2019年10月31日19:06:39
*/
public class Test {
public static void main(String[] args) throws Exception {
Player player = XPlayer.createPlayer();
player.load(new File("D:\\Kugou\\梦涵 - 加减乘除.mp3"));
player.play();
}
}