离线语音合成使用问题

本文为您介绍离线语音合成的常见问题和解答。

合成初始化失败通常有哪些原因?

原因

详述

鉴权失败

  • 因SDK需要进行鉴权,demo默认没有配置鉴权信息,所以需要获取鉴权信息申请配额,详情请参见开通授权。申请完成后将鉴权信息(ak_id、ak_secret、app_key、sdk_code)填入demo中即可调试。

  • 获取鉴权信息需要联网,首次使用SDK请确保网络畅通。

资源问题

  • 资源路径设置错误。

  • 资源校验失败:包括资源版本和引擎不兼容,资源损害等。

常见的鉴权失败情况有哪些?

注册失败的原因通常包括以下情况:

  • 参数设置不正确:例如Appkey错误或Appkey对应的项目为设备端解决方案类型。

  • 注册次数超过限制:管控台对单台设备每日注册次数有限制。

  • 没有配额:用户配额超过申请上限。

  • 没有网络:注册是需要联网的。

下表给出了常见的错误信息(初始化失败时,可以通过“error_msg”获取):

日志错误信息

含义

register_over_frequency

注册次数超过限额,详情请参见一个Deviceid一天可以注册几次

AccessKeyId is mandatory for this action

AccessKey不正确,配置信息错误。

quota not-enough

配额不足。

sdk_type_err

sdk_code不正确。请确认开通的是标准版(software_nls_tts_offline_standard)还是精品版(software_nls_tts_offline)。

Specified signature is not matched with our calculation

请校验AccessSecret是否填写正确。

unit_not_exist

Appkey没有申请过配额。

初始化成功但是播报失败该如何处理?

请核对语音包名称及路径是否设置正确。SDK和语音包是完全独立的,SDK里并没有预置语音包。

回调数据长度和时间对应关系是怎样的?

以采样率16000的pcm,每次回调8000个字节为例,一秒钟包含字节数:16000×sizeof(short)=32000个,所以8000个字节对应时间:8000/32000秒=250毫秒。

配额消耗的规则是什么?

设备标识(Deviceid)每发生一次变更,就会消耗一个配额。设备标识是进行管控的有效凭证,SDK使用者要保证设置的device_id有效性和唯一性,否则可能导致占用多个配额,甚至鉴权失败。

调用者可能要考虑以下场景:

  • 起初获取不到设备信息,后获取权限,Deviceid变化。

  • 已获取设备ID权限,但用户关闭,Deviceid变化。

  • Android Q升级后,App端突然获取不到有效设备信息,Deviceid变化。

一个Deviceid一天可以注册几次?

单个Deviceid每日只能注册5次。如已注册成功,设备卸载App并重新安装,将消耗一次注册机会,当5次机会消耗完后,只能等到24:00以后才能重新注册。

如果App不卸载,第一天登录和第二天登录分别会注册几次?

App注册成功之后,若有存储权限,鉴权信息成功保存至本地,不需要再次联网注册,可以永久使用。

配额消耗耗尽还能增加吗?

当一个Appkey对应的配额消耗完毕时,可以重新购买配额,系统将按照合同约定,增加相应的配额 。

申请离线配额后,能直接访问在线语音服务吗?

申请离线配额后,不关联在线语音服务(如在线合成、在线语音识别等),如果想使用在线语音服务需要额外购买相应的服务。

已经投入使用的在线语音服务Appkey可以用于申请离线配额吗?

除设备端解决方案外的其他Appkey可以。如果之前使用的是设备端解决方案的Appkey,需要重新申请一个仅语音合成的Appkey,详情请参见创建项目

SDK是如何进行打点的?

  • 为什么进行打点?

    • 方便问题排查:因为上线后通常会关闭log,能获取的信息比较有限,打点能更方便地排查问题。

    • 为发音人优化提供有效依据:例如xiaoyun这个发音人,如果大部分用户都调音量,说明该语音包默认音量偏小。

    • 统计latency,优化设备合成速度:如latency过高,可能会出现卡顿等问题,可以给用户提供优化方案;如大部分设备都出现卡顿,则引导调整算法等。

  • 打点会影响主流程吗?

    不会。打点是尝试性的,打点时机在初始化成功和初始化失败时,没有网络则直接退出。为减少资源消耗,打点内容小于1 KB。

  • 打点内容包含哪些?

    本着最小资源消耗,及充分保护用户隐私的原则,SDK打点不涉及用户任何信息,主要内容包括:

    类别

    触发时机

    内容

    初始化错误原因

    初始化失败时

    初始化失败详细信息

    • errror_msg:详细的错误信息

    • auth_time:鉴权耗时

    • inittime:初始化耗时

    统计信息

    初始化成功时:用户已经开始进行合成,因此异步尝试发送上次合成任务的统计信息

    • sdk_ver:使用的SDK版本

    • font:发音人

    • format:音频格式

    • speed:语速

    • volume:音量

    • latency:延迟,反映设备性能

    • sample_rate:采样率

    • length:合成长度

    • call_time:合成次数

  • 打点可以关闭吗?

    打点默认是开启的,SDK提供了关闭打点的接口。如果用户认为影响了主流程或者仍然担心隐私问题,可在生成初始化参数的时候,传入字段enable_et,并将值设为false,即可关闭该功能。代码如下:

    /**
       * @brief :按此方式填写鉴权信息
       * @param assets:资源存储路径,指配置文件及资源存放路径
       * @return std::string :打包成json格式的鉴权信息
       */
      std::string GenAuthInfo(const char *assets) {
        nuijson::Value root;
        std::string info;
        if (assets) {
          /*
           * 调用接口前,需配置环境变量,通过环境变量读取访问凭证。
           * 智能语音交互的AccessKey ID、AccessKey Secret和AppKey的环境变量名:NLS_AK_ENV、NLS_SK_ENV、NLS_APPKEY_ENV
           */
          root["ak_id"] = getenv("NLS_AK_ENV");  // ak_id也就是阿里云账号的AccessKey ID,和ak_secret对应,请注意不要设置成阿里云主账号ID(uid)
          root["ak_secret"] = getenv("NLS_SK_ENV");
          root["app_key"] = getenv("NLS_APPKEY_ENV");
          root["workspace"] = assets;
          root["sdk_code"] = "software_nls_tts_offline";  // 离线tts使用software_nls_tts_offline
          root["device_id"] = "012345678911a";   // 设备唯一标识,如Mac地址,cpu序列号等
          root["enable_et"] = "false";   // 打点默认是开启的,当设为false时关闭
          nuijson::FastWriter writer;
          info = writer.write(root);
          printf("info:%s\n", info.c_str());
        }
        return info;
      }
  • 打点示例

    • 一个初始化错误的打点内容如下:

    {
      "common": {
        "appcode": "026",
        "funcode": "6888",  // 该SDK具备功能
        "sdk_code": "software_nls_tts_offline",
        "sdk_ver": "V2.5.14-026-20210327"  // 对应SDK版本号
      },
      "content": {
        "tts": [
          {
            "auth_time": "277",   // 鉴权花费277ms,该值为监控鉴权服务提供有效依据
            "error_msg": "(170007)Specified access key is not found.-->(170800)register-failed-->(140008)tts-auth failed",  // 详细的错误信息,一目了然是用户没有设置appkey,加快问题排查速度
            "init_time": "277"    // 整个初始化耗时,包括“鉴权+资源加载”
          }
        ]
      }
    }
    • 一个基于统计的打点内容如下:

    {
      "common": {
        "appcode": "026",
        "funcode": "4840",
        "sdk_code": "software_nls_tts_offline",
        "sdk_ver": "V2.5.14-026-20210326"
      },
      "content": {
        "tts": [
          {
            "call_time": "1",
            "font": "xiaoyun",
            "format": "pcm",
            "latency": "6",
            "length": "168640",
            "mode": "local",
            "pitch": "0",
            "sample_rate": "16000",
            "speed": "1",
            "volume": "1"
          }
        ]
      }
    }

NTP的作用是什么?

NTP:网络时间协议(Network Time Protocol)

TTS SDK在首次使用时,需要访问阿里云鉴权,阿里云要求本地时间和阿里云时间差不能超过15分钟,否则会鉴权失败,因此SDK使用NTP模块获取网络时间。

需要注意的是,因为NTP本身和阿里云交互有一定时间消耗,网络差的时候可能长达十几秒。因此需要业务方综合评估,如果端侧时间不会存在异常,或者概率极小的设备时间异常对业务没有影响,可以在初始化的时候通过将enable_ntp设为false,即关闭NTP。