Clonagem de voz
Clone uma voz de amostras de áudio para uso com Qwen-Audio-TTS, CosyVoice, ou Qwen-Omni Modelos.
Clone uma voz de 10-20 segundos de áudio. A API devolve um identificador de voz instantaneamente. Não é necessário treinamento.
Como funciona
- Chame a API de clonagem de voz com uma amostra de áudio e um
target_model. A API devolve umvoiceIdentificador instantaneamente. - Use a voz clonada
voiceIdentificador da API do modelo alvo. O modelo deve ser igual aotarget_modeldo passo 1.
O target_model definido durante a criação de voz deve corresponder ao modelo usado em chamadas API subsequentes. Modelos desiguais causam falha na síntese.
Modelos apoiados.
** Modelo de clonagem de voz**:
- Qwen-Omni:
qwen-voice-enrollment - Qwen-Audio-TTS / CosyVoice:
voice-enrollment
** Modelos de alvo** (target_model):
- Qwen-Audio-TTS --
qwen-audio-3.0-tts-plus,qwen-audio-3.0-tts-flash. Use vozes clonadas com [texto-para-discurso modelos] (/developer-guides/speech/tts-models). - CosyVoice --
cosyvoice-v3-plus.cosyvoice-v3-flashnão suporta atualmente a síntese de fala com vozes clonadas na região de Singapura; useqwen-audio-3.0-tts-flashEm vez disso. Use vozes clonadas com [CosyVoice TTS] (/developer-guides/speech/realtime-streaming). - Qwen-Omni-Realtime --
qwen3.5-omni-plus-realtime,qwen3.5-omni-flash-realtime. Use vozes clonadas com a API multimodal em tempo real (/developer-guides/speech/realtime-multimodal-speech). - Qwen-Omni --
qwen3.5-omni-plus,qwen3.5-omni-flash. Use vozes clonadas com a API Omni (não-real) (/developer-guides/speech/multimodal-speech).
Requisitos de áudio
A qualidade do áudio de entrada afeta diretamente o resultado da clonagem. Cada família de modelos tem diferentes requisitos de áudio.
Qwen-Audio-TTS / CosyVoice
Ver a tabela estruturada nos quadros de referência desta página ↓
Qwen-Omni
Ver a tabela estruturada nos quadros de referência desta página ↓
Dicas de gravação
Lista de verificação de início rápido
Use esta lista de verificação em um quarto padrão ou quarto pequeno semelhante:
- Feche todas as janelas e portas para bloquear o ruído externo.
- Desliguem os aparelhos de ar condicionado, ventiladores e outros dispositivos elétricos.
- Esprema cortinas para reduzir reflexos de vidro.
- Cubra sua mesa com roupas ou um cobertor para reduzir os reflexos superficiais.
- Leia o seu roteiro. Defina o tom e a prática de seu personagem, entregando naturalmente.
- Posicione o dispositivo de gravação a aproximadamente 10 cm da boca. Muito perto causa distorção plosiva, muito longe produz um sinal fraco.
- Comece a gravar.
Dispositivos de gravação
Use um smartphone, gravador de voz digital, ou gravador de áudio profissional.
Configure seu ambiente de gravação.
Escolha o quarto certo.
Ver a tabela estruturada nos quadros de referência desta página ↓
- Ruído de controle: *
Ver a tabela estruturada nos quadros de referência desta página ↓
Grave alguns segundos de som ambiente no seu smartphone, então toque de volta em alto volume para identificar fontes de ruído oculto.
Reduzir reverberação:
A reverberação borra a fala e reduz a definição, impactando diretamente a fidelidade dos clones.
- Espreite cortinas, abra portas de armário, ou cubra mesas/cabinas com roupas ou lençóis para reduzir reflexos de superfícies lisas.
- Coloque objetos irregulares (caixas, móveis estofados) para dispersar ondas sonoras.
Prepare seu roteiro.
Ver a tabela estruturada nos quadros de referência desta página ↓
Exemplos de ponta a ponta
Crie uma voz clonada de um arquivo de áudio local, e use-a com um modelo compatível. Ambos os passos devem usar o mesmo. target_model.
Substituir voice.mp3 com o caminho para o seu próprio arquivo de áudio.
Qwen-Audio-TTS
Clone uma voz e use-a com Qwen-Audio-TTS. Aplica-se a qwen-audio-3.0-tts-plus e qwen-audio-3.0-tts-flash. Para detalhes, veja [Modelos de texto para fala] (/developer-guides/speech/tts-models).
Qwen-Audio-TTS clonagem de voz usa a mesma API que CosyVoice: o modelo de clonagem é voice-enrollment (não qwen-voice-enrollment), a ação é create_voice, e o áudio é passado como uma URL pública (não base64).
- Passo 1: Crie uma voz *
O url O parâmetro deve ser uma URL acessível publicamente do seu arquivo de áudio. O prefix parâmetro define um prefixo para o nome da voz.
curl -X POST https://maas.qwencloudapi.com/api/v1/services/audio/tts/customization \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "voice-enrollment",
"input": {
"action": "create_voice",
"target_model": "qwen-audio-3.0-tts-flash",
"prefix": "myvoice",
"url": "https://your-audio-url.wav",
"language_hints": ["en"]
}
}'
Discurso sintético com a voz clonada
Use o voice_id O valor retornado no passo anterior. Para exemplos SDK, veja [Síntese de fala em tempo real] (/developer-guides/speech/realtime-streaming).
# coding=utf-8
import dashscope
from dashscope.audio.tts_v2 import *
import os
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')
dashscope.base_websocket_api_url = 'wss://maas.qwencloudapi.com/api-ws/v1/inference'
model = "qwen-audio-3.0-tts-flash"
voice = "YOUR_VOICE_ID" # Replace with the voice_id returned in step 1
synthesizer = SpeechSynthesizer(model=model, voice=voice)
audio = synthesizer.call("How is the weather today?")
with open('output.mp3', 'wb') as f:
f.write(audio)
CosyVoice
Clone uma voz e use-a com CosyVoice TTS. Aplica-se a cosyvoice-v3-plus. Para detalhes, veja [CosyVoice TTS] (/developer-guides/speech/realtime-streaming).
CosyVoice A clonagem de voz usa uma API diferente da Qwen-Omni: o modelo de clonagem é voice-enrollment (não qwen-voice-enrollment), a ação é create_voice, e o áudio é passado como uma URL pública (não base64).
- Passo 1: Crie uma voz *
O url O parâmetro deve ser uma URL acessível publicamente do seu arquivo de áudio. O prefix parâmetro define um prefixo para o nome da voz.
curl -X POST https://maas.qwencloudapi.com/api/v1/services/audio/tts/customization \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "voice-enrollment",
"input": {
"action": "create_voice",
"target_model": "cosyvoice-v3-plus",
"prefix": "myvoice",
"url": "https://your-audio-url.wav",
"language_hints": ["en"]
}
}'
Discurso sintético com a voz clonada
Substituir YOUR_VOICE_ID com o valor da voz retornado no passo anterior.
curl -X POST https://maas.qwencloudapi.com/api/v1/services/audio/tts/SpeechSynthesizer \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "cosyvoice-v3-plus",
"input": {
"text": "How is the weather today?",
"voice": "YOUR_VOICE_ID",
"format": "wav",
"sample_rate": 24000
}
}'
Qwen-Omni Conversa em tempo real.
Clone uma voz e use-a em uma conversa em tempo real. Aplica-se a qwen3.5-omni-plus-realtime e qwen3.5-omni-flash-realtime. Para detalhes, veja [Discurso multimodal em tempo real] (/developer-guides/speech/realtime-multimodal-speech).
Python
```python
# Requirements: dashscope >= 1.23.9, pyaudio
import os
import requests
import base64
import pathlib
import time
import pyaudio
from dashscope.audio.qwen_omni import MultiModality, OmniRealtimeCallback, OmniRealtimeConversation
import dashscope
TARGET_MODEL = "qwen3.5-omni-plus-realtime"
PREFERRED_NAME = "guanyu"
VOICE_FILE_PATH = "voice.mp3"
def create_voice(file_path: str) -> str:
api_key = os.getenv("DASHSCOPE_API_KEY")
file_path_obj = pathlib.Path(file_path)
base64_str = base64.b64encode(file_path_obj.read_bytes()).decode()
data_uri = f"data:audio/mpeg;base64,{base64_str}"
resp = requests.post(
"https://maas.qwencloudapi.com/api/v1/services/audio/tts/customization",
headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
json={
"model": "qwen-voice-enrollment",
"input": {
"action": "create",
"target_model": TARGET_MODEL,
"preferred_name": PREFERRED_NAME,
"audio": {"data": data_uri}
}
}
)
if resp.status_code != 200:
raise RuntimeError(f"Failed to create voice: {resp.status_code}, {resp.text}")
return resp.json()["output"]["voice"]
class SimpleCallback(OmniRealtimeCallback):
def __init__(self, pya):
self.pya = pya
self.out = None
def on_open(self):
self.out = self.pya.open(format=pyaudio.paInt16, channels=1, rate=24000, output=True)
def on_event(self, response):
if response['type'] == 'response.audio.delta':
self.out.write(base64.b64decode(response['delta']))
elif response['type'] == 'conversation.item.input_audio_transcription.completed':
print(f"[User] {response['transcript']}")
elif response['type'] == 'response.audio_transcript.done':
print(f"[LLM] {response['transcript']}")
if __name__ == '__main__':
dashscope.api_key = os.getenv("DASHSCOPE_API_KEY")
# Step 1: Clone a voice
voice = create_voice(VOICE_FILE_PATH)
print(f"Voice cloning complete. Voice: {voice}")
# Step 2: Start a conversation with the cloned voice
pya = pyaudio.PyAudio()
callback = SimpleCallback(pya)
conv = OmniRealtimeConversation(
model=TARGET_MODEL, callback=callback,
url="wss://maas.qwencloudapi.com/api-ws/v1/realtime"
)
conv.connect()
conv.update_session(
output_modalities=[MultiModality.AUDIO, MultiModality.TEXT],
voice=voice
)
mic = pya.open(format=pyaudio.paInt16, channels=1, rate=16000, input=True)
print("Conversation started. Speak into your microphone (Ctrl+C to exit)...")
try:
while True:
audio_data = mic.read(3200, exception_on_overflow=False)
conv.append_audio(base64.b64encode(audio_data).decode())
time.sleep(0.01)
except KeyboardInterrupt:
conv.close()
mic.close()
callback.out.close()
pya.terminate()
print("\nConversation ended")
```
Java
```java
import com.alibaba.dashscope.audio.omni.*;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import javax.sound.sampled.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Base64;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
public class Main {
private static final String TARGET_MODEL = "qwen3.5-omni-plus-realtime";
private static final String PREFERRED_NAME = "guanyu";
private static final String AUDIO_FILE = "voice.mp3";
private static final String AUDIO_MIME_TYPE = "audio/mpeg";
public static String toDataUrl(String filePath) throws IOException {
byte[] bytes = Files.readAllBytes(Paths.get(filePath));
String encoded = Base64.getEncoder().encodeToString(bytes);
return "data:" + AUDIO_MIME_TYPE + ";base64," + encoded;
}
public static String createVoice() throws Exception {
String apiKey = System.getenv("DASHSCOPE_API_KEY");
String jsonPayload =
"{"
+ "\"model\": \"qwen-voice-enrollment\","
+ "\"input\": {"
+ "\"action\": \"create\","
+ "\"target_model\": \"" + TARGET_MODEL + "\","
+ "\"preferred_name\": \"" + PREFERRED_NAME + "\","
+ "\"audio\": {"
+ "\"data\": \"" + toDataUrl(AUDIO_FILE) + "\""
+ "}"
+ "}"
+ "}";
String url = "https://maas.qwencloudapi.com/api/v1/services/audio/tts/customization";
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Authorization", "Bearer " + apiKey);
con.setRequestProperty("Content-Type", "application/json");
con.setDoOutput(true);
try (OutputStream os = con.getOutputStream()) {
os.write(jsonPayload.getBytes(StandardCharsets.UTF_8));
}
int status = con.getResponseCode();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(status >= 200 && status < 300 ? con.getInputStream() : con.getErrorStream(),
StandardCharsets.UTF_8))) {
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
if (status == 200) {
JsonObject jsonObj = new Gson().fromJson(response.toString(), JsonObject.class);
return jsonObj.getAsJsonObject("output").get("voice").getAsString();
}
throw new IOException("Failed to create voice: " + status + " - " + response);
}
}
static class SimpleAudioPlayer {
private final SourceDataLine line;
private final Queue<byte[]> audioQueue = new ConcurrentLinkedQueue<>();
private final Thread playerThread;
private final AtomicBoolean shouldStop = new AtomicBoolean(false);
public SimpleAudioPlayer() throws LineUnavailableException {
AudioFormat format = new AudioFormat(24000, 16, 1, true, false);
line = AudioSystem.getSourceDataLine(format);
line.open(format);
line.start();
playerThread = new Thread(() -> {
while (!shouldStop.get()) {
byte[] audio = audioQueue.poll();
if (audio != null) {
line.write(audio, 0, audio.length);
} else {
try { Thread.sleep(10); } catch (InterruptedException ignored) {}
}
}
}, "AudioPlayer");
playerThread.start();
}
public void play(String base64Audio) {
audioQueue.add(Base64.getDecoder().decode(base64Audio));
}
public void close() {
shouldStop.set(true);
try { playerThread.join(1000); } catch (InterruptedException ignored) {}
line.drain();
line.close();
}
}
public static void main(String[] args) {
try {
String voice = createVoice();
System.out.println("Voice cloning complete. Voice: " + voice);
SimpleAudioPlayer player = new SimpleAudioPlayer();
AtomicBoolean shouldStop = new AtomicBoolean(false);
OmniRealtimeParam param = OmniRealtimeParam.builder()
.model(TARGET_MODEL)
.apikey(System.getenv("DASHSCOPE_API_KEY"))
.url("wss://maas.qwencloudapi.com/api-ws/v1/realtime")
.build();
OmniRealtimeConversation conversation = new OmniRealtimeConversation(param, new OmniRealtimeCallback() {
@Override public void onOpen() { System.out.println("Connection established"); }
@Override public void onClose(int code, String reason) {
System.out.println("Connection closed (" + code + "): " + reason);
shouldStop.set(true);
}
@Override public void onEvent(JsonObject event) {
String type = event.get("type").getAsString();
if ("response.audio.delta".equals(type)) {
player.play(event.get("delta").getAsString());
} else if ("conversation.item.input_audio_transcription.completed".equals(type)) {
System.out.println("[User] " + event.get("transcript").getAsString());
} else if ("response.audio_transcript.done".equals(type)) {
System.out.println("[LLM] " + event.get("transcript").getAsString());
}
}
});
conversation.connect();
conversation.updateSession(OmniRealtimeConfig.builder()
.modalities(Arrays.asList(OmniRealtimeModality.AUDIO, OmniRealtimeModality.TEXT))
.voice(voice)
.enableTurnDetection(true)
.enableInputAudioTranscription(true)
.build()
);
System.out.println("Conversation started. Speak into the microphone (Ctrl+C to exit)...");
AudioFormat format = new AudioFormat(16000, 16, 1, true, false);
TargetDataLine mic = AudioSystem.getTargetDataLine(format);
mic.open(format);
mic.start();
ByteBuffer buffer = ByteBuffer.allocate(3200);
while (!shouldStop.get()) {
int bytesRead = mic.read(buffer.array(), 0, buffer.capacity());
if (bytesRead > 0) {
conversation.appendAudio(Base64.getEncoder().encodeToString(buffer.array()));
}
Thread.sleep(20);
}
conversation.close(1000, "Normal exit");
player.close();
mic.close();
System.out.println("\nConversation ended");
} catch (NoApiKeyException e) {
System.err.println("API KEY not found. Set the DASHSCOPE_API_KEY environment variable.");
} catch (Exception e) {
e.printStackTrace();
}
System.exit(0);
}
}
```
Qwen-Omni Conversa não-real
Clone uma voz e use-a em uma conversa não-real. Aplica-se a qwen3.5-omni-plus e qwen3.5-omni-flash. Para detalhes, veja [discurso Multimodal] (/developer-guides/speech/multimodal-speech).
Python
```python
import os
import requests
import base64
import pathlib
import numpy as np
import soundfile as sf
import dashscope
TARGET_MODEL = "qwen3.5-omni-plus"
PREFERRED_NAME = "guanyu"
VOICE_FILE_PATH = "voice.mp3"
def create_voice(file_path: str) -> str:
api_key = os.getenv("DASHSCOPE_API_KEY")
file_path_obj = pathlib.Path(file_path)
base64_str = base64.b64encode(file_path_obj.read_bytes()).decode()
data_uri = f"data:audio/mpeg;base64,{base64_str}"
resp = requests.post(
"https://maas.qwencloudapi.com/api/v1/services/audio/tts/customization",
headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
json={
"model": "qwen-voice-enrollment",
"input": {
"action": "create",
"target_model": TARGET_MODEL,
"preferred_name": PREFERRED_NAME,
"audio": {"data": data_uri}
}
}
)
if resp.status_code != 200:
raise RuntimeError(f"Failed to create voice: {resp.status_code}, {resp.text}")
return resp.json()["output"]["voice"]
if __name__ == '__main__':
dashscope.base_http_api_url = 'https://maas.qwencloudapi.com/api/v1'
voice = create_voice(VOICE_FILE_PATH)
print(f"Voice cloning complete. Voice: {voice}")
messages = [{"role": "user", "content": [{"text": "Hello, please introduce yourself"}]}]
response = dashscope.MultiModalConversation.call(
api_key=os.getenv("DASHSCOPE_API_KEY"),
model=TARGET_MODEL,
messages=messages,
modalities=["text", "audio"],
audio={"voice": voice, "format": "wav"},
stream=True
)
print("Model response:")
audio_base64_string = ""
for r in response:
try:
content = r.output.choices[0].message.content
for item in content:
if isinstance(item, dict):
if "audio" in item:
audio_base64_string += item["audio"].get("data", "")
elif "text" in item:
print(item["text"], end="")
except Exception:
pass
if audio_base64_string:
wav_bytes = base64.b64decode(audio_base64_string)
audio_np = np.frombuffer(wav_bytes, dtype=np.int16)
sf.write("audio_cloned.wav", audio_np, samplerate=24000)
print("\nAudio saved to: audio_cloned.wav")
```
Java
```java
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class Main {
private static final String TARGET_MODEL = "qwen3.5-omni-plus";
private static final String PREFERRED_NAME = "guanyu";
private static final String AUDIO_FILE = "voice.mp3";
private static final String AUDIO_MIME_TYPE = "audio/mpeg";
public static void writeWav(String path, byte[] pcmData, int sampleRate) throws IOException {
int channels = 1, bitsPerSample = 16;
int byteRate = sampleRate * channels * bitsPerSample / 8;
int blockAlign = channels * bitsPerSample / 8;
ByteBuffer header = ByteBuffer.allocate(44).order(ByteOrder.LITTLE_ENDIAN);
header.put("RIFF".getBytes()); header.putInt(36 + pcmData.length);
header.put("WAVE".getBytes()); header.put("fmt ".getBytes());
header.putInt(16); header.putShort((short) 1); header.putShort((short) channels);
header.putInt(sampleRate); header.putInt(byteRate);
header.putShort((short) blockAlign); header.putShort((short) bitsPerSample);
header.put("data".getBytes()); header.putInt(pcmData.length);
try (FileOutputStream fos = new FileOutputStream(path)) {
fos.write(header.array());
fos.write(pcmData);
}
}
public static String toDataUrl(String filePath) throws IOException {
byte[] bytes = Files.readAllBytes(Paths.get(filePath));
String encoded = Base64.getEncoder().encodeToString(bytes);
return "data:" + AUDIO_MIME_TYPE + ";base64," + encoded;
}
public static String createVoice() throws Exception {
String apiKey = System.getenv("DASHSCOPE_API_KEY");
String jsonPayload =
"{"
+ "\"model\": \"qwen-voice-enrollment\","
+ "\"input\": {"
+ "\"action\": \"create\","
+ "\"target_model\": \"" + TARGET_MODEL + "\","
+ "\"preferred_name\": \"" + PREFERRED_NAME + "\","
+ "\"audio\": {"
+ "\"data\": \"" + toDataUrl(AUDIO_FILE) + "\""
+ "}"
+ "}"
+ "}";
String url = "https://maas.qwencloudapi.com/api/v1/services/audio/tts/customization";
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Authorization", "Bearer " + apiKey);
con.setRequestProperty("Content-Type", "application/json");
con.setDoOutput(true);
try (OutputStream os = con.getOutputStream()) {
os.write(jsonPayload.getBytes(StandardCharsets.UTF_8));
}
int status = con.getResponseCode();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(status >= 200 && status < 300 ? con.getInputStream() : con.getErrorStream(),
StandardCharsets.UTF_8))) {
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
if (status == 200) {
JsonObject jsonObj = new Gson().fromJson(response.toString(), JsonObject.class);
return jsonObj.getAsJsonObject("output").get("voice").getAsString();
}
throw new IOException("Failed to create voice: " + status + " - " + response);
}
}
public static void main(String[] args) {
try {
String apiKey = System.getenv("DASHSCOPE_API_KEY");
String voice = createVoice();
System.out.println("Voice cloning complete. Voice: " + voice);
String requestBody = "{"
+ "\"model\": \"" + TARGET_MODEL + "\","
+ "\"messages\": [{\"role\": \"user\", \"content\": \"Hello, please introduce yourself\"}],"
+ "\"modalities\": [\"text\", \"audio\"],"
+ "\"audio\": {\"voice\": \"" + voice + "\", \"format\": \"wav\"},"
+ "\"stream\": true,"
+ "\"stream_options\": {\"include_usage\": true}"
+ "}";
String url = "https://maas.qwencloudapi.com/compatible-mode/v1/chat/completions";
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Authorization", "Bearer " + apiKey);
con.setRequestProperty("Content-Type", "application/json");
con.setDoOutput(true);
try (OutputStream os = con.getOutputStream()) {
os.write(requestBody.getBytes(StandardCharsets.UTF_8));
}
StringBuilder audioBase64 = new StringBuilder();
System.out.println("Model response:");
try (BufferedReader br = new BufferedReader(
new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = br.readLine()) != null) {
if (!line.startsWith("data: ") || line.equals("data: [DONE]")) continue;
String json = line.substring(6);
JsonObject chunk = new Gson().fromJson(json, JsonObject.class);
if (!chunk.has("choices") || chunk.getAsJsonArray("choices").size() == 0) continue;
JsonObject delta = chunk.getAsJsonArray("choices").get(0)
.getAsJsonObject().getAsJsonObject("delta");
if (delta.has("content") && !delta.get("content").isJsonNull()) {
System.out.print(delta.get("content").getAsString());
}
if (delta.has("audio") && !delta.get("audio").isJsonNull()) {
JsonObject audio = delta.getAsJsonObject("audio");
if (audio.has("data")) {
audioBase64.append(audio.get("data").getAsString());
}
}
}
}
if (audioBase64.length() > 0) {
byte[] pcmBytes = Base64.getDecoder().decode(audioBase64.toString());
writeWav("audio_cloned.wav", pcmBytes, 24000);
System.out.println("\nAudio saved to: audio_cloned.wav");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
Cota e faturamento
Quota de voz e limpeza automática.
Todos os limites de voz QwenCloud Conta tem um limite de 1.000 vozes personalizadas para Qwen-Audio-TTS/CosyVoice.
Se uma voz não é usada em nenhum pedido de síntese de fala por um ano, o sistema automaticamente a apaga.
Regras de faturamento
Os preços listados abaixo são os preços de lista. Para promoções atuais e preços com desconto, visite o [Modelo Marketplace] (https://www.qwencloud.com/models).
- **Qwen-Audio-TTS / CosyVoiceA clonagem de voz é gratuita.
Solução de problemas
Se você encontrar erros, veja [Mensagens de erro] (/api-reference/preparation/error-messages).
Próximos passos
- Voz clonando referência API (Qwen) -- Qwen-Omni API de clonagem de voz
- [Discurso multimodal em tempo real] (/developer-guides/speech/realtime-multimodal-speechUse vozes clonadas em conversa em tempo real.
- [Discurso Multimodal] (/developer-guides/speech/multimodal-speechUse vozes clonadas em conversas não reais.
- [Transmissão em tempo real TTS] (/developer-guides/speech/realtime-streaming- Detalhes bidirecionais de transmissão.
- [Pegue uma chave API] (/api-reference/preparation/api-key-- Configurar autenticação
- [Instalar o DashScope SDK] (/api-reference/preparation/install-sdk) - Instalação SDK
Quadros de referência
Tabelas restauradas a partir da referência original; a ordem das colunas e os valores técnicos foram preservados.
Quadro 1
| Requisição | Detalhes |
|---|---|
| Tamanho do quarto | Registre em um pequeno espaço fechado (máx. 10 m2). |
| Tratamento acústico | Escolha uma sala com materiais absorventes de som: espuma acústica, tapetes, ou cortinas. |
| Espaços para evitar | Evite auditórios, salas de conferência e salas de aula, esses espaços grandes causam forte reverberação que degrada a qualidade dos clones. |
Quadro 2
| Fonte de ruído | Mitigação |
|---|---|
| Ruído ao ar livre | Feche todas as janelas e portas. Evite gravar perto do tráfego ou construção. |
| Ruído interior | Desligue os aparelhos de ar condicionado, ventiladores e lastros fluorescentes antes de gravar. |
Quadro 3
| Orientação | Detalhes |
|---|---|
| Conteúdo | Nenhuma restrição estrita se aplica. Alinhar conteúdo com seu caso de uso do alvo. |
| Estrutura da sentença | Use frases completas. Evite frases curtas ("Olá", "Sim") que não tenham informações vocais para clonagem. |
| Continuidade | Mantenha a continuidade semântica, pause pouco e mire em 3 segundos de fala ininterrupta por segmento. |
| Expressão emocional | Adicione expressão emocional apropriada (quente, amigável, seriedade). Entrega de monotones reduz a naturalidade dos clones. |
| Restrições de conteúdo | Não inclua palavras sensíveis (política, pornografia, violência). Gravações com esse conteúdo falharão na clonagem. |