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

简介: 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/注册一个帐号。


3.png


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

4.png


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


5.png


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

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

6.png


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


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

image.png

                   

相关实践学习
达摩院智能语音交互 - 声纹识别技术
声纹识别是基于每个发音人的发音器官构造不同,识别当前发音人的身份。按照任务具体分为两种: 声纹辨认:从说话人集合中判别出测试语音所属的说话人,为多选一的问题 声纹确认:判断测试语音是否由目标说话人所说,是二选一的问题(是或者不是) 按照应用具体分为两种: 文本相关:要求使用者重复指定的话语,通常包含与训练信息相同的文本(精度较高,适合当前应用模式) 文本无关:对使用者发音内容和语言没有要求,受信道环境影响比较大,精度不高 本课程主要介绍声纹识别的原型技术、系统架构及应用案例等。 讲师介绍: 郑斯奇,达摩院算法专家,毕业于美国哈佛大学,研究方向包括声纹识别、性别、年龄、语种识别等。致力于推动端侧声纹与个性化技术的研究和大规模应用。
相关文章
|
API 开发工具 Android开发
解决 Android App 上架 Google play后 ,签名变更,第三方sdk无法登录
解决 Android App 上架 Google play后 ,签名变更,第三方sdk无法登录
289 0
|
6月前
|
Java 开发工具 Android开发
如何在Eclipse中查看Android源码或者第三方组件包源码(转)
如何在Eclipse中查看Android源码或者第三方组件包源码(转)
53 4
|
6月前
|
机器学习/深度学习 Java Shell
[RK3568][Android12.0]--- 系统自带预置第三方APK方法
[RK3568][Android12.0]--- 系统自带预置第三方APK方法
623 0
|
6月前
|
存储 Java Android开发
Android系统 设置第三方应用为默认Launcher实现和原理分析
Android系统 设置第三方应用为默认Launcher实现和原理分析
940 0
|
6月前
|
JSON 自然语言处理 Java
Android App开发语音处理之系统自带的语音引擎、文字转语音、语音识别的讲解及实战(超详细 附源码)
Android App开发语音处理之系统自带的语音引擎、文字转语音、语音识别的讲解及实战(超详细 附源码)
307 0
|
6月前
|
Java Android开发
Android Studio的使用导入第三方Jar包
Android Studio的使用导入第三方Jar包
44 1
|
编解码 开发工具 Android开发
Android平台如何实现第三方模块编码后(H.264/H.265/AAC/PCMA/PCMU)数据实时预览播放
Android平台如何实现第三方模块编码后(H.264/H.265/AAC/PCMA/PCMU)数据实时预览播放
100 0
|
6月前
|
JSON 语音技术 Android开发
【Android App】在线语音识别功能实现(使用云知声平台与WebSocket 超详细 附源码)
【Android App】在线语音识别功能实现(使用云知声平台与WebSocket 超详细 附源码)
97 0
|
6月前
|
XML Java 语音技术
Android App开发在线语音识别处理中实现中文转拼音(Pinyin4j库)功能(超详细 附源码和演示)
Android App开发在线语音识别处理中实现中文转拼音(Pinyin4j库)功能(超详细 附源码和演示)
232 0
|
6月前
|
安全 Java Android开发
Android App开发之安全加固中反编译、代码混淆、第三方加固以及重签名的讲解及实战(图文解释 简单易懂)
Android App开发之安全加固中反编译、代码混淆、第三方加固以及重签名的讲解及实战(图文解释 简单易懂)
368 0

热门文章

最新文章

  • 1
    在人工智能和机器学习的领域中,语音识别(Speech Recognition,SR)是一个重要的研究方向。它旨在将人类的语音转换为计算机可读的文本。
    108
  • 2
    Python基于librosa和人工神经网络实现语音识别分类模型(ANN算法)项目实战
    123
  • 3
    深度学习在语音识别中的进展
    57
  • 4
    语音识别------ffmpeg的使用01,ffmpeg的安装,会做PPT很好,ffmpeg不具备直接使用,只可以操作解码数据,ffmpeg用C语言写的,得学C语言,ffmpeg的安装
    63
  • 5
    语音识别-----列表的常用操作课后练习讲解,用变量追加,取出第一个,取出最后一个,下标位置,列表的循环遍历,下标+1的写法,len下标可以小于这个值,while循环对index循环的遍历
    38
  • 6
    语音识别-免费开源的语音转文本软件Whisper的本地搭建详细教程,python版本是3.805,ffmpeg是专门处理音视频的,ffmpeg的下载链接,现在要求安装python和ffmpeg
    216
  • 7
    语音识别,列表的定义语法,列表[],列表的下标索引,从列表中取出来特定的数据,name[0]就是索引,反向索引,头部是-1,my[1][1],嵌套列表使用, 列表常用操作, 函数一样,需引入
    40
  • 8
    语音识别,函数综合案例,黑马ATM,/t/t一个对不齐,用两个/t,数据容器入门,数据容器可以分为列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)
    39
  • 9
    语音识别----函数基础定义联系案例,函数的参数,函数的参数练习案例,函数的返回值定义语法,函数返回值之None,函数的说明文档,函数的嵌套调用,变量在函数中的作用域,内部变量变全局变量用global
    42
  • 10
    语音识别,continue和break的使用,循环综合案例,完成发工资案例,函数的初体验,len()是内置好的函数,def 函数名 def xxx(),函数的定义 def xxx() ,调用函数
    34