讯飞语音云语音听写学习

        这几天两个舍友都买了iPhone 6S,玩起了“Hey, Siri”,我依旧对我的Nexus 5喊着“OK,Google”。但种种原因,国内的“OK,Google”并不能展示出他的全部威力,于是上网搜索国内Android平台的语音助手,个人觉得评价最好的是讯飞的——灵犀语音助手。其实讯飞语音云平台早就注册过了,并下载了相应的SDK,只是没仔细研究。今天突然想好好学习一下,以方便以后集成到自己开发的APP中,也可以方便大家参考。开发工具:Android Studio。

        好了,废话就说这些。先来看效果图:

下面是具体的步骤。

1,首先在讯飞开放平台注册开发者账号,注册流程很简单,就不详细介绍。网址:http://www.xfyun.cn/。然后就是像各大平台一样的步骤:新建Android应用获取APPID—〉下载语音听写SDK。此处需要注意的是一定要新建自己的应用,别人的工程虽然能用,但不方便后续开发。

2,解压下载的SDK目录,里面有详细的教程,可自行参考。然后新建工程,将MSC.jar(放入到libs文件夹下)和libmsc.so(放入到新建的jniLibs文件夹下)导入到自己的工程中(只有在线的所有功能,没有提供离线服务。)另外,讯飞提供了两种语音识别接口,一种是后台进行语音检测,没有界面UI提示;另一种是带UI的接口,在录音、播放音频的时候,会有dialog弹出,并伴有相应的动画,相对来说用户交互体验很不错。如果使用带UI接口时,请将assets下文件拷贝到项目中。这里注意的是每个SDK下载的assets可能不一样(没有亲自测试过,因为recognize.xml打开乱码),一定要将自己下载的SDK里的assets目录拷贝到XXX/src/main文件夹下。工程目录如下:

                    

3,在AndroidManifest.xml文件中添加权限:

<!-- 在工程 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" />
<!-- 获取当前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" />
<!-- 外存储写入权限, 构建语法需要用到此权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

4,布局文件activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/content_rec"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="识别内容" />

    <Button
        android:id="@+id/bt_start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:onClick="startRec"
        android:text="开始" />

    <Button
        android:id="@+id/btn_read"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/bt_start"
        android:layout_alignLeft="@+id/bt_start"
        android:layout_alignParentRight="true"
        android:onClick="read"
        android:text="朗读" />

</RelativeLayout>

5,Java代码:JsonParser.java 和 MainActivity.java

        (1),JsonParser.Java

package com.xiaobailong24.xunfeiyun;

import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;

/**
 * Json结果解析类
 */
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"));
//          如果需要多候选结果,解析数组其他字段
//          for(int j = 0; j < items.length(); j++)
//          {
//             JSONObject obj = items.getJSONObject(j);
//             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();
   }

   public static String parseLocalGrammarResult(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("\n");
            }
         }
         ret.append("【置信度】" + joResult.optInt("sc"));

      } catch (Exception e) {
         e.printStackTrace();
         ret.append("没有匹配结果.");
      }
      return ret.toString();
   }
}

        (2),MainActivity.java

package com.xiaobailong24.xunfeiyun;

import android.app.Activity;
import android.os.Environment;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.RecognizerListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechRecognizer;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.SynthesizerListener;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;

public class MainActivity extends Activity {

    private static String TAG = "MainActivity";
    // 函数调用返回值
    int ret = 0;
    // 语音听写对象
    private SpeechRecognizer mIat;
    // 语音听写UI
    private RecognizerDialog iatDialog;
    // 听写结果内容
    private EditText mResultText;
    // 语音合成对象
    private SpeechSynthesizer mTts;

    // 默认发音人
    private String voicer = "xiaoyan";

    // 缓冲进度
    private int mPercentForBuffering = 0;
    // 播放进度
    private int mPercentForPlaying = 0;

    private Toast mToast;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.e(TAG, "onCreate");
        super.onCreate(savedInstanceState);
//        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        // 用于验证应用的key,将XXXXXXXX改为你申请的APPID
        SpeechUtility.createUtility(MainActivity.this, SpeechConstant.APPID + "=XXXXXXXX");
        // 创建语音听写对象
        mIat = SpeechRecognizer.createRecognizer(this, mInitListener);
        // 初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizer
        // 创建语音听写UI
        iatDialog = new RecognizerDialog(MainActivity.this, mInitListener);
        // 创建语音合成对象
        mTts = SpeechSynthesizer.createSynthesizer(this, mInitListener);
        mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
        content_rec));
    }

    public void startRec(View view) {
        mResultText.setText(null);
        setParam();
        boolean isShowDialog = true;
        if (isShowDialog) {
            // 显示听写对话框
            iatDialog.setListener(recognizerDialogListener);
            iatDialog.show();
            // showTip("begin");
        } else {
            // 不显示听写对话框
            ret = mIat.startListening(recognizerListener);
            if (ret != ErrorCode.SUCCESS) {
                // showTip("听写失败,错误码:" + ret);
            } else {
                // showTip("begin");
            }
        }
    }

    public void read(View view) {
        String text = mResultText.getText().toString();
        // 设置参数
        setParam2();
        //朗读
        int code = mTts.startSpeaking(text, mTtsListener);
        if (code != ErrorCode.SUCCESS) {
            if (code == ErrorCode.ERROR_COMPONENT_NOT_INSTALLED) {
                // 未安装则跳转到提示安装页面
            } else {
                showTip("语音合成失败,错误码: " + code);
            }
        }
    }

    /**
     * 参数设置
     *
     * @param
     * @return
     */
    private void setParam2() {
        Log.e(TAG, "setParam2");
        // 设置合成
        mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
        // 设置发音人
        mTts.setParameter(SpeechConstant.VOICE_NAME, voicer);

        // 设置语速
        mTts.setParameter(SpeechConstant.SPEED, "50");

        // 设置音调
        mTts.setParameter(SpeechConstant.PITCH, "50");

        // 设置音量
        mTts.setParameter(SpeechConstant.VOLUME, "50");

        // 设置播放器音频流类型
        mTts.setParameter(SpeechConstant.STREAM_TYPE, "3");
    }

    public void setParam() {
        Log.e(TAG, "setParam");
        // 清空参数
        mIat.setParameter(SpeechConstant.PARAMS, null);
        // 设置听写引擎
        mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);

        // 设置语言
        mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        // 设置语言区域
        mIat.setParameter(SpeechConstant.ACCENT, "mandarin");

        // 设置语音前端点
        mIat.setParameter(SpeechConstant.VAD_BOS, "4000");
        // 设置语音后端点
        mIat.setParameter(SpeechConstant.VAD_EOS, "1000");
        // 设置标点符号 1为有标点 0为没标点
        mIat.setParameter(SpeechConstant.ASR_PTT, "0");
        // 设置音频保存路径
        mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH,
                Environment.getExternalStorageDirectory()
                        + "/xiaobailong24/xunfeiyun");
    }

    /**
     * 合成回调监听。
     */
    private SynthesizerListener mTtsListener = new SynthesizerListener() {
        @Override
        public void onSpeakBegin() {
            Log.e(TAG, "mTtsListener-->onSpeakBegin");
            showTip("开始播放");
        }

        @Override
        public void onSpeakPaused() {
            Log.e(TAG, "mTtsListener-->onSpeakPaused");
            showTip("暂停播放");
        }

        @Override
        public void onSpeakResumed() {
            Log.e(TAG, "mTtsListener-->onSpeakResumed");
            showTip("继续播放");
        }

        @Override
        public void onBufferProgress(int percent, int beginPos, int endPos,
                                     String info) {
            Log.e(TAG, "mTtsListener-->onBufferProgress");
            mPercentForBuffering = percent;
            showTip(String.format(getString(R.string.tts_toast_format),
                    mPercentForBuffering, mPercentForPlaying));
        }

        @Override
        public void onSpeakProgress(int percent, int beginPos, int endPos) {
            Log.e(TAG, "mTtsListener-->onSpeakProgress");
            mPercentForPlaying = percent;
            showTip(String.format(getString(R.string.tts_toast_format),
                    mPercentForBuffering, mPercentForPlaying));
        }

        @Override
        public void onCompleted(SpeechError error) {
            Log.e(TAG, "mTtsListener-->onCompleted");
            if (error == null) {
                showTip("播放完成");
            } else if (error != null) {
                showTip(error.getPlainDescription(true));
            }
        }

        @Override
        public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
            Log.e(TAG, "mTtsListener-->onEvent");
        }
    };
    /**
     * 听写监听器。
     */
    private RecognizerListener recognizerListener = new RecognizerListener() {

        @Override
        public void onVolumeChanged(int i, byte[] bytes) {
            Log.e(TAG, "recognizerListener-->onVolumeChanged");
            showTip("当前正在说话,音量大小:" + i);
        }

        @Override
        public void onBeginOfSpeech() {
            Log.e(TAG, "recognizerListener-->onBeginOfSpeech");
            showTip("开始说话");
        }

        @Override
        public void onEndOfSpeech() {
            Log.e(TAG, "recognizerListener-->onEndOfSpeech");
            showTip("结束说话");
        }

        @Override
        public void onResult(RecognizerResult results, boolean isLast) {
            Log.e(TAG, "recognizerListener-->onResult");
            String text = JsonParser.parseIatResult(results.getResultString());
            mResultText.append(text);
            mResultText.setSelection(mResultText.length());
            if (isLast) {
                // TODO 最后的结果
            }
        }

        @Override
        public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
            Log.e(TAG, "recognizerListener-->onEvent");
        }

        @Override
        public void onError(SpeechError arg0) {
            Log.e(TAG, "recognizerListener-->onError");
            // TODO Auto-generated method stub
        }
    };
    /**
     * 听写UI监听器
     */
    private RecognizerDialogListener recognizerDialogListener = new RecognizerDialogListener() {

        public void onResult(RecognizerResult results, boolean isLast) {
            Log.e(TAG, "recognizerDialogListener-->onResult");
            String text = JsonParser.parseIatResult(results.getResultString());
            mResultText.append(text);
            mResultText.setSelection(mResultText.length());
        }

        /**
         * 识别回调错误.
         */
        public void onError(SpeechError error) {
            Log.e(TAG, "recognizerDialogListener-->onError");
            showTip(error.getPlainDescription(true));
        }
    };
    private InitListener mInitListener = new InitListener() {
        @Override
        public void onInit(int code) {
            Log.e(TAG, "mInitListener-->onInit");
            Log.d(TAG, "SpeechRecognizer init() code = " + code);
            if (code != ErrorCode.SUCCESS) {
                showTip("初始化失败,错误码:" + code);
            }
        }
    };

    private void showTip(final String str) {
        Log.e(TAG, "showTip-->" + str);
        mToast.setText(str);
        mToast.show();
    }

    @Override
    protected void onDestroy() {
        Log.e(TAG, "onDestroy");
        super.onDestroy();
        // 退出时释放连接
        mIat.cancel();
        mIat.destroy();
    }

    @Override
    protected void onResume() {
        Log.e(TAG, "onResume");
        super.onResume();
    }

    @Override
    protected void onPause() {
        Log.e(TAG, "onPause");
        super.onPause();
    }

}

Android讯飞语音云语音听写学习的更多相关文章

  1. android讯飞语音开发常遇到的问题

    场景:android项目中共使用了3个语音组件:在线语音听写.离线语音合成.离线语音识别 11208:遇到这个错误,授权应用失败,先检查装机量(3台测试权限),以及appid的申请时间(35天期限), ...

  2. android 讯飞语音识别(离线)注意事项

    讯飞语音识别:使用注意事项:mainfest.xml中一定要记得权限写进去21001:我的情况是没有写SpeechApp类,并且需要在application中注册:20005:无匹配结果23300:本 ...

  3. Android 讯飞语音之语音合成(在线有声朗读)

    原文:http://www.cnblogs.com/scetopcsa/p/3845427.html 在线语音合成的使用方法: 首先下载相关的sdk,这个网址里有多种版本,我选择的Android. h ...

  4. 微信小程序语音与讯飞语音识别接口(Java),Kronopath/SILKCodec,ffmpeg处理silk,pcm,wav转换

    项目需求,需要使用讯飞的语音识别接口,将微信小程序上传的录音文件识别成文字返回 首先去讯飞开放平台中申请开通语音识别功能 在这里面下载sdk,然后解压,注意appid与sdk是关联的,appid在初始 ...

  5. 微信小程序语音与讯飞语音识别接口(Java)

    项目需求,需要使用讯飞的语音识别接口,将微信小程序上传的录音文件识别成文字返回 而微信小程序上传的文件格式是silk的,而讯飞接口能识别wav 格式的文件,所以需要将小程序上传的silk文件转成wav ...

  6. 初探机器学习之使用讯飞TTS服务实现在线语音合成

    最近在调研使用各个云平台提供的AI服务,有个语音合成的需求因此就使用了一下科大讯飞的TTS服务,也用.NET Core写了一个小示例,下面就是这个小示例及其相关背景知识的介绍. 一.什么是语音合成(T ...

  7. 关于讯飞语音SDK开发学习

    前奏,浑浑噩噩已经工作一年多,这一年多收获还是挺多的.逛园子应该有两年多了,工作后基本上是天天都会来园子逛逛,园子 里还是有很多牛人写了一些不错的博客,帮我解决很多问题.但是一直没写过博客,归根到底一 ...

  8. 一百元的智能家居——Asp.Net Mvc Api+讯飞语音+Android+Arduino

    大半夜的,先说些废话提提神 如今智能家居已经不再停留在概念阶段,高大上的科技公司都已经推出了自己的部分或全套的智能家居解决方案,不过就目前的现状而言,大多还停留在展厅阶段,还没有广泛的推广起来,有人说 ...

  9. 讯飞语音SDK Android平台使用

    1. 支持功能介绍: 2. Android API主要业务接口和流程介绍 -------------------------------------------------------- 工程代码: ...

随机推荐

  1. 学习javascript数据结构(二)——链表

    前言 人生总是直向前行走,从不留下什么. 原文地址:学习javascript数据结构(二)--链表 博主博客地址:Damonare的个人博客 正文 链表简介 上一篇博客-学习javascript数据结 ...

  2. K60——寄存器

    (1)PTx_BASE_PTR为GPIO寄存器结构体基址指针(PTR即point to register,x=A/B/C/D/E) /* GPIO - Peripheral instance base ...

  3. 基于centos的lnmp搭建

    部署lnmp环境 安装配置mariadb配置php配置phpmyadmin配置php-fpm配置nginx配置测试 LNMP(linux,nginx,mariadb,php)部署,以下默认在root权 ...

  4. Hadoop Linux安装

    Hadoop Linux安装 步骤流程 1.硬件准备 2.软件准备(推荐CDH) 3.将Hadoop安装包分发到各个节点下 4.安装JDK 5.修改/etc/hosts配置文件 6.设置SSH免密码登 ...

  5. Fibonacci(斐波那契数列)的最佳实践方式(JavaScript)

    1)低级版本 var fibonacci = function(n) { if (n == 0 || n == 1) { return n; } else { return fibonacci(n - ...

  6. Android 2016新技术

    Android 2016新技术 版权声明:本文为博主原创文章,未经博主允许不得转载. 2016你需要了解Android有以下新兴的技术与框架,有些也许还不成熟,但是你应该去了解下,也许就是未来的方向. ...

  7. SDL1.2学习

    http://wenku.baidu.com/view/c953c0878762caaedd33d4d8.html 一.安装: sudo apt-get install libsdl1.2-dev l ...

  8. Fiddler Web Debugger Tool

    The Fiddler tool helps you debug web applications by capturing network traffic between the Internet ...

  9. java装饰者模式理解

    java 装饰者模式其实就是扩展子类的功能,和继承是一个性质. 但继承是在编译时就固定扩展了父类的一些功能,而装饰者模式是在运行过程中动态绑定对象,实现一个子类可以随时扩展功能. 将方法排列组合,也可 ...

  10. Stimulsoft Reports筛选数据来绑定显示2个报表

    今天用Stimulsoft Reports做报表的时候,遇到一个问题,需要一个报表中显示2个报表视图,我在百度和博客园中搜索了一下,发现这方面的资料很少,我自己最后把问题解决了之后,整理了一下给大家分 ...