问题现象

文本转语音播报时如何区分是否手动停止?调用stop方法停止播报后,speak的回调顺序是先onComplete然后onStop。无论是正常结束停止还是手动停止都会执行onComplete,应该如何正确区分是用户手动停止还是已经正常结束停止。

背景知识

  • 文本转语音:支持将一篇不超过10000字数的中英文文本(简体中文、繁体中文、数字、英文)合成为语音,并以选定音色进行播报。
  • SpeakListener:合成及播报的回调对象,通过此对象可返回合成及播报过程的相关状态,例如开始合成及播报、合成完成、播报完成、停止播报完成等。
  • <'queueMode', number>播报模式:0:排队模式播报;1:抢占模式播报。
  • onComplete回调分为两种,CompleteResponse.type为0表示合成结束,CompleteResponse.type为1表示播报结束,两者的回调时序并不固定。而onStop回调必然会在播报结束(type为1)的onComplete回调之后触发,即当调用stop接口时,可能会出现两种回调时序。
    1. 调用stop前语音已经合成结束。

    2. 调用stop前语音还未合成完毕。

解决方案

采用排队模式播报,在onComplete回调中判断播报完成(CompleteResponse.type为1)时调用​​​​​​​speak方法加载下一个需要播报的文本。

import { textToSpeech } from '@kit.CoreSpeechKit';
import { BusinessError } from '@kit.BasicServicesKit';

// 调用speak播报方法
private
speak() {
  // 设置播报相关参数
  let extraParam: Record<string, Object> = {
    'queueMode': 0,
    'speed': 1,
    'volume': 2,
    'pitch': 1,
    'languageContext': 'zh-CN',
    'audioType': 'pcm',
    'soundChannel': 3,
    'playType': 1
  }
  let speakListener: textToSpeech.SpeakListener = {
    // 开始播报回调
    onStart(requestId: string, response: textToSpeech.StartResponse) {
      console.info(`onStart, requestId: ${requestId} response: ${JSON.stringify(response)}`);
    },
    // 完成播报回调
    onComplete: (requestId: string, response: textToSpeech.CompleteResponse) => {
      console.info(`onComplete, requestId: ${requestId} response: ${JSON.stringify(response)}`);
      if (response.type === 0) {
        // 语音合成结束
      } else if (response.type === 1) {
        // 语音播放结束,加载下一个需要播报的文本
        let speakParams: textToSpeech.SpeakParams = {
          requestId: '123456-b', // requestId在同一实例内仅能用一次,请勿重复设置
          extraParams: extraParam
        };
        ttsEngine.speak(this.nextText, speakParams)
      }
    },
    // 停止播报完成回调,调用stop方法并完成时会触发此回调
    onStop(requestId: string, response: textToSpeech.StopResponse) {
      console.info(`onStop, requestId: ${requestId} response: ${JSON.stringify(response)}`);
    },
    // 返回音频流
    onData(requestId: string, audio: ArrayBuffer, response: textToSpeech.SynthesisResponse) {
      console.info(`onData, requestId: ${requestId} sequence: ${JSON.stringify(response)} audio: ${JSON.stringify(audio)}`);
    },
    // 错误回调,播报过程发生错误时触发此回调
    onError(requestId: string, errorCode: number, errorMessage: string) {
      console.error(`onError, requestId: ${requestId} errorCode: ${errorCode} errorMessage: ${errorMessage}`);
    }
  };
  // 设置回调
  ttsEngine.setListener(speakListener);
  let speakParams: textToSpeech.SpeakParams = {
    requestId: '123456-a', // requestId在同一实例内仅能用一次,请勿重复设置
    extraParams: extraParam
  };
  // 调用speak播报方法
  ttsEngine.speak(this.originalText, speakParams);
};

      Logo

      作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

      更多推荐