返回顶部
首页 > 资讯 > 精选 >科大讯飞语音离线命令识别
  • 377
分享到

科大讯飞语音离线命令识别

javaandroid语音识别 2023-08-21 11:08:19 377人浏览 独家记忆
摘要

目录直达 准备工作1、必要文件包复制到自己的项目目录中1、在libs 目录下放置这些包2、将assets 文件放置在 app 目录下3、在build 目录下添加一下配置4、工具类拷贝到项目文件中5、在AndroidManifest.

准备工作

  • 注册讯飞账号,做相关的认证,只有认证通过才能下载部分免费的资源。官网地址:https://console.xfyun.cn/

  • 创建我的应用后再在离线命令识别

请添加图片描述

1、必要文件包复制到自己的项目目录中

1、在libs 目录下放置这些包

注意重新加载一些gradle

在这里插入图片描述

2、将assets 文件放置在 app 目录下

该文件下 iflytek/recognize.xml 文件是语音识别的ui文件,如果没有的话,点击语音识别app会直接闪退.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JhCKjT2W-1680255017857)(讯飞语音识别.assets/image-20230331101912961.png)]

3、在build 目录下添加一下配置

sourceSets 这目录一定要添加,不然会报错 (创建对象失败,请确认 libmsc.so 放置正确,\n 且有调用 createUtility 进行初始化) 实质上是 包找不到 SpeechRecognizer 对象创建失败。(天坑 天坑 天坑 天坑 天坑)

Android {    sourceSets{        main{            jniLibs.srcDir(['libs'])        }    }}dependencies {    implementation files('libs/Msc.jar')  }

4、工具类拷贝到项目文件中

这里主要是一些讯飞提供的工具类,主要使用到的是JSON转换工具

setting 文件下的是语音命令识别和语音合成(暂时不使用)的设置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c7hF2MxJ-1680255017859)(讯飞语音识别.assets/image-20230331102924007.png)]

5、在AndroidManifest.xml 添加权限

      <uses-permission android:name="android.permission.INTERNET"/>        <uses-permission android:name="android.permission.RECORD_AUDIO"/>        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

2、新建 IatActivity 声明必要的类成员

private static String TAG = "IatActivity";// 语音听写对象private SpeechRecognizer mIat;// 语音听写UIprivate RecognizerDialog mIatDialog;// 听写结果内容private EditText mResultText;// 用HashMap存储听写结果private HashMap<String, String> mIatResults = new LinkedHashMap<>();private SharedPreferences mSharedPreferences;private Toast mToast;private String mEngineType = "cloud";

3、初始化监听

  private InitListener mInitListener = new InitListener() {        @Override        public void onInit(int code) {            Log.d(TAG, "SpeechRecognizer init() code = " + code);            if (code != ErrorCode.SUCCESS) {                showTip("初始化失败,错误码:" + code + ",请点击网址Https://www.xfyun.cn/document/error-code查询解决方案");            }        }    };

4、语音命令识别的周期监听

        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) {            String text = jsonParser.parseIatResult(results.getResultString());            mResultText.append(text);            mResultText.setSelection(mResultText.length());            if (isLast) {                //TODO 最后的结果            }        }        @Override        public void onVolumeChanged(int volume, byte[] data) {            showTip("当前正在说话,音量大小:" + volume);            Log.d(TAG, "返回音频数据:" + data.length);        }        @Override        public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {            // 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因            // 若使用本地能力,会话id为null            if (SpeechEvent.EVENT_SESSION_ID == eventType) {                String sid = obj.getString(SpeechEvent.KEY_EVENT_AUDIO_URL);                Log.d(TAG, "session id =" + sid);            }        }    };

5、离线命令UI监听

 private RecognizerDialogListener mRecognizerDialogListener = new RecognizerDialogListener() {        public void onResult(RecognizerResult results, boolean isLast) {            Log.d(TAG, "recognizer result:" + results.getResultString());                        String text = JsonParser.parseIatResult(results.getResultString());            System.out.println("语音听写结果为:" + text);            if(!text.equals("")){                System.out.println("蓝牙发送了");                bluetoothUtils.write("1");            }            mResultText.append(text);            mResultText.setSelection(mResultText.length());        }                public void onError(SpeechError error) {            showTip(error.getPlainDescription(true));        }    };

6、获取离线资源

在离线命令识别这里其实没有使用到的,因为.jet文件是语音发音包,就是官方提供的免费语音发音包

private String getResourcePath() {    StringBuffer tempBuffer = new StringBuffer();    //识别通用资源    tempBuffer.append(ResourceUtil.generateResourcePath(this, ResourceUtil.RESOURCE_TYPE.assets, "iat/common.jet"));    tempBuffer.append(";");    tempBuffer.append(ResourceUtil.generateResourcePath(this, ResourceUtil.RESOURCE_TYPE.assets, "iat/sms_16k.jet"));    //识别8k资源-使用8k的时候请解开注释    return tempBuffer.toString();}

7、参数设置

参数设置这块,主要是为命令识别功能做配置,就像使用SpringBoot 一样需要在yml里面配置,这里只是举个例子,在讯飞这里,命令识别有参数设置,语音合成也有参数设置,需要区分好。

       public void setParam() {        // 清空参数        mIat.setParameter(SpeechConstant.PARAMS, null);        String lag = mSharedPreferences.getString("iat_language_preference", "mandarin");        // 设置引擎        mIat.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);        // 设置返回结果格式        mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");        //mIat.setParameter(MscKeys.REQUEST_AUDIO_URL,"true");        //this.mTranslateEnable = mSharedPreferences.getBoolean( this.getString(R.string.pref_key_translate), false );        if (mEngineType.equals(SpeechConstant.TYPE_LOCAL)) {            // 设置本地识别资源            mIat.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());        }        // 在线听写支持多种小语种,若想了解请下载在线听写能力,参看其speechDemo        if (lag.equals("en_us")) {            // 设置语言            mIat.setParameter(SpeechConstant.LANGUAGE, "en_us");            mIat.setParameter(SpeechConstant.ACCENT, null);            // 设置语言            mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");            // 设置语言区域            mIat.setParameter(SpeechConstant.ACCENT, lag);        }        // 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理        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权限        mIat.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");        mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH,                getExternalFilesDir("msc").getAbsolutePath() + "/iat.wav");    }

8、弹窗提示

private void showTip(final String str) {    if (mToast != null) {        mToast.cancel();    }    mToast = Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT);    mToast.show();}

9、语音权限提示窗口

平常我们使用app 都会获取手机的权限,只有用户同意后才能使用app。这里就是这样的一个效果

private void showPrivacyDialog() {    AppCompatTextView textView = new AppCompatTextView(this);    textView.setPadding(100, 50, 100, 50);    textView.setText(            htmlCompat.fromHtml("我们非常重视对您个人信息的保护,承诺严格按照讯飞开放平台《隐私政策》保护及处理您的信息,是否确定同意?",                    HtmlCompat.FROM_HTML_MODE_LEGACY));    textView.setOnClickListener(new View.OnClickListener() {        @Override        public void onClick(View v) {            Intent intent = new Intent(Intent.ACTION_VIEW);            intent.setData(Uri.parse("https://www.xfyun.cn/doc/policy/sdk_privacy.html"));            startActivity(intent);        }    });    AlertDialog dialog = new AlertDialog.Builder(this)            .setTitle("温馨提示")            .setView(textView)            .setPositiveButton("同意", new DialogInterface.OnClickListener() {                @Override                public void onClick(DialogInterface dialog, int which) {                    mSharedPreferences.edit().putBoolean(SpeechApp.PRIVACY_KEY, true).apply();                    dialog.dismiss();                }            })            .setNegativeButton("不同意", new DialogInterface.OnClickListener() {                @Override                public void onClick(DialogInterface dialog, int which) {                    mSharedPreferences.edit().putBoolean(SpeechApp.PRIVACY_KEY, false).apply();                    finish();                    System.exit(0);                }            })            .create();    dialog.setCanceledOnTouchOutside(false);    dialog.show();}

10、动态申请权限

andriod 的高版本在AndroidManifest.xml 配置了权限还不够,还需要在 onCreate()中动态申请权限

注意 安装12以上(sdk 33 )需要这样写

 String permissions[] = {android.Manifest.permission.RECORD_AUDIO,               android.Manifest.permission.ACCESS_NETWORK_STATE,               android.Manifest.permission.INTERNET,               android.Manifest.permission.WRITE_EXTERNAL_STORAGE       };
private void initPermission() {    String permissions[] = {Manifest.permission.RECORD_AUDIO,            Manifest.permission.ACCESS_NETWORK_STATE,            Manifest.permission.INTERNET,            Manifest.permission.WRITE_EXTERNAL_STORAGE    };    ArrayList<String> toApplyList = new ArrayList<String>();    for (String perm : permissions) {        if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, perm)) {            toApplyList.add(perm);        }    }    String tmpList[] = new String[toApplyList.size()];    if (!toApplyList.isEmpty()) {        ActivityCompat.requestPermissions(this, toApplyList.toArray(tmpList), 123);    }}

11、在onCreate() 方法中初始

 public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        this.requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_iat);        // 初始化识别无UI识别对象        // 使用SpeechRecognizer对象,可根据回调消息自定义界面;        mIat = SpeechRecognizer.createRecognizer(this, mInitListener);        // 初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizer        // 使用UI听写功能,请根据sdk文件目录下的notice.txt,放置布局文件和图片资源        mIatDialog = new RecognizerDialog(this, mInitListener);        mSharedPreferences = getSharedPreferences(IatSettings.PREFER_NAME, Activity.MODE_PRIVATE);        mResultText = findViewById(R.id.tv_result));        Button_Test();    }

12、按钮点击 处理识别命令测试

    private void Button_Test(){        Button button = findViewById(R.id.button);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if (null == mIat) {                    // 创建单例失败,与 21001 错误为同样原因,参考 http://bbs.xfyun.cn/forum.PHP?mod=viewthread&tid=9688                    showTip("创建对象失败,请确认 libmsc.so 放置正确,\n 且有调用 createUtility 进行初始化");                    return;                }                mResultText.setText(null);// 清空显示内容                mIatResults.clear();                // 设置参数                setParam();                boolean isshowDialog = mSharedPreferences.getBoolean(getString(R.string.pref_key_iat_show), true);                if (isShowDialog) {                    try {                        // 显示听写对话框                        mIatDialog.setListener(mRecognizerDialogListener);                        mIatDialog.show(); // todo 对话框显示不出来一直报错                        showTip(getString(R.string.text_begin));                    } catch (Exception e) {                        throw new RuntimeException(e);                    }                } else {                    // 不显示听写对话框                    ret = mIat.startListening(mRecognizerListener);                    if (ret != ErrorCode.SUCCESS) {                        showTip("听写失败,错误码:" + ret + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");                    } else {                        showTip(getString(R.string.text_begin));                    }                }            }        });    }

13、界面activity_iat.xml

<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent">    <Button        android:id="@+id/button"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="93Dp"        android:layout_marginBottom="46dp"        android:text="开始听写"        app:layout_constraintBottom_toTopOf="@+id/tv_result"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintHorizontal_bias="0.498"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toTopOf="parent" />    <EditText        android:id="@+id/tv_result"        android:layout_width="0dp"        android:layout_height="0dp"        android:layout_marginBottom="493dp"        android:layout_weight="1"        android:gravity="center"        android:text="语音识别到的内容"        android:textColor="#000"        app:layout_constraintBottom_toBottomOf="parent"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toBottomOf="@+id/button" /></androidx.constraintlayout.widget.ConstraintLayout>

14、strings.xml

该文件是讯飞官网下载后提供的,只要是一些公共的字符串,自己创建的项目大多数都没有用到,不过最好写上不然有的找不到报错(坑),可以将不要的删掉

<resources>    <string name="app_name">讯飞蓝牙集成appstring>        <string name="app_id">23810fb7string>    <string name="example_explain">本示例为讯飞语音Android平台开发者提供语音听写、语法识别、语义理解和语音合成等代码样例,旨在让用户能够依据该示例快速开发出基于语音接口的应用程序。string>    <string name="text_tts_source">        科大讯飞作为智能语音技术提供商,在智能语音技术领域有着长期的研究积累,并在中文语音合成、语音识别、口语评测等多项技术上拥有技术成果。科大讯飞是我国以语音技术为产业化方向的“国家863计划产业化基地”.....    string>    <string name="text_tts_source_en">iFLYTEK is a national key software enterprise dedicated to the research of intelligent speech and language technologies, development of software and chip products, provision of speech information services, and integration of E-Government systems. The intelligent speech technology of iFLYTEK, the core technology of the company, represents the top level in the world.    string>    <string name="text_isr_abnf_hint">\t上传内容为:\n\t#ABNF 1.0 gb2312;\n\tlanguage zh-CN;\n\tmode voice;\n\troot $main;\n\t$main = $place1 到$place2 ;\n\t$place1 = 北京 | 武汉 | 南京 | 天津 | 东京;\n\t$place2 = 上海 | 合肥;string>    <string name="text_understand_hint">\t您可以说:\n\t今天的天气怎么样?\n\t北京到上海的火车?\n\t来首歌吧?\n\n\t更多语义请登录:\n\thttp://aiui.xfyun.cn/ \n\t配置您的专属语义吧!string>        <string name="text_begin">请开始说话string>    <string name="text_begin_recognizer">开始音频流识别string>    <string name="text_upload_contacts">上传联系人string>    <string name="text_upload_userWords">上传用户词表string>    <string name="text_upload_success">上传成功string>    <string name="text_userword_empty">词表下载失败或内容为空string>    <string name="text_download_success">下载成功string>    <string name="pref_key_iat_show">iat_showstring>    <string name="pref_title_iat_show">显示听写界面string>    <string name="pref_key_translate">translatestring>    <string name="pref_title_translate">翻译string>        <string-array name="voicer_cloud_entries">        <item>小燕item>        <item>小宇item>        <item>凯瑟琳item>        <item>亨利item>        <item>玛丽item>        <item>小研item>        <item>小琪item>        <item>小峰item>        <item>小梅item>        <item>小莉item>        <item>小蓉item>        <item>小芸item>        <item>小坤item>        <item>小强 item>        <item>小莹item>        <item>小新item>        <item>楠楠item>        <item>老孙item>    string-array>    <string-array name="voicer_cloud_values">        <item>xiaoyanitem>        <item>xiaoyuitem>        <item>catherineitem>        <item>henryitem>        <item>vimaryitem>        <item>vixyitem>        <item>xiaoqiitem>        <item>vixfitem>        <item>xiaomeiitem>        <item>xiaolinitem>        <item>xiaorongitem>        <item>xiaoqianitem>        <item>xiaokunitem>        <item>xiaoqiangitem>        <item>vixyingitem>        <item>xiaoxinitem>        <item>nannanitem>        <item>vilsitem>    string-array>    <string-array name="voicer_xtts_entries">        <item>nannanitem>        <item>小关item>        <item>宜丰item>        <item>小曦item>        <item>小燕item>            string-array>    <string-array name="voicer_xtts_values">        <item>nannanitem>        <item>xiaoguanitem>        <item>yifengitem>        <item>xiaoxiitem>        <item>xiaoyanitem>            string-array>    <string-array name="voicer_local_entries">        <item>小燕item>        <item>小峰item>    string-array>    <string-array name="voicer_local_values">        <item>xiaoyanitem>        <item>xiaofengitem>    string-array>    <string-array name="stream_entries">        <item>通话item>        <item>系统item>        <item>铃声item>        <item>音乐item>        <item>闹铃item>        <item>通知item>    string-array>    <string-array name="stream_values">        <item>0item>        <item>1item>        <item>2item>        <item>3item>        <item>4item>        <item>5item>    string-array>    <string name="tts_toast_format" formatted="false">缓冲进度为%d%%,播放进度为%d%%string>        <string-array name="language_entries">        <item>普通话item>        <item>粤语item>        <item>英语item>    string-array>    <string-array name="language_values">        <item>mandarinitem>        <item>cantoneseitem>        <item>en_usitem>    string-array>        <string-array name="punc_entries">        <item>有标点item>        <item>无标点item>    string-array>    <string-array name="punc_values">        <item>1item>        <item>0item>    string-array>        <string name="example_explain_wake">唤醒是指通过说出特定的唤醒词来唤醒处于休眠状态下的设备,又分为唤醒和唤醒+识别。string>    <string name="wake_demo_hint">请点击“开始唤醒”后读出您在开放平台购买的唤醒词,当引擎计算得分大于您设置的门限值时,即可进行唤醒。string>    <string name="oneshot_demo_hint">请点击“唤醒+识别”后读出您在开放平台购买的唤醒词+语法中指定的识别对象,当引擎计算得分大于您设置的门限值时,即可进行唤醒+识别。string>    <string name="oneshot_resource_hint">本示例识别词语为“张三|李四|张海洋”,请开发者将语法文件中的唤醒词字段替换,本地语法定义详见demo工程的asset/wake.bnf文件。string>resources>

测试效果

请添加图片描述

博主打算将语音和蓝牙整合,通过语音命令发送蓝牙指令,如果想了解andriod蓝牙请参考以下线观文章

完整代码仓库:茶凡_Matrix/Bluetooth_Send - 码云 - 开源中国 (gitee.com)

蓝牙开发博客: andriod12(sdk33)以上整合蓝牙app_茶凡_Matrix的博客-CSDN博客

来源地址:https://blog.csdn.net/weixin_45833112/article/details/129885232

--结束END--

本文标题: 科大讯飞语音离线命令识别

本文链接: https://lsjlt.com/news/376943.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作