首页 > 其他分享 >【专栏精选】实战:百度语音合成

【专栏精选】实战:百度语音合成

时间:2023-04-28 16:37:14浏览次数:50  
标签:www REST 专栏 param 语音 var public 百度


本文节选自洪流学堂公众号技术专栏《大话Unity2019》,未经允许不可转载。

洪流学堂公众号回复语音识别获取源码工程。


洪流学堂,让你快人几步。你好,我是郑洪智。

大智:“昨天我们实战了语音识别,在人工智能的语音领域,还有很大一块是语音合成,也就是Text to Speech,文字转语音。”
小新:“是不是就是我们经常听到的siri或者智能音箱那种声音?”
大智:“没错,那些声音都是用语音合成的技术合成音频文件,然后播放出来的。”
小新:“我们今天就来搞这个?”
大智:“对,这就开始”

HTTP实战:百度语音合成

首先做些准备工作,和昨天的语音识别的流程很像,大致如下:

  1. http://ai.baidu.com/,首先你需要一个百度账号
  2. 登陆进去以后,在https://console.bce.baidu.com/页面左侧点击百度语音。
  1. 创建一个新应用,不需要设置语音包名,因为我们要使用HTTP接口,而不是用SDK。
  1. 在应用详情中可以看到API Key和Secret Key,一会需要用到。
  1. 阅读文档!阅读文档!阅读文档!
    语音合成:https://ai.baidu.com/docs#/TTS-API/top

语音识别

大智:“看完文档了没?”
小新:“看完了”
大智:“那我们就开始了。”

语音合成主要有两个过程:

  1. 鉴权认证:从百度获取一个令牌(token),请求的时候需要携带这个令牌,否则视为非法请求
  2. 在Unity中请求语音合成接口

第一步鉴权认证我们昨天已经实现了,可以拿来直接用。我们直接进入第二步,在Unity中请求语音合成接口。

REST API

小新:“我在文档中看到了这个词REST API,API我懂,就是应用程序接口嘛,这个REST是什么?休息接口么?”
大智:“哎嘿,什么休息接口!这个是Web开发中的一个技术,你不懂正常,我来简单解释一下。”

REST ( REpresentational State Transfer ),State Transfer 为 “状态传输” 或 "状态转移 “,Representational 中文有人翻译为"表征”、“具象”,合起来就是 “表征状态传输” 或 “具象状态传输” 或 “表述性状态转移”,不过,一般文章或技术文件都比较不会使用翻译后的中文来撰写,而是直接引用 REST 或 RESTful 来代表,因为 REST 一整个观念,想要只用六个中文字来完整表达真有难度。

REST 本身是设计风格而不是标准。REST 谈论一件非常重要的事,如何正确地使用 Web****标准,例如,HTTP 和 URI。想要了解 REST 最好的方式就是思索与了解Web及其工作方式。如果你设计的应用程序能符合 REST 原则 (REST principles),这些符合 REST 原则的 REST 服务可称为 “RESTful web service” 也称 “RESTful Web API”。"-ful" 字尾强调它们的设计完全符合 REST 论文里的建议内容。

如果你不需要做Web开发,了解到这就够了,否则建议你了解下REST的具体原则,RESTful的Web接口目前非常流程。

请求语音合成

百度语音合成支持两种方式请求:

  • POST方式
  • GET方式

百度文档中推荐使用POST方式,但是由于Unity的WebRequest类中,获取音频的现成接口是使用Get方法,所以我们下面的代码还是使用Get方法去获取。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;

public class BaiduTts : MonoBehaviour
{
    public string APIKey;
    public string SecretKey;
    public string Text = "洪流学堂,让你快人几步";
    private string Token;

    public AudioSource AudioSource { get; private set; }

    // 用于解析返回的json
    [Serializable]
    class TokenResponse
    {
        public string access_token = null;
    }

    /// <summary>
    ///     语音合成结果
    /// </summary>
    [Serializable]
    public class TtsResponse
    {
        public int err_no;
        public string err_msg;
        public string sn;
        public int idx;

        public bool Success
        {
            get { return err_no == 0; }
        }

        public AudioClip clip;
    }

    IEnumerator Start()
    {
        // 拼接请求的URL
        var uri = $"https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id={APIKey}&client_secret={SecretKey}";
        var www = UnityWebRequest.Get(uri);
        yield return www.SendWebRequest();

        if (www.isHttpError || www.isNetworkError)
        {
            Debug.LogError("[BaiduAip]" + www.error);
            Debug.LogError("[BaiduAip]Token was fetched failed. Please check your APIKey and SecretKey");
        }
        else
        {
            Debug.Log("[BaiduAip]" + www.downloadHandler.text);
            var result = JsonUtility.FromJson<TokenResponse>(www.downloadHandler.text);
            Token = result.access_token;
            Debug.Log("[WitBaiduAip]Token has been fetched successfully");
        }


        AudioSource = gameObject.AddComponent<AudioSource>();
    }

    void Update()
    {
        if (Input.GetKeyUp(KeyCode.A))
        {
            Debug.Log("[WitBaiduAip demo]开始合成");
            StartCoroutine(Tts(Text, s =>
            {
                AudioSource.clip = s.clip;
                AudioSource.Play();
            }));
        }
    }

    public IEnumerator Tts(string text, Action<TtsResponse> callback)
    {
        var url = "http://tsn.baidu.com/text2audio";

        var param = new Dictionary<string, string>();
        param.Add("tex", text);
        param.Add("tok", Token);
        param.Add("cuid", SystemInfo.deviceUniqueIdentifier);
        param.Add("ctp", "1");
        param.Add("lan", "zh");
        param.Add("spd", "5");
        param.Add("pit", "5");
        param.Add("vol", "10");
        param.Add("per", "1");
#if UNITY_STANDALONE || UNITY_EDITOR || UNITY_UWP
        param.Add("aue", "6"); //设置为wav格式,移动端需要mp3格式
#endif

        int i = 0;
        foreach (var p in param)
        {
            url += i != 0 ? "&" : "?";
            url += p.Key + "=" + p.Value;
            i++;
        }

        // 根据不同平台,获取不同类型的音频格式
#if UNITY_STANDALONE || UNITY_EDITOR || UNITY_UWP
        var www = UnityWebRequestMultimedia.GetAudioClip(url, AudioType.WAV);
#else
        var www = UnityWebRequestMultimedia.GetAudioClip(url, AudioType.MPEG);
#endif
        Debug.Log("[WitBaiduAip]" + www.url);
        yield return www.SendWebRequest();

        if (www.isHttpError || www.isNetworkError)
            Debug.LogError(www.error);
        else
        {
            var type = www.GetResponseHeader("Content-Type");
            Debug.Log("[WitBaiduAip]response type: " + type);

            if (type.Contains("audio"))
            {
                var response = new TtsResponse { clip = DownloadHandlerAudioClip.GetContent(www) };
                callback(response);
            }
            else
            {
                var textBytes = www.downloadHandler.data;
                var errorText = Encoding.UTF8.GetString(textBytes);
                Debug.LogError("[WitBaiduAip]" + errorText);
                callback(JsonUtility.FromJson<TtsResponse>(errorText));
            }
        }
    }
}

上面的代码写好以后,设置好APIKey和SecretKey就可以合成语音出来了。

总结

大智:“我们这两天通过实战学习了UnityWebRequest的具体用法,在请求Http时,结合接口说明,一般实现起来还是很容易的。

思考题

大智:“上面的语音合成中很有多参数可以设置,试试不同的参数看看有什么效果吧!”
小新:“好嘞!”
大智:“收获别忘了分享出来!也别忘了分享给你学Unity的朋友,也许能够帮到他。”


洪流学堂公众号回复语音识别获取源码工程。

《大话Unity2019》,大智带小新学Unity2019的有趣经历,让你学Unity更简单。


标签:www,REST,专栏,param,语音,var,public,百度
From: https://blog.51cto.com/u_5746184/6234789

相关文章

  • 【专栏精选】热更新之xLua
    本文节选自洪流学堂公众号技术专栏《大话Unity2019》,未经允许不可转载。洪流学堂公众号回复专栏,查看更多专栏文章。洪流学堂,让你快人几步。你好,我是郑洪智。小新:“之前你提到过,Unity热更新有两大流派,C#派和lua派,那lua派是啥样的呢?”大智:“lua是一门历史悠久的脚本语言,从端游那个年......
  • 【专栏精选】Unity热更新之ILRuntime
    本文节选自洪流学堂公众号技术专栏《大话Unity2019》,未经允许不可转载。洪流学堂公众号回复专栏,查看更多专栏文章。洪流学堂,让你快人几步。你好,我是郑洪智。小新:“热更新真的是打开了一片天啊,现在我越发感觉热更新能做的事情太多了。之前做了一个项目,每次打包都好花费半小时,如果有......
  • 【专栏精选】Unity中的HTTP网络通信
    本文节选自洪流学堂公众号技术专栏《大话Unity2019》,未经允许不可转载。洪流学堂公众号回复专栏,查看更多专栏文章。洪流学堂,让你快人几步。你好,我是郑洪智。大智:“小新,今天开始,我们来学习Unity中的HTTP通信。”小新:“为啥不先学Tcp和Udp呢?这俩不是基础么?”大智:“虽然这俩是基础,但......
  • 【专栏精选】实战:百度语音识别
    本文节选自洪流学堂公众号技术专栏《大话Unity2019》,未经允许不可转载。洪流学堂公众号回复语音识别获取源码工程。洪流学堂,让你快人几步。你好,我是郑洪智。大智:“今天给你来点刺激的。”小新满面红光:“啥刺激的?人家可还是个小孩子。”大智:“带你实战!”小新:“啊?智哥你变了!”大......
  • 微信QQ_语音提取
    测试2023年-02-22日可行准备工作获取手机本地语音文件夹参考https://www.qinyuanyang.com/post/296.html?app=ARMtoMP3在这里插入代码片服务器准备工作sudosumkdir/opt/ffmpegyum-yinstallbzip2下载、安装lame#cd/opt/ffmpeg#wgethttp://downloads.sourceforge.ne......
  • 视觉定位领域专栏(一)领域介绍、应用场景和研究难点
    前言 上一篇介绍了什么是视觉定位,以及视觉定位在各行各业的应用点和目前的研究难点在哪。本篇主要介绍视觉定位领域常用的一些数据集,分为室内定位数据集和室外定位数据集,每个数据集附有数据集获取地址和数据集样例。本教程禁止转载。同时,本教程来自知识星球【CV技术指南】更多技......
  • 语音处理加窗分帧
    语音处理加窗分帧一、分帧语音数据和视频数据不同,本没有帧的概念,但是为了传输与存储,我们采集的音频数据都是一段一段的。为了程序能够进行批量处理,会根据指定的长度(时间段或者采样数)进行分段,结构化为我们编程的数据结构,这就是分帧。二、帧移由于我们常用的信号处理方法都要......
  • 视觉定位领域专栏(一)领域介绍、应用场景和研究难点
    前言 本篇主要介绍三个方面,即视觉定位领域介绍、应用场景以及研究难点,同时会对专栏后续讲解内容做一个概述。本教程禁止转载。同时,本教程来自知识星球【CV技术指南】更多技术教程,可加入星球学习。欢迎关注公众号CV技术指南,专注于计算机视觉的技术总结、最新技术跟踪、经典论文......
  • 百度飞桨(PaddlePaddle)-数字识别
    手写数字识别任务用于对0~9的十类数字进行分类,即输入手写数字的图片,可识别出这个图片中的数字。使用pip工具安装matplotlib和numpypython-mpipinstallmatplotlibnumpy-ihttps://mirror.baidu.com/pypi/simpleD:\OpenSource\PaddlePaddle>python-mpipinstal......
  • 除螨仪语音方案芯片推荐:NV040D 家用8脚语音ic
    随着时代的发展,大家对于健康的重视程度越来越高,而螨虫这类生物对于特殊群体来说,可能会带来皮肤问题,甚至引发呼吸道疾病,困扰生活,由此,清除床上的螨虫就成为了一个较为刚性的需求。除螨仪也就随之被发明,通过拍打、紫外线照射、吸尘和一定温度实现除螨操作,保持床铺清洁。 NV040D除......