Clonez une voix à partir de 10 à 20 secondes d'audio sans entraînement. Cette rubrique détaille les paramètres et l'utilisation de l'API de clonage vocal. Pour invoquer le modèle, consultez Qwen-Omni-Realtime ou Non-real-time (Qwen-Omni) .
ImportantCette rubrique s'applique uniquement à l'API de clonage vocal Qwen-Omni et Qwen-Omni-Realtime. Si vous utilisez un modèle de synthèse vocale, reportez-vous à la rubrique Synthèse vocale.
ImportantAlibaba Cloud Model Studio a publié des domaines spécifiques aux espaces de travail pour les régions Chine (Pékin) et Singapour. Ces nouveaux domaines dédiés offrent des performances supérieures et une stabilité accrue pour les requêtes d'inférence. Nous vous recommandons de migrer vers ces nouveaux domaines :
- Chine (Pékin) : passez de
https://dashscope.aliyuncs.comàhttps://{WorkspaceId}.cn-beijing.maas.aliyuncs.com - Singapour : passez de
https://dashscope-intl.aliyuncs.comàhttps://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com
{WorkspaceId} correspond à votre ID d'espace de travail, disponible sur la page Workspace Details dans la console Alibaba Cloud Model Studio. Le domaine existant reste pleinement fonctionnel.
Exigences audio
Un fichier audio d'entrée de haute qualité garantit de meilleurs résultats de clonage.
Élément | Exigence |
|---|---|
Formats pris en charge | WAV (16 bits), MP3, M4A |
Durée | 10 à 20 secondes recommandées. Maximum : 60 secondes. |
Taille du fichier | < 10 Mo |
Taux d'échantillonnage | >= 24 kHz |
Canaux | Mono |
Contenu | L'audio doit contenir au moins 3 secondes de parole continue et claire, sans bruit de fond. Le reste peut inclure de brèves pauses (<= 2 secondes). Évitez toute musique de fond, bruit parasite ou autre voix sur l'ensemble de l'enregistrement. Utilisez un audio parlé normal comme entrée. Ne téléchargez pas de chansons ni d'enregistrements chantés. |
Langues | Chinois (zh), Anglais (en), Allemand (de), Italien (it), Portugais (pt), Espagnol (es), Japonais (ja), Coréen (ko), Français (fr), Russe (ru), Thaï (th), Indonésien (id), Arabe (ar), Tchèque (cs), Danois (da), Néerlandais (nl), Finnois (fi), Hébreu (he), Hindi (hi), Islandais (is), Malais (ms), Norvégien (no), Persan (fa), Polonais (pl), Suédois (sv), Tagalog (tl), Turc (tr), Ourdou (ur), Vietnamien (vi) Dialectes chinois : Dongbei, Shannxi, Sichuan, Henan, Changsha, Tianjin, Hangzhou, Liaoning, Shenyang, Anshan |
Prise en main rapide
1. Flux de travail
Le clonage vocal suit le principe « créer d'abord, utiliser ensuite » :
-
Créer une voix
Appelez l'API Créer une voix et chargez un extrait audio. Le système analyse l'audio et crée une voix clonée personnalisée. Vous devez spécifiertarget_modelà cette étape pour déclarer quel modèle omni pilotera la voix.
Si vous possédez déjà une voix créée (appelez l'API Lister les voix pour vérifier), ignorez cette étape et passez à la suivante.
-
Utiliser la voix dans une conversation
Appelez l'API Omni (temps réel ou non temps réel) et transmettez la voix obtenue à l'étape précédente. Le modèle omni spécifié à cette étape doit correspondre autarget_modelde l'étape précédente.
2. Configuration du modèle et prérequis
Sélectionnez les modèles et remplissez les prérequis avant de commencer.
Configuration du modèle
Le clonage vocal nécessite deux modèles :
-
Modèle de clonage vocal : qwen-voice-enrollment
-
Modèle omni pilotant la voix :
- qwen3.8-omni-flash-realtime
- qwen3.8-omni-flash-realtime
- qwen3.5-omni-plus-realtime
- qwen3.5-omni-flash-realtime
- qwen3.5-omni-plus
- qwen3.5-omni-flash
Prérequis
- Obtenir une clé API : Obtenir une clé API. Pour des raisons de sécurité, configurez la clé API comme variable d'environnement.
- Installer le SDK : Assurez-vous d'avoir installé la dernière version du SDK DashScope.
- Préparer l'audio pour le clonage : L'audio doit respecter les Exigences audio.
3. Exemple de bout en bout
Cet exemple clone une voix et l'utilise dans une conversation.
Principe clé : Le target_model spécifié lors du clonage doit correspondre au modèle utilisé dans l'appel ultérieur à l'API Omni. Sinon, la synthèse échoue. Remplacez le fichier d'exemple voice.mp3 par votre propre fichier audio.
Realtime
Applicable aux modèles de la série Qwen3.5-Omni-Realtime. Pour plus d'informations, consultez Qwen-Omni-Realtime.
# 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
# China (Beijing) region. Replace {WorkspaceId} with your Bailian workspace ID. URLs vary by region.
dashscope.base_http_api_url = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1"
# ======= Configuration =======
DEFAULT_TARGET_MODEL = "qwen3.5-omni-plus-realtime" # Must be the same model for cloning and conversation
DEFAULT_PREFERRED_NAME = "guanyu"
DEFAULT_AUDIO_MIME_TYPE = "audio/mpeg"
VOICE_FILE_PATH = "voice.mp3" # Path to the local audio file for voice cloning
def create_voice(file_path: str,
target_model: str = DEFAULT_TARGET_MODEL,
preferred_name: str = DEFAULT_PREFERRED_NAME,
audio_mime_type: str = DEFAULT_AUDIO_MIME_TYPE) -> str:
"""
Create a custom voice and return the voice parameter.
"""
# API keys differ between the Singapore and Beijing regions. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key
# If you haven't set an environment variable, replace the following line with: api_key = "sk-xxx"
api_key = os.getenv("DASHSCOPE_API_KEY")
file_path_obj = pathlib.Path(file_path)
if not file_path_obj.exists():
raise FileNotFoundError(f"Audio file not found: {file_path}")
base64_str = base64.b64encode(file_path_obj.read_bytes()).decode()
data_uri = f"data:{audio_mime_type};base64,{base64_str}"
# The following is the Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization"
payload = {
"model": "qwen-voice-enrollment",
"input": {
"action": "create",
"target_model": target_model,
"preferred_name": preferred_name,
"audio": {"data": data_uri}
}
}
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
resp = requests.post(url, json=payload, headers=headers)
if resp.status_code != 200:
raise RuntimeError(f"Failed to create voice: {resp.status_code}, {resp.text}")
try:
return resp.json()["output"]["voice"]
except (KeyError, ValueError) as e:
raise RuntimeError(f"Failed to parse voice response: {e}")
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__':
# If you haven't set an environment variable, replace the following line with: dashscope.api_key = "sk-xxx"
dashscope.api_key = os.getenv("DASHSCOPE_API_KEY")
# The following is the Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
url = "wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime"
# Step 1: Clone a voice
voice = create_voice(VOICE_FILE_PATH)
print(f"Voice cloning complete. Voice: {voice}")
# Step 2: Start a real-time conversation with the cloned voice
pya = pyaudio.PyAudio()
callback = SimpleCallback(pya)
conv = OmniRealtimeConversation(model=DEFAULT_TARGET_MODEL, callback=callback, url=url)
conv.connect()
conv.update_session(
output_modalities=[MultiModality.AUDIO, MultiModality.TEXT],
voice=voice # Use the cloned 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")
import com.alibaba.dashscope.audio.omni.*;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
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 {
// China (Beijing) region. Replace {WorkspaceId} with your Bailian workspace ID. URLs vary by region.
Constants.baseHttpApiUrl = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1";
// ===== Constants =====
// Use the same model for voice cloning and real-time conversation
private static final String TARGET_MODEL = "qwen3.5-omni-plus-realtime";
private static final String PREFERRED_NAME = "guanyu";
// Relative path to the local audio file for voice cloning
private static final String AUDIO_FILE = "voice.mp3";
private static final String AUDIO_MIME_TYPE = "audio/mpeg";
// Generate a data URI
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;
}
// Call the API to create a voice
public static String createVoice() throws Exception {
// The API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key
// If you haven't configured the environment variable, replace the following line with: String apiKey = "sk-xxx"
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) + "\""
+ "}"
+ "}"
+ "}";
// The following is the Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
String url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.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);
}
}
// Simple audio player
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 {
// 1. Voice cloning: create a custom voice
String voice = createVoice();
System.out.println("Voice cloning complete. Voice: " + voice);
// 2. Use the cloned voice in a real-time conversation
SimpleAudioPlayer player = new SimpleAudioPlayer();
AtomicBoolean shouldStop = new AtomicBoolean(false);
OmniRealtimeParam param = OmniRealtimeParam.builder()
.model(TARGET_MODEL)
// The API keys for the Singapore and Beijing regions are different. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key
// If you haven't configured the environment variable, replace the following line with: .apikey("sk-xxx")
.apikey(System.getenv("DASHSCOPE_API_KEY"))
// The following is the Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
.url("wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.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) // Use the cloned custom 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);
}
}
Non-realtime
Applicable aux modèles de la série Qwen3.5-Omni. Pour plus d'informations, consultez Non-real-time (Qwen-Omni).
# Requirements: dashscope >= 1.23.9, soundfile, numpy
import os
import requests
import base64
import pathlib
import numpy as np
import soundfile as sf
import dashscope
# China (Beijing) region. Replace {WorkspaceId} with your Bailian workspace ID. URLs vary by region.
dashscope.base_http_api_url = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1"
# ======= Configuration =======
DEFAULT_TARGET_MODEL = "qwen3.5-omni-plus" # Voice cloning and non-realtime calls must use the same model
DEFAULT_PREFERRED_NAME = "guanyu"
DEFAULT_AUDIO_MIME_TYPE = "audio/mpeg"
VOICE_FILE_PATH = "voice.mp3" # Path to the local audio file for voice cloning
def create_voice(file_path: str,
target_model: str = DEFAULT_TARGET_MODEL,
preferred_name: str = DEFAULT_PREFERRED_NAME,
audio_mime_type: str = DEFAULT_AUDIO_MIME_TYPE) -> str:
"""
Create a custom voice and return the voice parameter.
"""
# API keys differ between Singapore and Beijing regions. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key
# If the environment variable is not configured, replace the following line with: api_key = "sk-xxx"
api_key = os.getenv("DASHSCOPE_API_KEY")
file_path_obj = pathlib.Path(file_path)
if not file_path_obj.exists():
raise FileNotFoundError(f"Audio file not found: {file_path}")
base64_str = base64.b64encode(file_path_obj.read_bytes()).decode()
data_uri = f"data:{audio_mime_type};base64,{base64_str}"
# The following is the Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization"
payload = {
"model": "qwen-voice-enrollment",
"input": {
"action": "create",
"target_model": target_model,
"preferred_name": preferred_name,
"audio": {"data": data_uri}
}
}
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
resp = requests.post(url, json=payload, headers=headers)
if resp.status_code != 200:
raise RuntimeError(f"Failed to create voice: {resp.status_code}, {resp.text}")
try:
return resp.json()["output"]["voice"]
except (KeyError, ValueError) as e:
raise RuntimeError(f"Failed to parse voice response: {e}")
if __name__ == '__main__':
# The following is the Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
dashscope.base_http_api_url = 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1'
# 1. Voice cloning: create a custom voice
voice = create_voice(VOICE_FILE_PATH)
print(f"Voice cloning complete. Voice: {voice}")
# 2. Non-realtime conversation with the cloned voice
messages = [{"role": "user", "content": [{"text": "Hello, please introduce yourself"}]}]
response = dashscope.MultiModalConversation.call(
# If the environment variable is not configured, replace with: api_key="sk-xxx"
api_key=os.getenv("DASHSCOPE_API_KEY"),
model=DEFAULT_TARGET_MODEL,
messages=messages,
modalities=["text", "audio"],
audio={"voice": voice, "format": "wav"}, # Use the cloned voice
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")
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 {
// ===== Constants =====
// Voice cloning and non-realtime calls must use the same model
private static final String TARGET_MODEL = "qwen3.5-omni-plus";
private static final String PREFERRED_NAME = "guanyu";
// Path to the local audio file for voice cloning
private static final String AUDIO_FILE = "voice.mp3";
private static final String AUDIO_MIME_TYPE = "audio/mpeg";
// Write PCM data as a standard WAV file
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);
}
}
// Generate a data URI from a file
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;
}
// Call the API to create a voice
public static String createVoice() throws Exception {
// API keys differ between Singapore and Beijing regions. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key
// If the environment variable is not configured, replace the following line with: String apiKey = "sk-xxx"
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) + "\""
+ "}"
+ "}"
+ "}";
// The following is the Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
String url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.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 {
// API keys differ between Singapore and Beijing regions. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key
// If the environment variable is not configured, replace the following line with: String apiKey = "sk-xxx"
String apiKey = System.getenv("DASHSCOPE_API_KEY");
// 1. Voice cloning: create a custom voice
String voice = createVoice();
System.out.println("Voice cloning complete. Voice: " + voice);
// 2. Non-realtime conversation with the cloned voice (OpenAI-compatible API)
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}"
+ "}";
// The following is the Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region.
String url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.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));
}
// 3. Parse streaming SSE response
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());
}
}
}
}
// 4. Save audio file (API returns raw PCM data, WAV header required)
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();
}
}
}
Référence de l'API
Utilisez le même compte pour toutes les API.
Créer une voix
Chargez un fichier audio pour le clonage et créez une voix personnalisée.
-
URL
Chine du Nord 2 (Pékin) :
POST https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/audio/tts/customizationSingapour :
POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization -
En-têtes de requête
Parameter
Type
Required
Description
Authorization
string
Supported
Jeton d'authentification au format
Bearer <your_api_key>. Remplacez<your_api_key>par votre véritable clé API.Content-Type
string
Supported
Type MIME du corps de la requête. Définissez-le sur
application/json. -
Corps de la requête Le corps de la requête contient tous les paramètres. Omettez les champs facultatifs selon vos besoins. Notez la distinction entre :
Important
model: Modèle de clonage vocal. Définissez-le surqwen-voice-enrollment.target_model: Modèle omni pilotant la voix. Il doit correspondre au modèle utilisé dans l'appel ultérieur à l'API multimodale temps réel. Sinon, la synthèse échoue.{ "model": "qwen-voice-enrollment", "input": { "action": "create", "target_model": "qwen3.5-omni-plus-realtime", "preferred_name": "guanyu", "audio": { "data": "https://xxx.wav" }, "text": "Optional. The transcript of the audio in audio.data.", "language": "Optional. The language of the audio in audio.data, such as zh." }, "parameters": { "voice_clone_mode": "normal", "skip_audio_process": false } } -
Paramètres de la requête
Parameter Type Default Required Description model
string
Supported
Modèle de clonage vocal. Définissez-le sur
qwen-voice-enrollment.action
string
Supported
Type d'action. Définissez-le sur
create.target_model
string
Supported
Modèle omni pilotant la voix :
- qwen3.8-omni-flash-realtime
- qwen3.5-omni-plus-realtime
- qwen3.5-omni-flash-realtime
- qwen3.5-omni-plus
- qwen3.5-omni-flash
Il doit correspondre au modèle omni utilisé dans l'appel API ultérieur. Sinon, la synthèse échoue.
preferred_name
string
Supported
Nom lisible par l'homme pour la voix. Caractères autorisés : chiffres, lettres, traits de soulignement. Maximum : 16 caractères.
Ce mot-clé apparaît dans le nom final de la voix. Par exemple, si le mot-clé est « guanyu », le nom de voix résultant sera « qwen-omni-vc-guanyu-voice-20250812105009984-838b ».
audio.data
string
Supported
Audio à cloner (suivez le Guide d'enregistrement lors de la prise de son, et assurez-vous que l'audio respecte les Exigences audio).
Soumettez les données audio de l'une des manières suivantes :
-
Format :
data:<mediatype>;base64,<data>-
<mediatype>: Type MIME- WAV :
audio/wav - MP3 :
audio/mpeg - M4A :
audio/mp4
- WAV :
-
<data>: Chaîne encodée en Base64 de l'audioL'encodage Base64 augmente la taille du fichier. Maintenez le résultat encodé sous 10 Mo.
-
Exemple :
data:audio/wav;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4LjI5LjEwMAAAAAAAAAAAAAAA//PAxABQ/BXRbMPe4IQAhl9Voir l'exemple de code
import base64, pathlib # input.mp3 is the local audio file for voice cloning. Replace with your own file path. Make sure the file meets the audio requirements. file_path = pathlib.Path("input.mp3") base64_str = base64.b64encode(file_path.read_bytes()).decode() data_uri = f"data:audio/mpeg;base64,{base64_str}"import java.nio.file.*; import java.util.Base64; public class Main { /** * filePath is the local audio file for voice cloning. Replace with your own file path. Make sure the file meets the audio requirements. */ public static String toDataUrl(String filePath) throws Exception { byte[] bytes = Files.readAllBytes(Paths.get(filePath)); String encoded = Base64.getEncoder().encodeToString(bytes); return "data:audio/mpeg;base64," + encoded; } // Usage example public static void main(String[] args) throws Exception { System.out.println(toDataUrl("input.mp3")); } }
-
-
URL audio (nous recommandons de charger votre audio sur OSS)
- La taille du fichier ne doit pas dépasser 10 Mo.
- L'URL doit être accessible publiquement sans authentification.
text
string
Unsupported
Transcription correspondant à l'audio dans
audio.data.Lorsqu'elle est fournie, le serveur valide l'audio par rapport au texte. Si l'écart est trop important, une erreur Audio.PreprocessError est renvoyée.
language
string
Unsupported
Langue de l'audio dans
audio.data.Valeurs prises en charge :
zh(Chinois),en(Anglais),de(Allemand),it(Italien),pt(Portugais),es(Espagnol),ja(Japonais),ko(Coréen),fr(Français),ru(Russe),th(Thaï),id(Indonésien),ar(Arabe),cs(Tchèque),da(Danois),nl(Néerlandais),fi(Finnois),he(Hébreu),hi(Hindi),is(Islandais),ms(Malais),no(Norvégien),fa(Persan),pl(Polonais),sv(Suédois),tl(Tagalog),tr(Turc),ur(Ourdou),vi(Vietnamien).Dialectes chinois :
Dongbei,Shannxi,Sichuan,Henan,Changsha,Tianjin,Hangzhou,Liaoning,Shenyang,Anshan.Définissez cette valeur sur la langue réelle de l'audio utilisé pour le clonage.
-
Paramètres de réponse
Voir l'exemple de réponse
{ "output": { "voice": "yourVoice", "target_model": "qwen3.5-omni-plus-realtime" }, "usage": { "count": 1 }, "request_id": "yourRequestId" }Paramètres de réponse clés :
Parameter Type Description voice
string
Nom de la voix. Utilisez directement cette valeur comme paramètre
voicedans l'API multimodale temps réel.target_model
string
Modèle omni pilotant la voix :
- qwen3.5-omni-plus-realtime
- qwen3.5-omni-flash-realtime
Il doit correspondre au modèle utilisé dans l'appel ultérieur à l'API multimodale temps réel. Sinon, la synthèse échoue.
request_id
string
ID de la requête.
count
integer
Nombre d'opérations « créer une voix » facturées pour cette requête. Le coût est de $
count \times 0.01.Lors de la création d'une voix, count est toujours égal à 1.
-
Exemple de code
Important
model: Modèle de clonage vocal. Définissez-le surqwen-voice-enrollment.target_model: Modèle omni pilotant la voix. Il doit correspondre au modèle utilisé dans l'appel ultérieur à l'API multimodale temps réel. Sinon, la synthèse échoue.curl
Si vous n'avez pas défini la clé API comme variable d'environnement, remplacez
$DASHSCOPE_API_KEYdans l'exemple par votre véritable clé API.# ======= Important ======= # The following is the Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. # API keys differ between regions. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key # === Remove these comments before running === curl --location --request POST 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization' \ --header "Authorization: Bearer $DASHSCOPE_API_KEY" \ --header 'Content-Type: application/json' \ --data '{ "model": "qwen-voice-enrollment", "parameters": {"voice_clone_mode": "normal"}, "input": { "action": "create", "target_model": "qwen3.8-omni-flash-realtime", "preferred_name": "guanyu", "audio": {"data": "https://xxx.wav"} } }'python
import os import requests import base64, pathlib target_model = "qwen3.8-omni-flash-realtime" preferred_name = "guanyu" audio_mime_type = "audio/mpeg" file_path = pathlib.Path("input.mp3") base64_str = base64.b64encode(file_path.read_bytes()).decode() data_uri = f"data:{audio_mime_type};base64,{base64_str}" # API keys differ between regions. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key # If you haven't set an environment variable, replace the following line with: api_key = "sk-xxx" api_key = os.getenv("DASHSCOPE_API_KEY") # The following is the Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization" payload = { "model": "qwen-voice-enrollment", # Do not modify "parameters": {"voice_clone_mode": "normal"}, "input": { "action": "create", "target_model": target_model, "preferred_name": preferred_name, "audio": { "data": data_uri } } } headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } # Envoyer la requête POST resp = requests.post(url, json=payload, headers=headers) if resp.status_code == 200: data = resp.json() voice = data["output"]["voice"] print(f"Voix créée : {voice}") else: print("Échec de la requête :", resp.status_code, resp.text)java
import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; public class Main { public static void main(String[] args) { // API keys differ between regions. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key // If you haven't set an environment variable, replace the following line with: String apiKey = "sk-xxx" String apiKey = System.getenv("DASHSCOPE_API_KEY"); // The following is the Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. String apiUrl = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization"; // JSON request body String jsonPayload = "{" + "\"model\": \"qwen-voice-enrollment\"," // Do not modify + "\"input\": {" + "\"action\": \"list\"," + "\"page_size\": 10," + "\"page_index\": 0" + "}" + "}"; try { HttpURLConnection con = (HttpURLConnection) new URL(apiUrl).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("UTF-8")); } int status = con.getResponseCode(); BufferedReader br = new BufferedReader(new InputStreamReader( status >= 200 && status < 300 ? con.getInputStream() : con.getErrorStream(), "UTF-8")); StringBuilder response = new StringBuilder(); String line; while ((line = br.readLine()) != null) { response.append(line); } br.close(); System.out.println("HTTP status: " + status); System.out.println("Response JSON: " + response.toString()); if (status == 200) { Gson gson = new Gson(); JsonObject jsonObj = gson.fromJson(response.toString(), JsonObject.class); JsonArray voiceList = jsonObj.getAsJsonObject("output").getAsJsonArray("voice_list"); System.out.println("\n Voice list:"); for (int i = 0; i < voiceList.size(); i++) { JsonObject voiceItem = voiceList.get(i).getAsJsonObject(); String voice = voiceItem.get("voice").getAsString(); String gmtCreate = voiceItem.get("gmt_create").getAsString(); String targetModel = voiceItem.get("target_model").getAsString(); System.out.printf("- Voice: %s Created: %s Model: %s\n", voice, gmtCreate, targetModel); } } } catch (Exception e) { e.printStackTrace(); } } }
Lister les voix
Interrogez vos voix créées avec pagination.
-
URL
Chine du Nord 2 (Pékin) :
POST https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/audio/tts/customizationSingapour :
POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization -
En-têtes de requête
Parameter
Type
Required
Description
Authorization
string
Supported
Jeton d'authentification au format
Bearer <your_api_key>. Remplacez<your_api_key>par votre véritable clé API.Content-Type
string
Supported
Type MIME du corps de la requête. Définissez-le sur
application/json. -
Paramètres de la requête
Parameter
Type
Default
Required
Description
model
string
-
Supported
Modèle de clonage vocal. Définissez-le sur
qwen-voice-enrollment.action
string
-
Supported
Type d'action. Définissez-le sur
list.page_index
integer
0
Unsupported
Index de numéro de page. Valeurs valides : 0 à 1 000 000.
page_size
integer
10
Unsupported
Nombre d'éléments par page. Valeurs valides : 0 à 1 000 000.
-
Paramètres de réponse
Voir l'exemple de réponse
{ "output": { "voice_list": [ { "voice": "yourVoice1", "gmt_create": "2025-08-11 17:59:32", "target_model": "qwen3.5-omni-plus-realtime" }, { "voice": "yourVoice2", "gmt_create": "2025-08-11 17:38:10", "target_model": "qwen3.5-omni-plus-realtime" } ] }, "usage": { "count": 0 }, "request_id": "yourRequestId" }Paramètres de réponse clés :
Parameter Type Description voice
string
Nom de la voix. Utilisez directement cette valeur dans le paramètre
voicede l'API multimodale temps réel.gmt_create
string
Heure de création de la voix.
target_model
string
Modèle omni pilotant la voix :
- qwen3.8-omni-flash-realtime
- qwen3.5-omni-plus-realtime
- qwen3.5-omni-flash-realtime
- qwen3.5-omni-plus
- qwen3.5-omni-flash
Il doit correspondre au modèle omni utilisé dans l'appel API ultérieur. Sinon, la synthèse échoue.
request_id
string
ID de la requête.
count
integer
Cette requête est facturée en fonction du nombre réel d'opérations « Créer une voix ». Le coût de cette requête est de $
count \times 0.01.Le listage des voix est gratuit.
countest toujours égal à 0. -
Exemple de code
Important
model: Modèle de clonage vocal. La valeur est fixée àqwen-voice-enrollment. Ne modifiez pas cette valeur.cURL
Si vous n'avez pas défini la clé API comme variable d'environnement, remplacez
$DASHSCOPE_API_KEYdans l'exemple par votre véritable clé API.# ======= Important ======= # The following is the Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. # API keys differ between regions. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key # === Remove these comments before running === curl --location --request POST 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization' \ --header "Authorization: Bearer $DASHSCOPE_API_KEY" \ --header 'Content-Type: application/json' \ --data '{ "model": "qwen-voice-enrollment", "input": { "action": "list", "page_size": 10, "page_index": 0 } }'Python
import os import requests # API keys differ between regions. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key # If you haven't set an environment variable, replace the following line with: api_key = "sk-xxx" api_key = os.getenv("DASHSCOPE_API_KEY") # The following is the Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization" payload = { "model": "qwen-voice-enrollment", # Do not modify "input": { "action": "list", "page_size": 10, "page_index": 0 } } headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print("HTTP status:", response.status_code) if response.status_code == 200: data = response.json() voice_list = data["output"]["voice_list"] print("Voice list:") for item in voice_list: print(f"- Voice: {item['voice']} Created: {item['gmt_create']} Model: {item['target_model']}") else: print("Request failed:", response.text)Java
import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; public class Main { public static void main(String[] args) { // API keys differ between regions. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key // If you haven't set an environment variable, replace the following line with: String apiKey = "sk-xxx" String apiKey = System.getenv("DASHSCOPE_API_KEY"); // The following is the Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. String apiUrl = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization"; // JSON request body String jsonPayload = "{" + "\"model\": \"qwen-voice-enrollment\"," // Do not modify + "\"input\": {" + "\"action\": \"list\"," + "\"page_size\": 10," + "\"page_index\": 0" + "}" + "}"; try { HttpURLConnection con = (HttpURLConnection) new URL(apiUrl).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("UTF-8")); } int status = con.getResponseCode(); BufferedReader br = new BufferedReader(new InputStreamReader( status >= 200 && status < 300 ? con.getInputStream() : con.getErrorStream(), "UTF-8")); StringBuilder response = new StringBuilder(); String line; while ((line = br.readLine()) != null) { response.append(line); } br.close(); System.out.println("HTTP status: " + status); System.out.println("Response JSON: " + response.toString()); if (status == 200) { Gson gson = new Gson(); JsonObject jsonObj = gson.fromJson(response.toString(), JsonObject.class); JsonArray voiceList = jsonObj.getAsJsonObject("output").getAsJsonArray("voice_list"); System.out.println("\n Voice list:"); for (int i = 0; i < voiceList.size(); i++) { JsonObject voiceItem = voiceList.get(i).getAsJsonObject(); String voice = voiceItem.get("voice").getAsString(); String gmtCreate = voiceItem.get("gmt_create").getAsString(); String targetModel = voiceItem.get("target_model").getAsString(); System.out.printf("- Voice: %s Created: %s Model: %s\n", voice, gmtCreate, targetModel); } } } catch (Exception e) { e.printStackTrace(); } } }
Supprimer une voix
Supprimez une voix spécifique et libérez le quota correspondant.
-
URL
Chine du Nord 2 (Pékin) :
POST https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/audio/tts/customizationSingapour :
POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization -
En-têtes de requête
Parameter
Type
Required
Description
Authorization
string
Supported
Jeton d'authentification au format
Bearer <your_api_key>. Remplacez<your_api_key>par votre véritable clé API.Content-Type
string
Supported
Type MIME du corps de la requête. Définissez-le sur
application/json. -
Corps de la requête
Omettez les champs facultatifs selon vos besoins.
Important
model: Modèle de clonage vocal. La valeur est fixée àqwen-voice-enrollment. Ne modifiez pas cette valeur.{ "model": "qwen-voice-enrollment", "input": { "action": "delete", "voice": "yourVoice" } } -
Paramètres de la requête
Parameter
Type
Default
Required
Description
model
string
-
Supported
Modèle de clonage vocal. Définissez-le sur
qwen-voice-enrollment.action
string
-
Supported
Type d'action. Définissez-le sur
delete.voice
string
-
Supported
Voix à supprimer.
-
Paramètres de réponse
Voir l'exemple de réponse
{ "usage": { "count": 0 }, "request_id": "yourRequestId" }Paramètres de réponse clés :
Parameter
Type
Description
request_id
string
ID de la requête.
count
integer
Cette requête est facturée en fonction du nombre réel d'opérations « Créer une voix ». Le coût de cette requête est de $
count \times 0.01.La suppression d'une voix est gratuite.
countest toujours égal à 0. -
Exemple de code
Important
model: Modèle de clonage vocal. La valeur est fixée àqwen-voice-enrollment. Ne modifiez pas cette valeur.cURL
Si vous n'avez pas défini la clé API comme variable d'environnement, remplacez
$DASHSCOPE_API_KEYdans l'exemple par votre véritable clé API.# ======= Important ======= # The following is the Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. # API keys differ between regions. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key # === Remove these comments before running === curl --location --request POST 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization' \ --header "Authorization: Bearer $DASHSCOPE_API_KEY" \ --header 'Content-Type: application/json' \ --data '{ "model": "qwen-voice-enrollment", "input": { "action": "delete", "voice": "yourVoice" } }'Python
import os import requests # API keys differ between regions. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key # If you haven't set an environment variable, replace the following line with: api_key = "sk-xxx" api_key = os.getenv("DASHSCOPE_API_KEY") # The following is the Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization" voice_to_delete = "yourVoice" # Replace with the actual voice name payload = { "model": "qwen-voice-enrollment", # Do not modify "input": { "action": "delete", "voice": voice_to_delete } } headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } response = requests.post(url, json=payload, headers=headers) print("HTTP status:", response.status_code) if response.status_code == 200: data = response.json() request_id = data["request_id"] print(f"Deleted successfully") print(f"Request ID: {request_id}") else: print("Request failed:", response.text)Java
import com.google.gson.Gson; import com.google.gson.JsonObject; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; public class Main { public static void main(String[] args) { // API keys differ between regions. Get an API key: https://www.alibabacloud.com/help/en/model-studio/get-api-key // If you haven't set an environment variable, replace the following line with: String apiKey = "sk-xxx" String apiKey = System.getenv("DASHSCOPE_API_KEY"); // The following is the Singapore region URL. Replace {WorkspaceId} with your actual workspace ID. URLs vary by region. String apiUrl = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization"; String voiceToDelete = "yourVoice"; // Replace with the actual voice name // Build JSON request body String jsonPayload = "{" + "\"model\": \"qwen-voice-enrollment\"," // Do not modify + "\"input\": {" + "\"action\": \"delete\"," + "\"voice\": \"" + voiceToDelete + "\"" + "}" + "}"; try { // Create POST connection HttpURLConnection con = (HttpURLConnection) new URL(apiUrl).openConnection(); con.setRequestMethod("POST"); con.setRequestProperty("Authorization", "Bearer " + apiKey); con.setRequestProperty("Content-Type", "application/json"); con.setDoOutput(true); // Send request body try (OutputStream os = con.getOutputStream()) { os.write(jsonPayload.getBytes("UTF-8")); } int status = con.getResponseCode(); BufferedReader br = new BufferedReader(new InputStreamReader( status >= 200 && status < 300 ? con.getInputStream() : con.getErrorStream(), "UTF-8")); StringBuilder response = new StringBuilder(); String line; while ((line = br.readLine()) != null) { response.append(line); } br.close(); System.out.println("HTTP status: " + status); System.out.println("Response JSON: " + response.toString()); if (status == 200) { Gson gson = new Gson(); JsonObject jsonObj = gson.fromJson(response.toString(), JsonObject.class); String requestId = jsonObj.get("request_id").getAsString(); System.out.println("Deleted successfully"); System.out.println("Request ID: " + requestId); } } catch (Exception e) { e.printStackTrace(); } } }
Utilisation dans une conversation
Pour utiliser une voix clonée dans une conversation, consultez la section Prise en main rapide.
Quota de voix et nettoyage automatique
Limite totale : 1 000 voix par compte.
Aucun endpoint dédié au comptage n'existe. Appelez l'API Lister les voix pour compter vos voix.
Nettoyage automatique : Les voix inutilisées pendant un an sont automatiquement supprimées.
Facturation
Le clonage vocal et l'invocation du modèle sont facturés séparément :
-
Clonage vocal : facturé à 0,01 $/voix. Les créations échouées ne sont pas facturées.
RemarqueQuota gratuit (uniquement pour la région Pékin du site Chine et la région Singapour du site International) :
- 1 000 créations de voix gratuites dans les 90 jours suivant l'activation de Model Studio.
- Les créations échouées ne consomment pas le quota gratuit.
- La suppression d'une voix ne restaure pas le quota gratuit.
- Une fois le quota gratuit épuisé ou la période de 90 jours expirée, la création de voix est facturée à 0,01 $/voix.
-
Conversation avec une voix clonée : Facturée selon l'utilisation des tokens pour l'invocation du modèle. Pour plus de détails, consultez Tarification de l'inférence de modèle.
Droits d'auteur et conformité légale
Vous êtes responsable de la propriété et de l'utilisation légale de la voix que vous fournissez. Lisez l'Accord de service.
Guide d'enregistrement
Matériel d'enregistrement
Utilisez un microphone à réduction de bruit, ou enregistrez avec un téléphone à courte distance dans un environnement calme.
Environnement d'enregistrement
Emplacement
- Enregistrez dans un petit espace clos de 10 mètres carrés ou moins.
- Choisissez une pièce dotée de matériaux absorbants tels que de la mousse acoustique, des tapis ou des rideaux.
- Évitez les grands halls ouverts, les salles de conférence ou les classes où la réverbération est importante.
Contrôle du bruit
- Bruit extérieur : Fermez les portes et les fenêtres pour bloquer le trafic, les travaux et autres sons externes.
- Bruit intérieur : Éteignez les climatiseurs, les ventilateurs et les ballasts de lampes fluorescentes.
- Enregistrez le son ambiant avec votre téléphone et écoutez-le à volume élevé pour identifier les sources de bruit cachées.
Contrôle de la réverbération
- La réverbération rend l'audio étouffé et réduit la clarté.
- Réduisez les réflexions sur les surfaces lisses : fermez les rideaux, ouvrez les portes de placard et couvrez les bureaux et étagères avec des vêtements ou des couvertures.
- Utilisez des objets irréguliers tels que des bibliothèques et des meubles rembourrés pour créer des réflexions diffuses.
Préparation du script
- Adaptez le script au cas d'utilisation cible. Par exemple, utilisez un style de dialogue de service client pour un scénario de service client.
- Assurez-vous que le script ne contient pas de contenu sensible ou illégal (tel que du matériel politique, pornographique ou violent), car cela entraîne l'échec du clonage.
- Évitez les phrases courtes (comme « bonjour » ou « oui »). Utilisez des phrases complètes.
- Maintenez une cohérence sémantique et évitez les pauses fréquentes lors de la lecture. Au moins 3 secondes consécutives sans interruption sont recommandées.
- Vous pouvez transmettre l'émotion cible (comme amical ou sérieux), mais évitez un ton trop dramatique ou théâtral. Gardez un ton naturel.
Étapes recommandées
En prenant une chambre typique comme exemple :
- Fermez les portes et les fenêtres pour bloquer le bruit extérieur.
- Éteignez les climatiseurs, les ventilateurs et autres appareils électroménagers.
- Fermez les rideaux pour réduire les réflexions sur le verre.
- Couvrez la surface du bureau avec des vêtements ou une couverture pour réduire les réflexions du bureau.
- Familiarisez-vous avec le script, définissez le ton du personnage et livrez-le naturellement.
- Maintenez une distance d'environ 10 cm par rapport à l'appareil d'enregistrement pour éviter la distorsion des plosives ou un signal faible.
Messages d'erreur
Si vous rencontrez des erreurs, consultez la rubrique Codes d'erreur pour le dépannage.