相信各位同学在制作项目的过程中,或多或少都会有播放语音提示的功能,除了在线语音合成和和网上下载的语音合成软件进行语音合成以外,我们也可以自己选择接入sdk合成语音,为了方便大家入门和学习,推荐使用有道语音合成,简单并且方便上手,在注册后会送新人一定的体验金,学习语音识别或其他语音识别绰绰有余,这里直接进入主题。
一、注册账号
官网注册账号:https://ai.youdao.com/
二、创建应用
这里其实和咱们接入AR流程差不多,我们新建一个应用的目的就是使我们作为用户拥有接入sdk的权限,通过应用ID和应用密钥来识别到开发者用户。
可查看应用ID和应用密钥,后面在传入参数时需要。
三、WebAPI文档
通过以下链接可直接查看WebAPI接入文档。
https://ai.youdao.com/DOCSIRMA/html/语音合成TTS/API文档/语音合成服务/语音合成服务-API文档.html
我们使用WebAPI进行语音合成的流程其实非常简单,通过http协议的Post请求发送接口需要的参数,而后返回我们所需要的语音文件流二进制,保存到本地,以上三个步骤为有道语音合成WebAPI的三个流程,这里就不带各位同学看接入文档了,没有http协议与MD5加密经验的同学可翻看本人博客,针对http协议与MD5加密有具体的描述。
四、使用Unity与WebAPI文档结合制作语音合成案例
1、新建Unity项目
2、编写YouDaoTTS脚本与代码
直接上代码:
using System;
using System.IO;
using System.Text;
using System.Collections.Generic;
using System.Security.Cryptography;
using UnityEngine;
using System.Net;
public class YouDaoTTS : MonoBehaviour
{
private void Start()
{
string url = "https://openapi.youdao.com/ttsapi";
string q = "这是我的第一条语音合成";
string appKey = "你的应用ID";
string appSecret = "你的应用密钥";
string salt = DateTime.Now.Millisecond.ToString();
string langType = "zh-CHS";
string signStr = appKey + q + salt + appSecret; ;
string sign = EncryptMD5_32(signStr);
//初始化必传参数字典
Dictionary<string, string> dic = new Dictionary<string, string>()
{
{ "q",System.Web.HttpUtility.UrlEncode(q) },
{ "langType",langType },
{ "appKey", appKey },
{ "salt", salt },
{ "sign", sign }
};
byte[] audioDatas = HttpPostBytes(url, dic);
string filePath = Application.dataPath + "/FirstAudio.mp3";
SaveAudioData(audioDatas, filePath);
}
/// <summary>
/// MD5 32位加密
/// </summary>
/// <param name="_encryptContent">需要加密的内容</param>
/// <returns></returns>
private string EncryptMD5_32(string _encryptContent)
{
string content_Normal = _encryptContent;
string content_Encrypt = "";
MD5 md5 = MD5.Create();
byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(content_Normal));
for (int i = 0; i < s.Length; i++)
{
content_Encrypt = content_Encrypt + s[i].ToString("X2");
}
return content_Encrypt;
}
/// <summary>
/// HttpWebRequest Post请求 发送数据 返回byte数组
/// </summary>
/// <param name="_url">请求地址</param>
/// <param name="_dic">表单对应字典 键值对</param>
/// <returns></returns>
public byte[] HttpPostBytes(string _url, Dictionary<string, string> _dic)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
//参数拼接
StringBuilder builder = new StringBuilder();
int i = 0;
foreach (var item in _dic)
{
if (i > 0) { builder.Append("&"); }
builder.AppendFormat("{0}={1}", item.Key, item.Value);
i++;
}
//转化为byte[] 并 设置request 内容长度
byte[] data = Encoding.UTF8.GetBytes(builder.ToString());
request.ContentLength = data.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();
HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(webResponse.GetResponseStream());
//获取字节流
MemoryStream memoryStream = new MemoryStream();
reader.BaseStream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
/// <summary>
/// 保存语音数据
/// </summary>
/// <param name="data"></param>
/// <param name="filePath"></param>
private void SaveAudioData(byte[] data, string filePath)
{
byte[] buffer = new byte[1024];
if (File.Exists(filePath)) { File.Delete(filePath); }
Stream outStream = File.Create(filePath);
Stream inStream = new MemoryStream(data);
int dataCount;
do
{
dataCount = inStream.Read(buffer, 0, buffer.Length);
if (dataCount > 0)
{
outStream.Write(buffer, 0, dataCount);
}
}
while (dataCount > 0);
outStream.Close();
inStream.Close();
//刷新
UnityEditor.AssetDatabase.Refresh();
}
}
3、运行结果
这里为了方便测试,直接将脚本挂载至相机上
最终运行后,会在Assets根目录生成一段FirstAudio.mp3文件,各位同学可以打开mp3文件,发现可以正常播放,我们传进去的
q字段,最终合成了语音。
emm,女声声音还是怪好听的。