前言
本篇文章演示在unity引擎中接入百度语音识别API(适用于Windows平台,其它平台的后续更新)
需要的准备
(1)百度智能云账号
(2)百度智能云产品服务-语音技术-领取免费资源-创建应用
(3)创建Unity工程-UI面板制作
(4)调用百度语音识别
具体步骤
(1)注册好百度智能云账号之后就可以开始制作一个语音识别的程序。
(2)领取免费资源以及创建应用
可调用的接口功能都在此页面中
创建应用
(3)创建Unity工程,制作UI面板
这一步操作很简单,只需要一个Text文本框和两个按钮就OK了
(4)调用百度语音
现在就可以开始写脚本去调用百度语音识别了,可以分为两步:
①Access Token的获取
获取的详解可以查看鉴权认证机制
编写获取Access Token的代码:
/// <summary>
/// 获取accessToken请求令牌
/// </summary>
/// <returns></returns>
IEnumerator _GetAccessToken()
{
var uri =
string.Format(
"https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id={0}&client_secret={1}",
api_key, secret_Key);
UnityWebRequest unityWebRequest = UnityWebRequest.Get(uri);
yield return unityWebRequest.SendWebRequest();
if (unityWebRequest.isDone)
{
Match match = Regex.Match(unityWebRequest.downloadHandler.text, @"access_token.:.(.*?).,");
if (match.Success)
{
Debug.Log("Token已经匹配");
accessToken = match.Groups[1].ToString();
}
else
{
Debug.Log("验证错误,获取AccessToken失败!!!");
}
}
}
②进行语音识别,获取返回数据并显示
/// <summary>
/// 请求语音识别
/// </summary>
/// <returns></returns>
IEnumerator RequestASR()
{
if (string.IsNullOrEmpty(accessToken))
{
yield return _GetAccessToken();
}
resulrStr = string.Empty;
//处理当前录音数据为PCM16
float[] samples = new float[recordFrequency *10* saveAudioClip.channels];
saveAudioClip.GetData(samples, 0);
var samplesShort = new short[samples.Length];
for (var index = 0; index < samples.Length; index++)
{
samplesShort[index] = (short)(samples[index] * short.MaxValue);
}
byte[] datas = new byte[samplesShort.Length * 2];
Buffer.BlockCopy(samplesShort, 0, datas, 0, datas.Length);
string url = string.Format("{0}?cuid={1}&token={2}", "https://vop.baidu.com/server_api", SystemInfo.deviceUniqueIdentifier, accessToken);
WWWForm wwwForm = new WWWForm();
wwwForm.AddBinaryData("audio", datas);
UnityWebRequest unityWebRequest = UnityWebRequest.Post(url, wwwForm);
unityWebRequest.SetRequestHeader("Content-Type", "audio/pcm;rate=" + recordFrequency);
yield return unityWebRequest.SendWebRequest();
if (string.IsNullOrEmpty(unityWebRequest.error))
{
resulrStr = unityWebRequest.downloadHandler.text;
if (Regex.IsMatch(resulrStr, @"err_msg.:.success"))
{
Match match = Regex.Match(resulrStr, "result.:..(.*?)..]");
if (match.Success)
{
resulrStr = match.Groups[1].ToString();
}
}
else
{
resulrStr = "识别结果为空";
}
resultText.text = resulrStr;
}
}
全篇代码如下:
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System;
public class SpeechScript : MonoBehaviour
{
//自行填写自己的百度语音识别相关key
public string api_key;
public string secret_Key;
string accessToken = string.Empty;
bool ishaveMic=false; //检测是否连接麦克风
string currentDeviceName = string.Empty; //当前录音设备名称
int recordFrequency = 8000; //录音频率
int recordMaxTime=20;//最大录音时长
AudioClip saveAudioClip;//存储当前录音的片段
AudioSource source;
string resulrStr;//存储识别结果
Text resultText;//显示识别结果
Button startBtn;//开始识别按钮
Button endBtn;//结束识别按钮
void Start()
{
//saveAudioClip = this.transform.GetComponent<AudioClip>();
source = this.transform.GetComponent<AudioSource>();
resultText = GameObject.Find("Canvas/panel/speech").GetComponent<Text>();
startBtn = GameObject.Find("Canvas/Start").GetComponent<Button>();
endBtn = GameObject.Find("Canvas/End").GetComponent<Button>();
StartCoroutine(_GetAccessToken());//获取accessToken
startBtn.onClick.AddListener(StartRecord);
endBtn.onClick.AddListener(EndRecord);
}
/// <summary>
/// 开始录音
/// </summary>
void StartRecord()
{
saveAudioClip = Microphone.Start(currentDeviceName,false,recordMaxTime,recordFrequency);
}
/// <summary>
/// 结束录音
/// </summary>
void EndRecord()
{
Microphone.End(currentDeviceName);
source.PlayOneShot(saveAudioClip);
StartCoroutine(RequestASR());//请求语音识别
}
/// <summary>
/// 请求语音识别
/// </summary>
/// <returns></returns>
IEnumerator RequestASR()
{
if (string.IsNullOrEmpty(accessToken))
{
yield return _GetAccessToken();
}
resulrStr = string.Empty;
//处理当前录音数据为PCM16
float[] samples = new float[recordFrequency *10* saveAudioClip.channels];
saveAudioClip.GetData(samples, 0);
var samplesShort = new short[samples.Length];
for (var index = 0; index < samples.Length; index++)
{
samplesShort[index] = (short)(samples[index] * short.MaxValue);
}
byte[] datas = new byte[samplesShort.Length * 2];
Buffer.BlockCopy(samplesShort, 0, datas, 0, datas.Length);
string url = string.Format("{0}?cuid={1}&token={2}", "https://vop.baidu.com/server_api", SystemInfo.deviceUniqueIdentifier, accessToken);
WWWForm wwwForm = new WWWForm();
wwwForm.AddBinaryData("audio", datas);
UnityWebRequest unityWebRequest = UnityWebRequest.Post(url, wwwForm);
unityWebRequest.SetRequestHeader("Content-Type", "audio/pcm;rate=" + recordFrequency);
yield return unityWebRequest.SendWebRequest();
if (string.IsNullOrEmpty(unityWebRequest.error))
{
resulrStr = unityWebRequest.downloadHandler.text;
if (Regex.IsMatch(resulrStr, @"err_msg.:.success"))
{
Match match = Regex.Match(resulrStr, "result.:..(.*?)..]");
if (match.Success)
{
resulrStr = match.Groups[1].ToString();
}
}
else
{
resulrStr = "识别结果为空";
}
resultText.text = resulrStr;
}
}
/// <summary>
/// 获取accessToken请求令牌
/// </summary>
/// <returns></returns>
IEnumerator _GetAccessToken()
{
var uri =
string.Format(
"https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id={0}&client_secret={1}",
api_key, secret_Key);
UnityWebRequest unityWebRequest = UnityWebRequest.Get(uri);
yield return unityWebRequest.SendWebRequest();
if (unityWebRequest.isDone)
{
Match match = Regex.Match(unityWebRequest.downloadHandler.text, @"access_token.:.(.*?).,");
if (match.Success)
{
Debug.Log("Token已经匹配");
accessToken = match.Groups[1].ToString();
}
else
{
Debug.Log("验证错误,获取AccessToken失败!!!");
}
}
}
}
演示效果: