讯飞开放平台sdk集成之android

最近由于公司项目需要研究了一下讯飞的语音合成功能,其实挺简单的,这里写下来一是为了加深自己的印象,二是告诉大家我踩过的坑。

集成SDK之前,你得需要下载SDK,而下载SDK之前你需要在讯飞开放平台上创建一个你自己的应用,(这里注意一下创建一个应用时,会自动关联一个Appid,Appid和对应的SDK具有一致性,如:创建android平台的应用A,关联的Appid是12345678,即12345678和应用A对应的SDK是一一对应关系。

接下来我说明一下集成的具体步骤:

1 首先成为开发者
点击讯飞开放平台页面右上角“注册”按钮,在注册页面根据提示信息填写基本资料,成功提交后,即可成为一名开发者。

这里是讯飞开放平台的地址:http://www.xfyun.cn/

2 完善用户资料
为啥要完善用户资料呢,因为需要完善用户资料才能创建应用;

3 创建应用

登录讯飞开放平台后,有两种方式可以创建应用:

    1)点击“我的语音云”->“创建新应用”,请根据提示信息,完成应用的创建;

    2)点击“产品服务”,进入某个服务页面,如“语音基础能力”,选择右侧的“使用服务”,在弹出的窗口中点击“创建新应用”,请根据提示信息,完成应用的创建。

4 应用提交审核
如果你只是为了测试玩玩的话,这一步骤你也可以不操作,如果你是公司有这方面功能的需求,那就需要这步操作了,因为 SDK集成调试阶段,服务量会有500次/日的限制,通过审核后可无限次使用语音服务。
5 下载SDK

在讯飞开放平台首页顶部菜单栏选中SDK下载,选择好你要集成的服务如:在线语音合成,选择好你的平台如:android,选择好你刚刚在平台创建好的应用;


前期工作做好了,现在就可以将SDK集成到你的应用中了

6 集成SD

Step 1 导入SDK

将在官网下载的Android SDK 压缩包中libs目录下所有子文件拷贝至Android工程的libs目录下。如下图所示:

注:

  1. Android SDK提供了各个平台libmsc.so文件,开发者可以根据工程需求选取适当平台库文件进行集成。
  2. 如果您需要将应用push到设备使用,请将设备cpu对应指令集的libmsc.so push到/system/lib中。

Step 2 添加用户权限

在工程 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"/>
<!--外存储读权限,构建语法需要用到此权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!--配置权限,用来记录应用配置信息 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<!--手机定位信息,用来为语义等功能提供定位,提供更精准的服务-->
<!--定位信息是敏感信息,可通过Setting.setLocationEnable(false)关闭定位请求 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--如需使用人脸识别,还要添加:摄相头权限,拍照需要用到 -->
<uses-permission android:name="android.permission.CAMERA" />

注意:如需在打包或者生成APK的时候进行混淆,请在proguard.cfg中添加如下代码:

-keep class com.iflytek.**{*;}
-keepattributes Signature

Step 3 初始化

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

// 将“12345678”替换成您申请的APPID,申请地址:http://www.xfyun.cn
// 请勿在“=”与appid之间添加任何空字符或者转义符
SpeechUtility.createUtility(context, SpeechConstant.APPID +"=12345678");

createUtility方法的第二个参数为传入的初始化参数列表,可配置的参数如下:

参数说明必填
appid8位16进制数字字符串,应用的唯一标识,与下载的SDK一一对应。
usr开发者在云平台上注册的账号。
pwd账号对应的密码,与账号同时存在。
engine_mode引擎模式,可选值为:msc:只使用MSC的能力;plus:只使用语记能力;auto:云端使用MSC,本地使用语记;默认取值为auto。注:使用MSC本地功能的请设置为msc。
force_login 在createUtility时会对进程名称进行检查,如果名称与应用包名不一致则不进行login操作,返回null,用以规避在子进程反复进行调用的问题。此参数设置是否强制login。默认值:false (进行检查,不强制login)。
lib_name在createUtility时会加载动态库,此时可以传入动态库名称。例如:libmsc_xxx_1072.so(xxx为您的公司名,1072为科大讯飞sdk版本号), 默认值:msc。注:如您是预装软件,为了避免动态库冲突建议修改名称。

注意:参数需要以键值对的形式存储在字符串中传入createUtility方法,以逗号隔开,如“appid=12345678,usr=iflytekcloud,pwd=123456”。

作者:嗯上面集成SDK的几点都是我直接复制官网的,我这里直接贴出来也是为了方便大家不用再去官网找了大笑,不过有一点我要强调一下,用Android studio开发的同学们注意了,那些so文件必须要放下D:\project\VehicleTerminal\app\src\main\jniLibs目录下(“D:\project\VehicleTerminal\app\”前面这里的路径当然是根据你的项目来定了),如果你放在这里的话,你是初始化不了这个服务的,你调用初始化的时候会报错误码为21002的错误,官方文档是解释这个错误叫“引擎不支持”;

现在SDK也导入进来了,就剩下最后一步调用他的服务了。接下来我就举一个例子,主要是我现在只需要用到这个服务大笑,语音合成,就是将文字转化为语音。下面贴出官网上面的文档

语音合成

与语音听写相反,语音合成(SpeechSynthesizer)是将文字信息转化为可听的声音信息,让机器像人一样开口说话。

语音合成中,主要参数包括合成的

  • 语言(LANGUAGE,中文、英文等)
  • 方言(ACCENT,中文的普通话,粤语等)
  • 发音人特征(性别,年龄,语气)
  • 语速(SPEED)
  • 音量(VOLUME)
  • 语调(PITCH)
  • 音频采样率(SAMPLE_RATE)

在 MSC SDK 参数中的前三者(语言、方言和特征)基本由发音人决定——即不同的发音人,支持不一样的语言、方言和特征,参考附录中的发音人列表。

如果使用的是离线合成,MSC 模式下还必须设置合成资源的路径,需下载使用对应的离线合成SDK。

mTts.setParameter( SpeechConstant.ENGINE_TYPE, engineType ); 
mTts.setParameter( SpeechConstant.ENGINE_MODE, engineMode );

if( SpeechConstant.TYPE_LOCAL.equals(engineType)
    &&SpeechConstant.MODE_MSC.equals(engineMode) ){
    // 需下载使用对应的离线合成SDK
    mTts.setParameter( ResourceUtil.TTS_RES_PATH, ttsResPath );
}

mTts.setParameter( SpeechConstant.VOICE_NAME, voiceName );

final String strTextToSpeech = "科大讯飞,让世界聆听我们的声音";
mTts.startSpeaking( strTextToSpeech, mSynListener );
 作者:其实当时我看到这里是一脸懵逼的,那个mTs是啥,engineType又是啥,我先什么都没管把这段代码复制到了我的demo项目中,然后又仔细找啊找啊才找到了这么段文字

引擎类型

MSC SDK 有几种引擎类型(ENGINE_TYPE),此文章中我们主要关注并介绍以下两种:

  • 在线引擎(TYPE_CLOUD),又称为云端模式,需要使用网络,速度稍慢,并产生一定流量,但有更好的识别和合成的效果,如更高的识别匹配度,更多的发音人等。
  • 离线引擎(TYPE_LOCAL),又称为本地模式,不需要使用网络,且识别和合成的速度更快,但同时要求购买并使用对应的离线资源(下载对应离线功能的SDK包),或安装语记(语记的更多介绍,见后面章节)。

需要说明的是,在线引擎下,结果返回速度基本决定于用户网络的带宽限制。如在合成或识别下,默认的音频格式为 16000 HZ 采样,16 bit 精度,单声道, raw pcm,Little-endian;在未压缩的情况下,为 16000 * 16 = 256000 bit/s(比特每秒)。此时,如果要听写上传,或下载合成到的音频,时长为 t 秒,用户网络带宽为 x mpbs(兆比特每秒),则需要时长为 256000 * t / ( x(2^10)(2^10) ),假设 t 为 10,x 为 1,则10秒的音频,在1M的带宽下的传输时间约为 2.44s。

特别是在识别时,主要网络数据交互在音频的上传过程,此时网络上行带宽决定了音频上传的快慢,影响语音云服务器收到音频的快慢,继而决定了结果返回的快慢。

针对网络带宽的影响结果问题,MSC SDK 在识别音频上传和合成音频下载时,都做了相应的优化:

  • 会话模式( ssm ),默认开启。只要 SDK 获取到一部份音频数据,就会开始上传到语音云服务器,而不是等到整段识别音频数据都获取到再上传。在实时的录制音频并进行识别时,此优化效果尤其明显:音频的录制需要时间,而 SDK 会利用这些时间,每录制到一小段音频,就开始上传到语音云服务器,且在有部份小分句(如有停顿的地方)的结果时,就会把结果返回给客户端。待音频录制完时,音频也已即将完成上传,此时,结果返回就更快,几乎能达到说完即得到结果的情况。更特别的,VAD(关于VAD的更多说明,参考《MSC Reference Manual.html》)生效的情况下,在应用层还未告知 SDK 已完成音频录制时,结果可能已返回。
  • 音频压缩(aue),并默认开启。发送端对上下行的音频进行压缩(在客户端由 MSC SDK 自动压缩),压缩比约为 10:1,并在接收端解压还原(在客户端由 MSC SDK 自动解压),大大减少带宽占用,并减少网络交互的时间占用。

引擎模式

在引擎类型设置为离线引擎(TYPE_LOCAL)时,MSC SDK 提供两种方式(ENGINE_MODE)来使用离线功能:MSC,语记。

  • MSC 模式(MODE_MSC),使用 MSC SDK 本身提供的离线模块,需要在下载SDK时,选择离线功能,以购买对应的离线功能资源;
  • 语记模式(MODE_PLUS),使用讯飞语记应用提供的离线模式,离线功能资源由语记应用自带,不需要另外购买,但需要安装语记应用——应用在集成时,可以通过代码检查设备中是否已安装语记,并自动下载安装语记,检查已安装语记的资源等。可以通过以下链接 下载语记,或扫描下面的二维码下载,了解语记:

应用、MSC SDK 与语记间的关系大致如下图:

在引擎模式中,还有自动模式(MODE_AUTO),由SDK自动决定使用 MSC 模式,还是语记模式。在自动模式下,引擎类型为在线时,SDK 自动选择 MSC 模式;引擎类型为离线时,SDK 自动选择语记模式。

需要注意的是,为了方便应用的集成,MSC SDK 针对下仅有在线功能的 SDK,和含离线功能(唤醒、合成、识别)的 SDK,提供的 SDK 包会不一样:仅有在线功能的 SDK,默认的引擎模式为自动模式,方便应用使用语记提供的离线服务;含有离线功能的 SDK ,默认引擎模式为 MSC 模式,方便应用使用 MSC SDK 自带提供的离线服务。同时,为了减少 SDK 包的大小,在线 SDK 可能没有离线 SDK 的部份类。如果要混用 SDK 包,应用应明确指定使用的引擎模式。

在使用离线功能时,语记模式和 MSC 模式的区别在于,语记模式下,资源不必另外购买即可使用,但同时,资源覆盖程度也受语记的限制;MSC 模式下,如果有更多的需求,可以联系我们进行商务合作定制开发,提供更丰富的资源。

获取语记参数

用户可以通过语记中的资源下载(包括:识别资源、发音人资源)来提升语记离线能力,开发者可以通过以下接口获取当前语记包含的离线资源列表,此接口从语记1.032(99)版本开始支持。(通过getServiceVersion()获取版本号) 注:后续版本将支持获取语记当前设置的发音人字段

//1.设置所需查询的资源类型
/**
 *1.PLUS_LOCAL_ALL: 本地所有资源 
 *2.PLUS_LOCAL_ASR: 本地识别资源
 *3.PLUS_LOCAL_TTS: 本地合成资源
 */
String type = SpeechConstant.PLUS_LOCAL_ASR;

//2.获取当前《语记》包含资源列表
String resource = SpeechUtility.getUtility().getParameter(type);

//3.解析json-请参见下面示例及Demo中解析方法
{
  "ret": 0, 
  "result": {
    "version": 11, 
    "tts": [
      {
        "sex": "woman", 
        "language": "zh_cn", 
        "accent": "mandarin", 
        "nickname": "邻家姐姐", 
        "age": "22", 
        "name": "xiaojing"
      }, 
      {
        "sex": "woman", 
        "language": "zh_cn", 
        "accent": "mandarin", 
        "nickname": "王老师", 
        "age": "24", 
        "name": "xiaoyan"
      }
    ], 
    "asr": [
      {
        "domain": "asr", 
        "samplerate": "16000", 
        "language": "zh_cn", 
        "accent": "mandarin", 
        "name": "common"
      }
    ]
  }
}
作者:看了上面这两段文字就知道那个type和mode是什么了,然后我看到文档上面说可以改变语音声音的性别还有方言什么的,然后我就又找啊找,还上网查了一下有没有其他人写过,发现没有什么收获,这文档不是骗人的吧,想想也不可能,然后我就又想到我下载SDK的那个文件夹,发现原来源码的一些注解,还有规范都在里面

就在这个doc的文件夹下,下面我写一个我的例子吧
SpeechSynthesizer mTts = SpeechSynthesizer.createSynthesizer(this,this);
                String engineType = SpeechConstant.TYPE_CLOUD; // 设置云端
                String engineMode = SpeechConstant.MODE_AUTO;
                mTts.setParameter( SpeechConstant.ENGINE_TYPE, engineType );// 设置云端
                mTts.setParameter( SpeechConstant.ENGINE_MODE, engineMode );
                mTts.setParameter(SpeechConstant.SPEED, "50"); // 设置语速
                mTts.setParameter(SpeechConstant.VOLUME, "80"); // 设置音量,范围 0~100
                
                // 设置合成音频保存位置(可自定义保存位置),保存在 “./sdcard/iflytek.pcm”
                //  保存在 SD 卡需要在 AndroidManifest.xml 添加写 SD 卡权限
                // 仅支持保存为 pcm 和  wav 格式, 如果不需要保存合成音频,注释该行代码
                mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, "./sdcard/iflytek.pcm");


                mTts.setParameter( SpeechConstant.VOICE_NAME, "vils" ); // 设置发音人 默认是xiao yan


                final String strTextToSpeech = mEtContent.getText().toString();
                mTts.startSpeaking(strTextToSpeech, new SynthesizerListener() {
                    @Override
                    public void onSpeakBegin() {//开始播放
                    }
                    @Override
                    public void onSpeakPaused() {//暂停播放
                    }
                    @Override
                    public void onSpeakResumed() {//继续播放
                    }
                    @Override
                    public void onBufferProgress(int i, int i1, int i2, String s) {//合成进度
                    }
                    @Override
                    public void onSpeakProgress(int i, int i1, int i2) {//播放进度
                    }
                    @Override
                    public void onCompleted(SpeechError speechError) {
                        if (speechError == null) {
                            Toast.makeText(MainActivity.this,"播放完成 ",Toast.LENGTH_SHORT).show();
                        } else if (speechError != null ) {
                            Toast.makeText(MainActivity.this,speechError.getPlainDescription( true),Toast.LENGTH_SHORT).show();
                        }
                    }
                    @Override
                    public void onEvent(int i, int i1, int i2, Bundle bundle) {
                        // 以下代码用于获取与云端的会话 id,当业务出错时将会话 id提供给技术支持人员,可用于查询会话日志,定位出错原因
                        // 若使用本地能力,会话 id为null
                        //if (SpeechEvent.EVENT_SESSION_ID == eventType) {
                        //     String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
                        //     Log.d(TAG, "session id =" + sid);
                        //}
                    }
                });

作者:前面说那个语音可以设置很多种,其实是设置那个发音人,里面有特定的几种声音这里有个官方的表格大家可以设置玩一玩;不过其中粤语的应该怎么设置我还没找到方法,如果有知道的可以留言告诉我哦吐舌头
作者:好啦,我要说的就到这里了,如果有需要集成其他服务的同学,大体流程也就是这样了,具体调用服务的代码可以查相关文档啦,希望这篇文章可以帮助到大家,谢谢。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值