java wav音频文件播放器demo

java 简易wav音频文件播放器

测试文件

csdn下载 : https://download.csdn.net/download/qq_41054313/18704149
百度网盘 : 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  
	
	
	@Override
	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-----------------------------------------";
	}
	
}

相关资料

wav音频文件解析
java播放pcm音频文件

Java播放wav音频功能的实现代码,播放wav音频,压缩包中带有测试音频,是否能播放 MP3,未知。   boolean looping = false; //是否循环播放   String[] choics = { "chimes.wav", "start.wav" }; //声音文件名数组   URL file1 = getClass().getResource(choics[0]); //声音文件1   URL file2 = getClass().getResource(choics[1]); //声音文件2   AudioClip sound1 = java.applet.Applet.newAudioClip(file1); //声音剪辑对象1   AudioClip sound2 = java.applet.Applet.newAudioClip(file2); //声音剪辑对象2   AudioClip chosenClip = sound1; //选择的声音剪辑对象   JComboBox jcbFiles = new JComboBox(choics); //文件选择组合框   JButton playButton = new JButton("播放"); //播放按钮   JButton loopButton = new JButton("循环播放"); //循环播放按钮   JButton stopButton = new JButton("停止"); //停止播放按钮   JLabel status = new JLabel("选择播放文件"); //状态栏标签   JPanel controlPanel = new JPanel(); //控制面板用于包容按钮   Container container = getContentPane(); //获得窗口内容窗格   public AudioPlayDemo() { //构造器    super("声音播放程序"); //调用父类构造器设置窗口标题栏    jcbFiles.setSelectedIndex(0); //设置组合框选择项    jcbFiles.addItemListener(this); //为播放按钮添加项目监听器    //为播放按钮、循环播放按钮、停止播放按钮添加动作监听器    playButton.addActionListener(this);    loopButton.addActionListener(this);    stopButton.addActionListener(this);    stopButton.setEnabled(false); //设置停止播放按钮不可用    //把播放按钮、循环播放按钮、停止播放按钮加入控制面板    controlPanel.add(playButton);    controlPanel.add(loopButton);    controlPanel.add(stopButton);    //把文件选择组合框、控制面板、状态栏标签加入到窗口内容窗格    container.add(jcbFiles, BorderLayout.NORTH);    container.add(controlPanel, BorderLayout.CENTER);    container.add(status, BorderLayout.SOUTH);    setSize(300, 130); //设置窗口大小    setVisible(true); //设置窗口可视    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //关闭窗口时退出程序   }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dan淡淡的心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值