采用Unity导出讯飞离线语音听写APK

说明:讯飞离线语音听写目前只有Android平台,当前时间是2020年03月06号,本博客介绍使用Unity来搭建这个demo作为测试

描述:采用讯飞的离线语音SDK在unity上进行导出
条件:需要注册讯飞开放平台账号,Android Studio,Unity
原理:使用Android Studio导出AAR包给Unity,在Unity上进行操作控制

第一步:你得注册一个账号用来下载SDK

默认你已经注册好了,你需要注意免费试用是有时间限制的。
在这里插入图片描述
现在看看它下载下来的样子:
在这里插入图片描述

第二步:在Android Studio上的处理

1. 建立一个工程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面不使用布局文件,Generate Layout File 不勾选
在这里插入图片描述
很好,接下来调成Project模式,你的结构如下
在这里插入图片描述

2. 新增一个模块

在这里插入图片描述
在这里插入图片描述
填写库名,模块名,这里也有一个包名,记住它,接下来所有的操作都将在这个模块里完成
在这里插入图片描述
在这里插入图片描述

3. 添加第三方资源

找到从讯飞下载下来的文件夹,找到libs,选择这两项,添加到模块iatlibrary/libs
里面
在这里插入图片描述
在Unity安装目录下找到这个jar包,同样的添加到模块iatlibrary/libs.
在这里插入图片描述
然后再去sample里找到JsonParse这个文件,添加到iatlibrary/src/main/java/你的包名 下面
在这里插入图片描述
现在你的项目里是这样的
在这里插入图片描述
接下来把classes.jar和Msc.jar以库文件的形式进行添加
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这是完成后的样子
在这里插入图片描述
AndroidStudio要添加的东西完成了,接下来是写东西和导出AAR包

4. 写代码(活动)

在这里插入图片描述
代码如下:

package com.zy.iatlibrary;

import android.os.Bundle;
import android.widget.Toast;

import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.RecognizerListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechRecognizer;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.util.ResourceUtil;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;

/**
 * Created by zy on 2020/3/6.
 */

public class Iat extends UnityPlayerActivity{
    private SpeechRecognizer mIat;
    private String result= "";
    private String mEngineType = SpeechConstant.TYPE_LOCAL;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        SpeechUtility.createUtility(this, SpeechConstant.APPID + "=9y35h930h");
        mIat = SpeechRecognizer.createRecognizer(this, mTtsInitListener);
        if(mIat==null)
        {
            Toast.makeText(Iat.this,"对象为空,检查是否有jet资源",Toast.LENGTH_LONG).show();
            return;
        }
        else
        {
            mIat.setParameter(SpeechConstant.PARAMS,null);
            mIat.setParameter(SpeechConstant.ENGINE_TYPE,mEngineType);
            if (mEngineType.equals(SpeechConstant.TYPE_LOCAL))
            {
                mIat.setParameter(ResourceUtil.ASR_RES_PATH,getResourcePath());
            }
            mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
            mIat.setParameter(SpeechConstant.KEY_SPEECH_TIMEOUT, "20000"); //语音输入超时时间 设置录取音频的最长时间
            mIat.setParameter(SpeechConstant.VAD_BOS,"3000"); //开始录入音频后,音频前面部分最长静音时长
            mIat.setParameter(SpeechConstant.VAD_EOS, "2000"); //开始录入音频后,音频后面部分最长静音时长
        }
    }

    //Unity调用这个方法
    public void StartListening(String str)
    {
        Toast.makeText(Iat.this,str,Toast.LENGTH_LONG).show();
        int ret = mIat.startListening(mRecognizerListener);
        UnityPlayer.UnitySendMessage("GameObject","OnStartListening",String.valueOf(ret));
    }


    /**初始化监听**/
    private InitListener mTtsInitListener = new InitListener()
    {
        @Override
        public void onInit(int i)
        {
            if (i!= ErrorCode.SUCCESS)
            {
                Toast.makeText(Iat.this,"初始化失败,错误码:" + i+",请点击网址https://www.xfyun.cn/document/error-code查询解决方案",Toast.LENGTH_LONG).show();
            }
            UnityPlayer.UnitySendMessage("GameObject","OnStartListening",String.valueOf(i));
        }
    };

    private RecognizerListener mRecognizerListener =new RecognizerListener() {
        @Override
        public void onVolumeChanged(int i, byte[] bytes) {

        }

        @Override
        public void onBeginOfSpeech()
        {
            UnityPlayer.UnitySendMessage("GameObject","OnBeginOfSpeech","");
        }

        @Override
        public void onEndOfSpeech()
        {
            UnityPlayer.UnitySendMessage("GameObject","OnEndOfSpeech","");
        }

        @Override
        public void onResult(RecognizerResult recognizerResult, boolean b)
        {
            result+= JsonParser.parseIatResult(recognizerResult.getResultString());
            if(b)
            {
                UnityPlayer.UnitySendMessage("GameObject","OnResult",result);
                result = "";
                mIat.stopListening();
            }
        }

        @Override
        public void onError(SpeechError speechError)
        {
            UnityPlayer.UnitySendMessage("GameObject","OnError",speechError.getErrorCode()+"");
        }

        @Override
        public void onEvent(int i, int i1, int i2, Bundle bundle) {

        }
    };

    private String getResourcePath()
    {
        StringBuffer tempBuffer = new StringBuffer();
        tempBuffer.append(ResourceUtil.generateResourcePath(this,ResourceUtil.RESOURCE_TYPE.assets,"iat/common.jet"));
        tempBuffer.append(";");
        tempBuffer.append(ResourceUtil.generateResourcePath(this,ResourceUtil.RESOURCE_TYPE.assets,"iat/sms_16k.jet"));
        return tempBuffer.toString();
    }
}

不懂的查API:http://mscdoc.xfyun.cn/android/api/
如果之后报了出错码到这里查:https://www.xfyun.cn/document/error-code
代码很简单,有面向对象语言基础的都能看懂,说明一下:
这一条后面的9y35h930h是指你的appid,第一部分就圈了,你的换成自己的。

SpeechUtility.createUtility(this, SpeechConstant.APPID + "=9y35h930h");
UnityPlayer.UnitySendMessage(unity中对象名称,挂在对象上面脚本的方法,要传递的参数,没有就不写);

还有一点,JsonParse里的包名记得换成你的模块里的包名:
在这里插入图片描述

5. 修改AndroidManifest.xml

在这里插入图片描述
懂的自然懂,不懂的以后会懂

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.zy.iatlibrary"
          android:versionCode="1"
          android:versionName="1.0" >
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-sdk
        android:minSdkVersion="19"
        android:targetSdkVersion="24" />

    <application android:allowBackup="true"
                 android:supportsRtl="true">
                 <activity
                     android:name=".Iat">
                     <intent-filter>
                     <action android:name="android.intent.action.MAIN"/>
                     <category android:name="android.intent.category.LAUNCHER" />
                     </intent-filter>
                     <meta-data android:name="unityplayer.UnityActivity" android:value="true"/>
                  </activity>
    </application>
</manifest>

6.导出AAR

在这里插入图片描述
等待重构完成,再点击这个
在这里插入图片描述
我们看到建立的aar包已经完成了
在这里插入图片描述
在文件夹中打开
在这里插入图片描述
libs里面有classes.jar包,删除它,把外面这个classes.jar放进去,你发现libs里面没有armeabi-v7a,在你项目里找到它拷贝进去完成后进行下一步
在这里插入图片描述
留下这四个文件,待会要拷贝到Unity里面。
在这里插入图片描述

第三步:Unity中要做的事

1. 搭界面

建立工程搭建界面:
在这里插入图片描述

2. 放资源

建立一个文件夹Plugins/Android,刚刚的文件放进去
在这里插入图片描述

在之前下载的讯飞包里找到这两个文件然后放入Unity Assets/Android/Plugins/assets/iat里
在这里插入图片描述
补充一下:
打开Unity里刚刚导入的AndroidMainfest.xml,添加这两行,不然待会你在Unity里设置的名称和图标会无用
在这里插入图片描述

3.敲代码

新建一个脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Iatdemo : MonoBehaviour
{
    private AndroidJavaClass ajc;
    private AndroidJavaObject ajo;

    public Button startBtn;
    public Button exitBtn;
    public Text resultText;

    private void Awake()
    {
        startBtn = GameObject.Find("Canvas/Button").GetComponent<Button>();
        exitBtn = GameObject.Find("Canvas/Button_2").GetComponent<Button>();   
        resultText = GameObject.Find("Canvas/Text").GetComponent<Text>();
        
    }

    // Use this for initialization
    void Start ()
    {
        ajc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        ajo = ajc.GetStatic<AndroidJavaObject>("currentActivity");
        if (startBtn)
        {
            startBtn.onClick.AddListener(()=> { StartListening(); } );
        }
        if (exitBtn)
        {
            exitBtn.onClick.AddListener(()=> { Quit(); });
        }
 
	}

    public void StartListening()
    {        
        ajo.Call("StartListening", "点击了监听");
    }
  
    public void OnStartListening(string ret)
    {
        int result = int.Parse(ret);
        startBtn.interactable = result == 0;
    }

    public void OnResult(string result)
    {
        resultText.text = result;
    }

    public void OnError(string errorMessage)
    {
        resultText.text = errorMessage;
    }

    public void OnEndOfSpeech()
    {
        startBtn.GetComponentInChildren<Text>().text = "点击倾听";
        startBtn.interactable = true;
    }

    public void OnBeginOfSpeech()
    {
        startBtn.GetComponentInChildren<Text>().text = "倾听中";
        startBtn.interactable = false;
    }


    public void Quit()
    {
        Application.Quit();
    }
}

将这个脚本挂载在GameObject上

4.导出apk

这里的包名记得和之前AS里面的模块里的包名是一致的,这里的应用名称和应用图标也填一下,之前在xml里如果没有新增那两条的话,这里填了也没有用
在这里插入图片描述
接下来点击Build然后把apk安装在android上

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值