1. 程式人生 > >Unity接入科大訊飛的語音sdk

Unity接入科大訊飛的語音sdk

        在Unity中新增語音識別功能方法有許多,這裡像大家介紹怎麼接入科大訊飛的語音sdk

2.登入上之後選擇控制檯,進入後選擇建立新應用。

3. 建立完成後新增新服務,這時候我們可以看到APPID,一會我們會用到。

 4.選擇語音聽寫

5.新增完成後,選擇右邊的sdk下載進入下載頁面 

 6.下載完成後會得到一個壓縮檔案,資料夾最後的數字字母也就是APPID。

  • assets裡面就是一些資原始檔沒有什麼用
  • libs主要是.so檔案和訊飛的.jar包
  • res是個空資料夾
  • sample裡面有個訊飛自帶的speechDemo(我們會用到(不想用也可以自己做))。


7.這裡我們先AndroidStudio建立一個新Empty Activity的工程。然後倒入這個speechDemo模組。 

8.倒入之後如果AndroidStudio中sdk 沒有speechDemo所用的SDK平臺會出現下面這種情況。

9.如果遇到這種情況我們可以修改為我們現有的平臺即可。在Project檢視下開啟speechDemo->build.gradle

(1)把compileSdkVersion 23 修改為26(注:我有26的平臺,根據自己的SDK平臺修改)

(2)把buildToolsVersion '26.0.2' 刪除(不需要)

(3)把minSdkVersion 9 修改為Unity支援的最低16

(4)把targetSdkVersion 23 修改為自己的26

(5)把compile ' com.android.support:support-v4:23.+'中的23改為26

(6)這些都修改完成之後點選Try Again

10.等編譯完成後我們可以先Run->Run 'speechDemo' (手機要開啟USB除錯)現在手機上執行一下自帶的Demo

10.File->New->New Module...建立一個模組(名稱隨意),選擇Android Library

11.建立完成後在Project檢視把jar包放到自己建立的UnityLib庫中。

(1)Msc.jar在訊飛SDK的libs資料夾

(2)classes.jar在Unity的安裝目錄下的\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes資料夾

12.在classes.jar和Msc.jar包上分別右鍵Add As Library...,在unitylib上右鍵->Open Module Settings檢視是否都依賴上了。

如果沒有新增上兩個jar包,就手動新增即可。

13.在unitylib->src->main資料夾下面建立一個叫jniLibs的資料夾,把訊飛SDK下libs資料夾下的armeabi-v7a資料夾直接複製進去。

14.完成之後開啟安卓檢視,在unitylib->java->com.example.stt.unitylibFile上右鍵New->Activity->Empty Activity建立一個新的Activity。

(1)把佈局檔案給刪掉

(2)把setContentView(R.layou.activity_main);刪除掉

(3)把繼承自AppCompatActivity改為繼承自UnityPlayerActivity並把多餘的引用刪除。
(4)把unitylib->res裡面的layout裡的檔案刪掉

15.下面修改manifests檔案。

(1)開啟unitylib裡面的AndroidManifest.xml檔案,

(2)開啟app裡面的AndroidManifest.xml檔案,用裡面的application標籤裡的內容覆蓋掉unitylib裡面的AndroidManifest裡面,

把報紅的地方全部刪掉

(3)在intent-filter結束標籤後新增

<meta-data android:name="unityplayer.UnityActivity" android:value="true"/>

(4)找到speechDemo下面的AndroidManifest.xml檔案,把結束標籤前邊的設定許可權部分複製到unitylib的AnidroidManifest的結束標籤前面。

最後unitylib的檔案應該是以下這樣。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.stt.unitylib">

    <application
        android:allowBackup="true"
        android:label="@string/app_name"
        android:supportsRtl="true">
        <activity android:name=".MainActivity">
            <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>

    <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-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
</manifest>

16.在寫程式碼之前先把speechDemo->java->speech->util裡面的JsonParser複製到unitylib中(和MainActivity在同一目錄)。這是個解析Json資料的工具類。如果不用的話可以自己寫一個解析資料的類。

17.下面就是寫程式碼了,別的也就不多說了直接上程式碼就可以了。

package com.example.stt.unitylib;

import android.os.Bundle;

import com.iflytek.cloud.RecognizerListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechRecognizer;

import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechUtility;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.LinkedHashMap;

public class MainActivity extends UnityPlayerActivity {
    private SpeechRecognizer mIat;
    private HashMap<String, String> mIatResults = new LinkedHashMap<String, String>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //初始化
        SpeechUtility.createUtility(this, SpeechConstant.APPID+"=5b5594a3");
        mIat = SpeechRecognizer.createRecognizer(this, null);
        //設定mIat的引數
        //表示是什麼服務
        mIat.setParameter(SpeechConstant.DOMAIN,"iat");
        //設定語言
        mIat.setParameter(SpeechConstant.LANGUAGE,"zh_cn");
        //接受語言的型別
        mIat.setParameter(SpeechConstant.ACCENT,"mandarin");
        //使用什麼樣引擎
        mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
    }
    //建立一個監聽器
    RecognizerListener mRecognizerLis = new RecognizerListener() {
        @Override//當聲音改變的時候呼叫
        public void onVolumeChanged(int i, byte[] bytes) {}
        @Override//開始說話的時候呼叫
        public void onBeginOfSpeech() {}
        @Override//結束說話的時候呼叫
        public void onEndOfSpeech() {}
        @Override//返回結果
        public void onResult(RecognizerResult recognizerResult, boolean b) {
            printResult(recognizerResult);
        }
        @Override//出錯的時候呼叫
        public void onError(SpeechError speechError) {}
        @Override//自定義事件
        public void onEvent(int i, int i1, int i2, Bundle bundle) {}
    };
    //解析Json的方法
    //方法來自speechDemo->java->voicedemo->IatDemo中的printResult方法
    private void printResult(RecognizerResult results) {
        String text = JsonParser.parseIatResult(results.getResultString());

        String sn = null;
        // 讀取json結果中的sn欄位
        try {
            JSONObject resultJson = new JSONObject(results.getResultString());
            sn = resultJson.optString("sn");
        } catch (JSONException e) {
            e.printStackTrace();
        }

        mIatResults.put(sn, text);

        StringBuffer resultBuffer = new StringBuffer();
        for (String key : mIatResults.keySet()) {
            resultBuffer.append(mIatResults.get(key));
        }
        //把訊息傳送給Unity場景中MsgController物體上的OnResult方法
        UnityPlayer.UnitySendMessage("MsgController", "OnResult", resultBuffer.toString());
    }
    //這個方法讓Unity來呼叫
    public void beginListen(){
        //開始識別
        mIat.startListening(mRecognizerLis);
    }

18.這些搞完之後我們就快大功告成了,下面我們可以Build我們的模組

19.完成之後開啟Project檢視

(1)找到unitylib->build->outputs->aar裡面的aar包

(2)找到unitylib->build->intermediates->manifests->full->debug裡面的AndroidManifest.xml

把這兩個檔案複製出來我們需要對它們稍作修改

20.修改匯出的檔案

(1)aar包可以用壓縮檔案開啟(直接拖到壓縮軟體的快捷方式上就可以開啟)

(2)把libs裡面的classes.jar包刪除掉,

(3)把根目錄下的AndroidManifest檔案拖出來後刪除裡面的android:label="@string/app_name"後再拖進去,把裡面的給替換掉

(4)aar包搞好之後要修改AndroidManifest.xml檔案,把包名和label都可以修改下

21.完成後把這兩個檔案放到Unity的目錄下,必須按照下圖放 

22.後面的就是Unity中的部分了。下面是個簡單的介面

23.Unity中只要寫簡單的程式碼即可

using UnityEngine;
using UnityEngine.UI;
public class Test : MonoBehaviour {
    private AndroidJavaObject crtActivity;
    public Text message;
    // 放在MsgController的遊戲物體上
    void Start () {
        AndroidJavaClass javaClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        crtActivity = javaClass.GetStatic<AndroidJavaObject>("currentActivity");
	}
    //繫結按鈕
    public void BeginListen()
    {
        crtActivity.Call("beginListen");
    }
    //java中 UnityPlayer.UnitySendMessage("MsgController", "OnResult", resultBuffer.toString());來呼叫
    void OnResult(string str)
    {
        message.text = str;
    }
}

24.釋出完成後按下開始講話就可以識別了。