實(shí)現(xiàn)循環(huán)語音識(shí)別、合成簡單封裝

實(shí)現(xiàn)循環(huán)語音識(shí)別、合成簡單封裝

需求背景

最近項(xiàng)目上遇到一個(gè)需求:語音識(shí)別獲取文字后后臺(tái)交互獲取結(jié)果并語音合成播報(bào)

需求拆解

  • 語音識(shí)別(可打斷識(shí)別)
  • 語音播報(bào)(可打斷,打斷后開啟語音識(shí)別)


    image.png
graph LR
A[開始識(shí)別]-->B[是否識(shí)別成功]
B-->|是|C[識(shí)別成功]
B-->|否|D[識(shí)別失敗]
D-->|重新識(shí)別|A
C-->E[語音合成]
E-->A

代碼解析

1、此demo中集成了訊飛和云知聲兩個(gè)平臺(tái),此處解析以訊飛為例展開,云知聲解析在代碼中有注釋;

/**
     * iflytek訊飛
     * @param results
     * @param isLast
     */
    @Override
    public void onResult(RecognizerResult results, boolean isLast) {
        String text = JsonParser.parseIatResult(results.getResultString());
        result += text;
        if (isLast) {
            if (result.trim().length() > 0) {
                onResult(result);//識(shí)別到結(jié)果
                result = "";
            } else {
                result = "";
                Logger.i("Listener start");
               RecognizerManager.getInstance().startListening();//若沒有識(shí)別到結(jié)果再次開啟識(shí)別
            }
        }
    }
    

識(shí)別失敗再次開啟識(shí)別

@Override
    public void onError(SpeechError error) {
        // Tips:
        // 錯(cuò)誤碼:10118(您沒有說話),可能是錄音機(jī)權(quán)限被禁,需要提示用戶打開應(yīng)用的錄音權(quán)限。
        //         10114 網(wǎng)絡(luò)異常
        //         20002 獲取結(jié)果超時(shí)
        Logger.i(error.getPlainDescription(true));
        if (error.getErrorCode() == 10118 || error.getErrorCode() == 10114
                || error.getErrorCode() == 20002) {
            Logger.i("Listener start");
            RecognizerManager.getInstance().startListening();
        }
    }

音量回調(diào)方法

    @Override
    public void onVolumeChanged(int volume, byte[] data) {
        onVolumeChanged(volume);
    }

2、語音合成部分
播放完成開始識(shí)別

 @Override
    public void onCompleted(SpeechError error) {
        if (error == null) {
            Logger.i("播放完成");
        }
        completed();
        SpeechManager.getInstance().setStatus(Status.STATES_STOP);
        Logger.i("Listener start");
        RecognizerManager.getInstance().startListening();
    }

3、簡單封裝的語音管理類RecognizerManager、SpeechManager實(shí)現(xiàn)邏輯上的切換

RecognizerManager

1、初始化

  private void init() {
        if (PlatformConfig.PLATFORM_USC.equals(PlatformConfig.PLATFORM)) {//可配置的語音引擎
            mUnderstander = new SpeechUnderstander(AppUtils.getAppContext(), UscConfig.appKey,
                    UscConfig.secret);
            mUnderstander.setListener(mSpeechUnderstanderListener);
            setUscParam();
            mUnderstander.start();
        } else {
            mIat = SpeechRecognizer.createRecognizer(AppUtils.getAppContext(), mInitListener);
            Logger.d(mIat);
        }
    }

2、生命周期綁定

  public void startListening() {
        if (PlatformConfig.PLATFORM_USC.equals(PlatformConfig.PLATFORM)) {
            if (mUnderstander == null) {
                init();
                return;
            }
            mUnderstander.start();
        } else {
            if (mIat == null) {
                init();
                return;
            }
            int ret = mIat.startListening(mRecognizerListener);
            if (ret != ErrorCode.SUCCESS) {
                Logger.i("聽寫失敗,錯(cuò)誤碼:" + ret);
            } else {
                Logger.i(AppUtils.getAppContext().getString(R.string.text_begin));
            }
        }
    }
    
    public void pause() {
        if (PlatformConfig.PLATFORM_USC.equals(PlatformConfig.PLATFORM_USC)) {
            if (mUnderstander != null) {
                mUnderstander.stop();
                mUnderstander.cancel();
            }
        } else {
            if (null != mIat) {
                mIat.stopListening();
            }
        }
    }

    public void release() {
        if (PlatformConfig.PLATFORM.equals(PlatformConfig.PLATFORM_USC)) {
            if (mUnderstander != null) {
                mUnderstander.stop();
                mUnderstander.cancel();
                mUnderstander.release(SpeechConstants.ASR_RELEASE_ENGINE, "");
            }
        } else {
            if (mIat != null) {
                mIat.stopListening();
                mIat.cancel();
                mIat.destroy();
            }
        }
    }

SpeechManager

1、合成方法

   private void play() {
        if (PlatformConfig.PLATFORM_USC.equals(PlatformConfig.PLATFORM)) {
            int code = uscTts.playText(text);
            setStatus(Status.STATES_PLAYING);
            Logger.i("Listener stop");
            RecognizerManager.getInstance().release();
        } else {
            int code = iflytekTts.startSpeaking(text, synthesizer);
            if (code != ErrorCode.SUCCESS) {
                setStatus(Status.STATES_STOP);
                Logger.i("語音合成失敗,錯(cuò)誤碼: " + code);
            } else {
                setStatus(Status.STATES_PLAYING);
                Logger.i("Listener stop");
                RecognizerManager.getInstance().release();
            }
        }
    }

2、生命周期綁定

/**
     * 暫停
     */
    public void pause() {
        pauseSpeak();
        if (getStatus() == Status.STATES_PLAYING) {
            setStatus(Status.STATES_PAUSE);
        }
        Logger.i("Listener start");
//        RecognizerManager.getInstance().startListening();
    }

    /**
     * 停止播報(bào)
     *
     * @param isListen 停止播報(bào)是否開啟監(jiān)聽
     */
    public void stop(boolean isListen) {
        stopSpeak();
        if (getStatus() == Status.STATES_PAUSE || getStatus() == Status.STATES_PLAYING) {
            setStatus(Status.STATES_STOP);
        }
        if (isListen) {
            Logger.i("Listener start");
            RecognizerManager.getInstance().startListening();
        }
    }

    /**
     * 恢復(fù)播報(bào)
     */
    public void resume() {
        getInstance().resumeSpeak();
        if (getStatus() == Status.STATES_PAUSE) {
            getInstance().setStatus(Status.STATES_PLAYING);
        }
        Logger.i("Listener stop");
        RecognizerManager.getInstance().release();
    }

    private void resumeSpeak() {
        if (PlatformConfig.PLATFORM_USC.equals(PlatformConfig.PLATFORM)) {
            if (uscTts != null) {
                uscTts.resume();
            }
        } else {
            if (iflytekTts != null) {
                iflytekTts.resumeSpeaking();
            }
        }
    }

    private void stopSpeak() {
        if (PlatformConfig.PLATFORM_USC.equals(PlatformConfig.PLATFORM)) {
            if (uscTts != null) {
                uscTts.stop();
                uscTts.cancel();
            }
        } else {
            if (iflytekTts != null) {
                iflytekTts.stopSpeaking();
            }
        }
    }

    private void pauseSpeak() {
        if (PlatformConfig.PLATFORM_USC.equals(PlatformConfig.PLATFORM)) {
            if (uscTts != null) {
                uscTts.pause();
            }
        } else {
            if (iflytekTts != null) {
                iflytekTts.pauseSpeaking();
            }
        }
    }

    public void release() {
        if (PlatformConfig.PLATFORM_USC.equals(PlatformConfig.PLATFORM)) {
            if (uscTts != null) {
                uscTts.stop();
                uscTts.release(SpeechConstants.TTS_RELEASE_ENGINE, null);
            }
        } else {
            if (iflytekTts != null) {
                iflytekTts.stopSpeaking();
                iflytekTts.destroy();
            }
        }
    }

SDK替換

demo的訊飛可直接使用,云知聲需要申請(qǐng)appkey

友情鏈接

  1. 訊飛開發(fā)文檔

  2. 云知聲文檔

demo地址

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文寫于兩年前,一直是未公開狀態(tài),屬內(nèi)部交流使用,現(xiàn)在也換公司了,公開發(fā)布下。 一、相關(guān)公司介紹 1.科大訊飛 網(wǎng)...
    kevin282閱讀 8,258評(píng)論 1 23
  • 語音方案比對(duì)介紹 語音交互是現(xiàn)今應(yīng)用最多的智能交互方式,在人工智能越來越火的當(dāng)下應(yīng)用十分廣泛,所以特別針對(duì)車內(nèi)環(huán)境...
    莫君陌閱讀 3,830評(píng)論 0 6
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,022評(píng)論 4 61
  • 學(xué)習(xí)有用嗎? 學(xué)習(xí)確實(shí)是人類文明發(fā)展過程中最神秘也最引人入勝的話題之一,盡管我們每時(shí)每刻都在學(xué)習(xí),卻也無法給出一個(gè)...
    耳洞先生閱讀 1,005評(píng)論 0 5
  • 一、前幾天,女兒說數(shù)學(xué)有點(diǎn)問題,老公的朋友正好在女兒的學(xué)校教高三數(shù)學(xué),我聯(lián)系了老公的朋友,約好前天晚上給女兒補(bǔ)補(bǔ)課...
    幸福種子成長陜西三原分群群主閱讀 96評(píng)論 0 0

友情鏈接更多精彩內(nèi)容