科大讯飞sdk语音合成工具类

/*
* 科大讯飞sdk语音播报工具类
* @ param msg 需要播报的语音文字
* @ param fileName 保存文件
*/
public static String getSDKSpeech(String msg, String fileName, String filePath) throws Exception {

generateSpeechFile(msg, fileName, filePath);//生成语音文件

File file = new File(filePath + fileName+".pcm");//失败重试机制
if (!file.exists()){//若语音合成失败
generateSpeechFile(msg, fileName, filePath);//再次生成
}

Pcm2WaveUtils.convertAudioFiles(filePath + fileName+".pcm",filePath + fileName+".wav");
File file1 = new File(filePath + fileName+".wav");
if (!file1.exists()){
throw new Exception("生成wav文件失败");
}
byte[] bytes = Files.readAllBytes(Paths.get(filePath + fileName+".wav"));
log.info("main thread finished!");
return "data:audio/wav;base64," + Base64Utils.encode(bytes);
}



//生成语音文件
private static void generateSpeechFile(String msg, String fileName, String filePath) throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(1);
// 将“XXXXXXXX”替换成您申请的APPID
SpeechUtility.createUtility(SpeechConstant.APPID + "=" + SpeechConstants.appid);

//1.创建SpeechSynthesizer对象
SpeechSynthesizer mTts = SpeechSynthesizer.createSynthesizer();
mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstants.engine_type);//local
//2.合成参数设置,详见《MSC Reference Manual》SpeechSynthesizer 类
mTts.setParameter(SpeechConstant.VOICE_NAME, SpeechConstants.voice_name);//设置发音人
mTts.setParameter(SpeechConstant.SPEED, SpeechConstants.speed);//设置语速,范围0~100
mTts.setParameter(SpeechConstant.PITCH, SpeechConstants.pitch);//设置语调,范围0~100
mTts.setParameter(SpeechConstant.VOLUME, SpeechConstants.volume);//设置音量,范围0~100
//3.开始合成
//设置合成音频保存位置(可自定义保存位置),默认保存在“./tts_test.pcm”
log.info("执行语音文件生成" );
mTts.synthesizeToUri(msg, filePath +fileName+".pcm", new SynthesizeToUriListener() {
//progress为合成进度0~100
public void onBufferProgress(int progress) {
log.info("语音合成进度:" + progress);
}
//会话合成完成回调接口
//uri为合成保存地址,error为错误信息,为null时表示合成会话成功
public void onSynthesizeCompleted(String uri, SpeechError error) {
try {
countDownLatch.countDown();
setInteractiveCount();//设置交互次数
log.info("今天sdk交互次数:" + RedisUtils.get(SPEECH_KEY + getCurrentDateString()));
if (error == null){
log.info("语音合成成功");
}else {
log.info("调用sdk错误码:" + error.getErrorCode());
log.info("调用sdk错误类型:" + error.getErrorType());
throw new Exception("语音sdk调用错误:" + error.getErrorDesc());
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onEvent(int i, int i1, int i2, int i3, Object o, Object o1) {
}
}
);
countDownLatch.await(8000, TimeUnit.MILLISECONDS);//设置主线程超时时间
}



//设置交互次数
public static void setInteractiveCount() {
String currentDateString = getCurrentDateString();//获取当天时间
String key = SPEECH_KEY + currentDateString;
if (RedisUtils.exists(key)) {
String count = RedisUtils.get(key);
AtomicInteger atomicInteger = new AtomicInteger(Integer.valueOf(count));
int i = atomicInteger.incrementAndGet();
RedisUtils.set(key, i + "", 24 * 60 * 60);//设置交互次数
} else {
RedisUtils.set(key, "1", 24 * 60 * 60);//设置过期时间
}
}





//语音格式转换
public class Pcm2WaveUtils {
public static void convertAudioFiles(String src, String target) throws Exception {


FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(target);

//计算长度
byte[] buf = new byte[1024 * 4];
int size = fis.read(buf);
int PCMSize = 0;
while (size != -1) {
PCMSize += size;
size = fis.read(buf);
}
fis.close();

//填入参数,比特率等等。这里用的是16位单声道 8000 hz
WaveHeader header = new WaveHeader();
//长度字段 = 内容的大小(PCMSize) + 头部字段的大小(不包括前面4字节的标识符RIFF以及fileLength本身的4字节)
header.fileLength = PCMSize + (44 - 8);
header.FmtHdrLeth = 16;
header.BitsPerSample = 16;
header.Channels = 1;
header.FormatTag = 0x0001;
header.SamplesPerSec = 16000;//8000;
header.BlockAlign = (short)(header.Channels * header.BitsPerSample / 8);
header.AvgBytesPerSec = header.BlockAlign * header.SamplesPerSec;
header.DataHdrLeth = PCMSize;

byte[] h = header.getHeader();

assert h.length == 44; //WAV标准,头部应该是44字节
//write header
fos.write(h, 0, h.length);
//write data stream
fis = new FileInputStream(src);
size = fis.read(buf);
while (size != -1) {
fos.write(buf, 0, size);
size = fis.read(buf);
}
fis.close();
fos.close();
System.out.println("Convert OK!");
}


public static byte[] convertAudioToByte(String src) throws Exception {


FileInputStream fis = new FileInputStream(src);

//计算长度
byte[] buf = new byte[1024 * 4];
int size = fis.read(buf);
int PCMSize = 0;
while (size != -1) {
PCMSize += size;
size = fis.read(buf);
}
fis.close();

//填入参数,比特率等等。这里用的是16位单声道 8000 hz
WaveHeader header = new WaveHeader();
//长度字段 = 内容的大小(PCMSize) + 头部字段的大小(不包括前面4字节的标识符RIFF以及fileLength本身的4字节)
header.fileLength = PCMSize + (44 - 8);
header.FmtHdrLeth = 16;
header.BitsPerSample = 16;
header.Channels = 1;
header.FormatTag = 0x0001;
header.SamplesPerSec = 16000;//8000;
header.BlockAlign = (short)(header.Channels * header.BitsPerSample / 8);
header.AvgBytesPerSec = header.BlockAlign * header.SamplesPerSec;
header.DataHdrLeth = PCMSize;

byte[] h = header.getHeader();

assert h.length == 44; //WAV标准,头部应该是44字节
//write header
//write data stream
fis = new FileInputStream(src);
byte[] bytes = new byte[fis.available()];
fis.close();
System.out.println("Convert OK!");
return bytes;
}
}

猜你喜欢

转载自www.cnblogs.com/liuruilongdn/p/9719402.html
今日推荐