Unity 实战项目 ☀️| Unity接入 百度语音识别 SDK!一篇文章搞定在Unity中实现语音识别!(万字完整教程)

Posted 呆呆敲代码的小Y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity 实战项目 ☀️| Unity接入 百度语音识别 SDK!一篇文章搞定在Unity中实现语音识别!(万字完整教程)相关的知识,希望对你有一定的参考价值。

  • 📢博客主页:https://blog.csdn.net/zhangay1998
  • 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
  • 📢本文由 呆呆敲代码的小Y 原创,首发于 CSDN🙉
  • 📢未来很长,值得我们全力奔赴更美好的生活✨


📢前言

  • 最近有小伙伴在我之前写过的一篇怎样接入讯飞语音识别的文章下面留言
  • 说这篇文章有许多地方细节不到位,导致自己看不明白
  • 所以我就写了三篇系列文章从一个新手角度写了一篇接入讯飞语音的教程!在本文最后也有链接介绍!

注意:本文教程使用的Unity版本是2018.4.32,其他版本可能有出入,一般问题不大


🍉接入百度语音识别

  • 跟之前文章写过的接入讯飞语音识别一样,都要去官网下载对应的SDK
  • 所以我们去官网下载SDK,大家都是聪明人

百度语音SDK获取网址

  • 怎样获取SDK部分就不做过多介绍了,进入官网按照介绍
  • 注册登录获取语音识别的SDK就好了,然后创建一个应用


    这样应用就创建成功了,这里要记住APPID,后面会用到!

    找到SDK下载一个语音识别的SDK

那接下来就是获取到语音识别SDK后的部分了!


🍓android Studio端操作步骤

1.工程开始

老规矩,新建项目,修改名字和路径,准备开始!

然后新建一个module,起一个名字
File-new-new Module(下图)


2.接入Unity的classes.jar包

  • 把Unity的class接入,路径在安装Unity客户端的路径下
  • Unity\\Editor\\Data\\PlaybackEngines\\AndroidPlayer\\Variations\\mono\\Release\\Classes
  • 把Unity的jar包复制到AS的libs目录下,如下图:

3.接入讯飞语音的classess.jar包

  • 同样的方法,将百度语音的jar包也放进去
  • ar包位置就在我们在官网下载的SDK解压后的core->libs路径下
  • 直接也复制到AS的libs目录下就行!

    效果如下:

4.关联两个classes.jar包

  • 选中两个jar包,右键Add As Libray…
  • 等待编译完就好了
  • 也可以右键iflytevoice,Open Module Settings
  • 将.jar文件手动添加,添加完了记得点apply应用一下

    如果点击后这里显示已经有了这两个jar包,那说明就关联好了

5.添加libmsc.so

还是在我们下载的SDK目录下找到这个文件夹jniLibs

  • 然后把这个文件夹直接复制到AS的src->main目录下

如下图所示:


6.写SDK的接口

好了,到这一步才是写代码的阶段,前边做的几个步骤都是为了为最后的操作搭建一个"台子"

  • 我们接下来新建四个类,分别是CientBaiDuVoiceMainActivity、RecognHandler、RecognListener和GetActivity
  • 怎样新建就不说了,我这里还新建了两个文件夹Recogn和Util为了区分脚本类别,照着我这个做就行

直接看一下最终效果:

然后直接上各个脚本的代码,直接放进去就行
CientBaiDuVoiceMainActivity:

package com.example.baidu;


import android.content.Context;
import android.os.Bundle;
import android.util.Log;

import com.example.baidu.Recogn.RecognHandler;
import com.example.baidu.Recogn.RecognListener;
import com.unity3d.player.UnityPlayerActivity;

public class CientBaiDuVoiceMainActivity   {

    public static CientBaiDuVoiceMainActivity _instance;

    public static CientBaiDuVoiceMainActivity getInstance() {
        if (_instance == null) {
            _instance = new CientBaiDuVoiceMainActivity();
        }
        return _instance;
    }
    //语音识别
    RecognHandler mRecognHandler;

    //语音识别初始化
    public void InitRecogn(Context context) {
        Log.i("@@@", "安卓端开始初始化语音识别了 ");
        RecognListener listener=new RecognListener();
        mRecognHandler=new RecognHandler(context,listener);
    }
    //开始语音识别
    public void StartRecogn() {
        mRecognHandler.Start();
    }
    //停止语音识别
    public void StopRecogn() {
        mRecognHandler.Stop();
    }
    //释放语音识别实例
    public void ReleaseRecogn() {
        mRecognHandler.Release();
        mRecognHandler=null;
    }


}

RecognHandler:

package com.example.baidu.Recogn;//自己的包名

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.util.Log;

import com.baidu.speech.EventListener;
import com.baidu.speech.EventManager;
import com.baidu.speech.EventManagerFactory;
import com.baidu.speech.asr.SpeechConstant;

import org.json.JSONObject;

import java.util.LinkedHashMap;
import java.util.Map;
import static com.example.baidu.Util.GetActivity.getActivityByContext;

public class RecognHandler {

    private boolean mIsInit = false;
    private EventManager asr;
    private EventListener mEventLisener;

    public RecognHandler(Context context, EventListener listener) {
        if (mIsInit) {
            listener=null;
            return;
        }
        mIsInit = true;
        mEventLisener = listener;
        //动态申请权限
        initPermission(context);
        asr = EventManagerFactory.create(context, "asr");
        asr.registerListener(listener);
    }
    //开始识别
    public void Start() {
        Log.i("@@@", "点击开始语音识别了 ");
        Map<String, Object> params = new LinkedHashMap<String, Object>();
        // 基于SDK集成2.1 设置识别参数
        params.put(SpeechConstant.ACCEPT_AUDIO_VOLUME, true);
        params.put(SpeechConstant.DISABLE_PUNCTUATION, false);
        params.put(SpeechConstant.ACCEPT_AUDIO_DATA, false);
        params.put(SpeechConstant.PID, 1537); // 中文输入法模型,有逗号
        String json = null; // 可以替换成自己的json
        json = new JSONObject(params).toString(); // 这里可以替换成你需要测试的json
        asr.send(SpeechConstant.ASR_START, json, null, 0, 0);
    }
    //停止识别
    public void Stop() {
        asr.send(SpeechConstant.ASR_STOP, null, null, 0, 0);
    }
    //释放实例
    public void Release() {
        asr.unregisterListener(mEventLisener);
        mIsInit = false;
        asr=null;
    }

    /**
     * android 6.0 以上需要动态申请权限
     */
    private void initPermission(Context context) {
        String permissions[] = {Manifest.permission.RECORD_AUDIO,
                Manifest.permission.ACCESS_NETWORK_STATE,
                Manifest.permission.INTERNET,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
        };

        PackageManager pm = getActivityByContext(context).getPackageManager();
        boolean permission_readStorage = (PackageManager.PERMISSION_GRANTED ==
                pm.checkPermission("android.permission.RECORD_AUDIO", "com.cientx.tianguo"));
        boolean permission_network_state = (PackageManager.PERMISSION_GRANTED ==
                pm.checkPermission("android.permission.ACCESS_NETWORK_STATE", "com.cientx.tianguo"));
        boolean permission_internet = (PackageManager.PERMISSION_GRANTED ==
                pm.checkPermission("android.permission.INTERNET", "com.cientx.tianguo"));
        boolean permission_writeStorage = (PackageManager.PERMISSION_GRANTED ==
                pm.checkPermission("android.permission.WRITE_EXTERNAL_STORAGE", "com.cientx.tianguo"));

        if (!(permission_readStorage && permission_writeStorage && permission_network_state && permission_internet)) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                getActivityByContext(context).requestPermissions(permissions, 0x01);
            }
        }

    }

}

RecognListener:

package com.example.baidu.Recogn;//填写自己的包名

import android.util.Log;

import com.baidu.speech.EventListener;
import com.baidu.speech.asr.SpeechConstant;
import com.unity3d.player.UnityPlayer;

public class RecognListener implements EventListener {


    @Override
    public void onEvent(String name, String params, byte[] data, int i, int i1) {
        if (name.equals(SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL)) {
            Log.i("@@@", "进入开始语音识别的方法了 ");
            // 识别相关的结果都在这里
            if (params == null || params.isEmpty()) {
                return;
            }
            if (params.contains("\\"partial_result\\"")) {
                UnityPlayer.UnitySendMessage("NetLogic", "RecognResult", name + "&" + params);
                // 一句话的临时识别结果
            } else if (params.contains("\\"final_result\\"")) {
                UnityPlayer.UnitySendMessage("NetLogic", "RecognResult", name + "&" + params);
                // 一句话的最终识别结果
            } else {
                // 一般这里不会运行
                if (data != null) {
                }
            }
        } else {
            // 识别开始,结束,音量,音频数据回调
            if (params != null && !params.isEmpty()) {
            }
            if (data != null) {
            }
        }
    }
};


GetActivity:

package com.example.baidu.Util;//自己的包名

        import android.app.Activity;
        import android.content.Context;
        import android.content.ContextWrapper;

public class GetActivity {


    public static Activity getActivityByContext(Context context){
        while(context instanceof ContextWrapper){
            if(context instanceof Activity){
                return (Activity) context;
            }
            context = ((ContextWrapper) context).getBaseContext();
        }
        return null;
    }
}

这四个脚本就是核心类,语音识别就是AS端这几个脚本实现的!
下面来看一下AndroidManifest怎样修改吧!


7.修改AndroidManifest文件

直接把我这个代码复制到自己的AndroidManifest中就好了

  • 这里要注意两个问题
  • package要填写正确,填写自己的!
  • 下面的APPIDAPI_KEYSECRET_KEY都要填写自己在百度语音识别平台上创建的那个应用的
  • 如果忘记了就往上翻看一下哦,这个要在百度语音平台看一下自己的!每个人的都不同~
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.xxx.xxx">   <!-- 填写自己的包名 -->
    <!-- 通用权限 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
    <!-- 语音识别权限 -->
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
 
    <!-- 语音合成权限 -->
 
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS"
        tools:ignore="ProtectedPermissions" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
 
    <application android:allowBackup="true">
        <activity android:name=".Wakeup.WakeUpResult"></activity>
        <activity android:name=".Wakeup.WakeupHandler" />
        
        <activity
            android:name=".CientBaiDuVoiceMainActivity"
            android:launchMode="singleTask" />
 <!-- 请填写真实的APP_ID API_KEY SECRET_KEY -->
        <meta-data
            android:name="com.baidu.speech.APP_ID"
            android:value="xxxxx" />
        <meta-data
            android:name="com.baidu.speech.API_KEY"
            android:value="xxxxx" />
        <meta-data
            android:name="com.baidu.speech.SECRET_KEY"
            android:value="xxxxx" />
 
        <service
            android:name="com.baidu.speech.VoiceRecognitionService"
            android:exported="false" />
    </application>
 
</manifest>

8.打包aar

  • 好了,如果确定上面一步里的包名、ID和KEY等都填写正确了
  • 那在AS端的操作也就算完成了,接下来就是打包成aar给Unity使用就好了!
  • 按照下图所示,先选中baidu这个文件夹,然后Build - > Make Module “baidu”
  • 开始这三布之前先点击右边那个小按钮编译一下最好!
  • 然后就会看到baidu这个文件夹下多了一个Build文件夹!
  • 我们把下图中这个aar文件复制出来就好了,准备下一步中放到Unity中使用!!

🍑Unity端操作步骤

1.新建一个Unity工程

打开UnityHub新建一个Unity工程,我这里使用的Unity版本是2018.4.32


2.导入aar包

  • UnityAssets文件夹下新建一个文件夹 Plugins->Android
  • 别问为什么,照做就好啦~
  • 然后将我们在AS端打包的aar文件放到Unity中,就如下图所示:

3.简单搭建一个UI用做测试

新建一个画布,里面放两个Button按钮和一个Text文本就好了!

3.新建脚本写代码!

  • 这里我们新建一个空游戏对象,名字改为NetLogic
  • 名字一定要是这个,因为我们这次AS给Unity交互采用的是发消息机制UnityPlayer.UnitySendMessage
  • 是通过名字来找到这个对象的!(因为我写的讯飞语音中使用的是代理模式Proxy,所以这里换个方法体验一下!)
  • 然后新建一个脚本BD,代码如下,将两个ButtonText文本拖到脚本上即可!

如下图:

using LitJson;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class BD : MonoBehaviour
{
    AndroidJavaObject m_AndroidPluginObj;
    AndroidJavaClass _androidJC;
    AndroidJavaObject m_Android;
    public Text mRecognRes;
    public Button startASR_Btn;
    public Button stopASR_Btn;

    void Start()
    {
        AndroidJavaClass _androidJC = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        if (_androidJC == null)
        {
            Debug.Log("JNI initialization failure.");
            return;
        }
        m_AndroidPluginObj = _androidJC.GetStatic<AndroidJavaObject>("currentActivity");
        startASR_Btn.onClick.AddListener(StartRecogn);
        stopASR_Btn.onClick.AddListener(StopRecogn);

        Invoke("InitAsr", 3);
    }

    public void InitAsr()
    {
        AndroidJavaClass jc = new AndroidJavaClass("com.example.baidu.CientBaiDuVoiceMainActivity");//包名加类名
        AndroidJavaObject m_Android = jc.CallStatic<AndroidJavaObject>("getInstance");
        if (m_Android != null)
        {
            m_Android.Call("InitRecogn", m_AndroidPluginObj);
        }
        else
            Debug.Log("AndroidPlugin is Null");
    }
    public void StartRecogn()
    {
        AndroidJavaClass jc = new AndroidJavaClass("com.example.baidu.CientBaiDuVoiceMainActivity");
        AndroidJavaObject m_Android = jc.CallStatic<AndroidJavaObject>("getInstance");
        if (m_Android != null)
        {
            m_Android.Call("StartRecogn");
        }
        else
            Debug.Log("AndroidPlugin is Null");
    }
    public void StopRecogn()
    {
        AndroidJavaClass jc = new AndroidJavaClass("com.example.baidu.CientBaiDuVoiceMainActivity");
        以上是关于Unity 实战项目 ☀️| Unity接入 百度语音识别 SDK!一篇文章搞定在Unity中实现语音识别!(万字完整教程)的主要内容,如果未能解决你的问题,请参考以下文章

Unity 实战项目 ☀️| 接入科大讯飞语音SDK在Android Studio该如何操作! 系列共两万多字超级新手教程!

Unity 实战项目 ☀️| 接入科大讯飞语音SDK如何在科大讯飞平台搞到SDK!系列共两万多字超级新手教程!

Unity实战篇 | 接入 声网SDK 实现 视频通话——自己动手做一个 视频通话

Unity实战篇 | 接入 声网SDK 实现 音频通话 —— 自己动手做一个 语音聊天房

Unity 实战100例 教程 专栏《导航帖》,带你深入学习Unity实战经验

Unity 实战100例 教程 专栏《导航帖》,带你深入学习Unity实战经验