訊飛語音--喚醒Demo

寫的第一篇博客,因爲最近姐姐說起了一個段子, 一男子在地鐵站手機找不到了,但是帶了藍牙耳機,耳機還有內容,男子想手機一定還在附近,隨即大喊一句,悟空你在哪兒, 手機循環回答,我在這.....這時,拿手機那哥們回了男子一個尷尬而不失禮貌的微笑,哈哈

所以我想起訊飛語音,就試着寫了一下語音喚醒的Demo, 也借鑑了很多前輩的博客, 就不一一列舉了,各位不喜勿噴

接下來進入正題,首先在訊飛官網下載對應的SDK, 下載之前需要開通服務,如圖

Step1: 進入訊飛開放平臺


進入後點擊立即開通

Step2: 創建應用開通服務


Step3: 應用可享受3個裝機量,5個喚醒詞, 35天試用,需要用到的就是提供的APPID


Step4: 進來服務管理後, 輸入5個喚醒詞,生成體驗包


Step5: 下載體驗包,注意,每個喚醒詞不一樣,服務不一樣,生成的SDK裏的資源是不一樣的

下載完後的目錄是這樣

libs下是要用到的jar包和各個平臺的so文件,直接放入項目的libs目錄

res目錄下的爲對應APPID生成的資源文件,把裏面的東西放入項目的assets目錄下

sample中是官方提供的Demo,其實還是比較全面的

其他幾個txt大家可以自己看一下,是一些版本更新日誌,wordlist是你的關鍵詞


Step6:

在工程 AndroidManifest.xml 文件中添加如下權限

<!--連接網絡權限,用於執行雲端語音能力 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!--獲取手機錄音機使用權限,聽寫、識別、語義理解需要用到此權限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!--讀取網絡信息狀態 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--獲取當前wifi狀態 -->
<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.READ_CONTACTS"/>
<!--外存儲寫權限,構建語法需要用到此權限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--外存儲讀權限,構建語法需要用到此權限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!--配置權限,用來記錄應用配置信息 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<!--手機定位信息,用來爲語義等功能提供定位,提供更精準的服務-->
<!--定位信息是敏感信息,可通過Setting.setLocationEnable(false)關閉定位請求 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--如需使用人臉識別,還要添加:攝相頭權限,拍照需要用到 -->
<uses-permission android:name="android.permission.CAMERA" />

注意:如需在打包或者生成APK的時候進行混淆,請在proguard.cfg中添加如下代碼:

-keep class com.iflytek.**{*;}
-keepattributes Signature

Step7: 初始化, 可以放在Application或Activity的onCreate()中初始化(請勿在字符串加各種字符)

SpeechUtility.createUtility(this, SpeechConstant.APPID + "=你的appid");

還有其他可以設置的參數

createUtility方法的第二個參數爲傳入的初始化參數列表,可配置的參數如下:

參數說明必填
appid8位16進制數字字符串,應用的唯一標識,與下載的SDK一一對應。
usr開發者在雲平臺上註冊的賬號。
pwd賬號對應的密碼,與賬號同時存在。
engine_mode引擎模式,可選值爲:msc:只使用MSC的能力;plus:只使用語記能力;auto:雲端使用MSC,本地使用語記;默認取值爲auto。注:使用MSC本地功能的請設置爲msc。
force_login在createUtility時會對進程名稱進行檢查,如果名稱與應用包名不一致則不進行login操作,返回null,用以規避在子進程反覆進行調用的問題。此參數設置是否強制login。默認值:false (進行檢查,不強制login)。
lib_name在createUtility時會加載動態庫,此時可以傳入動態庫名稱。例如:libmsc_xxx_1072.so(xxx爲您的公司名,1072爲科大訊飛sdk版本號), 默認值:msc。注:如您是預裝軟件,爲了避免動態庫衝突建議修改名稱。

注意:參數需要以鍵值對的形式存儲在字符串中傳入createUtility方法,以逗號隔開,如“appid=12345678,usr=iflytekcloud,pwd=123456”。


Step8: 工具類

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

import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.VoiceWakeuper;
import com.iflytek.cloud.WakeuperListener;
import com.iflytek.cloud.WakeuperResult;
import com.iflytek.cloud.util.ResourceUtil;
import com.iflytek.cloud.util.ResourceUtil.RESOURCE_TYPE;

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

/**
 * Created by Administrator on 2018/2/28.
 * 訊飛語音喚醒
 */

public abstract class WakeUpUtil {
    /**
     * 喚醒的回調
     */
    public abstract void wakeUp();

    // Log標籤
    private static final String TAG = "WakeUpUtil";

    // 上下文
    private Context mContext;
    // 語音喚醒對象
    private VoiceWakeuper mIvw;

    private int curThresh = 40;

    public WakeUpUtil(Context context) {
        mContext = context;

        // 初始化喚醒對象
        mIvw = VoiceWakeuper.createWakeuper(context, null);
    }

    /**
     * 獲取喚醒詞功能
     *
     * @return 返回文件位置
     */
    private String getResource() {
        final String resPath = ResourceUtil.generateResourcePath(mContext,RESOURCE_TYPE.assets, "ivw/" + mContext.getString(R.string.IflytekAPP_id) + ".jet");
        return resPath;
    }

    /**
     * 喚醒
     */
    public void wake() {
        // 非空判斷,防止因空指針使程序崩潰
        mIvw = VoiceWakeuper.getWakeuper();
        if (mIvw != null) {
            // textView.setText(resultString);
            // 清空參數
            mIvw.setParameter(SpeechConstant.PARAMS, null);
            // 設置喚醒資源路徑
            mIvw.setParameter(SpeechConstant.IVW_RES_PATH, getResource());
            // 喚醒門限值,根據資源攜帶的喚醒詞個數按照“id:門限;id:門限”的格式傳入
            mIvw.setParameter(SpeechConstant.IVW_THRESHOLD, "0:" + curThresh);
            // 設置喚醒模式
            mIvw.setParameter(SpeechConstant.IVW_SST, "wakeup");
            // 設置持續進行喚醒
            mIvw.setParameter(SpeechConstant.KEEP_ALIVE, "1");
            mIvw.startListening(mWakeuperListener);
        } else {
            Toast.makeText(mContext, "喚醒未初始化", Toast.LENGTH_SHORT).show();
        }
    }

    public void stopWake() {
        mIvw = VoiceWakeuper.getWakeuper();
        if (mIvw != null) {
            mIvw.stopListening();
        } else {
            Toast.makeText(mContext, "喚醒未初始化", Toast.LENGTH_SHORT).show();
        }
    }

    String resultString = "";
    private WakeuperListener mWakeuperListener = new WakeuperListener() {

        @Override
        public void onResult(WakeuperResult result) {
            try {
                String text = result.getResultString();
                JSONObject object;
                object = new JSONObject(text);
                StringBuffer buffer = new StringBuffer();
                buffer.append("【RAW】 " + text);
                buffer.append("\n");
                buffer.append("【操作類型】" + object.optString("sst"));
                buffer.append("\n");
                buffer.append("【喚醒詞id】" + object.optString("id"));
                buffer.append("\n");
                buffer.append("【得分】" + object.optString("score"));
                buffer.append("\n");
                buffer.append("【前端點】" + object.optString("bos"));
                buffer.append("\n");
                buffer.append("【尾端點】" + object.optString("eos"));
                resultString = buffer.toString();
                stopWake();
                wakeUp();
            } catch (JSONException e) {
                resultString = "結果解析出錯";
                e.printStackTrace();
            }
        }

        @Override
        public void onError(SpeechError error) {
            Log.i(TAG, error.getPlainDescription(true));
        }

        @Override
        public void onBeginOfSpeech() {
            Log.i(TAG, "開始說話");
        }

        @Override
        public void onEvent(int eventType, int isLast, int arg2, Bundle obj) {

        }

        @Override
        public void onVolumeChanged(int i) {

        }
    };

}

Step9: 測試類

public class MainActivity extends AppCompatActivity {

    private TextView mTvLog;
    private WakeUpUtil wakeUpUtil;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SpeechUtility.createUtility(this, SpeechConstant.APPID + "=" +getString(R.string.IflytekAPP_id));

        mTvLog = (TextView) findViewById(R.id.tv_log);

        mTvLog.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 開啓喚醒
                wakeUpUtil.wake();
            }
        });

        wakeUpUtil = new WakeUpUtil(this) {
            @Override
            public void wakeUp() {
                Toast.makeText(MainActivity.this, "喚醒成功", Toast.LENGTH_SHORT).show();
                // 開啓喚醒
                wakeUpUtil.wake();
            }
        };

    }
}

佈局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#000">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FF000000"
        android:gravity="center"
        android:padding="10dp"
        android:text="喚醒詞:你好悟空, 悟空你好, 悟空出來"
        android:textColor="#FFFFFFFF"
        android:textSize="20dp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#FFFFFFFF" />

    <TextView
        android:id="@+id/tv_log"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FF000000"
        android:gravity="center"
        android:padding="10dp"
        android:text="點擊開始喚醒"
        android:textColor="#FFFFFFFF"
        android:textSize="10dp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#FFFFFFFF" />

</LinearLayout>

結果展示:




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章