科大讯飞语音开放平台基础环境搭建
1.用户注册
2.注册好后先创建一个自己的应用
创建完成后进入应用可以看到我们开发需要的三个参数:APPID,APISecret,APIKey
3.因为平台提供的SDK中只支持了简单的中英两种语言语音合成,所以这里我们不会用提供的Java的SDK包。
这里是直接使用WebAPI的方式进行整合。到这里你可以直接下载他提供的demo代码,然后把上面我们提到的三个参数换成你自己的就可以完成简单的中文语音的合成了,实际上还是挺简单的。当然后面我也会提供给大家我整合好的demo。
4.后续如果大家需要把demo中的jar使用到项目中可以将jar包安装到自己的maven仓库,安装方法的话可以参考这篇博客。
官方demo
我们主要使用到是WebTTSWS这个类。
1.替换三个参数,以及你需要合成的文本内容。
2.其实已经提示的很明显了,小语种需要和对应的小语种发音人进行配合使用,所以我们还需要在应用中添加对应的小语种发音人。
进入我们的控制台选流式版的语音合成,添加对应的小语种发音人。然后小语种发音人的参数就是我们需要在代码进行配置的。
3.业务参数说明(business),根据需求自行修改。
参数名 | 类型 | 必传 | 描述 | 示例 |
---|---|---|---|---|
aue | string | 是 | 音频编码,可选值: raw:未压缩的pcm lame:mp3 (当aue=lame时需传参sfl=1) speex-org-wb;7: 标准开源speex(for speex_wideband,即16k)数字代表指定压缩等级(默认等级为8) speex-org-nb;7: 标准开源speex(for speex_narrowband,即8k)数字代表指定压缩等级(默认等级为8) speex;7:压缩格式,压缩等级1~10,默认为7(8k讯飞定制speex) speex-wb;7:压缩格式,压缩等级1~10,默认为7(16k讯飞定制speex) | "raw" "speex-org-wb;7" 数字代表指定压缩等级(默认等级为8),数字必传 标准开源speex编码以及讯飞定制speex说明请参考音频格式说明 |
sfl | int | 否 | 需要配合aue=lame使用,开启流式返回 mp3格式音频 取值:1 开启 | 1 |
auf | string | 否 | 音频采样率,可选值: audio/L16;rate=8000:合成8K 的音频 audio/L16;rate=16000:合成16K 的音频 auf不传值:合成16K 的音频 | "audio/L16;rate=16000" |
vcn | string | 是 | 发音人,可选值:请到控制台添加试用或购买发音人,添加后即显示发音人参数值 | "xiaoyan" |
speed | int | 否 | 语速,可选值:[0-100],默认为50 | 50 |
volume | int | 否 | 音量,可选值:[0-100],默认为50 | 50 |
pitch | int | 否 | 音高,可选值:[0-100],默认为50 | 50 |
bgs | int | 否 | 合成音频的背景音 0:无背景音(默认值) 1:有背景音 | 0 |
tte | string | 否 | 文本编码格式 GB2312 GBK BIG5 UNICODE(小语种必须使用UNICODE编码,合成的文本需使用utf16小端的编码方式,详见java示例demo) GB18030 UTF8(小语种) | "UTF8" |
reg | string | 否 | 设置英文发音方式: 0:自动判断处理,如果不确定将按照英文词语拼写处理(缺省) 1:所有英文按字母发音 2:自动判断处理,如果不确定将按照字母朗读 默认按英文单词发音 | "2" |
rdn | string | 否 | 合成音频数字发音方式 0:自动判断(默认值) 1:完全数值 2:完全字符串 3:字符串优先 | "0" |
4.现在可以运行一下demo。运行成功,在对应的路径下就是我们合成的音频文件。如果你运行不了,那么就需要你自己去根据返回的错误代码去官方文档一步一步排查了。
需要使用到的相关pom依赖:
<!--utils-->
<dependency>
<groupId>ws.schild</groupId>
<artifactId>jave-core</artifactId>
<version>2.4.4</version>
</dependency>
<dependency>
<groupId>ws.schild</groupId>
<artifactId>jave-native-osx64</artifactId>
<version>2.4.6</version>
</dependency>
<dependency>
<groupId>com.googlecode.soundlibs</groupId>
<artifactId>mp3spi</artifactId>
<version>1.9.5.4</version>
</dependency>
格式转换
因为官方demo中合成的是pcm的格式,而一般我们使用的可播放格式是wav和mp3的格式。所以在使用api合成后我们还不能直接播放,所以我们需要在进行格式的转换。
转换工具类:
java
import ws.schild.jave.AudioAttributes;
import ws.schild.jave.Encoder;
import ws.schild.jave.EncodingAttributes;
import ws.schild.jave.MultimediaObject;
import java.io.*;
/**
* @Description: 语音合成工具类
*/
public class ConvertUtils {
/**
* 转换音频文件
* @param src 需要转换的pcm音频路径
* @param target 保存转换后wav格式的音频路径
* @throws Exception
*/
public static void convertPcm2Wav(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 = 2;
header.FormatTag = 0x0001;
header.SamplesPerSec = 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!");
}
/**
* wav格式转换成mp3格式
* @param source 源文件
* @param target 目标文件
* @return
*/
public static boolean convertWav2Mp3(File source, File target) {
boolean succeeded = true;
try {
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
audio.setBitRate(128000);
audio.setChannels(2);
audio.setSamplingRate(44100);
audio.setVolume(new Integer(256));
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("mp3");
attrs.setAudioAttributes(audio);
Encoder encoder = new Encoder();
encoder.encode(new MultimediaObject(source), target, attrs);
} catch (Exception ex) {
ex.printStackTrace();
succeeded = false;
}
return succeeded;
}
}
pcm文件转换wav需要的header:
java
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* @Description: wav转换mp3的header
*/
public class WaveHeader {
public final char fileID[] = {'R', 'I', 'F', 'F'};
public int fileLength;
public char wavTag[] = {'W', 'A', 'V', 'E'};;
public char FmtHdrID[] = {'f', 'm', 't', ' '};
public int FmtHdrLeth;
public short FormatTag;
public short Channels;
public int SamplesPerSec;
public int AvgBytesPerSec;
public short BlockAlign;
public short BitsPerSample;
public char DataHdrID[] = {'d','a','t','a'};
public int DataHdrLeth;
public byte[] getHeader() throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
WriteChar(bos, fileID);
WriteInt(bos, fileLength);
WriteChar(bos, wavTag);
WriteChar(bos, FmtHdrID);
WriteInt(bos,FmtHdrLeth);
WriteShort(bos,FormatTag);
WriteShort(bos,Channels);
WriteInt(bos,SamplesPerSec);
WriteInt(bos,AvgBytesPerSec);
WriteShort(bos,BlockAlign);
WriteShort(bos,BitsPerSample);
WriteChar(bos,DataHdrID);
WriteInt(bos,DataHdrLeth);
bos.flush();
byte[] r = bos.toByteArray();
bos.close();
return r;
}
private void WriteShort(ByteArrayOutputStream bos, int s) throws IOException {
byte[] mybyte = new byte[2];
mybyte[1] =(byte)( (s << 16) >> 24 );
mybyte[0] =(byte)( (s << 24) >> 24 );
bos.write(mybyte);
}
private void WriteInt(ByteArrayOutputStream bos, int n) throws IOException {
byte[] buf = new byte[4];
buf[3] =(byte)( n >> 24 );
buf[2] =(byte)( (n << 8) >> 24 );
buf[1] =(byte)( (n << 16) >> 24 );
buf[0] =(byte)( (n << 24) >> 24 );
bos.write(buf);
}
private void WriteChar(ByteArrayOutputStream bos, char[] id) {
for (int i=0; i<id.length; i++) {
char c = id[i];
bos.write(c);
}
}
}
本人项目中设置生成的文件为mp3格式
测试类的代码如下:
java
public static void main(String[] args) throws Exception {
//这里保存文件必须是mp3结尾
String mp3Path = XunFei.textConvertMP3("未来一周的天气以多云和阴天为主,温度波动不大,整体呈现出温暖且有些热的气候特征。空气质量多数天数为优,但有少数天出现轻微污染。风力总体较小,多为微风。", "D:/test/xunfei/test.mp3");
System.out.println("语音合成的音频文件位置: " + mp3Path);
}
接口测试类代码如下:
java
import com.hc.wordToaudio.xunfei.XunFei;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 测试语言合成
*/
@RestController
@RequestMapping("/test")
public class SpeechController {
/**
* 开始语言合成
* text:需要生成的文本
* path生成的音频存放路径 例如: "D:/test/test.mp3" 在D盘的test文件夹下生成一个test.mp3的文件
*
* @return
*/
@RequestMapping("/start")
public String Speech(@RequestParam("text") String text
, @RequestParam("path") String path
) {
String mp3 = null;
try {
mp3 = XunFei.textConvertMP3(text, path);
} catch (Exception e) {
e.printStackTrace();
}
return mp3;
}
}
如果想生成pcm格式的音频文件只需要把业务参数里面的值根据说明换成pcm的格式,并且报错的文件后缀改成.pcm就可以了
完整代码已经上传到CSDN,0积分下载,有需要的朋友自行下载。
感谢大家的阅读,觉得有所帮助的朋友点点关注点点赞!