Android集成科大訊飛SDK語音聽寫及語音合成功能實現

前言
  如今軟件設計愈來愈人性化、智能化。一些常見的輸入都慢慢向語音聽寫方向發展,一些常見的消息提示都向語音播報發展。因此語音合成和語音聽寫是手機軟件開發必不可少的功能。目前國內這方面作的比較好的應該是科大訊飛。不少搜索引擎,語音助手都有用到。本人也是第一次用初步研究了一下,和你們一塊兒分享學習。

 

 
聲明
  歡迎轉載,但請保留文章原始出處:) 
     總有刁民想害朕&:http://www.cnblogs.com/wangshuaiandroid
 
正文
  1、註冊開放者帳號、建立應用、下載SDK 

    訊飛開放平臺java

  2、集成SDKandroid

    2.1  將開發工具包中libs目錄下的Msc.jar和armeabi複製到Android工程的libs目錄(若是工程無libs目錄,請自行建立)json

    2.2  添加用戶權限vim

                    

<!--鏈接網絡權限,用於執行雲端語音能力 -->  
<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"/>  

 

    2.3   初始化
網絡

       初始化即建立語音配置對象,只有初始化後纔可使用MSC的各項服務。建議將初始化放在程序入口處(如Application、Activity的onCreate方法),初始化代碼以下:app

// 將「12345678」替換成您申請的APPID,申請地址:http://open.voicecloud.cn  
SpeechUtility.createUtility(context, SpeechConstant.APPID +"=12345678");   

          注意:  此接口在非主進程調用會返回null對象,如需在非主進程使用語音功能,請使用參數:SpeechConstant.APPID +"=12345678," + SpeechConstant.FORCE_LOGIN +"=true"。ide

    2.4   語音聽寫工具

      聽寫主要指將連續語音快速識別爲文字的過程,科大訊飛語音聽寫能識別通用常見的語句、詞彙,並且不限制說法。語音聽寫的調用方法以下: 學習

      
//1.建立SpeechRecognizer對象,第二個參數:本地聽寫時傳InitListener    
SpeechRecognizer mIat= SpeechRecognizer.createRecognizer(context, null);    
//2.設置聽寫參數,詳見《科大訊飛MSC API手冊(Android)》SpeechConstant類    
mIat.setParameter(SpeechConstant.DOMAIN, "iat");    
mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");    
mIat.setParameter(SpeechConstant.ACCENT, "mandarin ");    
//3.開始聽寫   mIat.startListening(mRecoListener);    
//聽寫監聽器    
private RecognizerListener mRecoListener = new RecognizerListener(){    
//聽寫結果回調接口(返回Json格式結果,用戶可參見附錄12.1);    
//通常狀況下會經過onResults接口屢次返回結果,完整的識別內容是屢次結果的累加;    
//關於解析Json的代碼可參見MscDemo中JsonParser類;    
//isLast等於true時會話結束。    
public void onResult(RecognizerResult results, boolean isLast) {    
            Log.d("Result:",results.getResultString ());}    
//會話發生錯誤回調接口    
    public void onError(SpeechError error) {    
error.getPlainDescription(true) //獲取錯誤碼描述}    
    //開始錄音    
    public void onBeginOfSpeech() {}    
    //音量值0~30    
    public void onVolumeChanged(int volume){}    
    //結束錄音    
    public void onEndOfSpeech() {}    
    //擴展用接口    
    public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {}    
};    

 

    2.5 語音交互動畫開發工具

     爲了便於快速開發,SDK還提供了一套默認的語音交互動畫以及調用接口,如需使用請將SDK資源包assets路徑下的資源文件拷貝至Android工程asstes目錄下,而後經過如下代碼使用交互動畫:

             

//1.建立SpeechRecognizer對象,第二個參數:本地聽寫時傳InitListener  
RecognizerDialog    iatDialog = new RecognizerDialog(this,mInitListener);  
//2.設置聽寫參數,同上節  
//3.設置回調接口  
iatDialog.setListener(recognizerDialogListener);  
//4.開始聽寫  
iatDialog.show();    

 

  3、語音合成

     與語音聽寫相反,合成是將文字信息轉化爲可聽的聲音信息,讓機器像人同樣開口說話。合成的調用方法以下:

//1.建立SpeechSynthesizer對象, 第二個參數:本地合成時傳InitListener  
SpeechSynthesizer mTts= SpeechSynthesizer.createSynthesizer(context, null);  
//2.合成參數設置,詳見《科大訊飛MSC API手冊(Android)》SpeechSynthesizer 類  
mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan");//設置發音人  
mTts.setParameter(SpeechConstant.SPEED, "50");//設置語速  
mTts.setParameter(SpeechConstant.VOLUME, "80");//設置音量,範圍0~100  
mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); //設置雲端  
//設置合成音頻保存位置(可自定義保存位置),保存在「./sdcard/iflytek.pcm」  
//保存在SD卡須要在AndroidManifest.xml添加寫SD卡權限  
//若是不須要保存合成音頻,註釋該行代碼  
mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, "./sdcard/iflytek.pcm");  
//3.開始合成  
mTts.startSpeaking("科大訊飛,讓世界聆聽咱們的聲音", mSynListener);    
//合成監聽器  
private SynthesizerListener mSynListener = new SynthesizerListener(){  
    //會話結束回調接口,沒有錯誤時,error爲null  
    public void onCompleted(SpeechError error) {}  
    //緩衝進度回調  
    //percent爲緩衝進度0~100,beginPos爲緩衝音頻在文本中開始位置,endPos表示緩衝音頻在文本中結束位置,info爲附加信息。  
    public void onBufferProgress(int percent, int beginPos, int endPos, String info) {}  
    //開始播放  
    public void onSpeakBegin() {}  
    //暫停播放  
    public void onSpeakPaused() {}  
    //播放進度回調  
    //percent爲播放進度0~100,beginPos爲播放音頻在文本中開始位置,endPos表示播放音頻在文本中結束位置.  
    public void onSpeakProgress(int percent, int beginPos, int endPos) {}  
    //恢復播放回調接口  
    public void onSpeakResumed() {}  
//會話事件回調接口  
    public void onEvent(int arg0, int arg1, int arg2, Bundle arg3) {}  };

 

  4、代碼整理

    上面只是按照官方文檔把主要方法介紹一下。下面我本身整理了這兩個功能。貼出源碼供你們學習:

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

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

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.SpeechSynthesizer;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.SynthesizerListener;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;
import com.iflytek.isvdemo.R;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

@SuppressLint("ShowToast")
public class YuTestActivity extends Activity implements OnClickListener {
    private static String TAG = YuTestActivity.class.getSimpleName();
    // 用HashMap存儲聽寫結果
    private HashMap<String, String> mIatResults = new LinkedHashMap<String, String>();
    private EditText et_content;
    private Button bt_speech;
    private SpeechSynthesizer mTts;// 語音合成
    private SpeechRecognizer mIat;// 語音聽寫
    private Button bt_write;
    private RecognizerDialog iatDialog;//聽寫動畫
    // 0 小燕 青年女聲 中英文(普通話) xiaoyan
    // 1 默認 小宇 青年男聲 中英文(普通話) xiaoyu
    // 2 凱瑟琳 青年女聲 英文 catherine
    // 3 亨利 青年男聲 英文 henry
    // 4 瑪麗 青年女聲 英文 vimary
    // 5 小研 青年女聲 中英文(普通話) vixy
    // 6 小琪 青年女聲 中英文(普通話) vixq xiaoqi
    // 7 小峯 青年男聲 中英文(普通話) vixf
    // 8 小梅 青年女聲 中英文(粵語) vixm xiaomei
    // 9 小莉 青年女聲 中英文(臺灣普通話) vixl xiaolin
    // 10 小蓉 青年女聲 漢語(四川話) vixr xiaorong
    // 11 小芸 青年女聲 漢語(東北話) vixyun xiaoqian
    // 12 小坤 青年男聲 漢語(河南話) vixk xiaokun
    // 13 小強 青年男聲 漢語(湖南話) vixqa xiaoqiang
    // 14 小瑩 青年女聲 漢語(陝西話) vixying
    // 15 小新 童年男聲 漢語(普通話) vixx xiaoxin
    // 16 楠楠 童年女聲 漢語(普通話) vinn nannan
    // 17 老孫 老年男聲 漢語(普通話)
    private String[] voiceName = { "xiaoyan", "xiaoyu", "catherine", "henry",
            "vimary", "vixy", "xiaoqi", "vixf", "xiaomei", "xiaolin",
            "xiaorong", "xiaoqian", "xiaokun", "xiaoqiang", "vixying",
            "xiaoxin", "nannan", "vils" };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.yuyin);
        et_content = (EditText) findViewById(R.id.et_content);
        bt_speech = (Button) findViewById(R.id.bt_speech);
        bt_write = (Button) findViewById(R.id.bt_write);
        bt_speech.setOnClickListener(this);
        bt_write.setOnClickListener(this);
        // 初始化即建立語音配置對象,只有初始化後纔可使用MSC的各項服務
        SpeechUtility.createUtility(this, SpeechConstant.APPID + "=56f25de3");
        // 語音合成 1.建立SpeechSynthesizer對象, 第二個參數:本地合成時傳InitListener
        mTts = SpeechSynthesizer.createSynthesizer(YuTestActivity.this,
                mTtsInitListener);
        // 語音聽寫1.建立SpeechRecognizer對象,第二個參數:本地聽寫時傳InitListener
        mIat = SpeechRecognizer.createRecognizer(this, mTtsInitListener);
        // 1.建立SpeechRecognizer對象,第二個參數:本地聽寫時傳InitListener
         iatDialog = new RecognizerDialog(this,
                mTtsInitListener);

    }

    /**
     * 初始化語音合成相關數據
     * 
     * @Description:
     */
    public void starSpeech() {
        String content = et_content.getText().toString().trim();

        // 2.合成參數設置,詳見《科大訊飛MSC API手冊(Android)》SpeechSynthesizer 類
        mTts.setParameter(SpeechConstant.VOICE_NAME, voiceName[5]);// 設置發音人
        mTts.setParameter(SpeechConstant.SPEED, "50");// 設置語速
        mTts.setParameter(SpeechConstant.VOLUME, "80");// 設置音量,範圍0~100
        mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); // 設置雲端
        // 設置合成音頻保存位置(可自定義保存位置),保存在「./sdcard/iflytek.pcm」
        // 保存在SD卡須要在AndroidManifest.xml添加寫SD卡權限
        // 若是不須要保存合成音頻,註釋該行代碼
        mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, "./sdcard/iflytek.pcm");
        // 3.開始合成
        mTts.startSpeaking(content, mSynListener);
        // 合成監聽器
        //

    }

    /**
     * 初始化參數開始聽寫
     * 
     * @Description:
     */
    private void starWrite() {
        // 2.設置聽寫參數,詳見《科大訊飛MSC API手冊(Android)》SpeechConstant類
        // 語音識別應用領域(:iat,search,video,poi,music)
        mIat.setParameter(SpeechConstant.DOMAIN, "iat");
        // 接收語言中文
        mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        // 接受的語言是普通話
        mIat.setParameter(SpeechConstant.ACCENT, "mandarin ");
        // 設置聽寫引擎(雲端)
        mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
        iatDialog.setListener(mRecognizerDialogListener);
        iatDialog.show();
        Toast.makeText(getApplication(), "請開始說話…", Toast.LENGTH_SHORT).show();
        // 3.開始聽寫
        //mIat.startListening(mRecoListener);
        // 聽寫監聽器

    }

    /**
     * 語音聽寫監聽
     */
    private RecognizerListener mRecoListener = new RecognizerListener() {
        // 聽寫結果回調接口(返回Json格式結果,用戶可參見附錄12.1);
        // 通常狀況下會經過onResults接口屢次返回結果,完整的識別內容是屢次結果的累加;
        // 關於解析Json的代碼可參見MscDemo中JsonParser類;
        // isLast等於true時會話結束。
        public void onResult(RecognizerResult results, boolean isLast) {
            Log.d(TAG, results.getResultString());
            printResult(results);
        }

        // 會話發生錯誤回調接口
        public void onError(SpeechError error) {
            // 錯誤碼:10118(您沒有說話),多是錄音機權限被禁,須要提示用戶打開應用的錄音權限。
            if(error.getErrorCode()==10118){
                Toast.makeText(getApplicationContext(), "你好像沒有說話哦",
                        Toast.LENGTH_SHORT).show();
            }
            Toast.makeText(getApplicationContext(), error.getPlainDescription(true),
                    Toast.LENGTH_SHORT).show();
            
        }// 獲取錯誤碼描述}

        // 開始錄音
        public void onBeginOfSpeech() {
            Log.d(TAG, "開始說話");
            Toast.makeText(getApplicationContext(), "開始說話",
                    Toast.LENGTH_SHORT).show();
        }

        // 結束錄音
        public void onEndOfSpeech() {
            Log.d(TAG, "說話結束");
            Toast.makeText(getApplicationContext(), "說話結束",
                    Toast.LENGTH_SHORT).show();
        }

        // 擴展用接口
        public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
        }

        //音量
        @Override
        public void onVolumeChanged(int volume, byte[] data) {
            // TODO Auto-generated method stub
            Log.d(TAG, "當前說話音量大小"+volume);
            
        }

    };

    /**
     * 聽寫UI監聽器
     */
    private RecognizerDialogListener mRecognizerDialogListener = new RecognizerDialogListener() {
        public void onResult(RecognizerResult results, boolean isLast) {
            printResult(results);
        }

        /**
         * 識別回調錯誤.
         */
        public void onError(SpeechError error) {
            Toast.makeText(getApplication(), error.getPlainDescription(true), Toast.LENGTH_SHORT).show();
        }

    };
    /**
     * 語音合成監聽
     */
    private SynthesizerListener mSynListener = new SynthesizerListener() {
        // 會話結束回調接口,沒有錯誤時,error爲null
        public void onCompleted(SpeechError error) {
            if (error != null) {
                Log.d("mySynthesiezer complete code:", error.getErrorCode()
                        + "");
            } else {
                Log.d("mySynthesiezer complete code:", "0");
            }
        }

        // 緩衝進度回調
        // percent爲緩衝進度0~100,beginPos爲緩衝音頻在文本中開始位置,endPos表示緩衝音頻在文本中結束位置,info爲附加信息。
        public void onBufferProgress(int percent, int beginPos, int endPos,
                String info) {
        }

        // 開始播放
        public void onSpeakBegin() {
        }

        // 暫停播放
        public void onSpeakPaused() {
        }

        // 播放進度回調
        // percent爲播放進度0~100,beginPos爲播放音頻在文本中開始位置,endPos表示播放音頻在文本中結束位置.
        public void onSpeakProgress(int percent, int beginPos, int endPos) {
        }

        // 恢復播放回調接口
        public void onSpeakResumed() {
        }

        // 會話事件回調接口
        public void onEvent(int arg0, int arg1, int arg2, Bundle arg3) {
        }
    };

    /**
     * 初始化語音合成監聽。
     */
    private InitListener mTtsInitListener = new InitListener() {
        @SuppressLint("ShowToast")
        @Override
        public void onInit(int code) {
            Log.d(TAG, "InitListener init() code = " + code);
            if (code != ErrorCode.SUCCESS) {
                // showTip("初始化失敗,錯誤碼:" + code);
                Toast.makeText(getApplicationContext(), "初始化失敗,錯誤碼:" + code,
                        Toast.LENGTH_SHORT).show();
            } else {
                // 初始化成功,以後能夠調用startSpeaking方法
                // 注:有的開發者在onCreate方法中建立完合成對象以後立刻就調用startSpeaking進行合成,
                // 正確的作法是將onCreate中的startSpeaking調用移至這裏
            }
        }
    };

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()) {
        case R.id.bt_speech:
            starSpeech();
            break;
        case R.id.bt_write:
            et_content.setText(null);
            mIatResults.clear();
            starWrite();
            break;
        default:
            break;
        }

    }
    
    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));
        }

        et_content.setText(resultBuffer.toString());
        et_content.setSelection(et_content.length());
    }

}

xml文件就一個EditText和兩個button就不貼了還有一個JsonParser類sdk文檔中sample中有

 

結束

  訊飛語音還有不少好玩的功能,好比人臉識別、聲紋識別、語音喚醒等你們看看文檔都很好實現的

相關文章
相關標籤/搜索