语音识别

前不久项目中用到了语音识别技术,因此就研究了一下语音识别技术在项目中的集成。由于我是在公司的设备上运行的,所以没有截图,为了直观方便的看一下效果,所以就在网上找了两张和我的项目运行后差不多的图片。

这里写图片描述

市场上的语音技术应用最广泛的有两种,一种是百度的语音识别,一种是科大讯飞的语音识别。两者之间的不同之处在于,前者是完全免费的,后者在离线状态识别语音是收费的。今天先记录一下科大讯飞在线的语音识别,等有机会在记录一下百度的语音识别。

首先需要在科大讯飞的开放平台上申请一个账号,申请的过程就不再描述。申请成功以后,平台会发放一个APPID号。这个ID号留待使用。 然后平台会让你创建一个应用,这时候你把自己的应用信息填好以后,选择SDK下载。

当SDK下载完以后,会得到一个ZIP压缩包,解开这个压缩包,会看到如下的文件:

这里写图片描述

其中assets目录里是资源文件,主要是语音识别的弹出框图片,可以原封不动拷过来。如果只是单纯的识别,还需要拷贝两个文件,一个是libs下的armeabi文件夹,一个是libs下的Msc.jar。拷贝完以后,放到项目的libs文件夹下。

准备工作完成以后,就可以进行代码的编写了,一般是在点击某个按钮以后,进入语音识别的情景。在这里假设点击了某个按钮的场景

package com.szh.speechdemo.activity;

import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;
import com.szh.speechdemo.R;
import com.szh.speechdemo.model.DictationResult;

public class MainActivity extends Activity {

    public static final String TAG = "MainActivity";
    private EditText etText;
    private Button btn_yysb;
    private Button btn_save;
    private RecognizerDialog iatDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        // 初始化即创建语音配置对象,只有初始化后才可以使用MSC的各项服务
        // 此接口在非主进程调用会返回null对象,如需在非主进程使用语音功能,请使用参数:SpeechConstant.APPID
        // +"=12345678," + SpeechConstant.FORCE_LOGIN +"=true"。
        setContentView(R.layout.activity_main);

        btn_yysb = (Button) findViewById(R.id.btn_yysb);
        etText = (EditText)findViewById(R.id.etText);
        btn_save = (Button) findViewById(R.id.btn_save);

        btn_save.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                SpeechUtility.getUtility().destroy();  
            }
        });



        btn_yysb.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // ①语音配置对象初始化
                SpeechUtility.createUtility(MainActivity.this, SpeechConstant.APPID + "=5a587636");
                // ②初始化有交互动画的语音识别器
                iatDialog = new RecognizerDialog(MainActivity.this, mInitListener);
                // ③设置监听,实现听写结果的回调
                iatDialog.setListener(new RecognizerDialogListener() {
                    String resultJson = "[";// 放置在外边做类的变量则报错,会造成json格式不对(?)

                    @Override
                    public void onResult(RecognizerResult recognizerResult, boolean isLast) {
                        System.out .println("-----------------   onResult   -----------------");
                        if (!isLast) {
                            resultJson += recognizerResult.getResultString() + ",";
                        } else {
                            resultJson += recognizerResult.getResultString() + "]";
                        }

                        if (isLast) {
                            // 解析语音识别后返回的json格式的结果
                            Gson gson = new Gson();
                            List<DictationResult> resultList = gson.fromJson(
                                    resultJson,
                                    new TypeToken<List<DictationResult>>() {
                                    }.getType());
                            String result = "";
                            for (int i = 0; i < resultList.size() - 1; i++) {
                                result += resultList.get(i).toString();
                            }
                            etText.setText(result);
                            // 获取焦点
                            etText.requestFocus();
                            // 将光标定位到文字最后,以便修改
                            etText.setSelection(result.length());
                        }
                    }

                    @Override
                    public void onError(SpeechError speechError) {
                        // 自动生成的方法存根
                        speechError.getPlainDescription(true);
                    }
                });
                // 开始听写,需将sdk中的assets文件下的文件夹拷入项目的assets文件夹下(没有的话自己新建)
                iatDialog.show();
            }
        });
    }

    // 3.开始听写 mIat.startListening(mRecoListener);
    // 听写监听器
    private InitListener mInitListener = new InitListener() {
        @Override
        public void onInit(int code) {
            Log.d(TAG, "SpeechRecognizer init() code = " + code);
            if (code != ErrorCode.SUCCESS) {
                Toast.makeText(MainActivity.this, "初始化失败,错误码:" + code, Toast.LENGTH_SHORT).show();
            }
        }
    };
}

当语音转化成文字的时候,我们还需要用到Gson进行转换成bean进行封装,bean结构如下:

package com.szh.speechdemo.model;

import java.util.List;

public class DictationResult {

    private String sn;
    private String ls;
    private String bg;
    private String ed;
    private List<Words> ws;

    public static class Words {
        private String bg;
        private List<Cw> cw;

        public static class Cw {
            private String w;
            private String sc;

            public String getW() {
                return w;
            }

            public void setW(String w) {
                this.w = w;
            }

            public String getSc() {
                return sc;
            }

            public void setSc(String sc) {
                this.sc = sc;
            }

            @Override
            public String toString() {
                return w;
            }
        }

        public String getBg() {
            return bg;
        }

        public void setBg(String bg) {
            this.bg = bg;
        }

        public List<Cw> getCw() {
            return cw;
        }

        public void setCw(List<Cw> cw) {
            this.cw = cw;
        }

        @Override
        public String toString() {
            String result = "";
            for (Cw cwTmp : cw) {
                result += cwTmp.toString();
            }
            return result;
        }
    }

    public String getSn() {
        return sn;
    }

    public void setSn(String sn) {
        this.sn = sn;
    }

    public String getLs() {
        return ls;
    }

    public void setLs(String ls) {
        this.ls = ls;
    }

    public String getBg() {
        return bg;
    }

    public void setBg(String bg) {
        this.bg = bg;
    }

    public String getEd() {
        return ed;
    }

    public void setEd(String ed) {
        this.ed = ed;
    }

    public List<Words> getWs() {
        return ws;
    }

    public void setWs(List<Words> ws) {
        this.ws = ws;
    }

    @Override
    public String toString() {
        String result = "";
        for (Words wsTmp : ws) {
            result += wsTmp.toString();
        }
        return result;
    }
}

在这里有些细节还需要注意:
第一点,SpeechUtility.getUtility().destroy();这句代码是注销语音的,如果语音已经被注销掉,但是在初始化的时候只初始化了一次,下次再注销的时候就会报错。
第二点,如果是在activity中,onCreate方法中如果不回调super.onCreate(savedInstanceState)方法,会出现闪退现象。

我把项目中用到的资源文件和jar包放上链接,有需要的可以自行下载。下载积分本来想设置成0积分,不过好像最少就是2,无法设置不要积分下载。如果嫌麻烦就从这下载,或者在网上搜别的也行。
链接如下:https://download.csdn.net/download/little_soybean/10354424

猜你喜欢

转载自blog.csdn.net/little_soybean/article/details/79727178