You need to enable JavaScript to run this app.
导航

接入流程

最近更新时间2023.12.12 11:41:52

首次发布时间2021.12.20 14:44:12

初始化

环境依赖

创建语音合成 SDK 引擎实例前调用,完成网络环境等相关依赖配置。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    return [SpeechEngine prepareEnvironment];
}

创建引擎实例

语音合成 SDK 通过以下方式获取实例。

//创建实例
self.engine = [[SpeechEngine alloc] init];
//添加引擎代理,需要实现回调方法
[self.engine createEngineWithDelegate:self];

参数配置

引擎类型

// 语音合成引擎
[self.engine setStringParam:SE_TTS_ENGINE forKey:SE_PARAMS_KEY_ENGINE_NAME_STRING];

日志

为便于开发者集成调试,有如下建议:

  • 日志级别 ,开发时设置为 DEBUG, 线上设置 WARN
  • 调试路径 ,语音合成 SDK 会在该路径下生成文件名前缀为 speech_sdk 的日志文件,开发时设置, 线上关闭
// 日志级别
[self.engine setStringParam:SE_LOG_LEVEL_WARN forKey:SE_PARAMS_KEY_LOG_LEVEL_STRING];
// 调试路径
[self.engine setStringParam:@"{DEBUG PATH}" forKey:SE_PARAMS_KEY_DEBUG_PATH_STRING];

线上问题定位

为了方便定位线上问题,需要开发者配置相关参数,包括:

  • UID, 用于区分不同的用户,在线合成必需配置;
  • DEVICE_ID, 用于区分不同的设备,可选配置;

因为 TTS 服务端的要求,如果不配置 UID 或配置为空字符串会导致无法使用在线合成,因此使用在线合成一定要配置 UID, 离线合成则没有这一要求。UID 配置为任意非空字符串都可以正常使用在线合成,但如果不能保证 UID 对每个用户都是不一样的就会影响问题定位,使我们无法还原问题发生时用户的操作路径。
DEVICE_ID 允许不配置或配置为空字符串,不配置设备 ID 或者无法保证设备 ID 的唯一性同样会影响线上问题定位。
SDK 不会自行采集用户 ID 和设备 ID, 不涉及相关敏感信息的获取。
用户 ID 配置方法

[self.engine setStringParam:@"USER ID" forKey:SE_PARAMS_KEY_UID_STRING];

设备 ID 配置方法,不配置则不采集该项

[self.engine setStringParam:@"DEVICE ID" forKey:PARAMS_KEY_DEVICE_ID_STRING];

授权

使用离在线语音合成能力时,需要完成相关授权验证。

在线授权

请先到火山控制台申请 AppidToken,申请方法参考这个页面的 Q1,配置 Token 时需要添加固定前缀 Bearer;

// 在线授权
[self.engine setStringParam:@"{APPID}" forKey:SE_PARAMS_KEY_APP_ID_STRING];
[self.engine setStringParam:@"Bearer;{TOKEN}" forKey:SE_PARAMS_KEY_APP_TOKEN_STRING];

离线授权

对离线合成的授权有两种授权方式,按包名授权按装机量授权均需联系商务获取。按包名授权是指开通了权限的 APP 可以不限次数的使用离线合成功能;按装机量授权不限制 APP 的包名,但是限制使用离线合成的设备数量。

无论使用哪一种授权方式,都需要首先配置证书文件的路径。 该路径应由使用 SDK 的 APP 提前创建好且确保具备读写权限。

// 配置证书文件路径
[self.curEngine setStringParam:@"{LICENSE DIRECTORY}" forKey:SE_PARAMS_KEY_LICENSE_DIRECTORY_STRING];

下面分别介绍两种授权方式及各自所需的配置:

  • 按包名授权
    • 本地证书,需要配置授权方式证书路径,同时开发者需要自行将证书文件放置到证书路径,并修改文件名为 speech_license.licbag;
    • 在线证书,语音合成 SDK 也支持在触发鉴权行为时自动下载证书到证书路径,开发者需要配置授权方式证书名场景ID证书路径
// 配置授权方式
[self.curEngine setStringParam:SE_AUTHENTICATE_TYPE_PRE_BIND forKey:SE_PARAMS_KEY_AUTHENTICATE_TYPE_STRING];
// 配置证书名
[self.curEngine setStringParam:@"{LICENSE_NAME}" forKey:SE_PARAMS_KEY_LICENSE_NAME_STRING];
// 配置场景ID
[self.curEngine setStringParam:@"{BUSI_ID}" forKey:SE_PARAMS_KEY_LICENSE_BUSI_ID_STRING];
  • 按装机量授权
    需要配置证书路径鉴权方式业务标识密钥证书服务域名证书服务 URI
// 配置授权方式
[self.curEngine setStringParam:SE_AUTHENTICATE_TYPE_LATE_BIND forKey:SE_PARAMS_KEY_AUTHENTICATE_TYPE_STRING];
// 配置业务标识
[self.curEngine setStringParam:@"{BUSINESS KEY}" forKey:SE_PARAMS_KEY_BUSINESS_KEY_STRING];
// 配置密钥
[self.curEngine setStringParam:@"{SECRET}" forKey:SE_PARAMS_KEY_AUTHENTICATE_SECRET_STRING];
// 配置证书服务域名
[self.curEngine setStringParam:@"https://cv-tob.bytedance.com" forKey:SE_PARAMS_KEY_AUTHENTICATE_ADDRESS_STRING];
// 配置证书服务 URI
[self.curEngine setStringParam:@"/v1/api/sdk/tob_license/getlicense" forKey:SE_PARAMS_KEY_AUTHENTICATE_URI_STRING];

合成场景

语音合成 SDK 提供了两种种合成场景,以满足不同的需求:

  • 单次合成场景 SE_TTS_SCENARIO_TYPE_NORMAL:引擎每次启动,只合成、播放一句音频的模式;
  • 连续合成场景 SE_TTS_SCENARIO_TYPE_NOVEL:适用于听书业务,每次启动引擎后可以根据需求合成多句音频;
// 合成场景:连续合成场景
[self.engine setStringParam:SE_TTS_SCENARIO_TYPE_NOVEL forKey:SE_PARAMS_KEY_TTS_SCENARIO_STRING]

合成策略

离在线语音合成 SDK,除了可以单独使用的在线合成及离线合成外,提供了在线合成发生网络错误后自动切换到离线合成的两种策略,开发者可以通过配置 建连超时 SE_PARAMS_KEY_TTS_CONN_TIMEOUT_INT接收超时 SE_PARAMS_KEY_TTS_RECV_TIMEOUT_INT 两个参数来控制切换的敏感程度。下面介绍 SDK 支持的几种合成模式:

  • 在线合成 kTtsWorkModeOnline:只进行在线合成,不需要配置离线合成相关参数;
  • 离线合成 kTtsWorkModeOffline:只进行离线合成,不需要配置在线合成相关参数;
  • 在线优先 kTtsWorkModeAlternate:优先发起在线合成,失败后(网络错误),启动离线合成引擎开始合成;
  • 并发合成 kTtsWorkModeBoth:同时发起在线合成与离线合成,在线请求失败的情况下,使用离线合成数据,该模式下,可以配置更短的超时时间以提升效果,但会消耗更多系统性能;
// 合成策略:在线合成
[self.curEngine setIntParam:kTtsWorkModeOnline forKey:SE_PARAMS_KEY_TTS_WORK_MODE_STRING];
// 建连超时,默认12000ms
[self.curEngine setIntParam:12000 forKey:SE_PARAMS_KEY_TTS_CONN_TIMEOUT_INT];
// 接收超时,默认8000ms
[self.curEngine setIntParam:8000 forKey:SE_PARAMS_KEY_TTS_RECV_TIMEOUT_INT];

在线请求资源配置

发起在线合成请求,需要配置 域名URI 以及 集群 参数。

// 在线请求资源配置
[self.engine setStringParam:@"{ADDRESS}" forKey:SE_PARAMS_KEY_TTS_ADDRESS_STRING];
[self.engine setStringParam:@"{URI}" forKey:SE_PARAMS_KEY_TTS_URI_STRING];
[self.engine setStringParam:@"{CLUSTER}" forKey:SE_PARAMS_KEY_TTS_CLUSTER_STRING];

离线请求资源配置

使用离线合成,需要提前下载好离线资源包,现阶段离线合成 SDK 及对应的资源分两个版本:V2和V4. 下载V4资源参考文档:下载V4模型,下载V2资源参考文档:下载V2模型。对于新客户,我们推荐使用效果更好的 V4, V2 版本目前已经停止迭代。
离线资源包下载完成后,需要配置 离线资源所在路径

// 配置离线资源包路径
[self.engine setStringParam:@"{OFFLINE RESOURCE PATH}" forKey:SE_PARAMS_KEY_TTS_OFF_RESOURCE_PATH_STRING];

控制合成效果

通过对 发音人音调音量语速 等参数的调整,可以获得不同的发声效果,更好满足您业务场景中的播报需求。

发音人

可以使用的发音人列表可以参考文档:发音人参数列表

// 在线合成使用的“发音人”
[self.engine setStringParam:@"{ONLINE VOICE}" forKey:SE_PARAMS_KEY_TTS_VOICE_ONLINE_STRING];
// 在线合成使用的“演绎风格”
[self.engine setStringParam:@"{ONLINE VOICE TYPE}" forKey:SE_PARAMS_KEY_TTS_VOICE_TYPE_ONLINE_STRING];
// 离线合成使用的“发音人”
[self.engine setStringParam:@"{OFFLINE VOICE}" forKey:SE_PARAMS_KEY_TTS_VOICE_OFFLINE_STRING];
// 离线合成使用的“演绎风格”
[self.engine setStringParam:@"{OFFLINE VOICE TYPE}" forKey:SE_PARAMS_KEY_TTS_VOICE_TYPE_OFFLINE_STRING];

音调、音量和语速

在 iOS 组件 5.4.3.2-bugfix 及后续版本,通过下面的方法设置音调、音量和语速:

// 音色对应音调
[self.engine setDoubleParam:1.0 forKey:SE_PARAMS_KEY_TTS_PITCH_RATIO_DOUBLE];
// 音色对应音量
[self.engine setDoubleParam:1.0 forKey:SE_PARAMS_KEY_TTS_VOLUME_RATIO_DOUBLE];
// 音色对应语速
[self.engine setDoubleParam:1.0 forKey:SE_PARAMS_KEY_TTS_SPEED_RATIO_DOUBLE];

在 iOS 组件 5.4.3.2-bugfix 之前的版本,通过下面的方法设置音调、音量和语速(与新版本相比,配置项的名字有所不同):

// 音色对应音调
[self.engine setIntParam:10 forKey:SE_PARAMS_KEY_TTS_PITCH_INT];
// 音色对应音量
[self.engine setIntParam:10 forKey:SE_PARAMS_KEY_TTS_VOLUME_INT];
// 音色对应语速
[self.engine setIntParam:10 forKey:SE_PARAMS_KEY_TTS_SPEED_INT];

注意

在 5.4.3.2-bugfix 之前的版本,音调、音量和语速的配置值与直觉不符,例如配置为 10 表示正常语速。配置值与实际值的映射关系参考文档:参数说明

合成文本

要合成的 文本,每次触发合成前配置。

// 要合成的文本
[self.engine setStringParam:@"TEXT" forKey:SE_PARAMS_KEY_TTS_TEXT_STRING];

播放进度

语音合成 SDK 支持返回播放进度,通过回调 SETtsPlaybackProgress 获取进度信息。离线线合成默认开启,在线合成需要配置以下参数:

[self.engine setIntParam:1 forKey:SE_PARAMS_KEY_TTS_WITH_FRONTEND_INT];

停止播放时使用淡出效果

向语音合成 SDK 发送STOP_ENGINE指令时,默认情况下会立即停止播放。如果您希望“淡出”地停止播放,可以配置以下参数使用这一效果:

// 根据需要来调整淡出持续的时间,单位为毫秒,且只支持设置成 20 毫秒的非负整数倍。
// 默认为 0,这时表示不使用淡出效果。
[self.engine setIntParam:{SUITABLE_DURATION} forKey:SE_PARAMS_KEY_AUDIO_FADEOUT_DURATION_INT];

禁用内建播放器

语音合成 SDK 默认使用内置的播放器播放合成的音频,如果开发者希望使用其他播放器,可以通过以下配置项禁用内置播放器。

[self.engine setBoolParam:FALSE forKey:SE_PARAMS_KEY_TTS_ENABLE_PLAYER_BOOL];

返回音频数据

语音合成 SDK 支持返回合成出来的音频数据,可以通过监听回调SETtsAudioData来拿到PCM格式的音频流。默认关闭,需要配置以下参数开启

[self.engine setIntParam:SETtsDataCallbackModeAll forKey:SE_PARAMS_KEY_TTS_DATA_CALLBACK_MODE_INT];

在离线切换断点续播

语音合成 SDK 在 Work Mode 为 kTtsWorkModeAlternate 时,可以在断网或弱网情况下自动从在线合成切换到离线合成,这种自动切换支持断点续播,也即离线合成从在线合成断开的地方继续合成、播放,而不是从头开始。开启断点续播除了要将 Work Mode 配置为 kTtsWorkModeAlternate 外,还依赖在线合成返回的 TTS 前端信息,需要添加以下配置

[self.engine setIntParam:1 forKey:SE_PARAMS_KEY_TTS_WITH_FRONTEND_INT];

为了让在离线切换足够平滑、无感,SDK 会淡出地播放完在线合成音频,然后淡入地开始播放离线合成音频。开发者可以通过下面两个配置项分别控制淡出与淡入效果持续的长度

/// @const SE_PARAMS_KEY_TTS_FADEOUT_DURATION_INT
/// Tts fadeout duration
/// The duration of the online tts audio fade-out when resuming from breakpoint.
/// Optional for online TTS, default is 30ms, config it before init engine.
extern const NSString* SE_PARAMS_KEY_TTS_FADEOUT_DURATION_INT;

/// @const SE_PARAMS_KEY_TTS_FADEIN_DURATION_INT
/// Tts fadein duration
/// The duration of offline tts fade-in audio when resuming from a breakpoint.
/// Optional for online TTS, default is 30ms, config it before init engine.
extern const NSString* SE_PARAMS_KEY_TTS_FADEIN_DURATION_INT;

限制离线合成的 CPU 占用

为了尽可能快速的合成完音频,默认情况下离线合成会倾向于使用更多的 CPU 资源。如果您 profiling 后认为离线合成的 CPU 占用太高了,或者要避免系统主动杀死 CPU 持续占用过高的进程,可以通过下面的配置来降低离线合成的 CPU 占用。
注意:开启以下选项会使离线合成的实时率(RTF)变大。

[self.engine setBoolParam:TRUE forKey:SE_PARAMS_KEY_TTS_LIMIT_CPU_USAGE_BOOL];

使用复刻音色

语音合成 SDK 支持使用复刻的音色进行合成,目前仅在线合成模式可以使用,且与预制的音色相比配置会有一些变化,需要配置一些额外参数。包括:

  • 集群,与其他音色相比,使用复刻音色合成时的集群配置可能有变化;
  • 后端集群,使用复刻音色合成时,需要额外加一项后端集群配置。
  • 发音人,复刻音色的发音人配置会在复刻流程中返回,将得到的voice type值设入即可。
  • 开启复刻音色,在配置中选择开启复刻音色,进入复刻音色合成流程。
  • 设置复刻风格,在复刻流程-查询用户训练任务状态的返回结果中,会说明复刻音色所支持的风格参数,如通用中文,通用美式英文等,配置所需的风格值即可。
// 集群,需要重新初始化引擎实例才会使修改后的配置生效
[self.engine setStringParam:@"{YOUR CLUSTER}" forKey:SE_PARAMS_KEY_TTS_CLUSTER_STRING];
// 后端集群
[self.engine setStringParam:@"{YOUR BACKEND CLUSTER}" forKey:SE_PARAMS_KEY_TTS_BACKEND_CLUSTER_STRING];
// 发音人,在复刻场景下,VOICE值固定为other,而VOICE_TYPE为复刻流程所提供的值
[self.engine setStringParam:@"other" forKey:SE_PARAMS_KEY_TTS_VOICE_ONLINE_STRING]; 
[self.engine setStringParam:@"{VOICE TYPE}" forKey:SE_PARAMS_KEY_TTS_VOICE_TYPE_ONLINE_STRING];
// 开启复刻音色,启动复刻音色合成流程
[self.engine setBoolParam:TRUE forKey:SE_PARAMS_KEY_TTS_USE_VOICECLONE_BOOL];
// 设置复刻风格
[self.engine setStringParam:@"" forKey:SE_PARAMS_KEY_TTS_VOICECLONE_STYLE_STRING];

初始化引擎实例

参数配置完成后,调用 初始化接口,完成引擎实例的初始化。

SEEngineErrorCode ret = [self.engine initEngine];
if (ret != SENoError) {
    NSLog(@"Init Engine failed: %d", ret);
}
发送指令

语音合成 SDK 通过发送指令接口 sendDirective 触发各种操作,需要注意以下两点:

  1. 该接口不要在回调线程中调用,我们推荐将所有的指令调用都放到一个单独的线程中。但不推荐放到 UI 线程,因为这可能造成 UI 卡顿;
  2. sendDirective 接口所支持的指令中,SEDirectiveStartEngineSEDirectiveStopEngine 是异步指令,在相应的回调到达后才真正完成了操作;

启动引擎 SEDirectiveStartEngine

不同场景下该接口的含义不同:

  • 单次合成场景 :启动一次合成,合成、播放完成后引擎停止,再次合成需要重新启动引擎;
  • 连续合成场景 :启动引擎,触发合成需要单独调用合成指令;
//注意这里先调用同步停止,避免SDK内部异步线程带来的问题
[self.engine sendDirective:SEDirectiveSyncStopEngine];
[self.engine sendDirective:SEDirectiveStartEngine];

关闭引擎 SEDirectiveStopEngine

取消请求,关闭引擎。单次合成场景下正常结束不需要调用,引擎内部会自动结束;连续合成场景下当不再使用合成功能时应主动调用。

[self.engine sendDirective:SEDirectiveStopEngine];

建立连接

建连指令用于在发送合成请求之前建立网络连接,可以在语音交互场景下减少在线合成的端到端延时。该指令需要在启动引擎之前调用。

[self.engine sendDirective:SEDirectiveCreateConnection];

合成语音 SEDirectiveSynthesis

连续合成场景下,使用该指令触发一次合成,可以多次调用。推荐的调用策略如下:

  • 第一句文本,直接调用;
  • 非首句文本,在收到 合成结束回调 后发送;
  • 使用 SDK 内置播放器时,如果返回值为 ERR_SYNTHESIS_PLAYER_IS_BUSY,表明内部缓存已经耗尽,应该在收到下一个 播放结回调时 再次调用;
// “合成”指令必须要在收到 SEEngineStart 后发送
[self.engine sendDirective:SEDirectiveSynthesis];

暂停/继续播放 SEDirectivePausePlayer/SEDirectiveResumePlayer

语音合成 SDK 支持播放器的暂停和恢复操作,该操作只影响播放,不影响合成,即播放被暂停但是合成还在继续。

// 暂停播放
[self.engine sendDirective:SEDirectivePausePlayer];
// 继续播放
[self.engine sendDirective:SEDirectiveResumePlayer];
销毁引擎实例

当不再需要语音合成后,应该对引擎实例进行销毁,释放内存资源。

[self.engine destroyEngine];
self.engine = nil;
回调接收返回数据

引擎启动成功 SEEngineStart

引擎启动成功,收到该回调后,在单次合成场景下收到该回调时语音合成已经开始,同时数据字段为该次请求的请求 ID; 连续合成场景下还需要再发送合成指令,才真正的开始合成。

引擎关闭 SEEngineStop

引擎关闭,收到该回调后,引擎进入空闲状态。

错误信息 SEEngineError

引擎发生错误。数据部分为 JSON 字符串,内部包含三个字段:

  • reqid: 请求 ID;
  • err_msg: 错误描述信息;
  • err_code: 错误码,不同错误码的处理方式参考文档:错误码说明

发生合成方式切换 SETtsSynthesisModeToggle

在线优先和并发合成策略下,在线合成失败切换离线合成时返回该事件;

合成开始 SETtsSynthesisBegin

合成开始回调。数据字段为当次合成的请求 ID。

合成结束 SETtsSynthesisEnd

当次合成完成。

播放开始 SETtsStartPlaying

播放开始回调。数据字段为当次播放的请求 ID, 开发者可以据此完成文本高亮等操作

播放结束 SETtsFinishPlaying

播放结束回调。

播放进度 SETtsPlaybackProgress

播放进度回调,数据部分是一个序列化的 JSON 字符串,包含正在播放的请求的播放进度(单位:百分比),格式如下:

{
    "progress": 0.3,
    "reqid": "bb081d44-0671-4789-8df5-0050edae517b",
}

音频数据 SETtsAudioData

合成出来的 PCM 格式音频数据。