收到一个需求就是将文本转语音,然后保存到本地,找了很多还是找到2种办法,一个是使用 jacob-project 插件。一个是调用百度API,当然也有其他开源的api,需要自行下载jar包导入。
第一种就是用jacob,需要下载jacob-1.18-x64.dll,因为自己是64位的操作系统,就下这个,32位是另一个,需要将jacob-1.18-x64.dll放入你安装jdk的bin目录下面。有个坑就是liunx上不支持jacob,Jacob是一个针对Windows平台的Java-COM桥梁,不支持Linux和其他操作系统。它依赖于Windows操作系统的注册表和COM接口系统来实现Java与Microsoft Office的交互。
链接: https://pan.baidu.com/s/1xQaniDVQO2qtvFRrw8gw4g
提取码: qrw1
public static void test(String text, String path){
ActiveXComponent component = new ActiveXComponent("Sapi.SpVoice");
Dispatch dispatch = component.getObject();
Long millis = System.currentTimeMillis();
String name = String.valueOf(millis);
Dispatch fileStreamDispatch=null;
Dispatch audioDispatch=null;
try {
// 生成空的语音文件
component = new ActiveXComponent("Sapi.SpFileStream");
fileStreamDispatch = component.getObject();
// 音频
component = new ActiveXComponent("Sapi.SpAudioFormat");
audioDispatch = component.getObject();
// 设置文件流格式
Dispatch.putRef(fileStreamDispatch, "Format", audioDispatch);
// 设置视频输出流的格式
Dispatch.put(audioDispatch, "Type", new Variant(22));
// 调用输出流打开方法,创建一个.wav .mp3 .mp4 .wma文件
Dispatch.call(fileStreamDispatch,"Open",new Variant(path+name+".mp3"),new Variant(3),new Variant(true));
// 设置声音对象的音频流输出流为输出文件对象
Dispatch.putRef(dispatch,"AudioOutputStream",fileStreamDispatch);
// 设置音量大小
Dispatch.put(dispatch,"Volume",new Variant(100));
// 将文本读取进去
Dispatch.call(dispatch, "Speak",new Variant(text));
}catch (Exception e){
e.printStackTrace();
}finally {
// 关闭输出文件流
Dispatch.call(fileStreamDispatch,"Close");
Dispatch.putRef(dispatch,"AudioOutputStream",null);
audioDispatch.safeRelease();
fileStreamDispatch.safeRelease();
dispatch.safeRelease();
component.safeRelease();
}
}
第二种就是调用百度api,百度是收费的,有免费的10w送,然后就是收费的。
调用百度api,需要自己配置。上图
然后调用百度的api,然后是用的单例去实现的。
public class AipSpeechl extends BaseClient {
public static final String APP_ID = "你的appid";
public static final String API_KEY = "你的appkey";
public static final String SECRET_KEY = "你的secrctkey";
// 声明一个 volatile关键字,确保 instance内存可见性
private static volatile AipSpeechl instance;
// 提供一个静态方法,用于获取唯一的实例对象
public static AipSpeechl getInstance() {
// 第一次校验,如果对象已经被创建,则直接返回它,避免不必要的同步操作
if (instance == null) {
// 同步代码块,确保在多线程环境下只有一个线程能够执行对象创建和赋值操作
synchronized (AipSpeechl.class) {
// 第二次校验,防止在同步代码块外等待锁的线程执行对象创建和赋值操作,避免并发冲突
if (instance == null) {
instance = new AipSpeechl(APP_ID,API_KEY,SECRET_KEY);
}
}
}
// 返回唯一的实例对象
return instance;
}
protected AipSpeechl(String appId, String apiKey, String secretKey) {
super(appId, apiKey, secretKey);
}
public TtsResponse synthesis(String text, String lang, int ctp, HashMap<String, Object> options) {
AipRequest request = new AipRequest();
this.preOperation(request);
if (this.isBceKey.get()) {
TtsResponse response = new TtsResponse();
JSONObject msg = Util.getGeneralError(AipClientConst.OPENAPI_NO_ACCESS_ERROR_CODE, "No permission to access data");
response.setResult(msg);
return response;
} else {
request.addBody("tex", text);
request.addBody("lan", lang);
request.addBody("tok", this.accessToken);
request.addBody("ctp", ctp);
String cuid = SignUtil.md5(this.accessToken, "UTF-8");
request.addBody("cuid", cuid);
if (options != null) {
request.addBody(options);
}
request.setUri("http://tsn.baidu.com/text2audio");
TtsResponse response = new TtsResponse();
AipResponse res = AipHttpClient.post(request);
if (res == null) {
response.setResult(Util.getGeneralError(-1, "null response from server"));
return response;
} else {
Map<String, List<String>> header = res.getHeader();
if (header.containsKey("content-type")) {
String contentType = (String)((List)res.getHeader().get("content-type")).get(0);
if (contentType.contains("json")) {
String data = res.getBodyStr();
JSONObject json = new JSONObject(data);
response.setResult(json);
} else {
byte[] binData = res.getBody();
response.setData(binData);
}
} else {
LOGGER.error("synthesis get no content-type in header: " + header);
LOGGER.info("synthesis response status: " + res.getStatus());
try {
JSONObject json = new JSONObject(res.getBodyStr());
response.setResult(json);
} catch (JSONException var13) {
response.setData(res.getBody());
}
}
return response;
}
}
}
}
public static void testBaiDu(String text,String path){
// 获取AipSpeech
AipSpeechl client = AipSpeechl.getInstance();
// 可选:设置网络连接参数
client.setConnectionTimeoutInMillis(2000);
client.setSocketTimeoutInMillis(60000);
// 调用接口
TtsResponse res = client.synthesis(text, "zh", 1, null);
byte[] data = res.getData();
JSONObject result = res.getResult();
if (data != null) {
try {
Util.writeBytesToFileSystem(data, path);
System.out.println("转换成功");
} catch (IOException e) {
e.printStackTrace();
}
}
if (result != null) {
System.out.println(result.toString(2));
}
}