手把手教你用JAVA调用Websocket实现“声音转换”功能(变声)标贝科技
前言
什么是声音转换? 基于深度学习和迁移学习技术,精准将原说话人的声音转换为目标说话人,同时保留原说话人的风格特色。让声音有更多的表现形式。
一、内容太长不愿意看,直接使用系列
首先确认接口调用要求: 实现方式:Websocket 支持音频文件的编码格式及文件名的后缀: pcm 支持音频文件的采样率/位深: 16000Hz/16bit 支持的语言:中文普通话 音频有效时长:不超过180分钟 确认无误后,直接执行 2.2获取权限+2.3.5完整代码示例
二、用JAVA调用标贝科技“声音转换”接口使用流程
2.1.环境准备
java
2.2.获取权限
2.1.1.登录
地址:标贝科技智能语音开放平台
点击上方地址登录,支持短信、密码、微信三种登录方式。
2.1.2.创建应用
登录后,点击创建应用,填写相关信息(未实名认证只能创建一个应用) (注:实名认证后可获得创建多个应用的权限) 进入应用,其中包含的技术产品有:语音识别、语音合成、声音复刻、声音转换 页面中功能主要包括:服务用量管理、购买服务量管理、开发者文档、授权管理、套餐管理 2.1.3.获取token 点击声音转换—>授权管理—>显示—>获取APISecret—>(获取访问令牌token)
2.3.代码实现
2.3.1.获取token
private static final String clientId = "输入你的clientid";
private static final String clientSecret = "输入你的clientsecret";
public static String tokenUrl = "https://openapi.data-baker.com/oauth/2.0/token?grant_type=client_credentials&client_secret=%s&client_id=%s";
public static String getAccessToken() {
String accessToken = "";
OkHttpClient client = new OkHttpClient();
String url = String.format(tokenUrl, clientSecret, clientId);
Request request = new Request.Builder().url(url).build();
JSONObject jsonObject;
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
String resultJson = response.body().string();
jsonObject = JSON.parseObject(resultJson);
accessToken = jsonObject.getString("access_token");
}
} catch (Exception e) {
e.printStackTrace();
}
return accessToken;
}
2.3.2.配置获取音频文件路径和声音转换后的保存路径
private static final String pcmFile = "";
private static final String dic = "";
2.3.3.创建webscoket连接,配置接口参数 参数: “access_token”:2.1.3中已获取 “voice_name”:代码中已提供(平台提供五种音色供你测试) “enable_vad”:true代表启动服务端vad功能,默认false。如果启动系统会根据输入音频进行检测,过 滤环境噪音。否则直接将原始输入音频进行转换。 “align_input”:true代表输出音频与输入音频进行对齐,默认false。即开启vad时会保留静音部分,false丢弃静音部分。 “lastpkg”:是否为最后一包,当时发送最后一包数据时设置为true 告诉系统输入完成
@Override
public void onOpen(WebSocket webSocket, Response response) {
super.onOpen(webSocket, response);
this.startTime = timeBegin.get();
new Thread(() -> {
File file = new File(pcmFile);
JSONObject jsonObject = new JSONObject();
jsonObject.put("access_token", accessToken);
jsonObject.put("voice_name", voiceName);
jsonObject.put("enable_vad", true);
jsonObject.put("align_input", true);
jsonObject.put("lastpkg", false);
int length = jsonObject.toJSONString().getBytes().length;
byte[] b = new byte[4];
b[0] = (byte) (length >> 24 & 0xFF);
b[1] = (byte) (length >> 16 & 0xFF);
b[2] = (byte) (length >> 8 & 0xFF);
b[3] = (byte) (length & 0xFF);
FileInputStream fileInputStream = null;
ByteArrayOutputStream byteOut = null;
try {
fileInputStream = new FileInputStream(file);
byteOut = new ByteArrayOutputStream();
int size = 32000;
byte[] byteArray = new byte[size];
int totalLength = 0;
int read = 0;
while ((read = fileInputStream.read(byteArray, 0, size)) > 0) {
totalLength += read;
System.out.println();
if (read == size && totalLength < file.length()) {
byte[] bytes = ArrayUtils.addAll(ArrayUtils.addAll(b, jsonObject.toJSONString().getBytes()), byteArray);
webSocket.send(new ByteString(bytes));
Thread.sleep(40);
} else {
jsonObject.put("lastpkg", true);
length = jsonObject.toJSONString().getBytes().length;
b[0] = (byte) (length >> 24 & 0xFF);
b[1] = (byte) (length >> 16 & 0xFF);
b[2] = (byte) (length >> 8 & 0xFF);
b[3] = (byte) (length & 0xFF);
byte[] subarray = ArrayUtils.subarray(byteArray, 0, read);
byte[] bytes = ArrayUtils.addAll(ArrayUtils.addAll(b, jsonObject.toJSONString().getBytes()), subarray);
webSocket.send(new ByteString(bytes));
}
}
System.out.println("all data is send");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (byteOut != null) {
try {
byteOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
2.3.4.接收返回的语音流并写入文件
@Override
public void onMessage(WebSocket webSocket, ByteString bytes) {
super.onMessage(webSocket, bytes);
byte[] byteArray = bytes.toByteArray();
int length = (byteArray[0] << 24) + (byteArray[1] << 16) + (byteArray[2] << 8) + byteArray[3];
byte[] jsonArray = ArrayUtils.subarray(byteArray, 4, 4 + length);
String jsonStr = new String(jsonArray);
JSONObject jsonObject = JSONObject.parseObject(jsonStr);
byte[] subarray = ArrayUtils.subarray(byteArray, 4 + length, byteArray.length);
File resultPcmFile = new File(dic, new File(pcmFile).getName().replace(".pcm", "_result.pcm"));
if (!resultPcmFile.exists()) {
try {
resultPcmFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
FileOutputStream outputStream = new FileOutputStream(resultPcmFile, true);
IOUtils.write(subarray, outputStream);
IOUtils.closeQuietly(outputStream);
if ((int) jsonObject.get("errcode") == 0) {
if (jsonObject.getBoolean("lastpkg")) {
System.out.println("session end ");
System.out.println(sdf.format(startTime) + "开始");
System.out.println(sdf.format(timeEnd.get()) + "结束");
System.out.println("耗时:" + (timeEnd.get().getTime() - startTime.getTime()) + "ms");
System.out.println("本次识别traceId ==》" + jsonObject.getString("traceid"));
webSocket.close(1000, "");
}
} else {
System.out.println("errCode=>" + jsonObject.getInteger("errcode") + " errMsg=>" + jsonObject.getString("errmsg") + " traceId=" + jsonObject.getString("traceid"));
webSocket.close(1000, "");
System.out.println("发生错误,关闭连接");
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
2.3.5.完整代码示例
package ......
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import okio.ByteString;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class VcWebSocketDemo extends WebSocketListener {
private static final String clientId = "输入你的clientid";
private static final String clientSecret = "输入你的clientSecret";
public static String tokenUrl = "https://openapi.data-baker.com/oauth/2.0/token?grant_type=client_credentials&client_secret=%s&client_id=%s";
private static final String hostUrl = "wss://openapi.data-baker.com/ws/voice_conversion";
private static final String pcmFile = "";
private static final String dic = "";
private static final SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HH:mm:ss.SSS");
private static ThreadLocal<Date> timeBegin = ThreadLocal.withInitial(() -> new Date());
private static ThreadLocal<Date> timeEnd = ThreadLocal.withInitial(() -> new Date());
private String voiceName = "Vc_baklong";
private Date startTime;
private String accessToken = getAccessToken();
@Override
public void onOpen(WebSocket webSocket, Response response) {
super.onOpen(webSocket, response);
this.startTime = timeBegin.get();
new Thread(() -> {
File file = new File(pcmFile);
JSONObject jsonObject = new JSONObject();
jsonObject.put("access_token", accessToken);
jsonObject.put("voice_name", voiceName);
jsonObject.put("enable_vad", true);
jsonObject.put("align_input", true);
jsonObject.put("lastpkg", false);
int length = jsonObject.toJSONString().getBytes().length;
byte[] b = new byte[4];
b[0] = (byte) (length >> 24 & 0xFF);
b[1] = (byte) (length >> 16 & 0xFF);
b[2] = (byte) (length >> 8 & 0xFF);
b[3] = (byte) (length & 0xFF);
FileInputStream fileInputStream = null;
ByteArrayOutputStream byteOut = null;
try {
fileInputStream = new FileInputStream(file);
byteOut = new ByteArrayOutputStream();
int size = 32000;
byte[] byteArray = new byte[size];
int totalLength = 0;
int read = 0;
while ((read = fileInputStream.read(byteArray, 0, size)) > 0) {
totalLength += read;
System.out.println();
if (read == size && totalLength < file.length()) {
byte[] bytes = ArrayUtils.addAll(ArrayUtils.addAll(b, jsonObject.toJSONString().getBytes()), byteArray);
webSocket.send(new ByteString(bytes));
Thread.sleep(40);
} else {
jsonObject.put("lastpkg", true);
length = jsonObject.toJSONString().getBytes().length;
b[0] = (byte) (length >> 24 & 0xFF);
b[1] = (byte) (length >> 16 & 0xFF);
b[2] = (byte) (length >> 8 & 0xFF);
b[3] = (byte) (length & 0xFF);
byte[] subarray = ArrayUtils.subarray(byteArray, 0, read);
byte[] bytes = ArrayUtils.addAll(ArrayUtils.addAll(b, jsonObject.toJSONString().getBytes()), subarray);
webSocket.send(new ByteString(bytes));
}
}
System.out.println("all data is send");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (byteOut != null) {
try {
byteOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
@Override
public void onMessage(WebSocket webSocket, String text) {
super.onMessage(webSocket, text);
}
@Override
public void onMessage(WebSocket webSocket, ByteString bytes) {
super.onMessage(webSocket, bytes);
byte[] byteArray = bytes.toByteArray();
int length = (byteArray[0] << 24) + (byteArray[1] << 16) + (byteArray[2] << 8) + byteArray[3];
byte[] jsonArray = ArrayUtils.subarray(byteArray, 4, 4 + length);
String jsonStr = new String(jsonArray);
JSONObject jsonObject = JSONObject.parseObject(jsonStr);
byte[] subarray = ArrayUtils.subarray(byteArray, 4 + length, byteArray.length);
File resultPcmFile = new File(dic, new File(pcmFile).getName().replace(".pcm", "_result.pcm"));
if (!resultPcmFile.exists()) {
try {
resultPcmFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
FileOutputStream outputStream = new FileOutputStream(resultPcmFile, true);
IOUtils.write(subarray, outputStream);
IOUtils.closeQuietly(outputStream);
if ((int) jsonObject.get("errcode") == 0) {
if (jsonObject.getBoolean("lastpkg")) {
System.out.println("session end ");
System.out.println(sdf.format(startTime) + "开始");
System.out.println(sdf.format(timeEnd.get()) + "结束");
System.out.println("耗时:" + (timeEnd.get().getTime() - startTime.getTime()) + "ms");
System.out.println("本次识别traceId ==》" + jsonObject.getString("traceid"));
webSocket.close(1000, "");
}
} else {
System.out.println("errCode=>" + jsonObject.getInteger("errcode") + " errMsg=>" + jsonObject.getString("errmsg") + " traceId=" + jsonObject.getString("traceid"));
webSocket.close(1000, "");
System.out.println("发生错误,关闭连接");
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
super.onFailure(webSocket, t, response);
try {
if (null != response) {
int code = response.code();
System.out.println("onFailure code:" + code);
System.out.println("onFailure body:" + response.body().string());
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient.Builder().build();
Request request = new Request.Builder().url(hostUrl).build();
client.newWebSocket(request, new VcWebSocketDemo());
}
public static String getAccessToken() {
String accessToken = "";
OkHttpClient client = new OkHttpClient();
String url = String.format(tokenUrl, clientSecret, clientId);
Request request = new Request.Builder().url(url).build();
JSONObject jsonObject;
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
String resultJson = response.body().string();
jsonObject = JSON.parseObject(resultJson);
accessToken = jsonObject.getString("access_token");
}
} catch (Exception e) {
e.printStackTrace();
}
return accessToken;
}
}
|