聲音複刻依託大模型進行特徵提取,無需訓練即可複刻聲音。僅需提供 10~20 秒的音頻,即可產生高度相似且聽感自然的定製音色。聲音複刻與模型調用是前後關聯的兩個步驟。本文檔聚焦於介紹聲音複刻的參數和介面細節,模型調用請參見 即時(Qwen-Omni-Realtime) 或 非即時(Qwen-Omni) 。
使用者指南:關於模型介紹和選型建議請參見即時(Qwen-Omni-Realtime)或非即時(Qwen-Omni)。
重要本文檔專用於千問Omni和千問Omni-Realtime聲音複刻介面;若您使用的是語音合成模型,請參見語音合成。
重要阿里雲百鍊為華北2(北京)、新加坡地區推出了業務空間專屬網域名稱,能夠為推理請求提供卓越的效能和更高的穩定性,建議遷移至新網域名稱:
- 華北2(北京)地區:從
https://dashscope.aliyuncs.com遷移至https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com - 新加坡地區:從
https://dashscope-intl.aliyuncs.com遷移至https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com
其中 {WorkspaceId} 為您的業務空間 ID,可在阿里雲百鍊控制台的業務空間詳情頁面查看。現有網域名稱仍可正常使用。
音頻要求
高品質的輸入音頻是獲得優質複刻效果的基礎。
專案 | 要求 |
|---|---|
支援格式 | WAV (16bit)、MP3、M4A |
音頻時間長度 | 推薦10~20秒,最長不得超過60秒 |
檔案大小 | < 10 MB |
採樣率 | ≥ 24 kHz |
聲道 | 單聲道 |
內容 | 音頻必須包含至少3秒連續清晰朗讀(無背景音),其餘部分僅允許短暫停頓(≤2秒);整段音頻應避免背景音樂、噪音或其他人聲,確保核心朗讀內容品質;請使用正常說話音頻作為輸入,不要上傳歌曲或唱歌音頻,以確保複刻效果準確和可用 |
語言 | 中文(zh)、英文(en)、德語(de)、意大利語(it)、葡萄牙語(pt)、西班牙語(es)、日語(ja)、韓語(ko)、法語(fr)、俄語(ru)、泰語(th)、印尼語(id)、阿拉伯語(ar)、捷克語(cs)、丹麥語(da)、荷蘭語(nl)、芬蘭語(fi)、希伯來語(he)、印地語(hi)、冰島語(is)、馬來語(ms)、挪威語(no)、波斯語(fa)、波蘭語(pl)、瑞典語(sv)、他加祿語(tl)、土耳其語(tr)、烏爾都語(ur)、越南語(vi) 中文方言:東北話(Dongbei)、陝西話(Shannxi)、四川話(Sichuan)、河南話(Henan)、長沙話(Changsha)、天津話(Tianjin)、杭州話(Hangzhou)、遼寧話(Liaoning)、瀋陽話(Shenyang)、鞍山話(Anshan) |
快速開始:複刻與使用音色
1. 工作流程
聲音複刻與模型調用是緊密關聯的兩個獨立步驟,遵循“先建立,後使用”的流程:
-
建立音色
調用建立音色介面,上傳一段音頻。系統會分析該音頻,建立一個專屬的複刻音色。此步驟必須指定
target_model,聲明建立的音色將由哪個全模態模型驅動。若已有建立好的音色(調用查詢音色列表介面查看),可跳過這一步直接進行下一步。
-
使用音色進行對話
調用 Omni 介面(即時或非即時),傳入上一步獲得的音色。此步驟指定的全模態模型必須和上一步的
target_model一致。
2. 模型配置與準備工作
選擇合適的模型並完成準備工作。
模型配置
聲音複刻時需要指定以下兩個模型:
-
聲音複刻模型:qwen-voice-enrollment
-
驅動音色的全模態模型:
- qwen3.8-omni-flash-realtime
- qwen3.5-omni-plus-realtime
- qwen3.5-omni-flash-realtime
- qwen3.5-omni-plus
- qwen3.5-omni-flash
準備工作
- 擷取API Key:擷取API Key,為安全起見,推薦將API Key配置到環境變數。
- 安裝SDK:確保已安裝最新版DashScope SDK。
- 準備待覆刻音頻:音頻需符合音頻要求。
3. 端到端樣本
以下樣本示範了如何在對話中使用聲音複刻產生的專屬音色,實現與原音高度相似的輸出效果。
- 關鍵原則:聲音複刻時,
target_model(驅動音色的全模態模型)必須與後續調用 Omni 介面時指定的模型一致,否則會合成失敗。 - 樣本使用本地音頻檔案
voice.mp3進行聲音複刻,運行代碼時,請注意替換。
即時
適用於千問Omni-Realtime系列模型,更多說明請參見即時(Qwen-Omni-Realtime)。
# 依賴: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
# ======= 常量配置 =======
DEFAULT_TARGET_MODEL = "qwen3.5-omni-plus-realtime" # 聲音複刻、即時對話要使用相同的模型
DEFAULT_PREFERRED_NAME = "guanyu"
DEFAULT_AUDIO_MIME_TYPE = "audio/mpeg"
VOICE_FILE_PATH = "voice.mp3" # 用於聲音複刻的本地音頻檔案的相對路徑
def create_voice(file_path: str,
url: str,
target_model: str = DEFAULT_TARGET_MODEL,
preferred_name: str = DEFAULT_PREFERRED_NAME,
audio_mime_type: str = DEFAULT_AUDIO_MIME_TYPE) -> str:
"""
建立音色,並返回 voice 參數
"""
# 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# 若沒有配置環境變數,請用百鍊API Key將下行替換為: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"音頻檔案不存在: {file_path}")
base64_str = base64.b64encode(file_path_obj.read_bytes()).decode()
data_uri = f"data:{audio_mime_type};base64,{base64_str}"
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"建立 voice 失敗: {resp.status_code}, {resp.text}")
try:
return resp.json()["output"]["voice"]
except (KeyError, ValueError) as e:
raise RuntimeError(f"解析 voice 響應失敗: {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__':
# 若沒有配置環境變數,請用百鍊API Key將下行替換為:dashscope.api_key = "sk-xxx"
dashscope.api_key = os.getenv("DASHSCOPE_API_KEY")
# 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。
base_url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com"
ws_url = base_url.replace("https://", "wss://") + "/api-ws/v1/realtime"
# 1. 聲音複刻:建立專屬音色
voice = create_voice(VOICE_FILE_PATH, url=f"{base_url}/api/v1/services/audio/tts/customization")
print(f"聲音複刻完成,音色: {voice}")
# 2. 使用複刻音色進行即時對話
pya = pyaudio.PyAudio()
callback = SimpleCallback(pya)
conv = OmniRealtimeConversation(model=DEFAULT_TARGET_MODEL, callback=callback, url=ws_url)
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("對話已開始,對著麥克風說話 (Ctrl+C 退出)...")
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("\n對話結束")
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 {
// ===== 常量定義 =====
// 聲音複刻、即時對話要使用相同的模型
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";
// 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。
private static final String BASE_URL = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com";
// 產生 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;
}
// 調用 API 建立 voice
public static String createVoice() throws Exception {
// 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
// 若沒有配置環境變數,請用百鍊API Key將下行替換為: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) + "\""
+ "}"
+ "}"
+ "}";
String url = BASE_URL + "/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("建立語音失敗: " + 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 {
// 1. 聲音複刻:建立專屬音色
String voice = createVoice();
System.out.println("聲音複刻完成,音色: " + voice);
// 2. 使用複刻音色進行即時對話
SimpleAudioPlayer player = new SimpleAudioPlayer();
AtomicBoolean shouldStop = new AtomicBoolean(false);
OmniRealtimeParam param = OmniRealtimeParam.builder()
.model(TARGET_MODEL)
// 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
// 若沒有配置環境變數,請用百鍊API Key將下行替換為:.apikey("sk-xxx")
.apikey(System.getenv("DASHSCOPE_API_KEY"))
.url(BASE_URL.replace("https://", "wss://") + "/api-ws/v1/realtime")
.build();
OmniRealtimeConversation conversation = new OmniRealtimeConversation(param, new OmniRealtimeCallback() {
@Override public void onOpen() { System.out.println("串連已建立"); }
@Override public void onClose(int code, String reason) {
System.out.println("串連已關閉 (" + 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("對話已開始,對著麥克風說話 (Ctrl+C 退出)...");
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, "正常結束");
player.close();
mic.close();
System.out.println("\n對話結束");
} catch (NoApiKeyException e) {
System.err.println("未找到API KEY: 請設定環境變數 DASHSCOPE_API_KEY");
} catch (Exception e) {
e.printStackTrace();
}
System.exit(0);
}
}
非即時
適用於千問Omni系列模型,更多說明請參見非即時(Qwen-Omni)。
# 依賴:dashscope >= 1.23.9,soundfile,numpy
import os
import requests
import base64
import pathlib
import numpy as np
import soundfile as sf
import dashscope
# ======= 常量配置 =======
DEFAULT_TARGET_MODEL = "qwen3.5-omni-plus" # 聲音複刻、非即時對話要使用相同的模型
DEFAULT_PREFERRED_NAME = "guanyu"
DEFAULT_AUDIO_MIME_TYPE = "audio/mpeg"
VOICE_FILE_PATH = "voice.mp3" # 用於聲音複刻的本地音頻檔案的相對路徑
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:
"""
建立音色,並返回 voice 參數
"""
# 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# 若沒有配置環境變數,請用百鍊API Key將下行替換為: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"音頻檔案不存在: {file_path}")
base64_str = base64.b64encode(file_path_obj.read_bytes()).decode()
data_uri = f"data:{audio_mime_type};base64,{base64_str}"
url = dashscope.base_http_api_url + "/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"建立 voice 失敗: {resp.status_code}, {resp.text}")
try:
return resp.json()["output"]["voice"]
except (KeyError, ValueError) as e:
raise RuntimeError(f"解析 voice 響應失敗: {e}")
if __name__ == '__main__':
# 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。
dashscope.base_http_api_url = 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1'
# 1. 聲音複刻:建立專屬音色
voice = create_voice(VOICE_FILE_PATH)
print(f"聲音複刻完成,音色: {voice}")
# 2. 使用複刻音色進行非即時對話
messages = [{"role": "user", "content": [{"text": "你好,請做一段自我介紹"}]}]
response = dashscope.MultiModalConversation.call(
# 若沒有配置環境變數,請用百鍊API Key將下行替換為: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"}, # 使用複刻產生的專屬音色
stream=True
)
print("模型回複:")
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("\n音頻檔案已儲存至: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 {
// ===== 常量定義 =====
// 聲音複刻、非即時對話要使用相同的模型
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";
// 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。
private static final String BASE_URL = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com";
// 將 PCM 資料寫入標準 WAV 檔案
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);
}
}
// 產生 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;
}
// 調用 API 建立 voice
public static String createVoice() throws Exception {
// 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
// 若沒有配置環境變數,請用百鍊API Key將下行替換為: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) + "\""
+ "}"
+ "}"
+ "}";
String url = BASE_URL + "/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("建立語音失敗: " + status + " - " + response);
}
}
public static void main(String[] args) {
try {
// 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key
// 若沒有配置環境變數,請用百鍊API Key將下行替換為:String apiKey = "sk-xxx"
String apiKey = System.getenv("DASHSCOPE_API_KEY");
// 1. 聲音複刻:建立專屬音色
String voice = createVoice();
System.out.println("聲音複刻完成,音色: " + voice);
// 2. 使用複刻音色進行非即時對話(OpenAI 相容介面)
String requestBody = "{"
+ "\"model\": \"" + TARGET_MODEL + "\","
+ "\"messages\": [{\"role\": \"user\", \"content\": \"你好,請做一段自我介紹\"}],"
+ "\"modalities\": [\"text\", \"audio\"],"
+ "\"audio\": {\"voice\": \"" + voice + "\", \"format\": \"wav\"},"
+ "\"stream\": true,"
+ "\"stream_options\": {\"include_usage\": true}"
+ "}";
String url = BASE_URL + "/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. 解析流式 SSE 響應
StringBuilder audioBase64 = new StringBuilder();
System.out.println("模型回複:");
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. 儲存音頻檔案(API 返回原始 PCM 資料,需添加 WAV 頭)
if (audioBase64.length() > 0) {
byte[] pcmBytes = Base64.getDecoder().decode(audioBase64.toString());
writeWav("audio_cloned.wav", pcmBytes, 24000);
System.out.println("\n音頻檔案已儲存至:audio_cloned.wav");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
API參考
使用不同 API 時,請確保使用同一帳號進行操作。
建立音色
上傳用於複刻的音頻,建立自訂音色。
-
URL
華北2(北京):
POST https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/audio/tts/customization
新加坡:
POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization
-
要求標頭
參數
類型
是否必須
說明
Authorization
string
支援
鑒權令牌,格式為
Bearer <your_api_key>,使用時,將“<your_api_key>”替換為實際的API Key。Content-Type
string
支援
請求體中傳輸的資料的媒體類型。固定為
application/json。 -
訊息體
包含所有請求參數的訊息體如下,對於可選欄位,在實際業務中可根據需求省略。
重要注意區分如下參數:
model:聲音複刻模型,固定為qwen-voice-enrollmenttarget_model:驅動音色的全模態模型,須和後續調用即時多模態介面時使用的全模態模型一致,否則合成會失敗
{
"model": "qwen-voice-enrollment",
"input": {
"action": "create",
"target_model": "qwen3.5-omni-plus-realtime",
"preferred_name": "guanyu",
"audio": {
"data": "https://xxx.wav"
},
"text": "可選項,填入audio.data對應的文本",
"language": "可選項,填入audio.data對應的語種,如zh"
},
"parameters": {
"voice_clone_mode": "normal",
"skip_audio_process": false
}
}
-
請求參數
參數 類型 預設值 是否必須 說明 model
string
支援
聲音複刻模型,固定為
qwen-voice-enrollment。action
string
支援
操作類型,固定為
create。target_model
string
支援
驅動音色的全模態模型:
- qwen3.8-omni-flash-realtime
- qwen3.5-omni-plus-realtime
- qwen3.5-omni-flash-realtime
- qwen3.5-omni-plus
- qwen3.5-omni-flash
必須與後續調用全模態介面時使用的模型一致,否則合成會失敗。
preferred_name
string
支援
為音色指定一個便於識別的名稱(僅允許數字、大小寫字母和底線,不超過16個字元)。建議選用與角色、情境相關的標識。
該關鍵字會在複刻的音色名中出現,例如關鍵字為“guanyu”,最終音色名為“qwen-omni-vc-guanyu-voice-20250812105009984-838b”
audio.data
string
支援
用於複刻的音頻(錄製時需遵循錄音操作指南,音頻需滿足音頻要求)。
可通過以下兩種方式提交音頻資料:
-
格式:
data:<mediatype>;base64,<data>-
<mediatype>:MIME類型- WAV:
audio/wav - MP3:
audio/mpeg - M4A:
audio/mp4
- WAV:
-
<data>:音頻轉成的Base64編碼的字串Base64編碼會增大體積,請控制原檔案大小,確保編碼後仍小於10MB
-
樣本:
data:audio/wav;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4LjI5LjEwMAAAAAAAAAAAAAAA//PAxABQ/BXRbMPe4IQAhl9點擊查看範例程式碼
import base64, pathlib # input.mp3為用於聲音複刻的本地音頻檔案,請替換為自己的音頻檔案路徑,確保其符合音頻要求 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為用於聲音複刻的本地音頻檔案,請替換為自己的音頻檔案路徑,確保其符合音頻要求 */ 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; } // 使用樣本 public static void main(String[] args) throws Exception { System.out.println(toDataUrl("input.mp3")); } }
-
-
音頻URL(推薦將音頻上傳至OSS)
- 檔案大小不超過10MB
- URL必須公網可訪問且無需鑒權
text
string
不支援
與
audio.data音頻內容相匹配的文本。傳入該參數後,服務端會對比音頻與該文本的差異,若差異過大,將返回Audio.PreprocessError。
language
string
不支援
audio.data音頻對應的語種。支援
zh(中文)、en(英文)、de(德語)、it(意大利語)、pt(葡萄牙語)、es(西班牙語)、ja(日語)、ko(韓語)、fr(法語)、ru(俄語)、th(泰語)、id(印尼語)、ar(阿拉伯語)、cs(捷克語)、da(丹麥語)、nl(荷蘭語)、fi(芬蘭語)、he(希伯來語)、hi(印地語)、is(冰島語)、ms(馬來語)、no(挪威語)、fa(波斯語)、pl(波蘭語)、sv(瑞典語)、tl(他加祿語)、tr(土耳其語)、ur(烏爾都語)、vi(越南語)。中文方言:
Dongbei(東北話)、Shannxi(陝西話)、Sichuan(四川話)、Henan(河南話)、Changsha(長沙話)、Tianjin(天津話)、Hangzhou(杭州話)、Liaoning(遼寧話)、Shenyang(瀋陽話)、Anshan(鞍山話)。若使用該參數,設定的語種要和實際用於複刻的音訊語種一致。
-
響應參數
點擊查看響應樣本
{ "output": { "voice": "yourVoice", "target_model": "qwen3.5-omni-plus-realtime" }, "usage": { "count": 1 }, "request_id": "yourRequestId" }需關注的參數如下:
參數
類型
說明
voice
string
音色名稱,可直接用於即時多模態介面的
voice參數。target_model
string
驅動音色的全模態模型:
qwen3.8-omni-flash-realtime
qwen3.5-omni-plus-realtime
qwen3.5-omni-flash-realtime
qwen3.5-omni-plus
qwen3.5-omni-flash
必須與後續調用全模態介面時使用的模型一致,否則合成會失敗。
request_id
string
Request ID。
count
integer
本次請求實際計入費用的“建立音色”次數,本次請求的費用為$ count × 0.01。
建立音色時,count恒為1。
-
範例程式碼
重要注意區分如下參數:
model:聲音複刻模型,固定為qwen-voice-enrollmenttarget_model:驅動音色的語音合成模型,須和後續調用語音合成介面時使用的語音合成模型一致,否則合成會失敗
cURL
若未將API Key配置到環境變數,需將樣本中的
$DASHSCOPE_API_KEY替換為實際的API Key。# ======= 重要提示 ======= # 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。 # 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key # === 執行時請刪除該注釋 === curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization \ -H "Authorization: Bearer $DASHSCOPE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "qwen-voice-enrollment", "input": { "action": "create", "target_model": "qwen3.5-omni-plus-realtime", "preferred_name": "guanyu", "audio": { "data": "https://xxx.wav" } } }'Python
import os import requests import base64, pathlib target_model = "qwen3.5-omni-plus-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 Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key # 若沒有配置環境變數,請用百鍊API Key將下行替換為:api_key = "sk-xxx" api_key = os.getenv("DASHSCOPE_API_KEY") # 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。 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" } # 發送 POST 請求 resp = requests.post(url, json=payload, headers=headers) if resp.status_code == 200: data = resp.json() voice = data["output"]["voice"] print(f"產生的 voice 參數為: {voice}") else: print("請求失敗:", resp.status_code, resp.text)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.file.*; import java.util.Base64; 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 = "input.mp3"; private static final String AUDIO_MIME_TYPE = "audio/mpeg"; public static String toDataUrl(String filePath) throws Exception { byte[] bytes = Files.readAllBytes(Paths.get(filePath)); String encoded = Base64.getEncoder().encodeToString(bytes); return "data:" + AUDIO_MIME_TYPE + ";base64," + encoded; } public static void main(String[] args) { // 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key // 若沒有配置環境變數,請用百鍊API Key將下行替換為:String apiKey = "sk-xxx" String apiKey = System.getenv("DASHSCOPE_API_KEY"); // 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。 String apiUrl = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization"; try { // 構造 JSON 請求體(注意內部的引號需轉義) String jsonPayload = "{" + "\"model\": \"qwen-voice-enrollment\"," // 不要修改該值 + "\"input\": {" + "\"action\": \"create\"," + "\"target_model\": \"" + TARGET_MODEL + "\"," + "\"preferred_name\": \"" + PREFERRED_NAME + "\"," + "\"audio\": {" + "\"data\": \"" + toDataUrl(AUDIO_FILE) + "\"" + "}" + "}" + "}"; 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(); InputStream is = (status >= 200 && status < 300) ? con.getInputStream() : con.getErrorStream(); StringBuilder response = new StringBuilder(); try (BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"))) { String line; while ((line = br.readLine()) != null) { response.append(line); } } System.out.println("HTTP 狀態代碼: " + status); System.out.println("返回內容: " + response.toString()); if (status == 200) { // 解析 JSON Gson gson = new Gson(); JsonObject jsonObj = gson.fromJson(response.toString(), JsonObject.class); String voice = jsonObj.getAsJsonObject("output").get("voice").getAsString(); System.out.println("產生的 voice 參數為: " + voice); } } catch (Exception e) { e.printStackTrace(); } } }
查詢音色列表
分頁查詢已建立的音色列表。
-
URL
華北2(北京):
POST https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/audio/tts/customization
新加坡:
POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization
-
要求標頭
參數
類型
是否必須
說明
Authorization
string
支援
鑒權令牌,格式為
Bearer <your_api_key>,使用時,將“<your_api_key>”替換為實際的API Key。Content-Type
string
支援
請求體中傳輸的資料的媒體類型。固定為
application/json。 -
訊息體
包含所有請求參數的訊息體如下,對於可選欄位,在實際業務中可根據需求省略。
重要
model:聲音複刻模型,固定為qwen-voice-enrollment,請勿修改。
{
"model": "qwen-voice-enrollment",
"input": {
"action": "list",
"page_size": 2,
"page_index": 0
}
}
-
請求參數
參數
類型
預設值
是否必須
說明
model
string
-
支援
聲音複刻模型,固定為
qwen-voice-enrollment。action
string
-
支援
操作類型,固定為
list。page_index
integer
0
不支援
頁碼索引。取值範圍:[0, 1000000]。
page_size
integer
10
不支援
每頁包含資料條數。取值範圍:[0, 1000000]。
-
響應參數
點擊查看響應樣本
{ "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" }需關注的參數如下:
參數
類型
說明
voice
string
音色名稱,可直接用於即時多模態介面的
voice參數。gmt_create
string
建立音色的時間。
target_model
string
驅動音色的全模態模型:
qwen3.8-omni-flash-realtime
qwen3.5-omni-plus-realtime
qwen3.5-omni-flash-realtime
qwen3.5-omni-plus
qwen3.5-omni-flash
必須與後續調用全模態介面時使用的模型一致,否則合成會失敗。
request_id
string
Request ID。
count
integer
本次請求實際計入費用的“建立音色”次數,本次請求的費用為$count × 0.01。
查詢音色不計費,因此
count恒為0。 -
範例程式碼
重要
model:聲音複刻模型,固定為qwen-voice-enrollment,請勿修改。cURL
若未將API Key配置到環境變數,需將樣本中的
$DASHSCOPE_API_KEY替換為實際的API Key。# ======= 重要提示 ======= # 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。 # 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key # === 執行時請刪除該注釋 === 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 Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key # 若沒有配置環境變數,請用百鍊API Key將下行替換為:api_key = "sk-xxx" api_key = os.getenv("DASHSCOPE_API_KEY") # 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。 url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization" payload = { "model": "qwen-voice-enrollment", # 不要修改該值 "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 狀態代碼:", response.status_code) if response.status_code == 200: data = response.json() voice_list = data["output"]["voice_list"] print("查詢到的音色列表:") for item in voice_list: print(f"- 音色: {item['voice']} 建立時間: {item['gmt_create']} 模型: {item['target_model']}") else: print("請求失敗:", 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 Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key // 若沒有配置環境變數,請用百鍊API Key將下行替換為:String apiKey = "sk-xxx" String apiKey = System.getenv("DASHSCOPE_API_KEY"); // 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。 String apiUrl = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization"; // JSON 請求體(舊版本 Java 無 """ 多行字串) String jsonPayload = "{" + "\"model\": \"qwen-voice-enrollment\"," // 不要修改該值 + "\"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); System.out.println("返回 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 查詢到的音色列表:"); 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("- 音色: %s 建立時間: %s 模型: %s\n", voice, gmtCreate, targetModel); } } } catch (Exception e) { e.printStackTrace(); } } }
刪除音色
刪除指定音色,釋放對應額度。
-
URL
華北2(北京):
POST https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/audio/tts/customization
新加坡:
POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization
-
要求標頭
參數
類型
是否必須
說明
Authorization
string
支援
鑒權令牌,格式為
Bearer <your_api_key>,使用時,將“<your_api_key>”替換為實際的API Key。Content-Type
string
支援
請求體中傳輸的資料的媒體類型。固定為
application/json。 -
訊息體
包含所有請求參數的訊息體如下,對於可選欄位,在實際業務中可根據需求省略:
重要
model:聲音複刻模型,固定為qwen-voice-enrollment,請勿修改。
{
"model": "qwen-voice-enrollment",
"input": {
"action": "delete",
"voice": "yourVoice"
}
}
-
請求參數
參數
類型
預設值
是否必須
說明
model
string
-
支援
聲音複刻模型,固定為
qwen-voice-enrollment。action
string
-
支援
操作類型,固定為
delete。voice
string
-
支援
待刪除的音色。
-
響應參數
點擊查看響應樣本
{ "usage": { "count": 0 }, "request_id": "yourRequestId" }需關注的參數如下:
參數
類型
說明
request_id
string
Request ID。
count
integer
本次請求實際計入費用的“建立音色”次數,本次請求的費用為$count × 0.01。
刪除音色不計費,因此
count恒為0。 -
範例程式碼
重要
model:聲音複刻模型,固定為qwen-voice-enrollment,請勿修改。cURL
若未將API Key配置到環境變數,需將樣本中的
$DASHSCOPE_API_KEY替換為實際的API Key。# ======= 重要提示 ======= # 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。 # 新加坡地區和北京地區的API Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key # === 執行時請刪除該注釋 === 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 Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key # 若沒有配置環境變數,請用百鍊API Key將下行替換為:api_key = "sk-xxx" api_key = os.getenv("DASHSCOPE_API_KEY") # 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。 url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization" voice_to_delete = "yourVoice" # 要刪除的音色(替換為真實值) payload = { "model": "qwen-voice-enrollment", # 不要修改該值 "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 狀態代碼:", response.status_code) if response.status_code == 200: data = response.json() request_id = data["request_id"] print(f"刪除成功") print(f"Request ID: {request_id}") else: print("請求失敗:", 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 Key不同。擷取API Key:https://www.alibabacloud.com/help/zh/model-studio/get-api-key // 若沒有配置環境變數,請用百鍊API Key將下行替換為:String apiKey = "sk-xxx" String apiKey = System.getenv("DASHSCOPE_API_KEY"); // 以下為新加坡地區URL,調用時請將{WorkspaceId}替換為真實的業務空間ID,各地區的URL不同。 String apiUrl = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization"; String voiceToDelete = "yourVoice"; // 要刪除的音色(替換為真實值) // 構造 JSON 請求體(字串拼接,相容 Java 8) String jsonPayload = "{" + "\"model\": \"qwen-voice-enrollment\"," // 不要修改該值 + "\"input\": {" + "\"action\": \"delete\"," + "\"voice\": \"" + voiceToDelete + "\"" + "}" + "}"; try { // 建立 POST 串連 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); System.out.println("返回 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("刪除成功"); System.out.println("Request ID: " + requestId); } } catch (Exception e) { e.printStackTrace(); } } }
對話使用
如何使用聲音複刻產生的專屬音色進行對話,請參見快速開始:複刻與使用音色。
音色配額與自動清理規則
-
總數限制:1000個音色/帳號
當前介面不提供音色數量查詢功能,可通過調用查詢音色列表介面自行統計音色數目
-
自動清理:若單個音色在過去一年內未被用於任何模型調用請求,系統將自動將其刪除
計費說明
聲音複刻和模型調用分開計費:
-
聲音複刻:建立音色按$0.01/個計費,建立失敗不計費
說明免費額度說明(僅中國站北京地區和國際站新加坡地區有免費額度):
- 阿里雲百鍊開通後90天內,可享1000次免費音色建立機會。
- 建立失敗不佔用免費次數。
- 刪除音色不會恢複免費次數。
- 免費額度用完或超出 90 天有效期間後,建立音色將按$0.01/個的價格計費。
-
使用複刻產生的專屬音色進行對話:按模型調用的 token 用量計費,詳情請參見模型調用計費
著作權與合法性
您需對所提供聲音的所有權及合法使用權負責,請注意閱讀服務合約。
錄音操作指南
錄音裝置
推薦使用具備降噪功能的麥克風,或在安靜環境下使用手機近距離錄音,以保證音源純淨。
錄音環境
場地
- 建議在 10 平方米以內的小型封閉空間錄音。
- 優先選擇配有吸音材料(如吸音棉、地毯、窗帘)的房間。
- 避免空曠大廳、會議室、教室等高混響場所。
噪音控制
- 室外噪音:關閉門窗,避免交通、施工等幹擾。
- 室內噪音:關閉空調、風扇、日光燈鎮流器等裝置;可通過手機錄製環境音並放大播放,識別潛在噪音源。
混響控制
- 混響會導致聲音模糊、清晰度下降。
- 減少光滑表面反射:拉上窗帘、開啟衣櫃門、鋪放衣物或床單覆蓋案頭/櫃面。
- 利用不規則物體(如書架、軟包傢具)實現聲波漫反射。
錄音文案
- 文案內容靈活,建議與目標應用情境一致(例如,若用於客服情境,文案應為客服對話風格),但必須確保不包含任何敏感或非法詞彙(如政治、色情、暴力相關內容),否則會導致複刻失敗。
- 避免短句(如“你好”、“是的”),應使用完整句子。
- 保持語義連貫,朗讀時避免頻繁停頓(建議至少連續 3 秒無中斷)。
- 可帶入目標情緒(如親切、嚴肅),但需避免過度誇張的戲劇化朗讀,保持語調自然。
操作建議
以普通臥室為例:
- 關閉門窗,隔絕外部噪音。
- 關閉空調、電扇等電器。
- 拉上窗帘,減少玻璃反射。
- 在案頭鋪放衣物或毛毯,降低案頭反射。
- 提前熟悉文案,設定角色語氣,自然演繹。
- 與錄音裝置保持約 10 厘米距離,避免噴麥或訊號過弱。
錯誤資訊
如遇報錯問題,請參見錯誤碼進行排查。