Unity調用訊飛做語音聽寫(Android Studio版)


以前做過一年Android開發,一直用的是Eclipse,但是AS是主流了,順手學一波AS,然后發現很多都不會操作了。整理一下昨天一天的工作成果,也算是拋磚引玉。

先去訊飛開放平台注冊帳號,然后去控制台創建應用,添加需要的服務,然后把SDK下載。這個流程一句話帶過,應該看這篇文章的沒人不會。

說一說怎么在AS里面使用訊飛和打包成AAR吧。

1.創建一個項目 

*因為用不到布局文件,所以沒必要生成。

 

2.添加一個庫

3.添加相關的庫文件

在這個位置找到Unity的Classes.jar,注意綠框里的信息,如果你的Unity使用的是MONO框架就用這個,如果是IL2CPP的話,就是下圖

 

然后找到剛才下載的SDK,找libs下的這兩個文件

*rmeabi-v7a是根據安裝的機器來做適配的,你可以自行使用libs下的其它庫

將以上三個文件Copy到flytek4unity/libs下

 

給MSC.jar和classes.jar以庫文件的形式添加到新增的模塊,非app。如果右鍵菜單不顯示這個項,我們可以在flytek4unity右鍵

 

選擇未能添加的庫依賴。

 

 3.編碼

package cn.egstudio.flytek4unity;

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.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;

import android.app.Activity;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends UnityPlayerActivity {
    SpeechRecognizer mIAT;
    String voiceResult = "";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SpeechUtility.createUtility(this, SpeechConstant.APPID + "=59eea647");
        mIAT = SpeechRecognizer.createRecognizer(this, mInitListener);
    }
    
    public void StartListening() {
        mIAT.setParameter(SpeechConstant.DOMAIN,"iat");
        mIAT.setParameter(SpeechConstant.LANGUAGE,"en_us");
        mIAT.setParameter(SpeechConstant.KEY_SPEECH_TIMEOUT,"4000");
        mIAT.setParameter(SpeechConstant.VAD_EOS,"2000");
        mIAT.setParameter(SpeechConstant.ASR_PTT,"0");
        int ret = mIAT.startListening(recognizerListener);
        UnityPlayer.UnitySendMessage("iFlyTek", "OnStartListening", String.valueOf(ret));
    } 
    
    private InitListener mInitListener = new InitListener() {
        
        @Override
        public void onInit(int arg0) {
            UnityPlayer.UnitySendMessage("iFlyTek", "OnStartListening", String.valueOf(arg0));
        }
    };  
    
    private RecognizerListener recognizerListener = new RecognizerListener() {
        
        @Override
        public void onVolumeChanged(int arg0, byte[] arg1) {
            // TODO Auto-generated method stub
            
        }
        
        @Override
        public void onResult(RecognizerResult arg0, boolean arg1) {
            voiceResult += JsonParser.parseIatResult(arg0.getResultString());
            if(arg1){
                UnityPlayer.UnitySendMessage("iFlyTek", "OnResult", voiceResult);
                voiceResult = "";
                mIAT.stopListening();
            }
        }
        
        @Override
        public void onEvent(int arg0, int arg1, int arg2, Bundle arg3) {
            // TODO Auto-generated method stub
            
        }
        
        @Override
        public void onError(SpeechError arg0) {
            UnityPlayer.UnitySendMessage("iFlyTek", "OnError", arg0.getErrorDescription());
        }
        
        @Override
        public void onEndOfSpeech() {
            UnityPlayer.UnitySendMessage("iFlyTek", "OnEndOfSpeech","");
        }
        
        @Override
        public void onBeginOfSpeech() {
            UnityPlayer.UnitySendMessage("iFlyTek", "OnBeginOfSpeech","");
        }
    };
}

在src/main/java下創建一個java類,寫上如上代碼,重點是APPID,后面的字符串填上訊飛開放平台你申請的應用ID,然后就是StartListening方法中系列參數,這個歡迎去訊飛官網找資料,不詳細講。

 然后你會遇到JsonParser沒有的問題,這個請在下載訊飛SDK壓縮包找找

*注意看紅框的路徑

4.修改Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.egstudio.flytek4unity"
    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="23" />

    <application
        android:allowBackup="true"
        android:label="@string/app_name">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

*添加權限,修改啟動Activity(這個需不需要我沒測試,之前在Eclipse的時候,因為導出jar和AS導出AAR不一樣,直接導了之前的清單文件)

5.生成AAR

 

Make一下Module,aar就生成了

將這個aar和這個模塊下的androidmanifest.xml導入Unity,記住,一定是剛剛修改的這個模塊下的androidmanifest,不是app的

 

Unity中的結構圖。

6.Unity中的編碼

創建一個iFlyTek的空物體,和MainActivity中的相對應。

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

public class iFlyTek : MonoBehaviour {

    private AndroidJavaClass ajc;
    private AndroidJavaObject ajo;

    public Button StartButton;
    public Text ResultText;

    private void Start() {
        ajc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        ajo = ajc.GetStatic<AndroidJavaObject>("currentActivity");
        if (StartButton) {
            StartButton.onClick.AddListener(() => { StartListening(); });
        }
    }

    public void StartListening() {
        ajo.Call("StartListening");
    }

    public void OnStartListening(string ret) {
        int result = int.Parse(ret);
        StartButton.interactable = result == 0;
    }

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

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

    public void OnEndOfSpeech() {
        StartButton.GetComponentInChildren<Text>().text = "已結束,點擊聆聽";
        StartButton.interactable = true;
    }

    public void OnBeginOfSpeech() {
        StartButton.GetComponentInChildren<Text>().text = "聆聽ing";
        StartButton.interactable = false;
    }
}

創建一個腳本,掛在iFlyTek下,里面很多方法是作為callback存在的,具體看MainActivity

然后在場景創建一個Button和Text,用來觸發聽寫和接收聽寫結果。

 

7.發布

 

這些都要能匹配的上,Unity的包名和導入的manifest文件報名一致,最小API支持等級得一致,classes.jar用mono還是IL2CPP得和Script Backend一致

 

 大功告成。不發真機截圖了,麻煩。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM