9.【小萌伴Android】機(jī)器人陪聊--語音功能及其實(shí)現(xiàn)

前幾篇都是介紹一些輔助功能殉挽,如新聞、H5游戲裳擎、段子趣圖涎永、原生手電筒應(yīng)用等,現(xiàn)在再來聊聊機(jī)器人陪聊主體功能--語音功能及其實(shí)現(xiàn)土辩。

【小萌伴】語音

【小萌伴】中的語音功能使用的是百度語音sdk支救,包含語音輸入抢野、語音播放拷淘、語音轉(zhuǎn)文字、文字轉(zhuǎn)語音指孤、聲音變換启涯、離線語音語義識別、語音喚醒等恃轩。

其中功能的主要可分為三部分:語音識別结洼、語音合成、語音喚醒叉跛。(我用的sdk比較老了松忍,下面代碼也許已經(jīng)不兼容新sdk,具體請參考 百度語音 官網(wǎng)

ChatActivity實(shí)現(xiàn)了RecognitionListener及SpeechSynthesizerListener接口筷厘,這兩個(gè)接口是語音識別與合成的監(jiān)聽鸣峭。

初始化

語音識別和語音合成需要在進(jìn)入Activity后執(zhí)行初始化,在銷毀時(shí)進(jìn)行銷毀酥艳。初始化如下摊溶,語音識別初始化沒有封裝,語音合成則用TtsUtils封裝了一下充石。

    mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(ChatActivity.this, new ComponentName(ChatActivity.this, VoiceRecognitionService.class));
    // 注冊監(jiān)聽器
    mSpeechRecognizer.setRecognitionListener(ChatActivity.this);
    mSpeechSynthesizer = TtsUtils.getSpeechSynthesizer(ChatActivity.this, ChatActivity.this, getVoice(mRobot));

語音輸入及識別

對這一塊莫换,通過BdVoiceUtil類進(jìn)行了封裝,通過調(diào)用如下方法即可開啟語音識別:

    BdVoiceUtil.startASR(mSpeechRecognizer, mSpeechSynthesizer, true);

在RecognitionListener的回調(diào)中獲取語音識別的結(jié)果骤铃,包括實(shí)時(shí)(部分)轉(zhuǎn)換及全量(整句話)轉(zhuǎn)換為文字拉岁,在onResults或者onPartialResults中將轉(zhuǎn)換的文字發(fā)送到機(jī)器人api,之后邏輯與正常機(jī)器人陪聊一致惰爬。

語音合成

將機(jī)器人返回的語音轉(zhuǎn)換為文字喊暖,這一塊也在BdVoiceUtil進(jìn)行了一下封裝:

    BdVoiceUtil.startTTS(mSpeechSynthesizer, msg.getContent());

通過以上代碼即可以開始轉(zhuǎn)換,將msg.getContent()轉(zhuǎn)換為語音补鼻,可以通過SpeechSynthesizerListener監(jiān)聽轉(zhuǎn)換是否成功哄啄,語音播放的進(jìn)度等。

語音合成后风范,也可以通過setParam控制聲音(0 (普通女聲), 1 (普通男聲), 2 (特別男聲), 3 (情感男聲), 4 (童聲))等

    mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, String.valueOf(getVoice(robot)));

語音喚醒

語音喚醒功能在這里沒有用到咨跌,主要是在后續(xù)介紹的“找手機(jī)”功能用到;包括語音喚醒硼婿、通過語音識別達(dá)到喚醒的目的锌半、與微信等的語音輸入沖突問題等,這些留到后續(xù)介紹“找手機(jī)”時(shí)再說寇漫。

BdVoiceUtil

對語音相關(guān)的簡單封裝刊殉,其實(shí)還有TtsUtils等殉摔,總的代碼太多,這里就不貼了...

public class BdVoiceUtil {

    /**
     * 開始識別(會先停止SpeechSynthesizer)
     * @param speechRecognizer
     * @param mSpeechSynthesizer
     * @param bindParams 是否需要提示音
     */
    public static void startASR(SpeechRecognizer speechRecognizer, SpeechSynthesizer mSpeechSynthesizer, boolean bindParams) {
        stopTTS(mSpeechSynthesizer);
        Intent intent = new Intent();
        bindParams(intent, bindParams);
        if(speechRecognizer != null) {
            speechRecognizer.startListening(intent);
        }
    }

    public static void stopASR(SpeechRecognizer speechRecognizer) {
        //  說完了
        if(speechRecognizer != null) {
            speechRecognizer.stopListening();
        }
    }

    public static void cancelASR(SpeechRecognizer speechRecognizer) {
        // 取消
        if(speechRecognizer != null) {
            speechRecognizer.cancel();
        }
    }

    public static void destroyASR(SpeechRecognizer speechRecognizer) {
        cancelASR(speechRecognizer);
        if(speechRecognizer != null) {
            speechRecognizer.destroy();
        }
    }

    public static void bindParams(Intent intent, boolean hintSound) {
        if(hintSound) {
            // 設(shè)置識別參數(shù)
            intent.putExtra(TtsUtils.EXTRA_SOUND_START, R.raw.bdspeech_recognition_start);
            intent.putExtra(TtsUtils.EXTRA_SOUND_END, R.raw.bdspeech_speech_end);
            intent.putExtra(TtsUtils.EXTRA_SOUND_SUCCESS, R.raw.bdspeech_recognition_success);
            intent.putExtra(TtsUtils.EXTRA_SOUND_ERROR, R.raw.bdspeech_recognition_error);
            intent.putExtra(TtsUtils.EXTRA_SOUND_CANCEL, R.raw.bdspeech_recognition_cancel);
        }
        intent.putExtra("sample", 16000); // 離線僅支持16000采樣率
        intent.putExtra("language", "cmn-Hans-CN"); // 離線僅支持中文普通話
        intent.putExtra("prop", 20000); // 輸入
        // 語音輸入附加資源记焊,value替換為資源文件實(shí)際路徑
        // 離線包過大逸月,暫不考慮支持 intent.putExtra("lm-res-file-path", "/path/to/s_2_InputMethod");
    }

    public static EventManager initEventWakeUp(final Activity context) {
        // 喚醒功能打開步驟
        // 1) 創(chuàng)建喚醒事件管理器
        EventManager mWpEventManager = EventManagerFactory.create(context, "wp");
        // 2) 注冊喚醒事件監(jiān)聽器
        mWpEventManager.registerListener(new EventListener() {
            @Override
            public void onEvent(String name, String params, byte[] data, int offset, int length) {
                try {
                    if(params == null) {
                        return;
                    }
                    JSONObject json = new JSONObject(params);
                    if ("wp.data".equals(name)) { // 每次喚醒成功, 將會回調(diào)name=wp.data的時(shí)間, 被激活的喚醒詞在params的word字段
                        String word = json.getString("word"); // 喚醒詞
                        WpEventManagerUtil.doEvent(context, word);
                        if(Logs.isDebug()) {
                            Logs.logI(BdVoiceUtil.class.getSimpleName(), "百度語音喚醒" + word);
                        }
                    } else if ("wp.exit".equals(name)) {
                        // 喚醒已經(jīng)停止
                    }
                } catch (JSONException e) {
                    throw new AndroidRuntimeException(e);
                }
            }
        });
        return mWpEventManager;
    }
    public static EventManager eventWakeUp(final Activity context, EventManager mWpEventManager) {
        if(mWpEventManager == null) {
            mWpEventManager = initEventWakeUp(context);
        }
        // 3) 通知喚醒管理器, 啟動喚醒功能
        HashMap params = new HashMap();
        params.put("kws-file", "assets:///WakeUp.bin"); // 設(shè)置喚醒資源, 喚醒資源請到 http://yuyin.baidu.com/wake#m4 來評估和導(dǎo)出
        mWpEventManager.send("wp.start", new JSONObject(params).toString(), null, 0, 0);
        return mWpEventManager;
    }

    public static void eventWekeUpStop(EventManager mWpEventManager) {
        if(mWpEventManager != null) {
            // 停止喚醒監(jiān)聽
            mWpEventManager.send("wp.stop", null, null, 0, 0);
        }
    }


    public static void stopTTS(SpeechSynthesizer mSpeechSynthesizer) {
        if(mSpeechSynthesizer != null) {
            mSpeechSynthesizer.stop();
        }
    }

    public static void releaseTTS(SpeechSynthesizer mSpeechSynthesizer) {
        stopTTS(mSpeechSynthesizer);
        if(mSpeechSynthesizer != null) {
            mSpeechSynthesizer.release();
        }
    }

    public static void startTTS(SpeechSynthesizer mSpeechSynthesizer, String text) {
        stopTTS(mSpeechSynthesizer);
        if(mSpeechSynthesizer != null) {
            mSpeechSynthesizer.speak(text);
        }
    }
}

頁面布局與一般輸入框沒大差別,這里就不多說了~~~

個(gè)人博客: IT老五
微信公眾號:IT老五(it-lao5)遍膜,一起源創(chuàng)碗硬,一起學(xué)習(xí)!

相關(guān)內(nèi)容:
【小萌伴Android】相關(guān)文章目錄
1.【小萌伴Android】思量再三瓢颅,終于鼓起勇氣開源~
2.【小萌伴Android】機(jī)器人陪聊模塊分享
3.【小萌伴Android】新聞/H5游戲模塊及廣告過濾
4.【小萌伴Android】段子趣圖模塊及其實(shí)現(xiàn)段子趣圖數(shù)據(jù)爬取
5.【小萌伴Android】原生小游戲及其實(shí)現(xiàn)(一)2048
6.【小萌伴Android】原生小游戲及其實(shí)現(xiàn)(二)小鳥
7.【小萌伴Android】原生小游戲及其實(shí)現(xiàn)(三)飛機(jī)
8.【小萌伴Android】手電筒功能及其實(shí)現(xiàn)
9.【小萌伴Android】機(jī)器人陪聊--語音功能及其實(shí)現(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恩尾,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子挽懦,更是在濱河造成了極大的恐慌翰意,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件信柿,死亡現(xiàn)場離奇詭異冀偶,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)角塑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門蔫磨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人圃伶,你說我怎么就攤上這事堤如。” “怎么了窒朋?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵搀罢,是天一觀的道長。 經(jīng)常有香客問我侥猩,道長榔至,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任欺劳,我火速辦了婚禮唧取,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘划提。我一直安慰自己枫弟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布鹏往。 她就那樣靜靜地躺著淡诗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上韩容,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天款违,我揣著相機(jī)與錄音,去河邊找鬼群凶。 笑死插爹,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的座掘。 我是一名探鬼主播递惋,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼溢陪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起睛廊,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤形真,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后超全,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咆霜,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年嘶朱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蛾坯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡疏遏,死狀恐怖脉课,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情财异,我是刑警寧澤倘零,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站戳寸,受9級特大地震影響呈驶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜疫鹊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一袖瞻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拆吆,春花似錦聋迎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春娄昆,著一層夾襖步出監(jiān)牢的瞬間佩微,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工萌焰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哺眯,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓扒俯,卻偏偏與公主長得像奶卓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子撼玄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容