创新实训——第二周2

我完成了语音识别功能。

1.因为我们的应用是基于英文环境,所以经过调查我们选择了科大讯飞语音云。

首先申请一个appid,然后添加语音听写服务,下载对应的SDK

2.下载完成,解压压缩包如下图所示


3.assets文件夹中的内容拷贝到项目assets文件夹(新建)中,将Msc.jar和Sunflower.jar拷贝到文件夹libs中,在和res同级的目录下创建jniLibs文件夹(),并将下载下来的libs目录下的所有libmsc.so文件拷贝到该文件夹下(很重要,目录结构一定不要创建错,否则会报错误“创建对象失败,请确认 libmsc.so 放置正确,且有调用 createUtility 进行初始化”)

4.在AndroidMainfest.xml中添加如下权限


<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<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.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

将申请的APPID记录下来,并保存到string文件中

5.在入口处初始化SpeechUtility对象

protected void onCreate(Bundle savedInstanceState) {
    SpeechUtility.createUtility(MainActivity.this,"appid="+getString(R.string.app_id));

6.初始化所需对象数据

private void initData() {
    context = MainActivity.this;    // 初始化识别无UI识别对象    // 使用SpeechRecognizer对象,可根据回调消息自定义界面;    mIat = SpeechRecognizer.createRecognizer(context, mInitListener);    // 初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizer    // 使用UI听写功能,请根据sdk文件目录下的notice.txt,放置布局文件和图片资源    mIatDialog = new RecognizerDialog(context, mInitListener);    mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT);    mSharedPreferences = getSharedPreferences(MainActivity.PREFER_NAME,            Activity.MODE_PRIVATE);}

7.点击开始按钮时,设置所需要的参数,弹出话筒框,并设置监听到的信息的监听,mIat是SpeechRecognizer类型的语音听写对象。

private void setOnclickListener() {
    btStart.setOnClickListener(new View.OnClickListener() {
        @Override        public void onClick(View v) {
            checkSoIsInstallSucceed();
            etContent.setText(null);// 清空显示内容
            mIatResults.clear();            // 设置参数
            setParam();
            boolean isShowDialog = mSharedPreferences.getBoolean(
                    getString(R.string.pref_key_iat_show), true);
            if (isShowDialog) {
                // 显示听写对话框                
                mIatDialog.setListener(mRecognizerDialogListener);
                mIatDialog.show();
                showTip(getString(R.string.text_begin));
            } else {
                // 不显示听写对话框
                ret = mIat.startListening(mRecognizerListener);
                if (ret != ErrorCode.SUCCESS) {
                    showTip("听写失败,错误码:" + ret);
                } else {
                    showTip(getString(R.string.text_begin));
public void setParam() {
    // 清空参数   
    mIat.setParameter(SpeechConstant.PARAMS, null);
    // 设置听写引擎
    mIat.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
    // 设置返回结果格式
    mIat.setParameter(SpeechConstant.RESULT_TYPE,"json");
    mIat.setParameter(SpeechConstant.LANGUAGE,"en_us");
    // 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理
    mIat.setParameter(SpeechConstant.VAD_BOS, mSharedPreferences.getString("iat_vadbos_preference", "4000"));
    // 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音
    mIat.setParameter(SpeechConstant.VAD_EOS, mSharedPreferences.getString("iat_vadeos_preference", "1000"));
    // 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
    mIat.setParameter(SpeechConstant.ASR_PTT, mSharedPreferences.getString("iat_punc_preference", "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");

8.在界面销毁的时候,释放连接

protected void onDestroy() {
super.onDestroy();
    if (null != mIat) {
        // 退出时释放连接
        mIat.cancel();
        mIat.destroy(); 
   }
}

9.对于结果的显示,要写一个JsonParser类用于结果解析(参考科大讯飞源码)

String text = JsonParser.parseIatResult(results.getResultString());
package com.example.liche.voicerecog2;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.json.JSONArray;
/** * Created by tx on 2018/4/25. */
public class JsonParser {
    public static String parseIatResult(String json) {
        StringBuffer ret = new StringBuffer();
        try {
            JSONTokener tokener = new JSONTokener(json);
            JSONObject joResult = new JSONObject(tokener);
            JSONArray words = joResult.getJSONArray("ws");
            for (int i = 0; i < words.length(); i++) {
                // 转写结果词,默认使用第一个结果
                JSONArray items = words.getJSONObject(i).getJSONArray("cw");               
	      JSONObject obj = items.getJSONObject(0);
                ret.append(obj.getString("w"));           }
        } catch (Exception e) {
            e.printStackTrace();        }
        return ret.toString();    }

    public static String parseGrammarResult(String json) {
        StringBuffer ret = new StringBuffer();
        try {
            JSONTokener tokener = new JSONTokener(json);
            JSONObject joResult = new JSONObject(tokener);
            JSONArray words = joResult.getJSONArray("ws");
            for (int i = 0; i < words.length(); i++) {
                JSONArray items = words.getJSONObject(i).getJSONArray("cw");
                for(int j = 0; j < items.length(); j++)
                {
                    JSONObject obj = items.getJSONObject(j);
                    if(obj.getString("w").contains("nomatch"))
                    {
                        ret.append("没有匹配结果.");
                        return ret.toString();                    }
                    ret.append("【结果】" + obj.getString("w"));
                    ret.append("【置信度】" + obj.getInt("sc"));
                    ret.append("\n");                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            ret.append("没有匹配结果.");        }
        return ret.toString();    }
}

10.在Android Studio中使用C/C++(否则报错)

使用 SDK Manager 来安装组件:

1. 打开一个项目,从菜单栏中选择 Tools > Android > SDK Manager

2. 点击 SDK Tools 选项卡。

3. 勾选 LLDB,CMake 和 NDK。

然后在新建项目时勾选Include C++ Support,运行时就不会报错。但我的项目已经建好,在此基础上添加c++支持我参考了以下网站:https://blog.csdn.net/wl9739/article/details/52607010

11在代码中实现语音识别的效果,现在可以实现输出正常本文,在以后的工作中会加工使其能够输出自定义手写字体

将识别结果转为String类型

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));
        }

        new_piece=resultBuffer.toString();
    }
监听器,用于监听语音输入时的动作,作用于监听的Button上
private RecognizerListener mRecognizerListener = new RecognizerListener() {

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

        @Override
        public void onError(SpeechError error) {
            // Tips:
            // 错误码:10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。
            // 如果使用本地功能(语记)需要提示用户开启语记的录音权限。
            showTip(error.getPlainDescription(true));
        }

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

        @Override
        public void onResult(RecognizerResult results, boolean isLast) {
            //Log.L(results.getResultString());
            System.out.println("间断结果——————————————————————————————————");
            printResult(results);
            if(isLast){
                //因为是last,所以new_piece稳定到了最终结果,不再变化。
                result_string+=new_piece;
                mEtInput.setText(result_string);
        @Override
        public void onVolumeChanged(int volume, byte[] data) {
            showTip("当前正在说话,音量大小:" + volume);
            //LogUtil.L("返回音频数据:"+data.length);
            if(volume>5){
                sound+=volume;
                soundCount+=1;
            }
        }
        @Override
        public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
        }
    };
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值