利用讯飞语音听写接口实现实时语音转写。

讯飞语音,识别真的很准确。

讯飞语音转写,实时的贵,不实时的慢。。。

今天尝试了用讯飞听写通过流的方式实现实时转写。

  1. 主要思路是这样。首先确认pcm文件的保存路径。
  2. 然后创建一个线程不断读写pcm内的内容变化。
  3. 每次读取1024*1024字节调用
    mIat.writeAudio(byte[] var1, int var2, int var3)方法,等待回调结果。
  4. 记录每次的回调结果,拼接字符串。

部分代码如下,下面代码是完整pcm文件的转写的代码。准确率和讯飞网页的识别率相差无几。

实现了之后发现。讯飞听写接口认证后才20000/天,没有认证500/天。可能讯飞也知道这个漏洞才加的限制吧

public static void startRecognizer(String path)
{
    audioDataList=null;
    resultText="";
    mIatResults.clear();
    // 设置参数
    setParam();

    // 也可以像以下这样直接设置音频文件路径识别(要求设置文件在sdcard上的全路径):
   /* mIat.setParameter(SpeechConstant.AUDIO_SOURCE, "-2");
    mIat.setParameter(SpeechConstant.ASR_SOURCE_PATH, path);
    mIat.startListening(mRecognizerListener);
    mIat.stopListening();*/

    // 设置音频来源为外部文件
    mIat.setParameter(SpeechConstant.AUDIO_SOURCE, "-1");
    byte[] audioData = FileUtil.readAudioFile(new File(path));

    if (null != audioData) {
        LogUtil.logInfo("开始音频流识别");
        // 一次(也可以分多次)写入音频文件数据,数据格式必须是采样率为8KHz或16KHz(本地识别只支持16K采样率,云端都支持),
        // 位长16bit,单声道的wav或者pcm
        // 写入8KHz采样的音频时,必须先调用setParameter(SpeechConstant.SAMPLE_RATE, "8000")设置正确的采样率
        // 注:当音频过长,静音部分时长超过VAD_EOS将导致静音后面部分不能识别。
        // 音频切分方法:FucUtil.splitBuffer(byte[] buffer,int length,int spsize);
        LogUtil.logInfo("audioData.length:"+audioData.length+",audioDataLen:"+audioDataLen);
        audioDataList= FileUtil.splitBuffer(audioData,audioData.length,audioDataLen);
        audioDataCurrIndex=0;
        writeAudio();

        /*mIat.startListening(mRecognizerListener);
        mIat.writeAudio(audioData, 0, audioData.length);
        mIat.stopListening();*/
    } else {
        mIat.cancel();
        LogUtil.logInfo("读取音频流失败");
    }
}
public static void writeAudio()
{
    if(audioDataList!=null)
    {
        if(audioDataList.size()>audioDataCurrIndex)
        {
            mIat.startListening(mRecognizerListener);
            mIat.writeAudio(audioDataList.get(audioDataCurrIndex), 0, audioDataList.get(audioDataCurrIndex).length);
            mIat.stopListening();
            audioDataCurrIndex++;
        }
    }

}

 

/**
 * 听写监听器。
 */
private static RecognizerListener mRecognizerListener = new RecognizerListener() {

    @Override
    public void onBeginOfSpeech() {
        // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入
        LogUtil.logInfo("开始说话");
    }

    @Override
    public void onError(SpeechError error) {
        // Tips:
        // 错误码:10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。
        if(mTranslateEnable && error.getErrorCode() == 14002) {
            LogUtil.logInfo( error.getPlainDescription(true)+"\n请确认是否已开通翻译功能" );
        } else {
            LogUtil.logInfo(error.getPlainDescription(true));
        }
        writeAudio();
    }

    @Override
    public void onEndOfSpeech() {
        // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
        LogUtil.logInfo("结束说话");
    }

    @Override
    public void onResult(RecognizerResult results, boolean isLast) {
        LogUtil.logInfo( results.getResultString());
        resultText+= JSON.parseObject(results.getResultString(), RecBean.class).getResult();
        LogUtil.logInfo(resultText);
        if( mTranslateEnable ){
            //printTransResult( results );
        }else{
           // printResult(results);
        }

        if (isLast) {
            // TODO 最后的结果
            writeAudio();
        }
    }

    @Override
    public void onVolumeChanged(int volume, byte[] data) {
        LogUtil.logInfo("当前正在说话,音量大小:" + volume);
        LogUtil.logInfo( "返回音频数据:"+data.length);
    }

    @Override
    public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
        // 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因
        // 若使用本地能力,会话id为null
        LogUtil.logInfo("事件eventType="+eventType);
        // if (SpeechEvent.EVENT_SESSION_ID == eventType) {
        //    String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
        //    Log.d(TAG, "session id =" + sid);
        // }
    }
};

/**
 * 参数设置
 *
 * @return
 */
public static void setParam() {
    // 清空参数
    mIat.setParameter(SpeechConstant.PARAMS, null);

    // 设置听写引擎
    mIat.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
    // 设置返回结果格式
    mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");

    if( mTranslateEnable ){
        LogUtil.logInfo( "translate enable" );
        mIat.setParameter( SpeechConstant.ASR_SCH, "1" );
        mIat.setParameter( SpeechConstant.ADD_CAP, "translate" );
        mIat.setParameter( SpeechConstant.TRS_SRC, "its" );
    }

    String lag = "mandarin";
    if (lag.equals("en_us")) {
        // 设置语言
        mIat.setParameter(SpeechConstant.LANGUAGE, "en_us");
        mIat.setParameter(SpeechConstant.ACCENT, null);

        if( mTranslateEnable ){
            mIat.setParameter( SpeechConstant.ORI_LANG, "en" );
            mIat.setParameter( SpeechConstant.TRANS_LANG, "cn" );
        }
    } else {
        // 设置语言
        mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        // 设置语言区域
        mIat.setParameter(SpeechConstant.ACCENT, lag);

        if( mTranslateEnable ){
            mIat.setParameter( SpeechConstant.ORI_LANG, "cn" );
            mIat.setParameter( SpeechConstant.TRANS_LANG, "en" );
        }
    }
    //此处用于设置dialog中不显示错误码信息
    //mIat.setParameter("view_tips_plain","false");

    // 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理
    mIat.setParameter(SpeechConstant.VAD_BOS, "10000");

    // 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音
    mIat.setParameter(SpeechConstant.VAD_EOS, "50000");

    // 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
    mIat.setParameter(SpeechConstant.ASR_PTT,  "1");

    // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
    // 注:AUDIO_FORMAT参数语记需要更新版本才能生效
    mIat.setParameter(SpeechConstant.AUDIO_FORMAT,"wav");
    mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory()+"/msc/iat.wav");
}

 

你可能感兴趣的:(利用讯飞语音听写接口实现实时语音转写。)