Qwen-Audio-TTS/CosyVoice SDK HarmonyOS
Aprenda sobre a integração, parâmetros, APIs, retornos de chamada e código de exemplo do HarmonyOS SDK para Qwen-Audio-TTS/CosyVoice síntese de fala em tempo real.
Para visões gerais de modelos e seleção de voz, consulte Modelos de conversão de texto em fala.
NativeNui
O HarmonyOS SDK fornece streaming de texto para fala por meio de NativeNui.
- Crie uma instância de streaming de texto para fala ligando para
new NativeNui(Constants.ModeType.MODE_STREAM_INPUT_TTS).NativeNui.GetInstance()retorna umMODE_DIALOGsingleton e não pode ser usado para streaming de texto para fala. - Não ligue
initialize()no modo de streaming de texto para fala. Passe credenciais e parâmetros de síntese diretamente parastartStreamInputTts(),playStreamInputTts(), ouasyncPlayStreamInputTts(). - Receba eventos de síntese e áudio através
INativeStreamInputTtsCallback. - O SDK retorna
STREAM_INPUT_TTS_EVENT_SYNTHESIS_STARTEDquando a tarefa é iniciada, o áudio passaonStreamInputTtsDataCallback,STREAM_INPUT_TTS_EVENT_SYNTHESIS_COMPLETEquando a tarefa terminar, eSTREAM_INPUT_TTS_EVENT_TASK_FAILEDquando a síntese falha.
import { Constants, INativeStreamInputTtsCallback, NativeNui, StreamInputTtsEvent } from 'neonui';
const nuiInstance = new NativeNui(Constants.ModeType.MODE_STREAM_INPUT_TTS);
Fluxos de chamadas
Qwen-Audio-TTS/CosyVoice suporta entrada única e entrada de streaming.
A entrada única é adequada para textos curtos ou cenários que exigem SSML.
- Chame playStreamInputTts ou asyncPlayStreamInputTts para passar o texto completo e iniciar a síntese. O primeiro bloqueia até que a síntese termine. Este último retorna imediatamente e sintetiza em segundo plano. Não ligue
startStreamInputTtsprimeiro e não chame um método stop depois. - Receba áudio em onStreamInputTtsDataCallback.
- A síntese termina quando
STREAM_INPUT_TTS_EVENT_SYNTHESIS_COMPLETEé recebido.
A entrada de streaming é adequada para conversas em tempo real ou síntese incremental de texto longo. SSML não é suportado neste modo.
- Chame startStreamInputTts para abrir a conexão e configurar o retorno de chamada e os parâmetros.
- Chame sendStreamInputTts para enviar fragmentos de texto.
- Receba áudio em onStreamInputTtsDataCallback.
- Depois que todo o texto for enviado, chame stopStreamInputTts.
- A síntese termina quando
STREAM_INPUT_TTS_EVENT_SYNTHESIS_COMPLETEé recebido.
Quando a conversão de texto em fala não for mais necessária, chame releaseStreamInputTts para liberar recursos.
Tanto o comprimento de uma única entrada de texto quanto o comprimento cumulativo de múltiplas entradas são limitados. Veja o CosyVoice API WebSocket.
startStreamInputTts
Inicia a síntese de streaming bidirecional, abre a conexão e registra o retorno de chamada. Este método pode bloquear. Não chame isso no thread da UI.
startStreamInputTts(
callback: INativeStreamInputTtsCallback,
ticket: string,
parameters: string,
session_id: string,
log_level: number,
save_log: boolean
): number
| Parâmetro | Tipo | Descrição |
|---|---|---|
callback |
INativeStreamInputTtsCallback |
Evento e retorno de chamada de áudio. |
ticket |
string |
String JSON que contém configurações de autenticação, conexão e depuração. |
parameters |
string |
String JSON que contém configurações de síntese. |
session_id |
string |
ID de sessão especificado pelo cliente. Passe uma string vazia para permitir que o servidor gere uma. |
log_level |
number |
Nível de log do SDK. Use um Constants.LogLevel valor: 0 (VERBOSE), 1 (DEBUG), 2 (INFO), 3 (AVISO), 4 (ERRO) ou 5 (NENHUMA). |
save_log |
boolean |
Se os logs devem ser salvos localmente. Se definido para true, definir debug_path em ticket. |
O método retorna um código de erro. Constants.NuiResultCode.SUCCESS (0) indica sucesso.
campos de ticket
{
"url": "wss://maas.qwencloudapi.com/api-ws/v1/inference",
"apikey": "st-****",
"device_id": "my_device_id"
}
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
url |
string |
Sim | Ponto final do serviço: wss://maas.qwencloudapi.com/api-ws/v1/inference |
apikey |
string |
Sim | Chave de API. Use uma chave de API temporária para reduzir o risco de exposição de uma chave de longa duração. |
device_id |
string |
Sim | Um identificador exclusivo do usuário final, como um ID de usuário no aplicativo ou um ID de dispositivo gerado pelo cliente. Ele é usado principalmente para rastreamento de log e solução de problemas. |
complete_waiting_ms |
number |
Não | Tempo em milissegundos para aguardar o evento de conclusão da síntese após stopStreamInputTts(false). Padrão: 10000. |
debug_path |
string |
Não | Diretório de log. Este campo é obrigatório quando save_log é true. O SDK mantém no máximo dois arquivos de log. |
max_log_file_size |
number |
Não | Tamanho máximo de um único arquivo de log em bytes. Padrão: 104857600 (100 MiB). Este campo só entra em vigor quando save_log é true. |
log_track_level |
number |
Não | Nível de filtro de log de rastreamento interno. Padrão: 2. Os valores válidos são iguais a log_level. A interface de retorno de chamada do HarmonyOS atualmente não expõe um retorno de chamada de log TTS de streaming, portanto, os logs filtrados são gravados apenas pelo SDK. |
campos de parâmetros
{
"model": "qwen-audio-3.0-tts-flash",
"voice": "longanlingxi",
"format": "mp3",
"sample_rate": 24000,
"volume": 50,
"rate": 1.0,
"pitch": 1.0,
"enable_audio_decoder": true
}
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
model |
string |
Sim | Nome do modelo. Consulte Modelos de conversão de texto em fala. |
voice |
string |
Sim | Voz. Para vozes do sistema, consulte Qwen-Audio-TTS vozes e CosyVoice vozes. Você também pode usar uma voz criada por meio de clonagem de voz ou design de voz. |
format |
string |
Não | Formato de codificação de áudio: pcm, wav, mp3 (padrão) ou opus. |
enable_audio_decoder |
boolean |
Não | Se deve ativar o decodificador SDK. Padrão: false. Para MP3 ou Opus, defina como true para decodificar o áudio para PCM antes que ele seja retornado por meio do retorno de chamada de dados. |
volume |
number |
Não | Volume. Padrão: 50. Intervalo válido: [0, 100]. |
sample_rate |
number |
Não | Taxa de amostragem em Hz. Valores válidos: 8000, 16000, 22050 (padrão), 24000, 44100e 48000. |
rate |
number |
Não | Taxa de fala. Padrão: 1.0. Intervalo válido: [0.5, 2.0]. |
pitch |
number |
Não | Passo. Padrão: 1.0. Intervalo válido: [0.5, 2.0]. |
bit_rate |
number |
Não | Taxa de bits de MP3 ou Opus em kbps. Padrão: 32. Intervalo válido: [6, 510]. |
enable_ssml |
boolean |
Não | Se deve ativar o SSML. Padrão: false. Consulte limites de SSML. |
word_timestamp_enabled |
boolean |
Não | Se os carimbos de data/hora no nível da palavra devem ser retornados. Padrão: false. Este campo está disponível apenas para saída de streaming. Suporta vozes clonadas de qwen-audio-3.0-tts-plus, qwen-audio-3.0-tts-flash, cosyvoice-v3-flashe cosyvoice-v3-pluse vozes do sistema marcadas como suportadas no Qwen-Audio-TTS lista de vozes e CosyVoice lista de vozes. Vozes clonadas de outros modelos não são suportadas. Os resultados do carimbo de data/hora estão incluídos em all_response de INativeStreamInputTtsCallback. |
seed |
number |
Não | Semente aleatória usada para variar o resultado sintetizado. Se a versão do modelo, texto, voz e todos os outros parâmetros forem iguais, o mesmo seed reproduz o mesmo resultado. Padrão: 0. Intervalo válido: [0, 65535]. |
language_hints |
string[] |
Não | Linguagem de síntese alvo. Esta configuração melhora a síntese e é independente do idioma da amostra de áudio usada para clonagem de voz. Para definir o idioma de origem de uma tarefa de clonagem de voz, consulte a referência da API Voice Cloning. A versão atual usa apenas o primeiro elemento do array, então passe um valor. Use este campo quando a leitura de números, abreviações ou símbolos for inesperada ou quando a síntese em uma linguagem menos comum não for natural. Por exemplo, pode fazer "hello, this is 110" leia como "um um zero" em inglês em vez da leitura chinesa, ou faça @ leia como "em". Valores suportados: zh, en, fr, de, ja, ko, ru, pt, th, id, vi, es, it, ms, file ar. |
instruction |
string |
Não | Instrução que controla dialeto, emoção ou papel. Consulte Controle de instruções. |
enable_aigc_tag |
boolean |
Não | Se deve incorporar uma etiqueta AIGC invisível. Padrão: false. Apoiado por qwen-audio-3.0-tts-plus, qwen-audio-3.0-tts-flash, cosyvoice-v3-flashe cosyvoice-v3-plus. |
aigc_propagator |
string |
Não | ContentPropagator campo na tag AIGC. Só entra em vigor quando enable_aigc_tag é true. Padrão: o UID. Os modelos suportados são os mesmos que para enable_aigc_tag. |
aigc_propagate_id |
string |
Não | PropagateID campo na tag AIGC. Só entra em vigor quando enable_aigc_tag é true. Padrão: o ID da solicitação atual. Os modelos suportados são os mesmos que para enable_aigc_tag. |
hot_fix |
object |
Não | Configurações de hot-fix de texto para pronúncia personalizada e substituição de texto. Qwen-Audio-3.0-TTS e outros modelos suportados suportam este campo. Para o esquema, consulte Eventos de cliente. |
sendStreamInputTts
sendStreamInputTts(text: string): number
Envia um fragmento de texto após startStreamInputTts consegue. Este método não analisa tags SSML. Depois que todo o texto for enviado, ligue stopStreamInputTts().
| Parâmetro | Tipo | Descrição |
|---|---|---|
text |
string |
Texto para sintetizar. SSML não é compatível. Tags SSML são lidas como texto comum. |
O método retorna um código de erro.
stopStreamInputTts
stopStreamInputTts(flag_async: boolean = true): number
Termina a entrada de streaming.
true(padrão): termina de forma assíncrona e retorna imediatamente. Espere porSTREAM_INPUT_TTS_EVENT_SYNTHESIS_COMPLETEpara determinar que a síntese foi concluída.false: Bloqueie até que todo o áudio e o evento de conclusão da síntese sejam recebidos. O tempo limite é controlado porcomplete_waiting_ms.
Chamar um método cancel após uma parada síncrona pode bloquear. Recomendamos o modo assíncrono padrão.
| Parâmetro | Tipo | Descrição |
|---|---|---|
flag_async |
boolean |
Se deve terminar de forma assíncrona. Padrão: true. true retorna sem esperar por uma resposta do servidor. false blocos até que a síntese seja concluída. |
O método retorna um código de erro.
cancelarStreamInputTts
cancelStreamInputTts(): number
Fecha imediatamente a conexão e encerra a tarefa atual. Não serão recebidos mais retornos de chamada de áudio após esta chamada. O método retorna um código de erro.
cancelStreamInputTtsKeepConnection
cancelStreamInputTtsKeepConnection(): number
Envia um comando de cancelamento em nível de protocolo para encerrar a tarefa atual, mas manter a conexão WebSocket aberta. Utilize este método quando outra rodada de síntese precisar começar imediatamente, evitando o custo de reabertura da conexão. O método retorna um código de erro.
###playStreamInputTts
playStreamInputTts(
callback: INativeStreamInputTtsCallback,
ticket: string,
parameters: string,
text: string,
session_id: string,
log_level: number,
save_log: boolean
): number
Síntese síncrona one-shot. Este método inicializa a tarefa, envia o texto, recebe todo o áudio e depois retorna. Não ligue startStreamInputTts primeiro e não chame um método stop depois. SSML está habilitado por padrão. Se enable_ssml for definido explicitamente, esse valor terá precedência. Não chame esse método no thread da UI.
callback, ticket, parameters, session_id, log_levele save_log são definidos em startStreamInputTts. text é o texto a ser sintetizado e suporta SSML. O método retorna um código de erro.
asyncPlayStreamInputTts
asyncPlayStreamInputTts(
callback: INativeStreamInputTtsCallback,
ticket: string,
parameters: string,
text: string,
session_id: string,
log_level: number,
save_log: boolean
): number
Síntese assíncrona one-shot. Este método retorna imediatamente e entrega resultados por meio de retornos de chamada. Não ligue startStreamInputTts primeiro e não chame um método stop depois. SSML está habilitado por padrão. Se enable_ssml for definido explicitamente, esse valor terá precedência.
callback, ticket, parameters, session_id, log_levele save_log são definidos em startStreamInputTts. text é o texto a ser sintetizado e suporta SSML. O método retorna um código de erro.
releaseStreamInputTts
releaseStreamInputTts(): number
Libera a instância TTS de streaming e seus recursos. Chame esse método quando a página for destruída ou a conversão de texto em fala não for mais necessária. O método retorna um código de erro.
INativeStreamInputTtsCallback
export interface INativeStreamInputTtsCallback {
onStreamInputTtsEventCallback(
event: StreamInputTtsEvent,
task_id: string,
session_id: string,
ret_code: number,
error_msg: string,
timestamp: string,
all_response: string
): void;
onStreamInputTtsDataCallback(data: ArrayBuffer | null): void;
}
onStreamInputTtsEventCallback
| Parâmetro | Tipo | Descrição |
|---|---|---|
event |
StreamInputTtsEvent |
Evento de síntese. |
task_id |
string |
ID da tarefa de síntese. |
session_id |
string |
ID da sessão. Um valor especificado pelo cliente é retornado inalterado. Caso contrário, o servidor gera um. |
ret_code |
number |
Código de erro. Válido apenas para um evento de falha de tarefa. |
error_msg |
string |
Mensagem de erro. Válido apenas para um evento de falha de tarefa. |
timestamp |
string |
Resultado do carimbo de data/hora. |
all_response |
string |
Resposta completa do servidor como uma string JSON. Analise-o para detalhes de uso, carimbo de data/hora e erro. |
onStreamInputTtsDataCallback
onStreamInputTtsDataCallback(data: ArrayBuffer | null): void;
Retorna continuamente fragmentos de áudio. Observe o seguinte:
- Os dados MP3 e Opus requerem um decodificador de streaming. Alternativamente, defina
enable_audio_decoderparatruepara permitir que o SDK retorne PCM. - Para montar um arquivo completo, anexe os dados de retorno de chamada em ordem.
- Para WAV e MP3, apenas o primeiro retorno de chamada contém o cabeçalho do arquivo. Cada quadro Opus é uma página Ogg independente e pode ser concatenada em ordem.
StreamInputTtsEvent
| Evento | Descrição |
|---|---|
STREAM_INPUT_TTS_EVENT_SYNTHESIS_STARTED |
O servidor aceitou a solicitação e iniciou o processamento. Os primeiros dados de áudio geralmente chegam através onStreamInputTtsDataCallback logo após este evento. |
STREAM_INPUT_TTS_EVENT_SENTENCE_BEGIN |
O servidor começou a sintetizar uma expressão. |
STREAM_INPUT_TTS_EVENT_SENTENCE_SYNTHESIS |
Sintetize informações de progresso, incluindo informações de cobrança e carimbos de data/hora. |
STREAM_INPUT_TTS_EVENT_SENTENCE_END |
O servidor concluiu a síntese de uma expressão. |
STREAM_INPUT_TTS_EVENT_SYNTHESIS_COMPLETE |
O servidor retornou todos os dados de áudio. onStreamInputTtsEventCallback não é chamado após este evento, que é o sinal explícito de fim de fluxo. Este evento não indica que a reprodução local foi concluída. |
STREAM_INPUT_TTS_EVENT_TASK_FAILED |
A síntese falhou. Recuperar task_id, error_codee error_message de all_response, ou use o ret_code e error_msg argumentos de retorno de chamada. |
Exemplo de resposta com falha na tarefa:
{
"header": {
"task_id": "2bf83b9a-baeb-4fda-8d9a-xxxxxxxxxxxx",
"event": "task-failed",
"error_code": "InvalidParameter",
"error_message": "[tts:]Engine return error code: 418",
"attributes": {}
},
"payload": {}
}
Código de exemplo
- Obtenha uma chave API. Não codifique uma chave de API de longa duração em um aplicativo cliente. Recomendamos que seu servidor de aplicativos obtenha uma chave de API temporária e envie para o cliente.
- Baixe o pacote SDK mais recente. Extraia o pacote, copie
entry/libs/neonui.harpara oentry/libsdiretório do seu aplicativo e adicione a dependência aoentry/oh-package.json5:
{
"dependencies": {
"neonui": "file:libs/neonui.har"
}
}
- Abra o projeto de amostra do pacote SDK no DevEco Studio. A página de exemplo é
entry/src/main/ets/pages/dashscope/DashCosyVoiceStreamTtsPage.ets. Configure uma chave de API e execute o projeto.
O código a seguir mostra o fluxo principal de entrada de streaming. Para reprodução completa de áudio, seleção de parâmetros e gerenciamento de estado de tarefa, consulte DashCosyVoiceStreamTtsPage.ets no pacote SDK.
import { Constants, INativeStreamInputTtsCallback, NativeNui, StreamInputTtsEvent } from 'neonui';
const callback: INativeStreamInputTtsCallback = {
onStreamInputTtsEventCallback: (event: StreamInputTtsEvent, taskId: string,
sessionId: string, retCode: number, errorMsg: string,
timestamp: string, allResponse: string): void => {
if (event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_SYNTHESIS_COMPLETE) {
// Synthesis is complete.
} else if (event == StreamInputTtsEvent.STREAM_INPUT_TTS_EVENT_TASK_FAILED) {
// Handle the error based on retCode, errorMsg, or allResponse.
}
},
onStreamInputTtsDataCallback: (data: ArrayBuffer | null): void => {
if (data != null) {
// Write PCM to AudioRenderer, or append encoded audio data in order.
}
}
};
const nuiInstance = new NativeNui(Constants.ModeType.MODE_STREAM_INPUT_TTS);
const ticket: Record<string, Object> = {
'url': 'wss://maas.qwencloudapi.com/api-ws/v1/inference',
'apikey': 'st-****',
'device_id': 'my_device_id'
};
const parameters: Record<string, Object> = {
'model': 'qwen-audio-3.0-tts-flash',
'voice': 'longanlingxi',
'format': 'mp3',
'sample_rate': 24000,
'enable_audio_decoder': true
};
const result = nuiInstance.startStreamInputTts(
callback,
JSON.stringify(ticket),
JSON.stringify(parameters),
'',
Constants.LogLevel.LOG_LEVEL_INFO,
false
);
if (result == Constants.NuiResultCode.SUCCESS) {
nuiInstance.sendStreamInputTts('Hello, ');
nuiInstance.sendStreamInputTts('welcome to real-time speech synthesis.');
nuiInstance.stopStreamInputTts(true);
}
// Call nuiInstance.releaseStreamInputTts() from the SYNTHESIS_COMPLETE handler.
Para entrada única, ligue diretamente playStreamInputTts ou asyncPlayStreamInputTts:
const oneShotInstance = new NativeNui(Constants.ModeType.MODE_STREAM_INPUT_TTS);
oneShotInstance.asyncPlayStreamInputTts(
callback,
JSON.stringify(ticket),
JSON.stringify(parameters),
'Hello, welcome to real-time speech synthesis.',
'',
Constants.LogLevel.LOG_LEVEL_INFO,
false
);
// Call oneShotInstance.releaseStreamInputTts() from the SYNTHESIS_COMPLETE handler.
Recursos avançados
###SSML
Objetivo: incorporar tags XML no texto para controlar a pronúncia, a velocidade da fala, as pausas e outros detalhes de síntese.
Limites: apenas APIs únicas playStreamInputTts e asyncPlayStreamInputTts suporte SSML. A API de entrada de streaming sendStreamInputTts não.
Uso: o SDK habilita SSML por padrão para playStreamInputTts e asyncPlayStreamInputTts. Passar texto SSML text. Para obter mais informações, consulte SSML e LaTeX.
Expressões matemáticas
Objetivo: fazer com que o modelo leia corretamente fórmulas e expressões matemáticas comuns.
Uso: Passe texto que contém uma expressão matemática formatada em LaTeX em text. Para sintaxe suportada, consulte Conversão de texto em fala do LaTeX.