java 简易wav音频文件播放器
源码
百度网盘 : https://pan.baidu.com/s/1U93rkCs-jqrPBE-Zgd_W7A 提取码:xhn8
import java.io.FileInputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
/**
* 简易wave音频文件播放器
* @author 作者 luhua
* @version 创建时间:2021年5月14日 下午3:20:11
*/
public class WavePlayer {
public static void main(String[] args) throws Exception {
String path = "F:\\testFile\\audio\\b.wav";
if(null != args && args.length > 0) {
path = args[0];
}
FileInputStream fis = new FileInputStream(path);
/**解析wav头*/
WavHeard pasrWaveHeard = pasrWaveHeard(fis);
if(null != pasrWaveHeard) {
System.out.println(pasrWaveHeard);
AudioFormat.Encoding encoding = new AudioFormat.Encoding("PCM_SIGNED");
//编码格式,采样率,每个样本的位数,声道,帧长(字节),帧数,是否按big-endian字节顺序存储
AudioFormat format = new AudioFormat(encoding,pasrWaveHeard.sampleRate, pasrWaveHeard.formatSize,
pasrWaveHeard.numChannels, pasrWaveHeard.blockAlign, pasrWaveHeard.sampleRate ,false);
SourceDataLine auline = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
System.out.println(format);
auline = (SourceDataLine) AudioSystem.getLine(info);
auline.open(format);
auline.start();
byte[] b = new byte[pasrWaveHeard.bytesPerSecond];
int len = 0;
while((len = fis.read(b))>0) {
auline.write(b, 0, len);
}
auline.close();
}
}
public static WavHeard pasrWaveHeard(FileInputStream fis) throws Exception{
WavHeard wavHeard = new WavHeard();
byte[] b = new byte[4];
/**RIFF部分*/
fis.read(wavHeard.riffType);
if(!"RIFF".equalsIgnoreCase(new String(wavHeard.riffType))) {
System.out.println("This is not a valid wav(RIFF) file.");
return null;
}
/**riffSize*/
fis.read(b);
wavHeard.riffSize = (b[3]&0xff)<<24|(b[2]&0xff)<<16|(b[1]&0xff)<<8|(b[0]&0xff);
/**wave*/
fis.read(wavHeard.waveType);
/**FMT */
fis.read(wavHeard.formatType);
if(!"FMT ".equalsIgnoreCase(new String(wavHeard.formatType))) {
System.out.println("This is not a valid wav(FMT) file.");
return null;
}
/**表示该区块数据的长度(不包含FMT 和fSize的长度)*/
fis.read(b);
wavHeard.formatSize = (b[3]&0xff)<<24 | (b[2]&0xff)<<16 | (b[1]&0xff)<<8 | (b[0]&0xff);
/**PCM音频数据的值为1*/
b = new byte[2];
fis.read(b);
wavHeard.compressionCode = (short) ((b[1]&0xff)<<8 | (b[0]&0xff));
/**音频数据的声道数,1:单声道,2:双声道*/
fis.read(b);
wavHeard.numChannels = (short) ((b[1]&0xff)<<8 | (b[0]&0xff));
/**采样率*/
b = new byte[4];
fis.read(b);
wavHeard.sampleRate = (b[3]&0xff) <<24 | (b[2]&0xff)<<16 | (b[1]&0xff)<<8 | (b[0]&0xff);
/**每秒数据字节数*/
fis.read(b);
wavHeard.bytesPerSecond = (b[3]&0xff) <<24 | (b[2]&0xff)<<16 | (b[1]&0xff)<<8 | (b[0]&0xff);
/**每个采样所需字节数*/
b = new byte[2];
fis.read(b);
wavHeard.blockAlign = (short) ((b[1]&0xff)<<8 | (b[0]&0xff));
/**每个采样存储的bit数*/
fis.read(b);
wavHeard.bitsPerSample = (short) ((b[1]&0xff)<<8 | (b[0]&0xff));
/**data*/
fis.read(wavHeard.dataType);
/**dataSize*/
b = new byte[4];
fis.read(b);
wavHeard.dataSize = (b[3]&0xff) <<24 | (b[2]&0xff)<<16 | (b[1]&0xff)<<8 | (b[0]&0xff);
return wavHeard;
}
}
class WavHeard{
public byte[] riffType = new byte[4]; //4byte,资源交换文件标志:RIFF
public int riffSize; //4byte,从下个地址到文件结尾的总字节数
public byte[] waveType = new byte[4]; //4byte,wav文件标志:WAVE
public byte[] formatType = new byte[4]; //4byte,波形文件标志:FMT(最后一位空格符)
public int formatSize; //4byte,音频属性(compressionCode,numChannels,sampleRate,bytesPerSecond,blockAlign,bitsPerSample)所占字节数
public short compressionCode; //2byte,格式种类(1-线性pcm-WAVE_FORMAT_PCM,WAVEFORMAT_ADPCM)
public short numChannels; //2byte,通道数
public int sampleRate; //4byte,采样率
public int bytesPerSecond; //4byte,传输速率
public short blockAlign; //2byte,数据块的对齐,即DATA数据块长度
public short bitsPerSample; //2byte,采样精度-PCM位宽
public byte[] dataType = new byte[4]; //4byte,数据标志:data
public int dataSize; //4byte,从下个地址到文件结尾的总字节数,即除了wav header以外的pcm data length
public String toString() {
return "------------------RIFF------------------\n"+
"\n riffType\t:"+new String(riffType)+
"\n riffSize\t:"+riffSize+
"\n waveType\t:"+new String(waveType)+
"\n\n------------------FORMAT----------------\n"+
"\n formatType\t:"+ new String(formatType) +
"\n formatSize\t:"+ formatSize +
"\n compressionCode:"+ compressionCode +
"\n numChannels\t:" + numChannels +
"\n sampleRate\t:" + sampleRate +
"\n bytesPerSecond\t:" + bytesPerSecond +
"\n blockAlign\t:" + blockAlign +
"\n bitsPerSample\t:" + bitsPerSample +
"\n dataType\t:" + new String(dataType) +
"\n dataSize\t:" + dataSize +
"\n\n-----------------------------------------";
}
}
相关资料