Unity3d C#实现语音合成试听并选择路径保存下载功能(含源码)

Unity3d C#实现语音合成试听并选择路径保存下载功能(含源码)

前言

计划实现语音的合成功能,将文字转语音,支持试听和保存功能,经过一段时间的研究,发现搜狗可以使用,用100–200万字的免费额度:
Unity3d C#实现语音合成试听并选择路径保存下载功能(含源码)

决定就对接搜狗接口完成这些功能。

效果:
Unity3d C#实现语音合成试听并选择路径保存下载功能(含源码)

准备工作

可以直接参考官方指南:https://ai.sogou.com/doc/?url=/docs/content/overview/guides/

注册账号

前往搜狗开发平台(https://ai.sogou.com/)自行操作,操作完成登录后,有个控制台按钮点击进入:
Unity3d C#实现语音合成试听并选择路径保存下载功能(含源码)

下载LitJson

这个网上有很多,主要用于传参和数据解析,自行下载吧。

##获取appid和key
操作步骤:
新建应用 > 填写名称>填写描述>勾选语音合成>勾选同意协议> 创建应用
Unity3d C#实现语音合成试听并选择路径保存下载功能(含源码)

这样就获得了appid和key,复制了备用。

实现功能

在上一步中我们获得了“appid” 和“appkey”,在脚本初始化的时候,将它记录下来:

    /*----------------------------------------||
    ||                                        ||
    ||       此处填写 appid appkey             ||  
    ||                                        || 
    ||----------------------------------------*/
    string appid = "";
    string appkey = "";

这一步请自行申请填入。

认证与鉴权

这个过程就是获取令牌的过程,代码如下:

 void GetToken() {
        string url = "https://api.zhiyin.sogou.com/apis/auth/v1/create_token";
        JsonData ReqParam = new JsonData();
        ReqParam["appid"] = appid;
        ReqParam["appkey"] = appkey;
        ReqParam["exp"] = "3600s";
        byte[] postBytes = System.Text.Encoding.Default.GetBytes(ReqParam.ToJson());
        StartCoroutine(DoPost(url, postBytes, GetTokenDone));
    }


    void GetTokenDone(string str)
    {
        try
        {
            JsonData data = JsonMapper.ToObject(str);
            token = data["token"].ToString();
            endDate =DateTime.Parse(data["end_time"].ToString());
            TTS();
            Debug.Log("Get Token:" + token);
        }
        catch (Exception e)
        {
            Debug.LogWarning("GetToken调用异常:" + e);;
        }
    }

在获取到令牌后,将其记录,还有个是有效时间(endDate),在超过有效时间后,需要重新获取令牌。

语音合成

根据选择的声音,调用语音合成接口,将输入的文字和转化的声音以及其它参数传入,即完成了语音合成的请求。

如下是根据官网给的音色列表以及每种音色所支持的语言预定义的参数,用于展示声音选项和传递的参数:

 List<string> titles = new List<string> 
    { 
        "康哥(中)", "晶晶(中)", "阿华(中)", "婉清(中)",
        "夕月(中)" , "阿星(中)", "青峰(中)", "若曦(中)", 
        "梦暄(中)", "思思(中)", "帅帅(中)", "宝哥(中)", 
        "婉贞(中)", "小玉(中)", "文雅(中)", "翠萍(中)",
        "强仔(中)", "宛如(中)", "小赵(中)", "燕燕(中)", 
        "小智(中)", "婉婷(中)", "瑶瑶(中)","男声(英)", 
        "女声(中英日韩)", "杰克(英)", "丽莉(英)"
    };
    List<string> Values = new List<string>
    {
        "kangge", "jingjing", "ahua", "wanqing",
        "xiyue" , "axing", "qingfeng", "xf5",
        "mengxuan", "sisi", "shuaishuai", "shanxi_male",
        "sichuan_female", "henan_female", "hubei_female", "dongbei_female",
        "guangpu_male", "taipu_female", "zhao", "yanyan",
        "xiaozhi", "wanting", "yaoyao","male",
        "female", "jack", "lily"
    };

核心的请求代码:

    void TTS() {
        if (string.IsNullOrEmpty(Ipt.text)) 
        {
            Debug.LogError("输入内容不能为空!");
            return; 
        }
        string url = "https://api.zhiyin.sogou.com/apis/tts/v1/synthesize";
        JsonData ReqParam = new JsonData();
        ReqParam["input"] = new JsonData();
        ReqParam["input"]["text"] = Ipt.text;
        ReqParam["config"] = new JsonData();
        ReqParam["config"]["audio_config"] = new JsonData();
        ReqParam["config"]["voice_config"] = new JsonData();
        ReqParam["config"]["audio_config"]["audio_encoding"] = "MP3";
        ReqParam["config"]["audio_config"]["pitch"] = 1;
        ReqParam["config"]["audio_config"]["volume"] = 1;
        ReqParam["config"]["audio_config"]["speaking_rate"] = 1;
        ReqParam["config"]["voice_config"]["language_code"] = "zh-cmn-Hans-CN";
        ReqParam["config"]["voice_config"]["speaker"] = Values[VoiceSel.value]+ "-pro";//"male";
        byte[] postBytes = System.Text.Encoding.Default.GetBytes(ReqParam.ToJson());
        StartCoroutine(DoTTSPost(url, postBytes, TTSDone));
    }

    void TTSDone(byte[] bytes) {
        try
        {
            //Debug.Log("返回音频:" + str);
            VoiceBytes = bytes;
            //ac.clip = GetAudioClipByBytes(bytes);
            File.WriteAllBytes(VoiceUrl, bytes);
            StartCoroutine(DoVioceClip());
            OptBtns.SetActive(true);
        }
        catch (Exception e)
        {
            Debug.LogWarning("GetToken调用异常:" + e); ;
        }
    }

官方推荐是声音参数增加"-pro",欢迎用户使用新版音色代码(增加-pro),新版音色大幅提升音效质量和自然度。同时,原音色代码(未加-pro)仍可使用。

选择路劲保存

大致思路就是根据选择的路劲写入字节数组:

 File.WriteAllBytes(path, VoiceBytes);

可以参照之前的文章:选择路径保存功能

试听功能

这个在做研究的时候也写过一个文章:
Unity3d C# 实现mp3的字节数组byte[] 转AudioClip并播放(含源码)

项目源码

https://download.csdn.net/download/qq_33789001/18239880

上一篇:python文档1-unittest单元测试之mock


下一篇:【POJ】1284 Primitive Roots