标签:错误 多线程 erp add audio utf-8 初始化 random public
很久都没打开编译器了,代码也生疏了,好在我会面向百度,哈哈,前前后后也搞了四五天总算是搞差不多了。
主要功能就是文字合成语音,语音转换为文字。支持安卓端,支持音频下载。
下面就开始我的开发过程。
注册之后,会送你一万次接口使用次数,感觉还不错哦!
这个我找了半天,我感觉讯飞的官方文档比较乱!
不会用没关系,像我这么笨的看了一天才会,相信你看一眼就会了
以我合成好的代码为例
public static Boolean flag = true;
// 合成监听器
public String convert(String message,String path){
try {
System.out.println(message);
//更换为自己 申请的APPID,初始化
SpeechUtility.createUtility(SpeechConstant.APPID + "=5eb64d51");
//Setting.setShowLog(true);
// 1.创建SpeechSynthesizer对象
SpeechSynthesizer mTts = SpeechSynthesizer.createSynthesizer();
// 2.合成参数设置,详见《MSC Reference Manual》SpeechSynthesizer 类
String act= XunfeiConvert.actor;
mTts.setParameter(SpeechConstant.VOICE_NAME, act);// 设置发音人
mTts.setParameter(SpeechConstant.SPEED, "50");// 设置语速
mTts.setParameter(SpeechConstant.VOLUME, "80");// 设置音量,范围0~100
// 3.开始合成
// mTts.setParameter(SpeechConstant.AUDIO_FORMAT, "pmc");
// mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, path);//设置语调,范围0~100
mTts.synthesizeToUri(message,path,mSynListener);
} catch (Exception e) {
e.printStackTrace();
}
return "文件生成成功!";
}
private final static SynthesizeToUriListener mSynListener = new SynthesizeToUriListener() {
//progress为合成进度0~100
public void onBufferProgress(int progress) {
}
//会话合成完成回调接口 URI为合成保存地址,error为错误信息,为null时表示合成会话成功
public void onSynthesizeCompleted(String uri, SpeechError error) {
System.out.println(uri);
System.out.println(error);
if(error==null){
System.out.println("生成路径地址:"+uri);
}else{
System.out.println(error);
}
flag = true;
}
@Override
public void onEvent(int arg0, int arg1, int arg2, int arg3,
Object arg4, Object arg5) {
}
};
你可以写一个man函数来将参数传入,message为文本内容,path为生成的pcm文件地址。
[SDK动态库未能加载-20021]
参考地址
https://www.cnblogs.com/john- yang/p/8067245.html
这里需要用到ffmpeg处理pcm和mp3互转。ffmpeg也是一个第三方动态库。
public static boolean processAudio(String oldfilepath,String newfilepath,String type) {
List<String> commend = new ArrayList<String>();
commend.add("D:\\ffmpeg\\bin\\ffmpeg.exe");//win
//commend.add("ffmpeg");//linux Docker
commend.add("-f");
commend.add("s16le");
commend.add("-ar");
commend.add("8000");
commend.add("-ac");
commend.add("2");
commend.add("-i");
commend.add(oldfilepath);
commend.add("-acodec");//音频选项, 一般后面加copy表示拷贝
commend.add("mp3");
commend.add("-y");//表示覆盖旧文件
commend.add(newfilepath+"."+type);
try {
Process process = new ProcessBuilder(commend).redirectErrorStream(true).start();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();// 加上这句,系统会等待转换完成。不加,就会在服务器后台自行转换。
System.out.println("exitCode = "+exitCode);
Boolean flag = exitCode==0?true:false;
return flag;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
请求到该接口就能播放语音了,因为sdk其实是应用于安卓上的一套代码,搞到web上实属勉强。
@RestController
public class XunfeiConvert {
public static String actor;
public static String MP3path=null;
@RequestMapping("/firstServlet")
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
String message = request.getParameter("message");
actor=request.getParameter("act");
System.out.println(actor);
System.out.println(message);
String basePath =request.getSession().getServletContext().getRealPath("");
Calendar c = Calendar.getInstance();
String audioName = String.valueOf(c.getTimeInMillis())+ Math.round(Math.random() * 100000);
//讯飞转PCM
String pcmPath = basePath+audioName+".pcm";
// pcmPath=pcmPath.replaceAll("\\\\","\\\\\\\\");
System.out.println(pcmPath);
try {
XcodeConvertUtil util = new XcodeConvertUtil();
String result=util.convert(message, pcmPath);
System.out.println(result);
}catch (Exception e){
e.printStackTrace();
}
XcodeConvertUtil util = new XcodeConvertUtil();
String result=util.convert(message, pcmPath);
System.out.println(result);
//由于生成PCM是异步的,这里while一直等待,直到生成
File file = new File(pcmPath);
if (!file.exists()){
System.out.println("file null");
}
while(true){
if(file.exists()){
//PCM转MP3
String audioPath = basePath+audioName;
response.setHeader("Content-type", "text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
Boolean flag = FfmpegUtil.processAudio(pcmPath,audioPath,"mp3");
if(flag){
out.println(audioName+".mp3");
MP3path=audioPath+".mp3";
System.out.println("转换成功");
System.out.println(MP3path);
}else{
out.println("转换失败");
}
break;
}
}
}
$(function () {
var vm = new Vue({
el: ‘#app‘,
data:{
title:‘语音合成‘,
message: ‘请在此处粘贴文本内容‘
},
methods: {
convert: function () {
if(vm.message===""){vm.open("请输入文字");return}
var act =document.getElementById(‘act‘).value;
$.ajax({
url : "firstServlet",
async : false,
type : ‘post‘,
data : {‘time‘ : (new Date()).toString(),‘message‘:vm.message,‘act‘:act},
success : function(result) {
$("#audio").attr("src",result);
document.getElementById("audio").play();
},
error : function() {
alert("网络异常");
}
});
},open: function (nodesc) {
this.$Notice.open({
title: ‘温馨提示‘,
desc: nodesc
});
}
}
});
});
<div id="app" v-cloak style="text-align: center">
<div>
<h1 v-text="title"></h1>
<i-input v-model="message" type="textarea" :autosize="{minRows: 8,maxRows: 20}" placeholder="请输入..."></i-input>
</div>
<div style="margin-top:10px;">
音色选择:
<select id="act">
<option value="x2_yezi" >少女</option>
<option value="aisjiuxu">男音</option>
<option value="xiaoyan">女音</option>
<option value="aisbabyxu">童音</option>
</select>
<i-button @click="convert" type="primary">合成播放</i-button>
<i-button type="primary"><a href="download" style="color: #e1f0fe">下载音频</a></i-button>
</div>
<div style="display: none">
<audio id="audio" controls="controls" ></audio>
</div>
</div>
也是看了这位大神的demo,利用多线程解决了流式api只能录制60秒的问题。
参数说明
STT stt = new STT(Filepath+"\\src\\main\\webapp\\recorder.wav", 30*1000);
stt.start();
//将前端传递过来的音频文件地址传递给第一个参数即可转换文字。
为了方便运行,集成了Springboot框架。
标签:错误 多线程 erp add audio utf-8 初始化 random public
原文地址:https://www.cnblogs.com/effortfordream/p/13301160.html