音声クローンは、モデルを使用して、トレーニングを必要とせずにオーディオサンプルから音声の特徴を抽出します。10〜20 秒のオーディオクリップを提供することで、元の音声に非常に似た、自然な響きのカスタム音声を生成できます。音声クローンと音声合成は、連続した 2 つのステップです。このドキュメントでは、音声クローンの API パラメーターと詳細について説明します。音声合成については、「リアルタイム音声合成 - Qwen」をご参照ください。
ユーザーガイド:モデルの概要と選択の提案については、「リアルタイム音声合成 - Qwen」をご参照ください。
音声要件
優れたクローン結果を得るには、高品質の入力音声が必要です。
項目 | 要件 |
サポート形式 | WAV (16-bit)、MP3、M4A |
音声の長さ | 推奨:10〜20 秒。最大長は 60 秒です。 |
ファイルサイズ | 10 MB 未満 |
サンプリングレート | 24 kHz 以上 |
サウンドチャンネル | モノラル |
コンテンツ | 音声には、背景音のない、3 秒以上の連続したクリアな読み上げが含まれている必要があります。音声の残りの部分には、短い休止 (2 秒以下) のみを含めることができます。コアとなる読み上げコンテンツの品質を確保するため、オーディオクリップ全体に BGM、ノイズ、または他の音声が含まれていないようにしてください。入力には通常の話し声の音声を使用してください。クローンされた音声の正確性と実用性を確保するため、歌や歌唱の音声をアップロードしないでください。 |
言語 | 中国語 (zh)、英語 (en)、ドイツ語 (de)、イタリア語 (it)、ポルトガル語 (pt)、スペイン語 (es)、日本語 (ja)、韓国語 (ko)、フランス語 (fr)、ロシア語 (ru) |
はじめに:クローンから合成まで
1. ワークフロー
音声クローンと音声合成は、2 つの異なる関連ステップであり、「最初に作成し、次に使用する」というワークフローに従います。
2. モデル構成と事前準備
適切なモデルを選択し、必要な準備を完了します。
モデル構成
音声をクローンする際は、次の 2 つのモデルを指定します。
音声クローンモデル:qwen-voice-enrollment
音声とともに使用する音声合成モデル:
qwen3-tts-vc-realtime-2026-01-15
qwen3-tts-vc-realtime-2025-11-27
事前準備
API キーの取得:API キーを取得します。セキュリティのため、API キーを環境変数として設定してください。
SDK のインストール:最新バージョンの DashScope SDK がインストールされていることを確認してください。
クローン用音声の準備:音声は音声要件を満たす必要があります。
3. エンドツーエンドの例
以下の例は、カスタムのクローン音声を使用して音声合成を行う方法を示しています。合成されたオーディオ出力は、ソース音声と非常に似ています。
重要な原則:音声クローン時に指定された
target_modelは、後続の音声合成 API 呼び出しで使用されるモデルと一致する必要があります。一致しない場合、合成は失敗します。この例では、音声クローンにローカルオーディオファイル
voice.mp3を使用します。コードを実行する際は、このファイルを独自のオーディオファイルに置き換えてください。
Python
# coding=utf-8
# pyaudio のインストール手順:
# APPLE Mac OS X
# brew install portaudio
# pip install pyaudio
# Debian/Ubuntu
# sudo apt-get install python-pyaudio python3-pyaudio
# または
# pip install pyaudio
# CentOS
# sudo yum install -y portaudio portaudio-devel && pip install pyaudio
# Microsoft Windows
# python -m pip install pyaudio
import pyaudio
import os
import requests
import base64
import pathlib
import threading
import time
import dashscope # DashScope Python SDK のバージョンは 1.23.9 以降である必要があります。
from dashscope.audio.qwen_tts_realtime import QwenTtsRealtime, QwenTtsRealtimeCallback, AudioFormat
# ======= 定数設定 =======
DEFAULT_TARGET_MODEL = "qwen3-tts-vc-realtime-2026-01-15" # 音声クローンと音声合成には同じモデルを使用する必要があります。
DEFAULT_PREFERRED_NAME = "guanyu"
DEFAULT_AUDIO_MIME_TYPE = "audio/mpeg"
VOICE_FILE_PATH = "voice.mp3" # 音声クローン用のローカルオーディオファイルの相対パス。
TEXT_TO_SYNTHESIZE = [
'そうでしょう?こういうスーパー、本当に好きなんです',
'特に新年の時期は。',
'スーパーに行くと',
'なんだか',
'すごく、すごく幸せな気分になります!',
'たくさん買いたくなっちゃいます!'
]
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 キーは異なります。API キーを取得するには、https://www.alibabacloud.com/help/ja/model-studio/get-api-key/ をご参照ください。
# 環境変数を設定していない場合は、次の行を実際の Model Studio API キーに置き換えてください: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 はシンガポールリージョン用です。北京リージョンのモデルを使用する場合は、URL を https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization に置き換えてください。
url = "https://dashscope-intl.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"音声の作成に失敗しました:{resp.status_code}, {resp.text}")
try:
return resp.json()["output"]["voice"]
except (KeyError, ValueError) as e:
raise RuntimeError(f"音声レスポンスの解析に失敗しました:{e}")
def init_dashscope_api_key():
"""
DashScope SDK の API キーを初期化します。
"""
# シンガポールリージョンと北京リージョンの API キーは異なります。API キーを取得するには、https://www.alibabacloud.com/help/ja/model-studio/get-api-key/ をご参照ください。
# 環境変数を設定していない場合は、次の行を実際の Model Studio API キーに置き換えてください:dashscope.api_key = "sk-xxx"
dashscope.api_key = os.getenv("DASHSCOPE_API_KEY")
# ======= コールバッククラス =======
class MyCallback(QwenTtsRealtimeCallback):
"""
カスタム TTS ストリーミングコールバック。
"""
def __init__(self):
self.complete_event = threading.Event()
self._player = pyaudio.PyAudio()
self._stream = self._player.open(
format=pyaudio.paInt16, channels=1, rate=24000, output=True
)
def on_open(self) -> None:
print('[TTS] 接続が確立されました。')
def on_close(self, close_status_code, close_msg) -> None:
self._stream.stop_stream()
self._stream.close()
self._player.terminate()
print(f'[TTS] 接続が閉じられました code={close_status_code}, msg={close_msg}')
def on_event(self, response: dict) -> None:
try:
event_type = response.get('type', '')
if event_type == 'session.created':
print(f'[TTS] セッションが開始されました:{response["session"]["id"]}')
elif event_type == 'response.audio.delta':
audio_data = base64.b64decode(response['delta'])
self._stream.write(audio_data)
elif event_type == 'response.done':
print(f'[TTS] レスポンスが完了しました、レスポンス ID:{qwen_tts_realtime.get_last_response_id()}')
elif event_type == 'session.finished':
print('[TTS] セッションが終了しました。')
self.complete_event.set()
except Exception as e:
print(f'[エラー] コールバックイベントの処理に失敗しました:{e}')
def wait_for_finished(self):
self.complete_event.wait()
# ======= メイン実行ロジック =======
if __name__ == '__main__':
init_dashscope_api_key()
print('[システム] Qwen TTS Realtime を初期化しています ...')
callback = MyCallback()
qwen_tts_realtime = QwenTtsRealtime(
model=DEFAULT_TARGET_MODEL,
callback=callback,
# 以下の URL はシンガポールリージョン用です。北京リージョンのモデルを使用する場合は、URL を wss://dashscope.aliyuncs.com/api-ws/v1/realtime に置き換えてください。
url='wss://dashscope-intl.aliyuncs.com/api-ws/v1/realtime'
)
qwen_tts_realtime.connect()
qwen_tts_realtime.update_session(
voice=create_voice(VOICE_FILE_PATH), # voice パラメーターを、クローンで生成されたカスタム音声に置き換えます。
response_format=AudioFormat.PCM_24000HZ_MONO_16BIT,
mode='server_commit'
)
for text_chunk in TEXT_TO_SYNTHESIZE:
print(f'[テキスト送信]:{text_chunk}')
qwen_tts_realtime.append_text(text_chunk)
time.sleep(0.1)
qwen_tts_realtime.finish()
callback.wait_for_finished()
print(f'[メトリック] session_id={qwen_tts_realtime.get_session_id()}, '
f'first_audio_delay={qwen_tts_realtime.get_first_audio_delay()}s')
Java
Gson 依存関係をインポートします。Maven または Gradle を使用している場合は、次のように依存関係を追加します。
Maven
pom.xml ファイルに次の内容を追加します。
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.13.1</version>
</dependency>Gradle
build.gradle ファイルに次の内容を追加します。
// https://mvnrepository.com/artifact/com.google.code.gson/gson
implementation("com.google.code.gson:gson:2.13.1")import com.alibaba.dashscope.audio.qwen_tts_realtime.*;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import javax.sound.sampled.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Queue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
public class Main {
// ===== 定数定義 =====
// 音声クローンと音声合成には同じモデルを使用する必要があります。
private static final String TARGET_MODEL = "qwen3-tts-vc-realtime-2026-01-15";
private static final String PREFERRED_NAME = "guanyu";
// 音声クローン用のローカルオーディオファイルの相対パス。
private static final String AUDIO_FILE = "voice.mp3";
private static final String AUDIO_MIME_TYPE = "audio/mpeg";
private static String[] textToSynthesize = {
"そうでしょう?こういうスーパー、本当に好きなんです",
"特に新年の時期は。",
"スーパーに行くと",
"なんだか",
"すごく、すごく幸せな気分になります!",
"たくさん買いたくなっちゃいます!"
};
// データ 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 を呼び出して音声を作成します。
public static String createVoice() throws Exception {
// シンガポールリージョンと北京リージョンの API キーは異なります。API キーを取得するには、https://www.alibabacloud.com/help/ja/model-studio/get-api-key/ をご参照ください。
// 環境変数を設定していない場合は、次の行を実際の Model Studio API キーに置き換えてください: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) + "\""
+ "}"
+ "}"
+ "}";
HttpURLConnection con = (HttpURLConnection) new URL("https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customization").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();
System.out.println("HTTP ステータスコード: " + status);
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);
}
System.out.println("レスポンス内容: " + response);
if (status == 200) {
JsonObject jsonObj = new Gson().fromJson(response.toString(), JsonObject.class);
return jsonObj.getAsJsonObject("output").get("voice").getAsString();
}
throw new IOException("音声の作成に失敗しました: " + status + " - " + response);
}
}
// リアルタイム PCM プレーヤークラス
public static class RealtimePcmPlayer {
private int sampleRate;
private SourceDataLine line;
private AudioFormat audioFormat;
private Thread decoderThread;
private Thread playerThread;
private AtomicBoolean stopped = new AtomicBoolean(false);
private Queue<String> b64AudioBuffer = new ConcurrentLinkedQueue<>();
private Queue<byte[]> RawAudioBuffer = new ConcurrentLinkedQueue<>();
// コンストラクターはオーディオフォーマットとオーディオラインを初期化します。
public RealtimePcmPlayer(int sampleRate) throws LineUnavailableException {
this.sampleRate = sampleRate;
this.audioFormat = new AudioFormat(this.sampleRate, 16, 1, true, false);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
line = (SourceDataLine) AudioSystem.getLine(info);
line.open(audioFormat);
line.start();
decoderThread = new Thread(new Runnable() {
@Override
public void run() {
while (!stopped.get()) {
String b64Audio = b64AudioBuffer.poll();
if (b64Audio != null) {
byte[] rawAudio = Base64.getDecoder().decode(b64Audio);
RawAudioBuffer.add(rawAudio);
} else {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
});
playerThread = new Thread(new Runnable() {
@Override
public void run() {
while (!stopped.get()) {
byte[] rawAudio = RawAudioBuffer.poll();
if (rawAudio != null) {
try {
playChunk(rawAudio);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} else {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
});
decoderThread.start();
playerThread.start();
}
// オーディオチャンクを再生し、再生が完了するまでブロックします。
private void playChunk(byte[] chunk) throws IOException, InterruptedException {
if (chunk == null || chunk.length == 0) return;
int bytesWritten = 0;
while (bytesWritten < chunk.length) {
bytesWritten += line.write(chunk, bytesWritten, chunk.length - bytesWritten);
}
int audioLength = chunk.length / (this.sampleRate*2/1000);
// バッファー内の音声が再生し終わるのを待ちます。
Thread.sleep(audioLength - 10);
}
public void write(String b64Audio) {
b64AudioBuffer.add(b64Audio);
}
public void cancel() {
b64AudioBuffer.clear();
RawAudioBuffer.clear();
}
public void waitForComplete() throws InterruptedException {
while (!b64AudioBuffer.isEmpty() || !RawAudioBuffer.isEmpty()) {
Thread.sleep(100);
}
line.drain();
}
public void shutdown() throws InterruptedException {
stopped.set(true);
decoderThread.join();
playerThread.join();
if (line != null && line.isRunning()) {
line.drain();
line.close();
}
}
}
public static void main(String[] args) throws Exception {
QwenTtsRealtimeParam param = QwenTtsRealtimeParam.builder()
.model(TARGET_MODEL)
// 以下の URL はシンガポールリージョン用です。北京リージョンのモデルを使用する場合は、URL を wss://dashscope.aliyuncs.com/api-ws/v1/realtime に置き換えてください。
.url("wss://dashscope-intl.aliyuncs.com/api-ws/v1/realtime")
// シンガポールリージョンと北京リージョンの API キーは異なります。API キーを取得するには、https://www.alibabacloud.com/help/ja/model-studio/get-api-key/ をご参照ください。
// 環境変数を設定していない場合は、次の行を実際の Model Studio API キーに置き換えてください:.apikey("sk-xxx")
.apikey(System.getenv("DASHSCOPE_API_KEY"))
.build();
AtomicReference<CountDownLatch> completeLatch = new AtomicReference<>(new CountDownLatch(1));
final AtomicReference<QwenTtsRealtime> qwenTtsRef = new AtomicReference<>(null);
// リアルタイムオーディオプレーヤーインスタンスを作成します。
RealtimePcmPlayer audioPlayer = new RealtimePcmPlayer(24000);
QwenTtsRealtime qwenTtsRealtime = new QwenTtsRealtime(param, new QwenTtsRealtimeCallback() {
@Override
public void onOpen() {
// 接続確立を処理します。
}
@Override
public void onEvent(JsonObject message) {
String type = message.get("type").getAsString();
switch(type) {
case "session.created":
// セッション作成を処理します。
break;
case "response.audio.delta":
String recvAudioB64 = message.get("delta").getAsString();
// オーディオをリアルタイムで再生します。
audioPlayer.write(recvAudioB64);
break;
case "response.done":
// レスポンス完了を処理します。
break;
case "session.finished":
// セッション終了を処理します。
completeLatch.get().countDown();
default:
break;
}
}
@Override
public void onClose(int code, String reason) {
// 接続終了を処理します。
}
});
qwenTtsRef.set(qwenTtsRealtime);
try {
qwenTtsRealtime.connect();
} catch (NoApiKeyException e) {
throw new RuntimeException(e);
}
QwenTtsRealtimeConfig config = QwenTtsRealtimeConfig.builder()
.voice(createVoice()) // voice パラメーターを、クローンで生成されたカスタム音声に置き換えます。
.responseFormat(QwenTtsRealtimeAudioFormat.PCM_24000HZ_MONO_16BIT)
.mode("server_commit")
.build();
qwenTtsRealtime.updateSession(config);
for (String text:textToSynthesize) {
qwenTtsRealtime.appendText(text);
Thread.sleep(100);
}
qwenTtsRealtime.finish();
completeLatch.get().await();
// 音声の再生が完了するのを待ってから、プレーヤーをシャットダウンします。
audioPlayer.waitForComplete();
audioPlayer.shutdown();
System.exit(0);
}
}API リファレンス
異なる API を使用する場合、すべての操作で同じアカウントを使用していることを確認してください。
音声の作成
オーディオファイルをアップロードして、カスタムのクローン音声を作成します。
URL
中国本土:
POST https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization国際:
POST https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customizationリクエストヘッダー
パラメーター
タイプ
必須
説明
Authorization
string
認証トークン。フォーマットは
Bearer <your_api_key>です。「<your_api_key>」を実際の API キーに置き換えてください。Content-Type
string
リクエストボディ内のデータのメディアタイプ。値は
application/jsonに固定されています。リクエストボディ
以下のリクエストボディには、すべてのリクエストパラメーターが含まれています。必要に応じて、オプションのパラメーターを省略できます。
重要以下のパラメーターの違いにご注意ください:
model:音声クローンモデル。値はqwen-voice-enrollmentに固定されています。target_model:クローンされた音声を使用する音声合成モデル。このパラメーターは、後続の音声合成 API 呼び出しで使用されるモデルと一致する必要があります。一致しない場合、合成操作は失敗します。
{ "model": "qwen-voice-enrollment", "input": { "action": "create", "target_model": "qwen3-tts-vc-realtime-2026-01-15", "preferred_name": "guanyu", "audio": { "data": "https://xxx.wav" }, "text": "オプション。audio.data の音声に対応するテキスト。", "language": "オプション。audio.data の音声の言語、例:zh。" } }リクエストパラメーター
パラメーター
タイプ
デフォルト
必須
説明
model
string
-
音声クローンモデル。値は
qwen-voice-enrollmentに固定されています。action
string
-
操作のタイプ。値は
createに固定されています。target_model
string
-
音声を駆動する音声合成モデル。サポートされているモデル:
qwen3-tts-vc-realtime-2026-01-15
qwen3-tts-vc-realtime-2025-11-27
このパラメーターは、後で音声合成 API を呼び出す際に使用する音声合成モデルと一致する必要があります。一致しない場合、合成は失敗します。
preferred_name
string
-
音声の識別可能な名前。名前には数字、文字、アンダースコア (_) のみを含めることができ、長さは 16 文字以下でなければなりません。ロールやシナリオに関連する識別子を使用することを推奨します。
このキーワードはクローンされた音声名に表示されます。例えば、キーワードが "guanyu" の場合、最終的な音声名は "qwen-tts-vc-guanyu-voice-20250812105009984-838b" となります。
audio.data
string
-
クローン用の音声。音声を録音する際は、録音ガイドに従ってください。音声は音声要件を満たす必要があります。
音声データは、次の 2 つの方法のいずれかで送信できます。
フォーマット:
data:<mediatype>;base64,<data><mediatype>:MIME (Multipurpose Internet Mail Extensions) タイプWAV:
audio/wavMP3:
audio/mpegM4A:
audio/mp4
<data>:Base64 エンコードされた文字列としての音声データ。Base64 エンコーディングはファイルサイズを増加させます。エンコードされたファイルが 10 MB 未満になるように、ソースファイルのサイズを制御してください。
例:
data:audio/wav;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4LjI5LjEwMAAAAAAAAAAAAAAA//PAxABQ/BXRbMPe4IQAhl9
オーディオ URL。音声を OSS にアップロードすることを推奨します。
ファイルサイズは 10 MB を超えることはできません。
URL はパブリックネットワークからアクセス可能で、認証を必要としない必要があります。
text
string
-
audio.dataの音声コンテンツに一致するテキスト。このパラメーターを提供すると、サーバーは音声とテキストを比較します。差が大きすぎる場合、Audio.PreprocessError を返します。
language
string
-
audio.dataの音声の言語。zh(中国語)、en(英語)、de(ドイツ語)、it(イタリア語)、pt(ポルトガル語)、es(スペイン語)、ja(日本語)、ko(韓国語)、fr(フランス語)、ru(ロシア語) をサポートします。このパラメーターを使用する場合、指定された言語はクローンに使用される音声の言語と一致する必要があります。
レスポンスパラメーター
パラメーターは次のとおりです:
パラメーター
タイプ
説明
voice
string
音声の名前。この名前は、音声合成 API の
voiceパラメーターとして直接使用できます。target_model
string
音声を駆動する音声合成モデル。サポートされているモデル:
qwen3-tts-vc-realtime-2026-01-15
qwen3-tts-vc-realtime-2025-11-27
このパラメーターは、後で音声合成 API を呼び出す際に使用する音声合成モデルと一致する必要があります。一致しない場合、合成は失敗します。
request_id
string
リクエスト ID。
count
integer
このリクエストで課金される「音声作成」操作の数です。このリクエストのコストは $
です。 音声を作成する場合、count の値は常に 1 です。
サンプルコード
重要以下のパラメーターの違いにご注意ください:
model:音声クローンモデル。値はqwen-voice-enrollmentに固定されています。target_model:クローンされた音声を使用する音声合成モデル。このパラメーターは、後続の音声合成 API 呼び出しで使用されるモデルと一致する必要があります。一致しない場合、合成操作は失敗します。
cURL
API キーを環境変数として設定していない場合は、例の
$DASHSCOPE_API_KEYを実際の API キーに置き換えてください。https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customization# ======= 重要 ======= # 以下はシンガポールリージョンの URL です。中国 (北京) リージョンのモデルを使用する場合は、URL を https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization に置き換えてください。 # シンガポールリージョンと中国 (北京) リージョンの API キーは異なります。API キーの取得:https://www.alibabacloud.com/help/ja/model-studio/get-an-api-key # === コマンドを実行する前にこのコメントを削除してください。=== curl -X POST https://dashscope-intl.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-tts-vc-realtime-2026-01-15", "preferred_name": "guanyu", "audio": { "data": "https://xxx.wav" } } }'Python
import os import requests import base64, pathlib target_model = "qwen3-tts-vc-realtime-2026-01-15" 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 キーは異なります。API キーの取得:https://www.alibabacloud.com/help/ja/model-studio/get-an-api-key # 環境変数を設定していない場合は、次の行を実際の Model Studio API キーに置き換えてください:api_key = "sk-xxx" api_key = os.getenv("DASHSCOPE_API_KEY") # 以下はシンガポールリージョンの URL です。中国 (北京) リージョンのモデルを使用する場合は、URL を https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization に置き換えてください。 url = "https://dashscope-intl.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-tts-vc-realtime-2026-01-15"; 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 キーは異なります。API キーの取得:https://www.alibabacloud.com/help/ja/model-studio/get-an-api-key // 環境変数を設定していない場合は、次の行を実際の Model Studio API キーに置き換えてください:String apiKey = "sk-xxx" String apiKey = System.getenv("DASHSCOPE_API_KEY"); // 以下はシンガポールリージョンの URL です。中国 (北京) リージョンのモデルを使用する場合は、URL を https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization に置き換えてください。 String apiUrl = "https://dashscope-intl.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
中国本土:
POST https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization国際:
POST https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customizationリクエストヘッダー
パラメーター
タイプ
必須
説明
Authorization
string
認証トークン。フォーマットは
Bearer <your_api_key>です。「<your_api_key>」を実際の API キーに置き換えてください。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
1 ページあたりのエントリ数。有効値:[0, 1000000]。
レスポンスパラメーター
以下のレスポンスパラメーターが重要です:
パラメーター
タイプ
説明
voice
string
音声の名前。この名前は、音声合成 API の
voiceパラメーターとして直接使用できます。gmt_create
string
音声が作成された時刻。
target_model
string
音声を駆動する音声合成モデル。サポートされているモデル:
qwen3-tts-vc-realtime-2026-01-15
qwen3-tts-vc-realtime-2025-11-27
このパラメーターは、後で音声合成 API を呼び出す際に使用する音声合成モデルと一致する必要があります。一致しない場合、合成は失敗します。
request_id
string
リクエスト ID。
count
integer
このリクエストで課金される「音声作成」操作の数です。このリクエストのコストは $
です。 音声のクエリは課金されません。したがって、
countの値は常に 0 です。サンプルコード
重要model:音声クローンモデル。値はqwen-voice-enrollmentに固定されています。この値は変更しないでください。cURL
API キーを環境変数として設定していない場合は、例の
$DASHSCOPE_API_KEYを実際の API キーに置き換えてください。# ======= 重要 ======= # 以下はシンガポールリージョンの URL です。中国 (北京) リージョンのモデルを使用する場合は、URL を https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization に置き換えてください。 # シンガポールリージョンと中国 (北京) リージョンの API キーは異なります。API キーの取得:https://www.alibabacloud.com/help/ja/model-studio/get-an-api-key # === コマンドを実行する前にこのコメントを削除してください。=== curl --location --request POST 'https://dashscope-intl.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 キーは異なります。API キーの取得:https://www.alibabacloud.com/help/ja/model-studio/get-an-api-key # 環境変数を設定していない場合は、次の行を実際の Model Studio API キーに置き換えてください:api_key = "sk-xxx" api_key = os.getenv("DASHSCOPE_API_KEY") # 以下はシンガポールリージョンの URL です。中国 (北京) リージョンのモデルを使用する場合は、URL を https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization に置き換えてください。 url = "https://dashscope-intl.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 キーは異なります。API キーの取得:https://www.alibabacloud.com/help/ja/model-studio/get-an-api-key // 環境変数を設定していない場合は、次の行を実際の Model Studio API キーに置き換えてください:String apiKey = "sk-xxx" String apiKey = System.getenv("DASHSCOPE_API_KEY"); // 以下はシンガポールリージョンの URL です。中国 (北京) リージョンのモデルを使用する場合は、URL を https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization に置き換えてください。 String apiUrl = "https://dashscope-intl.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
中国本土:
POST https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization国際:
POST https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customizationリクエストヘッダー
パラメーター
タイプ
必須
説明
Authorization
string
認証トークン。フォーマットは
Bearer <your_api_key>です。「<your_api_key>」を実際の API キーに置き換えてください。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
-
削除する音声。
レスポンスパラメーター
以下のレスポンスパラメーターが重要です:
パラメーター
タイプ
説明
request_id
string
リクエスト ID。
count
integer
このリクエストで課金される「音声作成」操作の数です。このリクエストのコストは $
です。 音声の削除は課金されません。したがって、
countの値は常に 0 です。サンプルコード
重要model:音声クローンモデル。値はqwen-voice-enrollmentに固定されています。この値は変更しないでください。cURL
API キーを環境変数として設定していない場合は、例の
$DASHSCOPE_API_KEYを実際の API キーに置き換えてください。# ======= 重要 ======= # 以下はシンガポールリージョンの URL です。中国 (北京) リージョンのモデルを使用する場合は、URL を https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization に置き換えてください。 # シンガポールリージョンと中国 (北京) リージョンの API キーは異なります。API キーの取得:https://www.alibabacloud.com/help/ja/model-studio/get-an-api-key # === コマンドを実行する前にこのコメントを削除してください。=== curl --location --request POST 'https://dashscope-intl.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 キーは異なります。API キーの取得:https://www.alibabacloud.com/help/ja/model-studio/get-an-api-key # 環境変数を設定していない場合は、次の行を実際の Model Studio API キーに置き換えてください:api_key = "sk-xxx" api_key = os.getenv("DASHSCOPE_API_KEY") # 以下はシンガポールリージョンの URL です。中国 (北京) リージョンのモデルを使用する場合は、URL を https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization に置き換えてください。 url = "https://dashscope-intl.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"リクエスト 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 キーは異なります。API キーの取得:https://www.alibabacloud.com/help/ja/model-studio/get-an-api-key // 環境変数を設定していない場合は、次の行を実際の Model Studio API キーに置き換えてください:String apiKey = "sk-xxx" String apiKey = System.getenv("DASHSCOPE_API_KEY"); // 以下はシンガポールリージョンの URL です。中国 (北京) リージョンのモデルを使用する場合は、URL を https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization に置き換えてください。 String apiUrl = "https://dashscope-intl.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("リクエスト ID: " + requestId); } } catch (Exception e) { e.printStackTrace(); } } }
音声合成
音声クローンによって生成されたカスタム音声を使用してパーソナライズされた音声を合成する方法の詳細については、「はじめに:クローンから合成まで」をご参照ください。
qwen3-tts-vc-realtime-2026-01-15 などの音声クローン用の音声合成モデルは、専用モデルです。これらのモデルは、クローンによって作成されたカスタム音声のみをサポートし、Chelsie、Serena、Ethan、Cherry などの公開プリセット音声はサポートしていません。
音声クォータと自動クリーンアップルール
合計制限:アカウントごとに 1,000 音声
音声の総数は API から返されません。音声リストのクエリ操作を呼び出して、音声数をカウントできます。
自動クリーンアップ:過去 1 年間に音声合成リクエストで使用されなかった音声は、システムによって自動的に削除されます。
課金
音声クローンと音声合成は別々に課金されます:
音声クローン:音声作成は、$0.01/音声で課金されます。作成に失敗した場合は課金されません。
説明無料クォータ (Alibaba Cloud 中国サイト (www.aliyun.com) の北京リージョン、および Alibaba Cloud 国際サイト (www.alibabacloud.com) のシンガポールリージョンでのみ利用可能):
Alibaba Cloud Model Studio を有効化してから 90 日間有効な、1,000 回の音声作成の無料クォータが付与されます。
作成に失敗しても、無料クォータは消費されません。
音声を削除しても、無料クォータは復元されません。
無料クォータを使い切るか、有効期限が切れた後、音声作成は$0.01/音声で課金されます。
音声クローンで作成されたカスタム音声を使用する音声合成は、テキスト文字数に基づいて従量課金制で課金されます。詳細については、「リアルタイム音声合成 - Qwen」をご参照ください。
著作権と合法性
提供するすべての音声の所有権とその合法的な使用について、お客様が責任を負うものとします。利用規約をお読みください。
録音ガイド
録音機器
ノイズ除去機能付きのマイクを使用するか、静かな環境で携帯電話を近距離で録音して、クリーンな音源を確保してください。
録音環境
場所
10 平方メートル未満の小さな密閉空間で録音してください。
吸音材 (音響フォーム、カーペット、カーテンなど) のある部屋を選んでください。
残響の大きい、広く開放的なホール、会議室、教室は避けてください。
ノイズコントロール
屋外の騒音:ドアや窓を閉めて、交通や建設などの外部からの騒音を遮断してください。
屋内の騒音:エアコン、扇風機、蛍光灯の安定器、その他の機器の電源を切ってください。携帯電話で周囲の音を録音し、大音量で再生して、潜在的な騒音源を特定できます。
残響コントロール
残響は音をぼやけさせ、明瞭度を低下させる可能性があります。
滑らかな表面からの反射を減らす:カーテンを引く、クローゼットのドアを開ける、机やキャビネットを服やシーツで覆う。
本棚や布張りの家具など、不規則な物体を使用して音波を拡散させてください。
録音スクリプト
ターゲットのアプリケーションシナリオに合わせてスクリプトをカスタマイズしてください。例えば、カスタマーサービスのシナリオ用のスクリプトは、会話形式であるべきです。政治、ポルノ、暴力に関連するような、機密情報や違法な単語を含めないでください。含めると、クローンプロセスが失敗します。
「こんにちは」や「はい」などの短いフレーズは避け、完全な文章を使用してください。
スクリプトをスムーズに、一貫して読んでください。頻繁な休止を避け、少なくとも 3 秒間は中断せずに話してください。
親しみやすさや真剣さなど、ターゲットの感情を伝えてください。過度に劇的な読み方を避け、自然なトーンを保ってください。
操作の提案
例えば、標準的な寝室を考えます:
ドアと窓を閉めて、外部の騒音を遮断します。
エアコン、扇風機、その他の家電製品の電源を切ります。
カーテンを引いて、ガラスからの反射を減らします。
机の上に服や毛布を置いて、表面からの反射を減らします。
事前にスクリプトに慣れておきます。キャラクターのトーンを設定し、自然な声で読みます。
破裂音や信号の弱さを避けるため、録音デバイスから約 10 cm 離れてください。
エラーメッセージ
エラーが発生した場合は、「エラーメッセージ」でトラブルシューティング情報をご参照ください。