码迷,mamicode.com
首页 > 其他好文 > 详细

语音识别(本地+第三方)

时间:2015-05-28 21:34:24      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:android   语音识别   

语音识别主要的功能就是在用户不方便输入的时候找一个替代输入的选择。


1.本地语音识别


下面的代码首先创建SpeechRecognizer对象,并设置回调函数监听器。当在点击监听器中调用doSpeechRecognition()方法时,会使用语言参数和一个指示要在处理过程中分发部分结果的标志参数初始化语音识别。

public class MainActivity extends Activity implements View.OnClickListener{
    private Button speechBut;
    private TextView result;
    private SpeechRecognizer mSpeechRecognizer;
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.speechBut:
                doSpeechRecognition(v);
                break;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.speechBut=(Button)findViewById(R.id.speechBut);
        this.speechBut.setOnClickListener(this);
        this.result=(TextView)findViewById(R.id.result);
        this.mSpeechRecognizer=SpeechRecognizer.createSpeechRecognizer(this);
        this.mSpeechRecognizer.setRecognitionListener(new MyRecognitionListener());
    }

    public void doSpeechRecognition(View view){
        view.setEnabled(false);
        Intent recognitionIntent=new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        recognitionIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS,true);
        recognitionIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE,"zh-CN");
        this.mSpeechRecognizer.startListening(recognitionIntent);
    }

    private class MyRecognitionListener implements RecognitionListener{
        @Override
        public void onReadyForSpeech(Bundle params) {

        }

        @Override
        public void onBeginningOfSpeech() {
            Log.i("llllllllllllllllllll","onBeginningOfSpeech");
            result.setText("");
        }

        @Override
        public void onRmsChanged(float rmsdB) {

        }

        @Override
        public void onBufferReceived(byte[] buffer) {

        }

        @Override
        public void onEndOfSpeech() {
            Log.i("llllllllllllllllllll","onEndOfSpeech");
            speechBut.setEnabled(true);
        }

        @Override
        public void onError(int error) {
            Log.i("llllllllllllllllllll","onError");
            speechBut.setEnabled(true);
        }

        @Override
        public void onResults(Bundle results) {
            Log.i("llllllllllllllllllll","onResults");
            ArrayList<String> partialResults=results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
            if(partialResults!=null && partialResults.size()>0){
                String bestResult=partialResults.get(0);
                result.setText(bestResult+".");
            }
        }

        @Override
        public void onPartialResults(Bundle bundle) {
            Log.i("llllllllllllllllllll","onPartialResults");
            ArrayList<String> partialResults=bundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
            if(partialResults!=null && partialResults.size()>0){
                String bestResult=partialResults.get(0);
                result.setText(bestResult);
            }
        }

        @Override
        public void onEvent(int eventType, Bundle params) {

        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        this.mSpeechRecognizer.destroy();
    }
}

现在监听器会按照顺序接受每个方法的调用。本例在onPartialResult()方法中展现部分识别的结果,直到在onResult()方法中得到最终的结果。


一个更高级的应用程序还可以拦截单词,并监听特定的命令。这样一来,应用程序可以一直进行语音识别,直到用户明确告诉它停止-----例如,一个听写应用允许用户说“停止”单词并暂停一会后在句子间添加句号。


2.第三方语音识别(以讯飞为例)


我们大家都知道,一般Android手机是不支持中文语音识别的,我们有时候连文字转语音都要下载第三方文字转语音(TTS)API,更何况语音转文字。所以一般时候必须利用第三方提供SDK来丰富我们自己的应用功能。


就目前国内而言,在语音方面做的最好的也就属讯飞语音了。下面的开发以讯飞为例。


首先我们得到讯飞开放平台http://www.xfyun.cn/注册一个帐号。

技术分享

然后如上图所示创建一个新应用,创建完应用后我们会得到如图所示的Appid:

技术分享

然后下载相关的SDK包放到指定的位置,本文以Android Studio为例:

技术分享

下面就可以进入开发阶段了,首先本例语音识别必须借助网络,所以本例需要的权限如下:

<!--连接网络权限,用于执行云端语音能力 -->
<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" />

本来想讲解一下具体的代码突然觉得自己的代码已经注解够详细了,并不需要一句一句的讲解。相信大家都看的懂。

public class MainActivity extends Activity {
    private static String TAG = MainActivity.class.getSimpleName();
    private Toast mToast;
    private Button showDialogs;
    private Button stop;
    private Button cancel;
    private TextView content;
    // 语音听写对象
    private SpeechRecognizer mIat;
    // 语音听写UI
    private RecognizerDialog mIatDialog;
    // 用HashMap存储听写结果
    private HashMap<String, String> mIatResults = new LinkedHashMap<String, String>();
    // 引擎类型
    private String mEngineType = SpeechConstant.TYPE_CLOUD;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.showDialogs = (Button) findViewById(R.id.showDialogs);
        this.stop = (Button) findViewById(R.id.stopL);
        this.cancel=(Button)findViewById(R.id.cancel);
        this.content = (TextView) findViewById(R.id.content);
        SpeechUtility.createUtility(this, SpeechConstant.APPID + "=5566a1f6");
        // 初始化识别无UI识别对象
        // 使用SpeechRecognizer对象,可根据回调消息自定义界面;
        mIat = SpeechRecognizer.createRecognizer(this, mInitListener);
        // 初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizer
        // 使用UI听写功能,请根据sdk文件目录下的notice.txt,放置布局文件和图片资源
        mIatDialog = new RecognizerDialog(MainActivity.this, mInitListener);
        this.showDialogs.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                content.setText("");// 清空显示内容
                mIatResults.clear();
                myRecognize();
                // 显示听写对话框
                mIatDialog.show();
                showTip(getString(R.string.text_begin));
            }
        });
        this.stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mIat.stopListening();
                showTip("停止听写");
            }
        });
        this.cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mIat.cancel();
                showTip("取消听写");
            }
        });
    }

    /**
     * 初始化监听器。
     */
    private InitListener mInitListener = new InitListener() {

        @Override
        public void onInit(int code) {
            Log.d(TAG, "SpeechRecognizer init() code = " + code);
            if (code != ErrorCode.SUCCESS) {
                showTip("初始化失败,错误码:" + code);
            }
        }
    };
    
    private void showTip(final String str) {
       this.mToast.makeText(this,str,Toast.LENGTH_SHORT).show();
    }

    private void myRecognize() {
        // 清空参数
        mIat.setParameter(SpeechConstant.PARAMS, null);
        // 设置听写引擎
        mIat.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
        // 设置返回结果格式
        mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");
        //设置引擎为转写
        mIatDialog.setParameter(SpeechConstant.DOMAIN, "iat");
        //设置识别语言为中文
        mIatDialog.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        //设置方言为普通话
        mIatDialog.setParameter(SpeechConstant.ACCENT, "mandarin");
        //设置录音采样率为
        mIatDialog.setParameter(SpeechConstant.SAMPLE_RATE, "16000");
        //设置监听对象
        mIatDialog.setListener(recognizerDialogListener);
        // 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理
        mIat.setParameter(SpeechConstant.VAD_BOS, "4000");
        // 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音
        mIat.setParameter(SpeechConstant.VAD_EOS, "4000");
        // 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
        mIat.setParameter(SpeechConstant.ASR_PTT, "1");
        // 设置听写结果是否结果动态修正,为“1”则在听写过程中动态递增地返回结果,否则只在听写结束之后返回最终结果
        // 注:该参数暂时只对在线听写有效
        mIat.setParameter(SpeechConstant.ASR_DWA, "0");
    }

    private RecognizerDialogListener recognizerDialogListener = new RecognizerDialogListener() {
        @Override
        public void onError(SpeechError error) {
            // TODO Auto-generated method stub
        }
        //当说话说完后,会回调该方法,JSON字符串在result
        @Override
        public void onResult(RecognizerResult result, boolean isLast) {
            Log.d(TAG, result.getResultString());
            printResult(result);
        }
    };

    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));
        }
        content.setText(resultBuffer.toString());
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 退出时释放连接
        mIat.cancel();
        mIat.destroy();
    }
}
当然里面有一个JSON解析,你可以自己写,也可以用SDK里面包装好的JsonParser类。

技术分享

JSON解析不会的可以参考http://blog.csdn.net/liyuanjinglyj/article/details/45890825该网址

最后运行结果如下图所示:

技术分享                     技术分享

语音识别(本地+第三方)

标签:android   语音识别   

原文地址:http://blog.csdn.net/liyuanjinglyj/article/details/46127607

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!