Android集成科大讯飞SDK语音听写及语音合成功能实现

前言

  现在软件设计越来越人性化、智能化。一些常见的输入都慢慢向语音听写方向发展,一些常见的消息提示都向语音播报发展。所以语音合成和语音听写是手机软件开发必不可少的功能。目前国内这方面做的比较好的应该是科大讯飞。很多搜索引擎,语音助手都有用到。本人也是第一次用初步研究了一下,和大家一起分享学习。

声明

  欢迎转载,但请保留文章原始出处:)

    总有刁民想害朕&:http://www.cnblogs.com/wangshuaiandroid

正文

  一、注册开放者账号、创建应用、下载SDK

    讯飞开放平台

  二、集成SDK

    2.1  将开发工具包中libs目录下的Msc.jar和armeabi复制到Android工程的libs目录(如果工程无libs目录,请自行创建)

    2.2  添加用户权限

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

    2.3   初始化

       初始化即创建语音配置对象,只有初始化后才可以使用MSC的各项服务。建议将初始化放在程序入口处(如Application、Activity的onCreate方法),初始化代码如下:

// 将“12345678”替换成您申请的APPID,申请地址:http://open.voicecloud.cn
SpeechUtility.createUtility(context, SpeechConstant.APPID +"=12345678");   

注意:  此接口在非主进程调用会返回null对象,如需在非主进程使用语音功能,请使用参数:SpeechConstant.APPID +"=12345678," + SpeechConstant.FORCE_LOGIN +"=true"。

    2.4   语音听写

      听写主要指将连续语音快速识别为文字的过程,科大讯飞语音听写能识别通用常见的语句、词汇,而且不限制说法。语音听写的调用方法如下:

      

//1.创建SpeechRecognizer对象,第二个参数:本地听写时传InitListener
SpeechRecognizer mIat= SpeechRecognizer.createRecognizer(context, null);
//2.设置听写参数,详见《科大讯飞MSC API手册(Android)》SpeechConstant类
mIat.setParameter(SpeechConstant.DOMAIN, "iat");
mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
mIat.setParameter(SpeechConstant.ACCENT, "mandarin ");
//3.开始听写   mIat.startListening(mRecoListener);
//听写监听器
private RecognizerListener mRecoListener = new RecognizerListener(){
//听写结果回调接口(返回Json格式结果,用户可参见附录12.1);
//一般情况下会通过onResults接口多次返回结果,完整的识别内容是多次结果的累加;
//关于解析Json的代码可参见MscDemo中JsonParser类;
//isLast等于true时会话结束。
public void onResult(RecognizerResult results, boolean isLast) {
            Log.d("Result:",results.getResultString ());}
//会话发生错误回调接口
    public void onError(SpeechError error) {
error.getPlainDescription(true) //获取错误码描述}
    //开始录音
    public void onBeginOfSpeech() {}
    //音量值0~30
    public void onVolumeChanged(int volume){}
    //结束录音
    public void onEndOfSpeech() {}
    //扩展用接口
    public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {}
};    

    2.5 语音交互动画

     为了便于快速开发,SDK还提供了一套默认的语音交互动画以及调用接口,如需使用请将SDK资源包assets路径下的资源文件拷贝至Android工程asstes目录下,然后通过以下代码使用交互动画:

//1.创建SpeechRecognizer对象,第二个参数:本地听写时传InitListener
RecognizerDialog    iatDialog = new RecognizerDialog(this,mInitListener);
//2.设置听写参数,同上节
//3.设置回调接口
iatDialog.setListener(recognizerDialogListener);
//4.开始听写
iatDialog.show();    

  三、语音合成

与语音听写相反,合成是将文字信息转化为可听的声音信息,让机器像人一样开口说话。合成的调用方法如下:

//1.创建SpeechSynthesizer对象, 第二个参数:本地合成时传InitListener
SpeechSynthesizer mTts= SpeechSynthesizer.createSynthesizer(context, null);
//2.合成参数设置,详见《科大讯飞MSC API手册(Android)》SpeechSynthesizer 类
mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan");//设置发音人
mTts.setParameter(SpeechConstant.SPEED, "50");//设置语速
mTts.setParameter(SpeechConstant.VOLUME, "80");//设置音量,范围0~100
mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); //设置云端
//设置合成音频保存位置(可自定义保存位置),保存在“./sdcard/iflytek.pcm”
//保存在SD卡需要在AndroidManifest.xml添加写SD卡权限
//如果不需要保存合成音频,注释该行代码
mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, "./sdcard/iflytek.pcm");
//3.开始合成
mTts.startSpeaking("科大讯飞,让世界聆听我们的声音", mSynListener);
//合成监听器
private SynthesizerListener mSynListener = new SynthesizerListener(){
    //会话结束回调接口,没有错误时,error为null
    public void onCompleted(SpeechError error) {}
    //缓冲进度回调
    //percent为缓冲进度0~100,beginPos为缓冲音频在文本中开始位置,endPos表示缓冲音频在文本中结束位置,info为附加信息。
    public void onBufferProgress(int percent, int beginPos, int endPos, String info) {}
    //开始播放
    public void onSpeakBegin() {}
    //暂停播放
    public void onSpeakPaused() {}
    //播放进度回调
    //percent为播放进度0~100,beginPos为播放音频在文本中开始位置,endPos表示播放音频在文本中结束位置.
    public void onSpeakProgress(int percent, int beginPos, int endPos) {}
    //恢复播放回调接口
    public void onSpeakResumed() {}
//会话事件回调接口
    public void onEvent(int arg0, int arg1, int arg2, Bundle arg3) {}  };

  四、代码整理

    上面只是按照官方文档把主要方法介绍一下。下面我自己整理了这两个功能。贴出源码供大家学习:

import java.util.HashMap;
import java.util.LinkedHashMap;

import org.json.JSONException;
import org.json.JSONObject;

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;
import com.iflytek.isvdemo.R;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

@SuppressLint("ShowToast")
public class YuTestActivity extends Activity implements OnClickListener {
    private static String TAG = YuTestActivity.class.getSimpleName();
    // 用HashMap存储听写结果
    private HashMap<String, String> mIatResults = new LinkedHashMap<String, String>();
    private EditText et_content;
    private Button bt_speech;
    private SpeechSynthesizer mTts;// 语音合成
    private SpeechRecognizer mIat;// 语音听写
    private Button bt_write;
    private RecognizerDialog iatDialog;//听写动画
    // 0 小燕 青年女声 中英文(普通话) xiaoyan
    // 1 默认 小宇 青年男声 中英文(普通话) xiaoyu
    // 2 凯瑟琳 青年女声 英文 catherine
    // 3 亨利 青年男声 英文 henry
    // 4 玛丽 青年女声 英文 vimary
    // 5 小研 青年女声 中英文(普通话) vixy
    // 6 小琪 青年女声 中英文(普通话) vixq xiaoqi
    // 7 小峰 青年男声 中英文(普通话) vixf
    // 8 小梅 青年女声 中英文(粤语) vixm xiaomei
    // 9 小莉 青年女声 中英文(台湾普通话) vixl xiaolin
    // 10 小蓉 青年女声 汉语(四川话) vixr xiaorong
    // 11 小芸 青年女声 汉语(东北话) vixyun xiaoqian
    // 12 小坤 青年男声 汉语(河南话) vixk xiaokun
    // 13 小强 青年男声 汉语(湖南话) vixqa xiaoqiang
    // 14 小莹 青年女声 汉语(陕西话) vixying
    // 15 小新 童年男声 汉语(普通话) vixx xiaoxin
    // 16 楠楠 童年女声 汉语(普通话) vinn nannan
    // 17 老孙 老年男声 汉语(普通话)
    private String[] voiceName = { "xiaoyan", "xiaoyu", "catherine", "henry",
            "vimary", "vixy", "xiaoqi", "vixf", "xiaomei", "xiaolin",
            "xiaorong", "xiaoqian", "xiaokun", "xiaoqiang", "vixying",
            "xiaoxin", "nannan", "vils" };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.yuyin);
        et_content = (EditText) findViewById(R.id.et_content);
        bt_speech = (Button) findViewById(R.id.bt_speech);
        bt_write = (Button) findViewById(R.id.bt_write);
        bt_speech.setOnClickListener(this);
        bt_write.setOnClickListener(this);
        // 初始化即创建语音配置对象,只有初始化后才可以使用MSC的各项服务
        SpeechUtility.createUtility(this, SpeechConstant.APPID + "=56f25de3");
        // 语音合成 1.创建SpeechSynthesizer对象, 第二个参数:本地合成时传InitListener
        mTts = SpeechSynthesizer.createSynthesizer(YuTestActivity.this,
                mTtsInitListener);
        // 语音听写1.创建SpeechRecognizer对象,第二个参数:本地听写时传InitListener
        mIat = SpeechRecognizer.createRecognizer(this, mTtsInitListener);
        // 1.创建SpeechRecognizer对象,第二个参数:本地听写时传InitListener
         iatDialog = new RecognizerDialog(this,
                mTtsInitListener);

    }

    /**
     * 初始化语音合成相关数据
     *
     * @Description:
     */
    public void starSpeech() {
        String content = et_content.getText().toString().trim();

        // 2.合成参数设置,详见《科大讯飞MSC API手册(Android)》SpeechSynthesizer 类
        mTts.setParameter(SpeechConstant.VOICE_NAME, voiceName[5]);// 设置发音人
        mTts.setParameter(SpeechConstant.SPEED, "50");// 设置语速
        mTts.setParameter(SpeechConstant.VOLUME, "80");// 设置音量,范围0~100
        mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); // 设置云端
        // 设置合成音频保存位置(可自定义保存位置),保存在“./sdcard/iflytek.pcm”
        // 保存在SD卡需要在AndroidManifest.xml添加写SD卡权限
        // 如果不需要保存合成音频,注释该行代码
        mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, "./sdcard/iflytek.pcm");
        // 3.开始合成
        mTts.startSpeaking(content, mSynListener);
        // 合成监听器
        //

    }

    /**
     * 初始化参数开始听写
     *
     * @Description:
     */
    private void starWrite() {
        // 2.设置听写参数,详见《科大讯飞MSC API手册(Android)》SpeechConstant类
        // 语音识别应用领域(:iat,search,video,poi,music)
        mIat.setParameter(SpeechConstant.DOMAIN, "iat");
        // 接收语言中文
        mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        // 接受的语言是普通话
        mIat.setParameter(SpeechConstant.ACCENT, "mandarin ");
        // 设置听写引擎(云端)
        mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
        iatDialog.setListener(mRecognizerDialogListener);
        iatDialog.show();
        Toast.makeText(getApplication(), "请开始说话…", Toast.LENGTH_SHORT).show();
        // 3.开始听写
        //mIat.startListening(mRecoListener);
        // 听写监听器

    }

    /**
     * 语音听写监听
     */
    private RecognizerListener mRecoListener = new RecognizerListener() {
        // 听写结果回调接口(返回Json格式结果,用户可参见附录12.1);
        // 一般情况下会通过onResults接口多次返回结果,完整的识别内容是多次结果的累加;
        // 关于解析Json的代码可参见MscDemo中JsonParser类;
        // isLast等于true时会话结束。
        public void onResult(RecognizerResult results, boolean isLast) {
            Log.d(TAG, results.getResultString());
            printResult(results);
        }

        // 会话发生错误回调接口
        public void onError(SpeechError error) {
            // 错误码:10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。
            if(error.getErrorCode()==10118){
                Toast.makeText(getApplicationContext(), "你好像没有说话哦",
                        Toast.LENGTH_SHORT).show();
            }
            Toast.makeText(getApplicationContext(), error.getPlainDescription(true),
                    Toast.LENGTH_SHORT).show();

        }// 获取错误码描述}

        // 开始录音
        public void onBeginOfSpeech() {
            Log.d(TAG, "开始说话");
            Toast.makeText(getApplicationContext(), "开始说话",
                    Toast.LENGTH_SHORT).show();
        }

        // 结束录音
        public void onEndOfSpeech() {
            Log.d(TAG, "说话结束");
            Toast.makeText(getApplicationContext(), "说话结束",
                    Toast.LENGTH_SHORT).show();
        }

        // 扩展用接口
        public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
        }

        //音量
        @Override
        public void onVolumeChanged(int volume, byte[] data) {
            // TODO Auto-generated method stub
            Log.d(TAG, "当前说话音量大小"+volume);

        }

    };

    /**
     * 听写UI监听器
     */
    private RecognizerDialogListener mRecognizerDialogListener = new RecognizerDialogListener() {
        public void onResult(RecognizerResult results, boolean isLast) {
            printResult(results);
        }

        /**
         * 识别回调错误.
         */
        public void onError(SpeechError error) {
            Toast.makeText(getApplication(), error.getPlainDescription(true), Toast.LENGTH_SHORT).show();
        }

    };
    /**
     * 语音合成监听
     */
    private SynthesizerListener mSynListener = new SynthesizerListener() {
        // 会话结束回调接口,没有错误时,error为null
        public void onCompleted(SpeechError error) {
            if (error != null) {
                Log.d("mySynthesiezer complete code:", error.getErrorCode()
                        + "");
            } else {
                Log.d("mySynthesiezer complete code:", "0");
            }
        }

        // 缓冲进度回调
        // percent为缓冲进度0~100,beginPos为缓冲音频在文本中开始位置,endPos表示缓冲音频在文本中结束位置,info为附加信息。
        public void onBufferProgress(int percent, int beginPos, int endPos,
                String info) {
        }

        // 开始播放
        public void onSpeakBegin() {
        }

        // 暂停播放
        public void onSpeakPaused() {
        }

        // 播放进度回调
        // percent为播放进度0~100,beginPos为播放音频在文本中开始位置,endPos表示播放音频在文本中结束位置.
        public void onSpeakProgress(int percent, int beginPos, int endPos) {
        }

        // 恢复播放回调接口
        public void onSpeakResumed() {
        }

        // 会话事件回调接口
        public void onEvent(int arg0, int arg1, int arg2, Bundle arg3) {
        }
    };

    /**
     * 初始化语音合成监听。
     */
    private InitListener mTtsInitListener = new InitListener() {
        @SuppressLint("ShowToast")
        @Override
        public void onInit(int code) {
            Log.d(TAG, "InitListener init() code = " + code);
            if (code != ErrorCode.SUCCESS) {
                // showTip("初始化失败,错误码:" + code);
                Toast.makeText(getApplicationContext(), "初始化失败,错误码:" + code,
                        Toast.LENGTH_SHORT).show();
            } else {
                // 初始化成功,之后可以调用startSpeaking方法
                // 注:有的开发者在onCreate方法中创建完合成对象之后马上就调用startSpeaking进行合成,
                // 正确的做法是将onCreate中的startSpeaking调用移至这里
            }
        }
    };

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()) {
        case R.id.bt_speech:
            starSpeech();
            break;
        case R.id.bt_write:
            et_content.setText(null);
            mIatResults.clear();
            starWrite();
            break;
        default:
            break;
        }

    }

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

        et_content.setText(resultBuffer.toString());
        et_content.setSelection(et_content.length());
    }

}

xml文件就一个EditText和两个button就不贴了还有一个JsonParser类sdk文档中sample中有

结束

  讯飞语音还有很多好玩的功能,比如人脸识别、声纹识别、语音唤醒等大家看看文档都很好实现的

时间: 2024-10-25 08:40:33

Android集成科大讯飞SDK语音听写及语音合成功能实现的相关文章

科大讯飞(1) 语音听写(语音转换成文字)

一.科大讯飞开放平台: http://www.xfyun.cn/ 注册.登录之后创建新应用. 因为本项目只实现了语音听写,所以在SDK下载中心勾选语音听写单项SDK就可以了 开发平台选择iOS,应用选择你要实现语音听写的应用,然后点击"下载SDK"按钮 程序中会用到Appid,程序中导入的SDK一定是要与这个应用相关联的SDK,下载下来的SDK压缩包就是以Appid结尾命名的. 二.项目配置 官方文档:http://www.xfyun.cn/doccenter/iOS 1.添加静态库

UI进阶 科大讯飞(1) 语音听写(语音转换成文字)

一.科大讯飞开放平台: http://www.xfyun.cn/ 注册.登录之后创建新应用. 因为本项目只实现了语音听写,所以在SDK下载中心勾选语音听写单项SDK就可以了 开发平台选择iOS,应用选择你要实现语音听写的应用,然后点击"下载SDK"按钮 程序中会用到Appid,程序中导入的SDK一定是要与这个应用相关联的SDK,下载下来的SDK压缩包就是以Appid结尾命名的. 二.项目配置 官方文档:http://www.xfyun.cn/doccenter/iOS 1.添加静态库

Android集成Facebook sdk,Key Hashes生成步骤

如上图所示,使用facebook sdk进行login和share的时候,需要新建android平台,用到key hashes,生成方法有两种: 方法一: keytool -exportcert -alias 'Nom Nom Eat' -keystore nomnom.jks |openssl sha1 -binary | openssl base64 注意事项: 1,使用上述命令请替换-alias 和 -keystore后面的东西,只需要替换这两处即可. 2,-alias后面跟的是自己的ke

Android 集成sina sdk 开发中,不能使用web授权,停止运行解决办法

在使用新浪SDK的时候,就出现了这个问题,一直以为是代码问题,但核对新浪SDK的DEMO后,发现代码流程都对呀 在Manifest.xml中注入SDK的WebBrowser <activity             android:name="com.sina.weibo.sdk.component.WeiboSdkBrowser"             android:configChanges="keyboardHidden|orientation"

Android集成讯飞语音、百度语音、阿里语音识别

项目实践:https://blog.csdn.net/Jsagacity/article/details/80094164 demo下载地址:https://fir.im/jy28 demo源码:https://github.com/wapchief/android-CollectionDemo 百度网盘:https://pan.baidu.com/s/1gvoTlcddstxb7tyS8MvWzw密码:l5gd 2 科大讯飞  https://www.xfyun.cn/ 网友使用1https:

Android 使用第三方SDK—友盟实现分享功能

今天给大家写一下友盟的分享,这段时间在项目有用到,这里简单给大家介绍一下. 友盟的官网链接:点击打开链接 首先,到微信,QQ,微博开放平台添加应用,获取key,下面列出链接: QQ开放平台 微信开放平台  微博开放平台 到友盟官网注册,添加应用获取唯一的key, 下载友盟分享的SDK,需要引入到自己项目当中.我这只用到了微信,QQ,微博,就只选了一部分功能. 再添加相应的res资源文件到你的项目中,到这里,准备工作就完成了. 接下来,开始实现分享功能.友盟分享有它自己给的分享界面,可以直接使用,

Android集成讯飞SDK实现语音拨号、语音导航、语音启动应用

转载请注明出处:周木水的CSDN博客 http://blog.csdn.net/zhoumushui 科大讯飞语音SDK的语义分析还是挺强大的,可使我们的应用更加强大. 上篇博文介绍了讯飞SDK的一些简单功能: Android 使用讯飞语音SDK 今天来看看对语义分析结果JSON的解析并处理: 实现语音拨号 首先,我们看看"打电话给张三"这句话在服务器分析之后,传给我们的JSON是什么样的: { "semantic": { "slots": {

集成Android免费语音合成功能(在线、离线、离在线融合)

集成Android免费语音合成功能(在线.离线.离在线融合),有这一篇文章就够了(离线)集成Android免费语音合成功能(在线.离线.离在线融合),有这一篇文章就够了(离在线融合) 转眼间,大半年没写文章了,没什么理由,就是人变懒了.囧~ 看标题,其实大家都被骗了,有这一篇文章还不够,我其实是打算分3篇文章来写的,如果合在一章里面就太长了,不过现在这个标题党横行的网络世界,我也被污染了,哈.那么为什么要分3篇文章来讲呢?看标题也能猜到了,就是在线.离线.离在线融合这3种语音合成方式,我将分别使

Android讯飞语音云语音听写学习

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