zoukankan      html  css  js  c++  java
  • BaiduSpeechDemo【百度语音SDK集成】(基于v3.0.8.1)

    版权声明:本文为HaiyuKing原创文章,转载请注明出处!

    前言

    上一篇集成的是V3.0.7.3版本的SDK《BaiduSpeechDemo【百度语音SDK集成】(基于v3.0.7.3)》,这次发现官网的SDK进行了升级,感觉有必要进行重新集成。

    1、修复了APP同时集成多个SDK,不能同时使用的问题;——所以需要使用新sdk的jar文件;

    2、既然官网也使用了module方式;——那么就不需要自己创建module了,直接在官网的core这个module中优化;

    3、修复长语音无结束回调;——增加长语音结束回调的监听;

    本Demo中使用的appkey已失效,请自行创建应用,使用新的appkey。

    效果图

    和《BaiduSpeechDemo【百度语音SDK集成】(基于v3.0.7.3)》类似,这里就不单独截图了。

    代码分析

    普通话 search搜索模型:参考SpeechBottomSheetDialog.java类

    普通话 input输入法模型,适用于长句及长语音,有逗号分割,无语义:参考SpeechLongBottomSheetDialog.java类

    注意:关于语音识别状态维护,API调用的代码,是自己根据官网demo的理解进行整理的,可能有所偏颇,仅供参考。【希望官网demo可以添加百度APP的语音对话框效果就好了】

    使用步骤

    一、项目组织结构图

    注意事项:

    1、  导入类文件后需要change包名以及重新import R文件路径

    2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

    二、导入步骤

    (1)在项目中导入官网demo中的core这个module,同时修改名称,修改为baiduspeech

    (2)修改baiduspeech的AndroidManifest.xml(修改官网申请的应用信息)

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="test2.baidu.com.baseasr">
        <uses-permission android:name="android.permission.RECORD_AUDIO" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.READ_PHONE_STATE" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <application>
            <meta-data
                    android:name="com.baidu.speech.APP_ID"
                    android:value="11588936"/>
            <meta-data
                    android:name="com.baidu.speech.API_KEY"
                    android:value="XRF3IOf2tNGePzlv47cBnvF3"/>
            <meta-data
                    android:name="com.baidu.speech.SECRET_KEY"
                    android:value="diC8lQ7XDcGBKQ6FzCpvnan54F5CnMZI"/>
        </application>
    </manifest>

    (3)修改MessageStatusRecogListener.java文件【根据实际情况进行修改】

    package com.baidu.aip.asrwakeup3.core.recog.listener;
    
    import android.os.Handler;
    import android.os.Message;
    import android.util.Log;
    import com.baidu.aip.asrwakeup3.core.recog.RecogResult;
    import com.baidu.speech.asr.SpeechConstant;
    
    /**
     * Created by fujiayi on 2017/6/16.
     */
    
    public class MessageStatusRecogListener extends StatusRecogListener {
        private Handler handler;
    
        private long speechEndTime = 0;
    
        private boolean needTime = true;
    
        private static final String TAG = "MesStatusRecogListener";
    
        public MessageStatusRecogListener(Handler handler) {
            this.handler = handler;
        }
    
    
        @Override
        public void onAsrReady() {
            super.onAsrReady();
            speechEndTime = 0;
            sendStatusMessage(SpeechConstant.CALLBACK_EVENT_WAKEUP_READY, "引擎就绪,可以开始说话。");
        }
    
        @Override
        public void onAsrBegin() {
            super.onAsrBegin();
            sendStatusMessage(SpeechConstant.CALLBACK_EVENT_ASR_BEGIN, "检测到用户说话");
        }
    
        @Override
        public void onAsrEnd() {
            super.onAsrEnd();
            speechEndTime = System.currentTimeMillis();
            sendMessage("【asr.end事件】检测到用户说话结束");
        }
    
        @Override
        public void onAsrPartialResult(String[] results, RecogResult recogResult) {
            sendStatusMessage(SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL,
                    "临时识别结果,结果是“" + results[0] + "”;原始json:" + recogResult.getOrigalJson());
            super.onAsrPartialResult(results, recogResult);
        }
    
        @Override
        public void onAsrFinalResult(String[] results, RecogResult recogResult) {
            super.onAsrFinalResult(results, recogResult);
            //String message = "识别结束,结果是”" + results[0] + "”";//why 实际中可以去掉,不需要
            String message = recogResult.getOrigalJson();//{"results_recognition":["什么什么"],"origin_result":{"corpus_no":6522034498058113957,"err_no":0,"result":{"word":["什么什么"]},"sn":"bfa8b286-ab0e-4f86-9209-1d36d38b1224","voice_energy":16191.7705078125},"error":0,"best_result":"什么什么","result_type":"final_result"}
            sendStatusMessage(SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL,
                    message + ";原始json:" + recogResult.getOrigalJson());
            if (speechEndTime > 0) {
                long currentTime = System.currentTimeMillis();
                long diffTime = currentTime - speechEndTime;
                //message += ";说话结束到识别结束耗时【" + diffTime + "ms】";// why 实际中可以去掉,不需要
    
            }
            speechEndTime = 0;
            sendMessage(message, status, true);
        }
    
        @Override
        public void onAsrFinishError(int errorCode, int subErrorCode, String descMessage,
                                     RecogResult recogResult) {
            super.onAsrFinishError(errorCode, subErrorCode, descMessage, recogResult);
            //String message = "识别错误, 错误码:" + errorCode + " ," + subErrorCode + " ; " + descMessage;// why 实际中可以去掉,不需要
            String message = recogResult.getOrigalJson();//{"origin_result":{"sn":"","error":7,"desc":"No recognition result match","sub_error":7001},"error":7,"desc":"No recognition result match","sub_error":7001}
            sendStatusMessage(SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL, message);
            if (speechEndTime > 0) {
                long diffTime = System.currentTimeMillis() - speechEndTime;
                //message += "。说话结束到识别结束耗时【" + diffTime + "ms】";// why实际中可以去掉,不需要
            }
            speechEndTime = 0;
            sendMessage(message, status, true);
            speechEndTime = 0;
        }
    
        @Override
        public void onAsrOnlineNluResult(String nluResult) {
            super.onAsrOnlineNluResult(nluResult);
            if (!nluResult.isEmpty()) {
                sendStatusMessage(SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL, "原始语义识别结果json:" + nluResult);
            }
        }
    
        @Override
        public void onAsrFinish(RecogResult recogResult) {
            super.onAsrFinish(recogResult);
            sendStatusMessage(SpeechConstant.CALLBACK_EVENT_ASR_FINISH, "识别一段话结束。如果是长语音的情况会继续识别下段话。");
    
        }
    
        /**
         * 长语音识别结束
         */
        @Override
        public void onAsrLongFinish() {
            super.onAsrLongFinish();
            sendStatusMessage(SpeechConstant.CALLBACK_EVENT_ASR_LONG_SPEECH, "长语音识别结束。");
        }
    
    
        /**
         * 使用离线命令词时,有该回调说明离线语法资源加载成功
         */
        @Override
        public void onOfflineLoaded() {
            sendStatusMessage(SpeechConstant.CALLBACK_EVENT_ASR_LOADED, "离线资源加载成功。没有此回调可能离线语法功能不能使用。");
        }
    
        /**
         * 使用离线命令词时,有该回调说明离线语法资源加载成功
         */
        @Override
        public void onOfflineUnLoaded() {
            sendStatusMessage(SpeechConstant.CALLBACK_EVENT_ASR_UNLOADED, "离线资源卸载成功。");
        }
    
        @Override
        public void onAsrExit() {
            super.onAsrExit();
            sendStatusMessage(SpeechConstant.CALLBACK_EVENT_ASR_EXIT, "识别引擎结束并空闲中");
        }
    
        private void sendStatusMessage(String eventName, String message) {
            message = "[" + eventName + "]" + message;
            sendMessage(message, status);
        }
    
        private void sendMessage(String message) {
            sendMessage(message, WHAT_MESSAGE_STATUS);
        }
    
        private void sendMessage(String message, int what) {
            sendMessage(message, what, false);
        }
    
    
        private void sendMessage(String message, int what, boolean highlight) {
    
    
            if (needTime && what != STATUS_FINISHED) {
                message += "  ;time=" + System.currentTimeMillis();
            }
            if (handler == null) {
                Log.i(TAG, message);
                return;
            }
            Message msg = Message.obtain();
            msg.what = what;
            msg.arg1 = status;
            if (highlight) {
                msg.arg2 = 1;
            }
            msg.obj = message + "
    ";
            handler.sendMessage(msg);
        }
    }

    至此,百度语音SDK集成到baiduspeech中了,下一步就是创建UI对话框(建议再单独创建一个新的module)。

    (4)新建baiduspeechdialog这个module

    1、在baiduspeechdialog的build.gradle中引用recyclerview【版本号和项目的appcompat保持一致】【因为demo中用到了】【注意:还需要导入baiduspeech这个module

    apply plugin: 'com.android.library'
    
    android {
        compileSdkVersion 27
    
    
    
        defaultConfig {
            minSdkVersion 16
            targetSdkVersion 27
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    
    }
    
    dependencies {
        implementation fileTree(include: ['*.jar'], dir: 'libs')
        implementation 'com.android.support:appcompat-v7:27.1.1'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'com.android.support.test:runner:1.0.2'
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
        //RecyclerView
        compile 'com.android.support:recyclerview-v7:27.1.1'
        //baiduspeech
        implementation project(':baiduspeech')
    }

    2、对话框类、列表适配器类、布局文件xml文件、图片资源、动画style样式等复制到baiduspeechdialog中【参考《BaiduSpeechDemo【百度语音SDK集成】(基于v3.0.7.3)》】

    3、SpeechBottomSheetDialog.java和SpeechLongBottomSheetDialog.java在V3.0.7.3版本和V3.0.8.1版本的区别

    3.1、需要将Logger修改为MyLogger

    修改为:

    三、使用方法

    (1)因为需要使用到运行时权限,所以参考《Android6.0运行时权限(基于RxPermission开源库)》在APP的build.gradle中引入第三方库

    (2)在APP的build.gradle中引入baiduspeechdialog

     

    (3)在Activity中调用

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.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"
        tools:context="com.why.project.baiduspeechdemo.MainActivity">
    
        <TextView
            android:id="@+id/tv_result"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintHorizontal_bias="0.448"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.325"/>
    
        <Button
            android:id="@+id/btn_openSpeechDialog"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="32dp"
            android:text="打开搜索模型语音识别对话框"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.419"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>
    
        <Button
            android:id="@+id/btn_openSpeechLongDialog"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="16dp"
            android:text="打开input输入模型语音识别对话框"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.4"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/btn_openSpeechDialog"/>
    
    </android.support.constraint.ConstraintLayout>
    activity_main.xml
    package com.why.project.baiduspeechdemo;
    
    import android.Manifest;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import com.tbruyelle.rxpermissions2.RxPermissions;
    import com.why.project.baiduspeechdialog.dialog.SpeechBottomSheetDialog;
    import com.why.project.baiduspeechdialog.dialog.SpeechLongBottomSheetDialog;
    
    import io.reactivex.functions.Action;
    import io.reactivex.functions.Consumer;
    
    public class MainActivity extends AppCompatActivity {
    
        private static final String TAG = MainActivity.class.getSimpleName();
    
        private Button mOpenSpeechDialogBtn;
        private Button mOpenSpeechLongDialogBtn;
        private TextView mResultTv;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            onePermission();
    
            initViews();
            initEvents();
        }
    
        private void initViews() {
            mOpenSpeechDialogBtn = findViewById(R.id.btn_openSpeechDialog);
            mOpenSpeechLongDialogBtn = findViewById(R.id.btn_openSpeechLongDialog);
            mResultTv = findViewById(R.id.tv_result);
        }
    
        private void initEvents() {
            mOpenSpeechDialogBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //打开百度语音对话框
                    SpeechBottomSheetDialog speechBottomSheetDialog = SpeechBottomSheetDialog.getInstance(MainActivity.this);
                    speechBottomSheetDialog.seOnResultListItemClickListener(new SpeechBottomSheetDialog.OnResultListItemClickListener() {
                        @Override
                        public void onItemClick(String title) {
                            //填充到输入框中
                            mResultTv.setText(title);
                        }
                    });
                    speechBottomSheetDialog.show(getSupportFragmentManager(), TAG);
                }
            });
            mOpenSpeechLongDialogBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //打开百度语音对话框
                    SpeechLongBottomSheetDialog speechLongBottomSheetDialog = SpeechLongBottomSheetDialog.getInstance(MainActivity.this);
                    speechLongBottomSheetDialog.seOnResultListItemClickListener(new SpeechLongBottomSheetDialog.OnResultListItemClickListener() {
                        @Override
                        public void onItemClick(String title) {
                            //填充到输入框中
                            mResultTv.setText(mResultTv.getText()+title);
                        }
                    });
                    speechLongBottomSheetDialog.show(getSupportFragmentManager(), TAG);
                }
            });
    
        }
    
        /**只有一个运行时权限申请的情况*/
        private void onePermission(){
            RxPermissions rxPermissions = new RxPermissions(MainActivity.this); // where this is an Activity instance
            rxPermissions.request(Manifest.permission.RECORD_AUDIO,
                    Manifest.permission.READ_PHONE_STATE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE) //权限名称,多个权限之间逗号分隔开
                    .subscribe(new Consumer<Boolean>() {
                        @Override
                        public void accept(Boolean granted) throws Exception {
                            Log.e(TAG, "{accept}granted=" + granted);//执行顺序——1【多个权限的情况,只有所有的权限均允许的情况下granted==true】
                            if (granted) { // 在android 6.0之前会默认返回true
                                // 已经获取权限
                            } else {
                                // 未获取权限
                                Toast.makeText(MainActivity.this, "您没有授权该权限,请在设置中打开授权", Toast.LENGTH_SHORT).show();
                            }
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            Log.e(TAG,"{accept}");//可能是授权异常的情况下的处理
                        }
                    }, new Action() {
                        @Override
                        public void run() throws Exception {
                            Log.e(TAG,"{run}");//执行顺序——2
                        }
                    });
        }
    }

    混淆配置

    #=====================百度语音混淆=====================
    -keep class com.baidu.speech.**{*;}

    参考资料

    http://ai.baidu.com/tech/speech

    项目demo下载地址

    https://github.com/haiyuKing/BaiduSpeechNewDemo

  • 相关阅读:
    二纬码标签打印
    写JQuery 插件
    Java中System.getProperty()的参数
    (Java实现) 车站
    (Java实现) 活动选择
    (Java实现) 活动选择
    (Java实现) 过河卒
    (Java实现) 过河卒
    (Java实现) N皇后问题
    (Java实现) N皇后问题
  • 原文地址:https://www.cnblogs.com/whycxb/p/9500369.html
Copyright © 2011-2022 走看看