Unity 讯飞实时语音转写(三)—— 分析转写结果

目录

Unity 讯飞实时语音转写(一)—— 使用WebSocket连接讯飞语音服务器
Unity 讯飞实时语音转写(二)—— 接收转写结果
Unity 讯飞实时语音转写(三)—— 分析转写结果
(应该没有后续了)

说在前面
这段时间一直在忙其他事情,所以语音识别的工作暂时交接到了同事手中,今天同事将后边的工作完成了,我就把源代码要了过来,也在此做一下记录。

分析结果如下:

Unity 讯飞实时语音转写(三)—— 分析转写结果_第1张图片上面是原文,下面是解析语音后的结果。

Unity 讯飞实时语音转写(三)—— 分析转写结果_第2张图片这个是加上了热词高亮的样子

正文

一、连接字符串
在上一篇文中说到,我们已经可以得到讯飞返回给我们的转写结果,只不过是某种格式的json字符串,可读性差,那么就需要我们将该json字符串中有用的字段提取出来。

    /// 
    /// 获取识别并返回字符串
    /// 
    /// 所获取的识别的Json字符串
    /// 所识别的连贯的一句话
    void AnalysisResult(string data)
    {
        Data result = JsonUtility.FromJson<Data>(data); // 等效于 JsonConvert.DeserializeObject(data)
        StringBuilder stringBuilder = new StringBuilder();

        //Debug.Log(result.cn.st.rt[0].ws.Length);
        for (int i = 0; i < result.cn.st.rt[0].ws.Length; i++)
        {
            //******只有w字段有用,将其提取出来即可******
            stringBuilder.Append(result.cn.st.rt[0].ws[i].cw[0].w);
        }

        string _thisType = result.cn.st.type;
        string testing = stringBuilder.ToString();

        //Debug.Log(stringBuilder + "***" + _thisType);
        //type	结果类型标识	0-最终结(即这句话说完了);1-中间结果(即这句话没说完,下一句转写结果可能推翻前面的内容)
        if (_thisType.Equals("0"))
        {
            endText = endText + testing;
            _text.text = endText;
        }
        else
        {
            _text.text = endText + testing;
        }
    }

这样我们就能得到一段连续的,可读性非常好的一句话。

二、个性化热词
下一步我们想要能够在转写的结果中找到一些热词,这些热词可以是当前流行的,或是某个行业的(金融、游戏等等),也可以是我们自定义的一些热词。
那如何设置自定义热词呢,讯飞官方已经给我们提供了一些接口。
打开讯飞开放平台,以此找到:语音识别-实时语音转写-个性化热词,然后按照要求填写热词,然后保存热词即可。
官方要求:
热词配置格式:每行一句热词(2000行以内,每行不多于10个字),以回车键隔开。
热词内容要求:限UTF-8 编码中文字符,不能有数字和字母。

需要注意的是中英文都是各占一个字符,比如hologarment是11个字符,就不能作为热词,可以拆分成holo,garment两个关键词。
Unity 讯飞实时语音转写(三)—— 分析转写结果_第3张图片

三、热词筛选
有了热词后,接下来就是如何在程序中识别热词,并高亮显示热词。

  1. 首先在工程中新建一个txt文档,然后将网站上的热词保存进去。之后让Unity以文本资源的形式读取成字符串。
    void Start()
    {
        path = Application.streamingAssetsPath + "/hologarment.txt";
        ReadText();
    }
  1. 然后按行读取文本,并存储到一个字符串中
    public void ReadText()
    {
        string line;
        using (StreamReader stream = new StreamReader(path))
        {
            while ((line=stream.ReadLine())!=null)
            {
                //Debug.Log(line);

                keyWord.Add(line.Trim());//keyWord就是热词的集合
                readText.text = readText.text + "\n" + line;
            }
        }
    }
  1. 识别热词算法如下:
/// 
    /// 关键词标识
    /// 
    /// 待处理文本
    /// 关键字集合
    /// 关键词前加入string
    /// 关键词后加入
    /// 
   
    public string SclectKeyWord(string content,List<string> keyWord,string befordLabel, string afterLabel)
    {
        char[] charArr = content.ToCharArray();
       
        List<string> keyArr = keyWord;
        List<char> listArr = new List<char>();
        int matchCount = 0;
        string buffWord = "";
        for (int i = 0; i < charArr.Length; i++)
        {
            matchCount = keyArr.Where(r => r.StartsWith(buffWord + charArr[i].ToString())).Count();

            if (matchCount == 0)
            {
                if (buffWord.Length > 0)
                {
                    if (keyArr.Contains(buffWord))
                    {
                        listArr.AddRange((befordLabel + buffWord + afterLabel).ToCharArray());
                    }
                    else
                    {
                        listArr.AddRange(buffWord.ToCharArray());
                    }
                    buffWord = "";
                    matchCount = keyArr.Where(r => r.StartsWith(buffWord + charArr[i].ToString())).Count();
                    if (matchCount > 0)
                    {
                        buffWord += charArr[i];
                    }
                    else
                    {
                        listArr.Add(charArr[i]);
                    }

                }
                else
                {
                    listArr.Add(charArr[i]);
                }
            }
            else
            {
                if (matchCount == 1)
                {
                    if (keyArr.Contains(buffWord + charArr[i]))
                    {
                        listArr.AddRange((befordLabel + buffWord + charArr[i] + afterLabel).ToCharArray());
                        buffWord = "";
                    }
                    else
                    {
                        buffWord += charArr[i];
                    }
                }
                else
                {
                    buffWord += charArr[i];
                }
            }

            //收尾判断
            if (i == charArr.Length - 1)
            {
                if (keyArr.Contains(buffWord))
                {
                    listArr.AddRange((befordLabel + buffWord + afterLabel).ToCharArray());
                }
                else
                {
                    listArr.AddRange(buffWord.ToCharArray());
                }
            }

        }

        return string.Join("", listArr);
    }
  1. 使用Unity的富文本红色高亮显示热词
    public string SetKeyWordColor(string contont)
    {
        
        string resutl= SclectKeyWord(contont, keyWord, "", "");

        return resutl;
    }

至此,功能暂时告一段落。
这是我们老板的一段演讲词,我们以这段话为例
Unity 讯飞实时语音转写(三)—— 分析转写结果_第4张图片
可能有小伙伴发现并非所有的热词都被识别出来了,表明热词识别算法有待优化,以后有时间再搞吧。。。

三、示例工程
考虑了一下,还是附上完整的工程文件吧,希望可以帮助正在测试该功能的小伙伴们。加油哦!
如何测试

  1. 下载后解压工程,Unity打开工程(我使用的是Unity 2019.4.9f1,需要Crack的同学可以看下我这篇文章)
  2. 找到脚本VisualCommunication.cs,在166,167行修改appid,appkey为你自己项目的对应值
  3. 启动工程,点击“开始转写”,然后对着麦克风说话;说完后点击“结束转写”,或者直接关闭程序都行,讯飞官方会在15s内没有接到转写请求时,自动关闭WebSocket连接,不用担心时长被意外耗尽

转载注明出处!!!

你可能感兴趣的:(Unity3D,笔记)