获得语音播报的功能

package util;


import java.applet.Applet;
import java.applet.AudioClip;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;


import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;


/**
 * 获得语音播报的工具类
 * @author chao.zhang@quauq.com
 *
 */
public class SoundUtils {
private static final int BUFFER_SIZE=64000;
//无参构造
public SoundUtils(){

}
/**
* 播报语音方法
* @param musicFile
* @throws IOException
*/
public static void playMusic(File musicFile) throws IOException{
byte[] audioData=new byte[BUFFER_SIZE];
AudioInputStream ais=null;
//源数据行是可以写入数据的数据行。它充当其混频器的源。
//应用程序将音频字节写入源数据行,这样可处理字节缓冲并将它们传递给混频器。
//混频器可以将这些样本与取自其他源的样本混合起来,
//然后将该混合物传递到输出端口之类的目标(它可表示声卡上的音频输出设备)。
SourceDataLine line=null;
AudioFormat baseFormat=null;
try {
//获得音频输入流
ais=AudioSystem.getAudioInputStream(musicFile);
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
throw new RuntimeException("can't play wav file",e);
}
if(ais!=null){
// 获得此音频输入流中声音数据的音频格式。
baseFormat=ais.getFormat();
//获得指定格式的源数据行
line=getLine(baseFormat);
if(line==null){
/**
*encoding - 音频编码技术
*sampleRate - 每秒的样本数
*sampleSizeInBits - 每个样本中的位数
*channels - 声道数(单声道 1 个,立体声 2 个,等等)
*frameSize - 每帧中的字节数
*frameRate - 每秒的帧数
*bigEndian - 指示是否以 big-endian 字节顺序存储单个样本中的数据(false 意味着 little-endian)。
*/
//创建一个指定格式的音频
AudioFormat decodeFormat = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,//音频编码技术
baseFormat.getSampleRate(), //每秒的样本数
16,//每个样本中的位数
baseFormat.getChannels(),//声道数(单声道1个,立体声2个等等)
baseFormat.getChannels() * 2,//每帧中的字节数
baseFormat.getSampleRate(), //每秒的帧数
false);//是否yibig-endian字节顺序存储单个样本中的数据(false 意味着 little-endian)。
//获得音频输入流
ais=AudioSystem.getAudioInputStream(decodeFormat,ais);
//获得指定格式的源数据行
line=getLine(decodeFormat);
}
}
if(line==null){
//不能播放 wav file
return;
}
//允许某一数据行执行数据 I/O。
line.start();
int intBytes=0;
while(intBytes!=-1){
//从音频流读取指定的最大数量的数据字节,并将其放入给定指定格式的字节数组中。
intBytes=ais.read(audioData,0,BUFFER_SIZE);
if(intBytes>=0){
//输出音频
line.write(audioData, 0, intBytes);
}
}
/*
* 通过在清空数据行的内部缓冲区之前继续数据 I/O,排空数据行中的列队数据。
* 在完成排空操作之前,此方法发生阻塞。因为这是一个阻塞方法,所以应小心使用它。
* 如果在队列中有数据的终止行上调用 drain(),则在该行正在运行和数据队列变空之前,此方法将发生阻塞。
* 如果通过一个线程调用 drain(),另一个线程继续填充数据队列,则该操作没有完成。
* 此方法总是在关闭数据行时返回。
*  line.drain();可以与line.flush()比较
* flush() 刷新数据行中已列队的数据。已刷新的数据将被丢弃。
*/
line.drain();
//停止行。停止的行应该停止 I/O 活动。但是,如果行已被打开并且正在运行,它应该保留恢复活动所需的资源
line.stop();
//关闭流
line.close();
}
/**
* 获得指定格式的源数据行
* @param audioFormat
* @return
*/
private static SourceDataLine getLine(AudioFormat audioFormat){
SourceDataLine  res=null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
try {
//从混频器获得源数据行
res=(SourceDataLine) AudioSystem.getLine(info);
//打开具有指定格式的行,这样可使行获得所有所需的系统资源并变得可操作。
res.open(audioFormat);
} catch (LineUnavailableException e) {
e.printStackTrace();
throw new RuntimeException("can't get source data line",e);
}
return res;
}

@SuppressWarnings("deprecation")
public static void playWav(File wavFile) throws MalformedURLException{
//用于播放音频剪辑的简单抽象
AudioClip audioClip = Applet.newAudioClip(wavFile.toURL());
// void play() 开始播放此音频剪辑。每次调用此方法时,剪辑都从头开始重新播放。
audioClip.play();
//void loop()以循环方式开始播放此音频剪辑。
//void stop()停止播放此音频剪辑。
}

public static void main(String[] args) {
try {
SoundUtils.playMusic(new File("C:\\Users\\Public\\Pictures\\Sample Pictures\\企鹅.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值