与语音听写相反,语音合成是将一段文字转换为语音,可根据需要合成出不同音色、语速和语调的声音,让机器像人一样开口说话,更为详细的信息可查看官网文档中的语音服务部分。
合成详细的接口介绍及说明请参考: MSC iOS API 文档, 在集成过程中如有疑问,可登录讯飞开放平台论坛,查找答案或与其他开发者交流。
合成支持在线和离线两种工作方式,默认使用在线方式。如果使用离线服务,有2种方式,一种是使用语记SDK(原语音+ SDK)提供的免费服务,一种是付费购买后在应用内部集成。相关细节请关注讯飞开放平台( https://www.ai-tj.cn/ )
小语种及少数民族方言:暂不支持,敬请期待!
MSC SDK的主要功能接口如下图所示(关注合成部分):
appid是第三方应用集成讯飞开放平台SDK的身份标识,SDK静态库和appid是绑定的,每款应用必须保持唯一,否则会出现10407错误码。appid在开放平台申请应用时可以获得,下载SDK后可从SDK中sample文件夹的Demo工程里找到(例如: /sample/MSCDemo/MSCDemo/Definition.h 的APPID_VALUE)。
将开发工具包中lib目录下的iflyMSC.framework添加到工程中。同时请将Demo中依赖的其他库也添加到工程中。 按下图示例添加 SDK 所需要的 iOS系统库:
库名称 | 添加范围 | 功能 |
---|---|---|
iflyMSC.framework | 必要 | 讯飞开放平台静态库。 |
libz.tbd | 必要 | 用于压缩、加密算法。 |
AVFoundation.framework | 必要 | 用于系统录音和播放 。 |
SystemConfiguration.framework | 系统库 | 用于系统设置。 |
Foundation.framework | 必要 | 基本库。 |
CoreTelephony.framework | 必要 | 用于电话相关操作。 |
AudioToolbox.framework | 必要 | 用于系统录音和播放。 |
UIKit.framework | 必要 | 用于界面显示。 |
CoreLocation.framework | 必要 | 用于定位。 |
Contacts.framework | 必选 | 用于联系人。 |
AddressBook.framework | 必选 | 用于联系人。 |
QuartzCore.framework | 必要 | 用于界面显示。 |
CoreGraphics.framework | 必要 | 用于界面显示。 |
libc++.tbd | 必要 | 用于支持C++。 |
注意:
在Xcode 7,8默认开启了Bitcode,而Bitcode 需要工程依赖的所有类库同时支持。MSC SDK暂时还不支持Bitcode,可以先临时关闭。后续MSC SDK支持Bitcode 时,会在讯飞开放平台上进行SDK版本更新,请关注。关闭此设置,只需在Targets - Build Settings 中搜索Bitcode 即可,找到相应选项,设置为NO。
iOS 10发布以来,苹果为了用户信息安全,加入隐私权限设置机制,让用户来选择是否允许。 隐私权限配置可在info.plist 新增相关privacy字段,MSC SDK中需要用到的权限主要包括麦克风权限、联系人权限和地理位置权限:
<key>NSMicrophoneUsageDescription</key>
<string></string>
<key>NSLocationUsageDescription</key>
<string></string>
<key>NSLocationAlwaysUsageDescription</key>
<string></string>
<key>NSContactsUsageDescription</key>
<string></string>
即在Info.plist 中增加下图设置:
初始化示例:
//Appid是应用的身份信息,具有唯一性,初始化时必须要传入Appid。
NSString *initString = [[NSString alloc] initWithFormat:@"appid=%@", @"YourAppid"];
[IFlySpeechUtility createUtility:initString];
参数 | 说明 | 必填 |
---|---|---|
appid | 8位16进制数字字符串,应用的唯一标识,与下载的SDK一一对应。 | 是 |
usr | 保留字段,无需关注。 | 否 |
pwd | 保留字段,无需关注。 | 否 |
注意: 初始化是一个异步过程,可放在App启动时执行初始化,具体代码可以参照Demo的MSCAppDelegate.m。
所有的服务皆遵循如下的流程,如下图:
所有服务的API详细说明可参见:https://www.ai-tj.cn/doc/mscapi/iOS/iossynthesizer.html。
本示例对应Demo的TTSUIController文件,为在线合成的代码示例。
//包含头文件
#import "iflyMSC/IFlyMSC.h"
//需要实现IFlySpeechSynthesizerDelegate合成会话的服务代理
@interface TTSUIController : UIViewController<IFlySpeechSynthesizerDelegate>
@property (nonatomic, strong) IFlySpeechSynthesizer *iFlySpeechSynthesizer;
@end
//获取语音合成单例
_iFlySpeechSynthesizer = [IFlySpeechSynthesizer sharedInstance];
//设置协议委托对象
_iFlySpeechSynthesizer.delegate = self;
//设置合成参数
//设置在线工作方式
[_iFlySpeechSynthesizer setParameter:[IFlySpeechConstant TYPE_CLOUD]
forKey:[IFlySpeechConstant ENGINE_TYPE]];
//设置音量,取值范围 0~100
[_iFlySpeechSynthesizer setParameter:@"50"
forKey: [IFlySpeechConstant VOLUME]];
//发音人,默认为”xiaoyan”,可以设置的参数列表可参考“合成发音人列表”
[_iFlySpeechSynthesizer setParameter:@" xiaoyan "
forKey: [IFlySpeechConstant VOICE_NAME]];
//保存合成文件名,如不再需要,设置为nil或者为空表示取消,默认目录位于library/cache下
[_iFlySpeechSynthesizer setParameter:@" tts.pcm"
forKey: [IFlySpeechConstant TTS_AUDIO_PATH]];
//启动合成会话
[_iFlySpeechSynthesizer startSpeaking: @"你好,我是科大讯飞的小燕"];
//IFlySpeechSynthesizerDelegate协议实现
//合成结束
- (void) onCompleted:(IFlySpeechError *) error {}
//合成开始
- (void) onSpeakBegin {}
//合成缓冲进度
- (void) onBufferProgress:(int) progress message:(NSString *)msg {}
//合成播放进度
- (void) onSpeakProgress:(int) progress beginPos:(int)beginPos endPos:(int)endPos {}
离线合成指的是语音引擎和资源放置在应用内部,不需要连接到语音云时也可以使用的语音合成服务。因此使用时,需要在应用中添加离线引擎和发音人资源。离线引擎在提供离线服务的SDK中已内置。在使用时只需要根据选择的发音人来设置对应的离线发音人资源即可。 以Demo为例:
ttsres是离线合成的引擎资源集合,common.jet是基础资源,其他文件是发音人各自对应的资源。在实际使用时,common.jet和发音人资源需要同时设置。发音人可以根据需要自行选择。 引擎大小:
状态 | 大小 |
---|---|
编译前静态库 | 18.2MB |
编译后(ipa) | 4.3MB |
资源大小:
类型 | 大小 |
---|---|
基础资源 | 4.3 MB |
小燕 | 4.1 MB |
小峰 | 1.3 MB |
小梅 | 1.7 MB |
凯瑟琳 | 3.0 MB |
空间大小:(不同的编译器编译后大小会有不同,请以实际为准) ipa文件大小 = 引擎编译后(4.3MB) + 基础资源(4.3MB) + 所选择的发音人资源(如:小燕4.1MB)。 下面代码是集成本地资源时需要添加的部分,其他代码与在线一致。
//设置语音合成的启动参数
[[IFlySpeechUtility getUtility] setParameter:@"tts" forKey:[IFlyResourceUtil ENGINE_START]];
//获得语音合成的单例
_iFlySpeechSynthesizer = [IFlySpeechSynthesizer sharedInstance];
//设置协议委托对象
_iFlySpeechSynthesizer.delegate = self;
//设置本地引擎类型
[_iFlySpeechSynthesizer setParameter:[IFlySpeechConstant TYPE_LOCAL] forKey:[IFlySpeechConstant ENGINE_TYPE]];
//设置发音人为小燕
[_iFlySpeechSynthesizer setParameter:@"xiaoyan" forKey:[IFlySpeechConstant VOICE_NAME]];
//获取离线语音合成发音人资源文件路径。以发音人小燕为例,请确保资源文件的存在。
NSString *resPath = [[NSBundle mainBundle] resourcePath];
NSString *vcnResPath = [[NSString alloc] initWithFormat:@"%@/aisound/common.jet;%@/aisound/xiaoyan.jet",resPath,resPath];
//设置离线语音合成发音人资源文件路径
[_iFlySpeechSynthesizer setParameter:vcnResPath forKey:@"tts_res_path"];
在createUtility接口的params参数中添加:
net_type=custom, proxy_ip=<host>, proxy_port=<port>
其中,<host>,<port>替换为实际的代理服务器地址和端口。
例如:
NSString *initString = [[NSString alloc] initWithFormat:@"appid=%@, net_type=custom, proxy_ip=192.168.1.2, proxy_port=8080", @"12345678"]; //注意:各参数间,以英文逗号分隔。
[IFlySpeechUtility createUtility:initString];
接口原型: (IFlySpeechUtility *)createUtility:(NSString *)params
注意: 若在设置代理参数后,使用语音服务过程中,报错10204/10205/10212等网络异常错误时,请查阅以下内容,做出相关操作:
讯飞语音SDK的通信协议使用的是标准HTTP1.1协议,其代理协议使用的是标准HTTP代理协议。
代理服务器需要支持全双工多问多答方式,即 pipeline 模式。
代理服务器不能对80端口做限制,不能对如下域名做拦截: hdns.openspeech.cn scs.openspeech.cn open.xf-yun.com dev.voicecloud.cn
需要确保代理服务器只负责转发数据包,不能改变数据包的完整性和时序性。
代理服务器在转发数据包时,不能在HTTP协议头部添加 IE6 标识头。
答:请参见论坛帖子:iOS MSC SDK常见问题总结
答:使用[IFLYSetting getVersion]获取SDK的版本,然后和目前线上的对比就能知道是否是最新的SDK。
答:SDK与APPID是绑定的,一个APPID对应一个SDK。请检查是否有以下情况:
(1)代码传入的参数和下载选择的APPID不一致。
(2)新申请了新的APPID,Framework Search Path里引用了旧的SDK。
答:对于一些特殊服务,需要在createUtility接口中添加:server_url = http://YourDomainName/msp.do (YourDomainName是指语音云服务域名,请开发者自行替换) 例如:
NSString *initString = [[NSString alloc] initWithFormat:@"appid=%@,server_url=%@", @"12345678",@"http://sdk.openspeech.cn/msp.do"]; //注意:各参数间,以英文逗号分隔。
[IFlySpeechUtility createUtility:initString];
接口原型: (IFlySpeechUtility *)createUtility:(NSString *)params
答:暂不支持合成应用退出后台、息屏播报。
答:请参见论坛帖子:讯飞语音iOS SDK音频问题详解