すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud Model Studio:音声デザイン(Qwen)API リファレンス

最終更新日:Feb 12, 2026

音声デザインは、テキストによる説明からカスタム音声を生成します。複数の言語および多次元的な音声特徴定義をサポートしており、CM のナレーション、キャラクター音声の作成、オーディオコンテンツ制作などのアプリケーションに適しています。音声デザインと音声合成は、順次実行される 2 つのステップです。本ドキュメントでは、音声デザインのパラメーターおよびインターフェイスの詳細について説明します。音声合成については、「リアルタイム音声合成 - Qwen」または「音声合成 - Qwen」をご参照ください。

ユーザーガイド:モデルの概要および選択推奨事項については、「リアルタイム音声合成 - Qwen」または「音声合成 - Qwen」をご参照ください。

対応言語

音声デザインサービスは、以下の言語で音声の作成および音声合成をサポートしています:中国語 (zh)、英語 (en)、ドイツ語 (de)、イタリア語 (it)、ポルトガル語 (pt)、スペイン語 (es)、日本語 (ja)、韓国語 (ko)、フランス語 (fr)、ロシア語 (ru)

音声説明文の作成

要件および制限事項

voice_prompt(音声説明文)を作成する際は、以下の技術的制約に従ってください:

  • 長さ制限: voice_prompt の内容は 2048 文字を超えてはなりません。

  • 対応言語: 説明文の記述には、中国語および英語のみがサポートされます。

基本原則

高品質な音声説明文(voice_prompt)は、理想の音声を作成する上で鍵となる要素です。これは音声デザインの設計図であり、モデルが特定の特徴を持つ音声を生成するよう直接指示する役割を果たします。

以下の基本原則に従って音声を説明してください:

  1. 曖昧ではなく、具体的である: 「低音」「クリア」「早口」など、具体的な音声特性を表す単語を使用してください。「良い」「普通」などの主観的かつ情報量の少ない用語は避けてください。

  2. 単一のディメンションではなく、複数のディメンションを活用する: 良質な説明文は、性別、年齢、感情など、複数のディメンションを組み合わせたものになります(以下に記載)。単一のディメンション(例:「女性の声」)だけでは、個性的な音声を生成するには不十分です。

  3. 主観ではなく、客観的である: 音声の物理的・知覚的な特徴に焦点を当て、個人的な好みを述べないでください。たとえば、「高音でエネルギッシュ」ではなく、「私の好きな音声」という表現は避けます。

  4. 模倣ではなく、独自性を重んじる: 有名人や俳優など特定の人物を模倣するよう依頼せず、音声の特性そのものを説明してください。このような依頼は著作権上のリスクを伴い、モデルではサポートされていません。

  5. 冗長ではなく、簡潔である: すべての単語に意味があり、目的があることを確認してください。「非常に、非常に素晴らしい声」のように同義語や無意味な強調語を重ねることは避けてください。

説明のディメンション

ディメンション

性別

男性、女性、中立

年齢

子供(5~12 歳)、ティーンエイジャー(13~18 歳)、若年成人(19~35 歳)、中年(36~55 歳)、高齢者(55 歳以上)

ピッチ

高、中、低、高音、低音

話速

速い、中程度、遅い、早口、ゆっくり

感情

明るい、落ち着いた、優しい、真剣な、生き生きとした、冷静な、癒し系

特性

磁石のような、クリア、かすれた、まろやかな、甘い、豊かな、力強い

用途

ニュース放送、CM ナレーション、オーディオブック、アニメーションキャラクター、音声アシスタント、ドキュメンタリー解説

比較例

✅ 推奨

  • 「ファッション製品の紹介に適した、若々しく生き生きとした女性の声で、話速が速く、明確な上がり調子が特徴です。」

    分析: 年齢、性格、話速、イントネーションを組み合わせており、適用シーンも明示しているため、バランスの取れたプロファイルになっています。

  • 「ニュース放送やドキュメンタリー解説に適した、落ち着いた中年男性の声で、話速はゆっくり、深くて豊かで磁石のようなトーンが特徴です。」

    分析: 性別、年齢層、話速、音声特性、適用領域を明確に定義しています。

  • 「アニメーションキャラクターのナレーションに適した、約 8 歳の子供の声で、やや子供っぽいトーンが特徴です。」

    分析: 特定の年齢と音声品質(子供っぽさ)まで正確に指定しており、目的も明確です。

  • 「オーディオブックのナレーションに適した、落ち着いたトーンの知的で優しい 30 歳前後の女性の声です。」

    分析: 「知的」「落ち着いた」といった言葉で、感情とスタイルを効果的に伝えています。

❌ 非推奨例

主な問題点

改善案

良い声

曖昧すぎ、主観的であり、実行可能な特徴が欠如しています。

「クリアなボーカルラインと優しいトーンを持つ、若い女性の声」など、具体的なディメンションを追加してください。

ある有名人のような声

著作権上のリスクがあるため、モデルは直接的な模倣を許可していません。

「落ち着いたペースの成熟した磁石のような男性の声」など、音声の特性を抽出して説明してください。

とても、とても、とても良い女性の声

冗長な情報です。繰り返しの単語は音声の定義に寄与しません。

繰り返しの単語を削除し、「20~24 歳の女性の声で、軽やかなトーン、生き生きとしたピッチ、甘い質感」など、有効な説明を追加してください。

123456

無効な入力です。音声特徴として解析できません。

意味のあるテキスト説明を提供してください。上記の推奨例を参照してください。

はじめに:音声デザインから音声合成へ

image

1. ワークフロー

音声デザインと音声合成は、密接に関連しながらも独立した 2 つのステップであり、「まず作成し、その後使用する」というワークフローに従います:

  1. 音声デザインに必要な音声説明文およびプレビュー音声のテキストを準備します。

    • 音声説明文(voice_prompt): 対象音声の特徴を定義します。音声説明文の作成方法については、「音声説明文の作成」をご参照ください。

    • プレビュー音声のテキスト(preview_text): 対象音声のプレビュー音声が読み上げる内容です(例:「みなさん、こんにちは。ようこそお越しくださいました。」)。

  2. 音声の作成 API を呼び出してカスタム音声を作成し、音声名およびプレビュー音声を取得します。

    このステップでは、作成された音声を駆動する音声合成モデルを宣言するために、target_model を必ず指定する必要があります。

    プレビュー音声を聴いて、ご期待通りかどうかを確認してください。満足した場合は、次のステップに進んでください。そうでない場合は、音声の再設計を行ってください。

    すでに作成済みの音声をお持ちの場合は(音声一覧の照会 API を呼び出して確認できます)、このステップをスキップして次のステップに進むことができます。

  3. 音声を使用して(音声合成を実行)します。

    音声合成 API を呼び出し、前のステップで取得した音声を渡します。このステップで指定する音声合成モデルは、前のステップで指定した target_model と同一である必要があります。

2. モデル構成および事前準備

適切なモデルを選択し、必要な準備を完了してください。

モデル構成

音声デザインには、以下の 2 つのモデルを指定します:

  • 音声デザインモデル: qwen-voice-design

  • 音声駆動型音声合成モデルは、以下の 2 種類に分類されます:

事前準備

  1. API キーの取得API キーの取得。セキュリティのため、API キーは環境変数として設定することを推奨します。

  2. SDK のインストールDashScope SDK の最新版をインストール済み であることを確認してください。

3. サンプルコード

双方向ストリーミング合成

これは Qwen3-TTS-VC-Realtime シリーズのモデルに適用されます。詳細については、「リアルタイム音声合成 - Qwen」をご参照ください。

  1. カスタム音声を作成し、結果をプレビューします。結果に満足した場合は、次のステップに進んでください。そうでない場合は、再度作成してください。

    Python

    import requests
    import base64
    import os
    
    def create_voice_and_play():
        # シンガポールおよび北京リージョンの API キーは異なります。API キーの取得方法: https://www.alibabacloud.com/help/model-studio/get-api-key
        # 環境変数が設定されていない場合、次の行を Model Studio の API キーに置き換えてください: api_key = "sk-xxx"
        api_key = os.getenv("DASHSCOPE_API_KEY")
        
        if not api_key:
            print("エラー: DASHSCOPE_API_KEY 環境変数が見つかりません。まず API キーを設定してください。")
            return None, None, None
        
        # リクエストデータの準備
        headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
        
        data = {
            "model": "qwen-voice-design",
            "input": {
                "action": "create",
                "target_model": "qwen3-tts-vd-realtime-2026-01-15",
                "voice_prompt": "ニュース放送やドキュメンタリー解説に適した、落ち着いた中年男性アナウンサーの声で、深くて豊かで磁石のようなトーン、一定の話速、明瞭な発音が特徴です。",
                "preview_text": "皆様、こんにちは。夜のニュースへようこそ。",
                "preferred_name": "announcer",
                "language": "en"
            },
            "parameters": {
                "sample_rate": 24000,
                "response_format": "wav"
            }
        }
        
        # 以下はシンガポールリージョン向けの URL です。北京リージョンのモデルを使用する場合は、URL を次のように置き換えてください: https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization
        url = "https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customization"
        
        try:
            # リクエストの送信
            response = requests.post(
                url,
                headers=headers,
                json=data,
                timeout=60  # タイムアウト設定を追加
            )
            
            if response.status_code == 200:
                result = response.json()
                
                # 音声名の取得
                voice_name = result["output"]["voice"]
                print(f"音声名: {voice_name}")
                
                # プレビュー音声データの取得
                base64_audio = result["output"]["preview_audio"]["data"]
                
                # Base64 形式の音声データをデコード
                audio_bytes = base64.b64decode(base64_audio)
                
                # 音声ファイルをローカルに保存
                filename = f"{voice_name}_preview.wav"
                
                # 音声データをローカルファイルに書き込み
                with open(filename, 'wb') as f:
                    f.write(audio_bytes)
                
                print(f"音声をローカルファイルに保存しました: {filename}")
                print(f"ファイルパス: {os.path.abspath(filename)}")
                
                return voice_name, audio_bytes, filename
            else:
                print(f"リクエストが失敗しました。ステータスコード: {response.status_code}")
                print(f"レスポンス内容: {response.text}")
                return None, None, None
                
        except requests.exceptions.RequestException as e:
            print(f"ネットワーク要求エラーが発生しました: {e}")
            return None, None, None
        except KeyError as e:
            print(f"レスポンスデータ形式エラー、必須フィールドが不足しています: {e}")
            print(f"レスポンス内容: {response.text if 'response' in locals() else 'No response'}")
            return None, None, None
        except Exception as e:
            print(f"不明なエラーが発生しました: {e}")
            return None, None, None
    
    if __name__ == "__main__":
        print("音声の作成を開始しています...")
        voice_name, audio_data, saved_filename = create_voice_and_play()
        
        if voice_name:
            print(f"\n音声 '{voice_name}' の作成に成功しました")
            print(f"音声ファイルは '{saved_filename}' として保存されました")
            print(f"ファイルサイズ: {os.path.getsize(saved_filename)} バイト")
        else:
            print("\n音声の作成に失敗しました")

    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.google.gson.JsonObject;
    import com.google.gson.JsonParser;
    import java.io.*;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.Base64;
    
    public class Main {
        public static void main(String[] args) {
            Main example = new Main();
            example.createVoice();
        }
    
        public void createVoice() {
            // シンガポールおよび北京リージョンの API キーは異なります。API キーの取得方法: https://www.alibabacloud.com/help/model-studio/get-api-key
            // 環境変数が設定されていない場合、次の行を Model Studio の API キーに置き換えてください: String apiKey = "sk-xxx"
            String apiKey = System.getenv("DASHSCOPE_API_KEY");
    
            // JSON リクエストボディ文字列を作成
            String jsonBody = "{\n" +
                    "    \"model\": \"qwen-voice-design\",\n" +
                    "    \"input\": {\n" +
                    "        \"action\": \"create\",\n" +
                    "        \"target_model\": \"qwen3-tts-vd-realtime-2026-01-15\",\n" +
                    "        \"voice_prompt\": \"ニュース放送やドキュメンタリー解説に適した、落ち着いた中年男性アナウンサーの声で、深くて豊かで磁石のようなトーン、一定の話速、明瞭な発音が特徴です。\",\n" +
                    "        \"preview_text\": \"皆様、こんにちは。夜のニュースへようこそ。\",\n" +
                    "        \"preferred_name\": \"announcer\",\n" +
                    "        \"language\": \"en\"\n" +
                    "    },\n" +
                    "    \"parameters\": {\n" +
                    "        \"sample_rate\": 24000,\n" +
                    "        \"response_format\": \"wav\"\n" +
                    "    }\n" +
                    "}";
    
            HttpURLConnection connection = null;
            try {
                // 以下はシンガポールリージョン向けの URL です。北京リージョンのモデルを使用する場合は、URL を次のように置き換えてください: https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization
                URL url = new URL("https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customization");
                connection = (HttpURLConnection) url.openConnection();
    
                // リクエストメソッドおよびヘッダーを設定
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Authorization", "Bearer " + apiKey);
                connection.setRequestProperty("Content-Type", "application/json");
                connection.setDoOutput(true);
                connection.setDoInput(true);
    
                // リクエストボディを送信
                try (OutputStream os = connection.getOutputStream()) {
                    byte[] input = jsonBody.getBytes("UTF-8");
                    os.write(input, 0, input.length);
                    os.flush();
                }
    
                // レスポンスを取得
                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    // レスポンス内容を読み取り
                    StringBuilder response = new StringBuilder();
                    try (BufferedReader br = new BufferedReader(
                            new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
                        String responseLine;
                        while ((responseLine = br.readLine()) != null) {
                            response.append(responseLine.trim());
                        }
                    }
    
                    // JSON レスポンスを解析
                    JsonObject jsonResponse = JsonParser.parseString(response.toString()).getAsJsonObject();
                    JsonObject outputObj = jsonResponse.getAsJsonObject("output");
                    JsonObject previewAudioObj = outputObj.getAsJsonObject("preview_audio");
    
                    // 音声名の取得
                    String voiceName = outputObj.get("voice").getAsString();
                    System.out.println("音声名: " + voiceName);
    
                    // Base64 エンコードされた音声データの取得
                    String base64Audio = previewAudioObj.get("data").getAsString();
    
                    // Base64 音声データをデコード
                    byte[] audioBytes = Base64.getDecoder().decode(base64Audio);
    
                    // 音声をローカルファイルに保存
                    String filename = voiceName + "_preview.wav";
                    saveAudioToFile(audioBytes, filename);
    
                    System.out.println("音声をローカルファイルに保存しました: " + filename);
    
                } else {
                    // エラーレスポンスを読み取り
                    StringBuilder errorResponse = new StringBuilder();
                    try (BufferedReader br = new BufferedReader(
                            new InputStreamReader(connection.getErrorStream(), "UTF-8"))) {
                        String responseLine;
                        while ((responseLine = br.readLine()) != null) {
                            errorResponse.append(responseLine.trim());
                        }
                    }
    
                    System.out.println("リクエストが失敗しました。ステータスコード: " + responseCode);
                    System.out.println("エラーレスポンス: " + errorResponse.toString());
                }
    
            } catch (Exception e) {
                System.err.println("リクエスト中にエラーが発生しました: " + e.getMessage());
                e.printStackTrace();
            } finally {
                if (connection != null) {
                    connection.disconnect();
                }
            }
        }
    
        private void saveAudioToFile(byte[] audioBytes, String filename) {
            try {
                File file = new File(filename);
                try (FileOutputStream fos = new FileOutputStream(file)) {
                    fos.write(audioBytes);
                }
                System.out.println("音声を保存しました: " + file.getAbsolutePath());
            } catch (IOException e) {
                System.err.println("音声ファイルの保存中にエラーが発生しました: " + e.getMessage());
                e.printStackTrace();
            }
        }
    }
  2. 前のステップで作成したカスタム音声を音声合成に使用します。

    この例では、システム音声を使用した DashScope SDK の音声合成の「サーバー確定モード」サンプルコードを参照しています。音声合成 API の voice パラメーターを、音声デザインで作成したカスタム音声に置き換えています。

    重要な原則: 音声デザインで使用するモデル(target_model)と、後続の音声合成で使用するモデル(model)は、同一である必要があります。そうでない場合、音声合成は失敗します。

    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 base64
    import threading
    import time
    import dashscope  # DashScope Python SDK のバージョンは 1.23.9 以降である必要があります
    from dashscope.audio.qwen_tts_realtime import QwenTtsRealtime, QwenTtsRealtimeCallback, AudioFormat
    
    # ======= 定数設定 =======
    TEXT_TO_SYNTHESIZE = [
        'そうですよね?こんなスーパーが大好きなんです。',
        '特に新年の時期は。',
        'スーパーに行くと',
        '本当に',
        'すごく、すごく嬉しいんです!',
        'たくさん買いたいものがいっぱいあります!'
    ]
    
    def init_dashscope_api_key():
        """
        DashScope SDK の API キーを初期化します。
        """
        # シンガポールおよび北京リージョンの API キーは異なります。API キーの取得方法: https://www.alibabacloud.com/help/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] 接続が終了しました。コード={close_status_code}、メッセージ={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="qwen3-tts-vd-realtime-2026-01-15",
            callback=callback,
            # 以下はシンガポールリージョン向けの URL です。北京リージョンのモデルを使用する場合は、URL を次のように置き換えてください: wss://dashscope-intl.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="myvoice", # 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()}秒')

    Java

    import com.alibaba.dashscope.audio.qwen_tts_realtime.*;
    import com.alibaba.dashscope.exception.NoApiKeyException;
    import com.google.gson.JsonObject;
    
    import javax.sound.sampled.*;
    import java.io.*;
    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 String[] textToSynthesize = {
                "そうですよね?こんなスーパーが大好きなんです。",
                "特に新年の時期は。",
                "スーパーに行くと",
                "本当に",
                "すごく、すごく嬉しいんです!",
                "たくさん買いたいものがいっぱいあります!"
        };
    
        // リアルタイム音声プレーヤークラス
        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("qwen3-tts-vd-realtime-2026-01-15")
                    // 以下はシンガポールリージョン向けの 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/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("myvoice") // 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);
        }
    }

非ストリーミング/片方向ストリーミング合成

これは Qwen3-TTS-VC シリーズのモデルに適用されます。詳細については、「音声合成 - Qwen」をご参照ください。

  1. カスタム音声を作成し、結果をプレビューします。結果に満足した場合は、次のステップに進んでください。そうでない場合は、再度作成してください。

    Python

    import requests
    import base64
    import os
    
    def create_voice_and_play():
        # シンガポールおよび北京リージョンの API キーは異なります。API キーの取得方法: https://www.alibabacloud.com/help/model-studio/get-api-key
        # 環境変数が設定されていない場合、次の行を Model Studio の API キーに置き換えてください: api_key = "sk-xxx"
        api_key = os.getenv("DASHSCOPE_API_KEY")
        
        if not api_key:
            print("エラー: DASHSCOPE_API_KEY 環境変数が見つかりません。まず API キーを設定してください。")
            return None, None, None
        
        # リクエストデータの準備
        headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
        
        data = {
            "model": "qwen-voice-design",
            "input": {
                "action": "create",
                "target_model": "qwen3-tts-vd-2026-01-26",
                "voice_prompt": "ニュース放送やドキュメンタリー解説に適した、落ち着いた中年男性アナウンサーの声で、深くて豊かで磁石のようなトーン、一定の話速、明瞭な発音が特徴です。",
                "preview_text": "皆様、こんにちは。夜のニュースへようこそ。",
                "preferred_name": "announcer",
                "language": "en"
            },
            "parameters": {
                "sample_rate": 24000,
                "response_format": "wav"
            }
        }
        
        # 以下はシンガポールリージョン向けの URL です。北京リージョンのモデルを使用する場合は、URL を次のように置き換えてください: https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization
        url = "https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customization"
        
        try:
            # リクエストの送信
            response = requests.post(
                url,
                headers=headers,
                json=data,
                timeout=60  # タイムアウト設定を追加
            )
            
            if response.status_code == 200:
                result = response.json()
                
                # 音声名の取得
                voice_name = result["output"]["voice"]
                print(f"音声名: {voice_name}")
                
                # プレビュー音声データの取得
                base64_audio = result["output"]["preview_audio"]["data"]
                
                # Base64 形式の音声データをデコード
                audio_bytes = base64.b64decode(base64_audio)
                
                # 音声ファイルをローカルに保存
                filename = f"{voice_name}_preview.wav"
                
                # 音声データをローカルファイルに書き込み
                with open(filename, 'wb') as f:
                    f.write(audio_bytes)
                
                print(f"音声をローカルファイルに保存しました: {filename}")
                print(f"ファイルパス: {os.path.abspath(filename)}")
                
                return voice_name, audio_bytes, filename
            else:
                print(f"リクエストが失敗しました。ステータスコード: {response.status_code}")
                print(f"レスポンス内容: {response.text}")
                return None, None, None
                
        except requests.exceptions.RequestException as e:
            print(f"ネットワーク要求エラーが発生しました: {e}")
            return None, None, None
        except KeyError as e:
            print(f"レスポンスデータ形式エラー、必須フィールドが不足しています: {e}")
            print(f"レスポンス内容: {response.text if 'response' in locals() else 'No response'}")
            return None, None, None
        except Exception as e:
            print(f"不明なエラーが発生しました: {e}")
            return None, None, None
    
    if __name__ == "__main__":
        print("音声の作成を開始しています...")
        voice_name, audio_data, saved_filename = create_voice_and_play()
        
        if voice_name:
            print(f"\n音声 '{voice_name}' の作成に成功しました")
            print(f"音声ファイルは '{saved_filename}' として保存されました")
            print(f"ファイルサイズ: {os.path.getsize(saved_filename)} バイト")
        else:
            print("\n音声の作成に失敗しました")

    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")
    重要

    音声デザインで作成したカスタム音声を音声合成に使用する場合、音声を次のように設定する必要があります:

    MultiModalConversationParam param = MultiModalConversationParam.builder()
                    .parameter("voice", "your_voice") // voice パラメーターを音声デザインで作成したカスタム音声に置き換えます
                    .build();
    import com.google.gson.JsonObject;
    import com.google.gson.JsonParser;
    import java.io.*;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.Base64;
    
    public class Main {
        public static void main(String[] args) {
            Main example = new Main();
            example.createVoice();
        }
    
        public void createVoice() {
            // シンガポールおよび北京リージョンの API キーは異なります。API キーの取得方法: https://www.alibabacloud.com/help/model-studio/get-api-key
            // 環境変数が設定されていない場合、次の行を Model Studio の API キーに置き換えてください: String apiKey = "sk-xxx"
            String apiKey = System.getenv("DASHSCOPE_API_KEY");
    
            // JSON リクエストボディ文字列を作成
            String jsonBody = "{\n" +
                    "    \"model\": \"qwen-voice-design\",\n" +
                    "    \"input\": {\n" +
                    "        \"action\": \"create\",\n" +
                    "        \"target_model\": \"qwen3-tts-vd-2026-01-26\",\n" +
                    "        \"voice_prompt\": \"ニュース放送やドキュメンタリー解説に適した、落ち着いた中年男性アナウンサーの声で、深くて豊かで磁石のようなトーン、一定の話速、明瞭な発音が特徴です。\",\n" +
                    "        \"preview_text\": \"皆様、こんにちは。夜のニュースへようこそ。\",\n" +
                    "        \"preferred_name\": \"announcer\",\n" +
                    "        \"language\": \"en\"\n" +
                    "    },\n" +
                    "    \"parameters\": {\n" +
                    "        \"sample_rate\": 24000,\n" +
                    "        \"response_format\": \"wav\"\n" +
                    "    }\n" +
                    "}";
    
            HttpURLConnection connection = null;
            try {
                // 以下はシンガポールリージョン向けの URL です。北京リージョンのモデルを使用する場合は、URL を次のように置き換えてください: https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization
                URL url = new URL("https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customization");
                connection = (HttpURLConnection) url.openConnection();
    
                // リクエストメソッドおよびヘッダーを設定
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Authorization", "Bearer " + apiKey);
                connection.setRequestProperty("Content-Type", "application/json");
                connection.setDoOutput(true);
                connection.setDoInput(true);
    
                // リクエストボディを送信
                try (OutputStream os = connection.getOutputStream()) {
                    byte[] input = jsonBody.getBytes("UTF-8");
                    os.write(input, 0, input.length);
                    os.flush();
                }
    
                // レスポンスを取得
                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    // レスポンス内容を読み取り
                    StringBuilder response = new StringBuilder();
                    try (BufferedReader br = new BufferedReader(
                            new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
                        String responseLine;
                        while ((responseLine = br.readLine()) != null) {
                            response.append(responseLine.trim());
                        }
                    }
    
                    // JSON レスポンスを解析
                    JsonObject jsonResponse = JsonParser.parseString(response.toString()).getAsJsonObject();
                    JsonObject outputObj = jsonResponse.getAsJsonObject("output");
                    JsonObject previewAudioObj = outputObj.getAsJsonObject("preview_audio");
    
                    // 音声名の取得
                    String voiceName = outputObj.get("voice").getAsString();
                    System.out.println("音声名: " + voiceName);
    
                    // Base64 エンコードされた音声データの取得
                    String base64Audio = previewAudioObj.get("data").getAsString();
    
                    // Base64 音声データをデコード
                    byte[] audioBytes = Base64.getDecoder().decode(base64Audio);
    
                    // 音声をローカルファイルに保存
                    String filename = voiceName + "_preview.wav";
                    saveAudioToFile(audioBytes, filename);
    
                    System.out.println("音声をローカルファイルに保存しました: " + filename);
    
                } else {
                    // エラーレスポンスを読み取り
                    StringBuilder errorResponse = new StringBuilder();
                    try (BufferedReader br = new BufferedReader(
                            new InputStreamReader(connection.getErrorStream(), "UTF-8"))) {
                        String responseLine;
                        while ((responseLine = br.readLine()) != null) {
                            errorResponse.append(responseLine.trim());
                        }
                    }
    
                    System.out.println("リクエストが失敗しました。ステータスコード: " + responseCode);
                    System.out.println("エラーレスポンス: " + errorResponse.toString());
                }
    
            } catch (Exception e) {
                System.err.println("リクエスト中にエラーが発生しました: " + e.getMessage());
                e.printStackTrace();
            } finally {
                if (connection != null) {
                    connection.disconnect();
                }
            }
        }
    
        private void saveAudioToFile(byte[] audioBytes, String filename) {
            try {
                File file = new File(filename);
                try (FileOutputStream fos = new FileOutputStream(file)) {
                    fos.write(audioBytes);
                }
                System.out.println("音声を保存しました: " + file.getAbsolutePath());
            } catch (IOException e) {
                System.err.println("音声ファイルの保存中にエラーが発生しました: " + e.getMessage());
                e.printStackTrace();
            }
        }
    }
  2. 前のステップで作成したカスタム音声を非ストリーミング音声合成に使用します。

    この例では、DashScope SDK の音声合成向け「非ストリーミング出力」サンプルコード(システム音声使用)を参照しています。この例では、voice パラメーターをボイスデザインで生成したカスタム音声に置き換えます。単方向ストリーミング音声合成については、「音声合成 - Qwen」をご参照ください。

    重要な原則: 音声デザインで使用するモデル(target_model)と、後続の音声合成で使用するモデル(model)は、同一である必要があります。そうでない場合、音声合成は失敗します。

    Python

    import os
    import dashscope
    
    
    if __name__ == '__main__':
        # 以下はシンガポールリージョン向けの URL です。北京リージョンのモデルを使用する場合は、URL を次のように置き換えてください: https://dashscope.aliyuncs.com/api/v1
        dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
    
        text = "今日の天気はどうですか?"
        # SpeechSynthesizer インターフェイスの使い方: dashscope.audio.qwen_tts.SpeechSynthesizer.call(...)
        response = dashscope.MultiModalConversation.call(
            model="qwen3-tts-vd-2026-01-26",
            # シンガポールおよび北京リージョンの API キーは異なります。API キーの取得方法: https://www.alibabacloud.com/help/model-studio/get-api-key
            # 環境変数が設定されていない場合、次の行を Model Studio の API キーに置き換えてください: api_key = "sk-xxx"
            api_key=os.getenv("DASHSCOPE_API_KEY"),
            text=text,
            voice="myvoice", # voice パラメーターを音声デザインで作成したカスタム音声に置き換えます
            stream=False
        )
        print(response)

    Java

    import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
    import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
    import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
    import com.alibaba.dashscope.exception.ApiException;
    import com.alibaba.dashscope.exception.NoApiKeyException;
    import com.alibaba.dashscope.exception.UploadFileException;
    
    import com.alibaba.dashscope.utils.Constants;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.net.URL;
    
    public class Main {
        private static final String MODEL = "qwen3-tts-vd-2026-01-26";
        public static void call() throws ApiException, NoApiKeyException, UploadFileException {
            MultiModalConversation conv = new MultiModalConversation();
            MultiModalConversationParam param = MultiModalConversationParam.builder()
                    // シンガポールおよび北京リージョンの API キーは異なります。API キーの取得方法: https://www.alibabacloud.com/help/model-studio/get-api-key
                    // 環境変数が設定されていない場合、次の行を Model Studio の API キーに置き換えてください: .apiKey("sk-xxx")
                    .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                    .model(MODEL)
                    .text("今日は、人々が愛するものを創るのに最適な日です!")
                    .parameter("voice", "myvoice") // voice パラメーターを音声デザインで作成したカスタム音声に置き換えます
                    .build();
            MultiModalConversationResult result = conv.call(param);
            String audioUrl = result.getOutput().getAudio().getUrl();
            System.out.print(audioUrl);
    
            // 音声ファイルをローカルにダウンロード
            try (InputStream in = new URL(audioUrl).openStream();
                 FileOutputStream out = new FileOutputStream("downloaded_audio.wav")) {
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = in.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesRead);
                }
                System.out.println("\n音声ファイルをローカルにダウンロードしました: downloaded_audio.wav");
            } catch (Exception e) {
                System.out.println("\n音声ファイルのダウンロード中にエラーが発生しました: " + e.getMessage());
            }
        }
        public static void main(String[] args) {
            try {
                // 以下はシンガポールリージョン向けの URL です。北京リージョンのモデルを使用する場合は、URL を次のように置き換えてください: https://dashscope.aliyuncs.com/api/v1
                Constants.baseHttpApiUrl = "https://dashscope-intl.aliyuncs.com/api/v1";
                call();
            } catch (ApiException | NoApiKeyException | UploadFileException e) {
                System.out.println(e.getMessage());
            }
            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-design です。

    • target_model: 音声を駆動する音声合成モデルです。後続の音声合成 API 呼び出しで使用する音声合成モデルと同一である必要があります。そうでない場合、音声合成は失敗します。

    {
        "model": "qwen-voice-design",
        "input": {
            "action": "create",
            "target_model": "qwen3-tts-vd-realtime-2026-01-15",
            "voice_prompt": "ニュース放送やドキュメンタリー解説に適した、落ち着いた中年男性アナウンサーの声で、深くて豊かで磁石のようなトーン、一定の話速、明瞭な発音が特徴です。",
            "preview_text": "皆様、こんにちは。夜のニュースへようこそ。",
            "preferred_name": "announcer",
            "language": "zh"
        },
        "parameters": {
            "sample_rate": 24000,
            "response_format": "wav"
        }
    }
  • リクエストパラメーター

    パラメーター

    タイプ

    デフォルト

    必須

    説明

    model

    string

    -

    対応

    音声デザインモデルで、固定値は qwen-voice-design です。

    action

    string

    -

    対応

    操作タイプで、固定値は create です。

    target_model

    string

    -

    はい

    音声を駆動する音声合成モデルです。対応するモデルは以下のとおりです(2 種類):

    これは、後続の音声合成 API 呼び出しで使用する音声合成モデルと同一である必要があります。そうでない場合、音声合成は失敗します。

    voice_prompt

    string

    -

    対応

    音声説明文です。最大長は 2048 文字です。

    中国語および英語のみがサポートされます。

    音声説明文の作成方法については、「音声説明文の作成」をご参照ください。

    preview_text

    string

    -

    対応

    プレビュー音声に対応するテキストです。最大長は 1024 文字です。

    中国語 (zh)、英語 (en)、ドイツ語 (de)、イタリア語 (it)、ポルトガル語 (pt)、スペイン語 (es)、日本語 (ja)、韓国語 (ko)、フランス語 (fr)、ロシア語 (ru) をサポートします。

    preferred_name

    string

    -

    対応

    音声に分かりやすい名前を付ける(数字、英字、アンダースコアのみ使用可能、最大 16 文字)。キャラクターやシナリオに関連した識別子を使用することを推奨します。

    このキーワードは、作成された音声名に含まれます。たとえば、キーワードが「announcer」の場合、最終的な音声名は「qwen-tts-vd-announcer-voice-20251201102800-a1b2」になります。

    language

    string

    zh

    いいえ

    言語コードで、生成される音声の言語の優先度を指定します。このパラメーターは、生成される音声の言語機能および発音傾向に影響を与えます。実際のユースケースに基づいて適切な言語コードを選択することを推奨します。

    このパラメーターを使用する場合、設定した言語は preview_text の言語と一致させる必要があります。

    有効な値: zh(中国語)、en(英語)、de(ドイツ語)、it(イタリア語)、pt(ポルトガル語)、es(スペイン語)、ja(日本語)、ko(韓国語)、fr(フランス語)、ru(ロシア語)。

    sample_rate

    int

    24000

    非対応

    音声デザインによって生成されるプレビュー音声のサンプルレート(Hz 単位)です。

    有効な値:

    • 8000

    • 16000

    • 24000

    • 48000

    response_format

    string

    wav

    非対応

    音声デザインによって生成されるプレビュー音声のフォーマットです。

    有効な値:

    • pcm

    • wav

    • mp3

    • opus

  • レスポンスパラメーター

    レスポンス例を表示

    {
        "output": {
            "preview_audio": {
                "data": "{base64_encoded_audio}",
                "sample_rate": 24000,
                "response_format": "wav"
            },
            "target_model": "qwen3-tts-vd-realtime-2026-01-15",
            "voice": "yourVoice"
        },
        "usage": {
            "count": 1
        },
        "request_id": "yourRequestId"
    }

    以下のパラメーターについて説明します:

    パラメーター

    タイプ

    説明

    voice

    string

    音声名で、音声合成 API の voice パラメーターに直接使用できます。

    data

    string

    音声デザインによって生成されるプレビュー音声データで、Base64 エンコードされた文字列として返されます。

    sample_rate

    int

    音声デザインによって生成されるプレビュー音声のサンプルレート(Hz 単位)です。音声作成時に設定したサンプルレートと一致し、未指定の場合はデフォルトで 24000 Hz になります。

    response_format

    string

    音声デザインによって生成されるプレビュー音声のフォーマットです。音声作成時に設定した音声フォーマットと一致し、未指定の場合はデフォルトで wav になります。

    target_model

    string

    音声を駆動する音声合成モデルです。対応するモデルは以下のとおりです(2 種類):

    これは、後続の音声合成 API 呼び出しで使用する音声合成モデルと同一である必要があります。そうでない場合、音声合成は失敗します。

    request_id

    string

    リクエスト ID です。

    count

    integer

    このリクエストに対して課金される「音声作成」操作の回数です。このリクエストの費用は $

    音声作成時、count は常に 1 になります。

  • サンプルコード

    重要

    以下のパラメーターの違いに注意してください:

    • model: 音声デザインモデルで、固定値は qwen-voice-design です。

    • target_model: 音声を駆動する音声合成モデルです。後続の音声合成 API 呼び出しで使用する音声合成モデルと同一である必要があります。そうでない場合、音声合成は失敗します。

    cURL

    API キーを環境変数として設定していない場合は、例の $DASHSCOPE_API_KEY を実際の API キーに置き換えてください。

    https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customization<a data-init-id="9f104f338c7kz" href="https://poc-dashscope.aliyuncs.com/api/v1/services/audio/tts/customization" id="28f184e9f7vq7">https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customization</a># ======= 重要事項 =======
    # 以下はシンガポールリージョン向けの URL です。北京リージョンのモデルを使用する場合は、URL を次のように置き換えてください: https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization
    # シンガポールおよび北京リージョンの API キーは異なります。API キーの取得方法: https://www.alibabacloud.com/help/model-studio/get-api-key
    # === 実行前にこのコメントを削除してください ===
    
    curl -X POST <a data-init-id="9f104f338c7kz" href="https://poc-dashscope.aliyuncs.com/api/v1/services/audio/tts/customization" id="28f184e9f7vq7">https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customization</a> \
    -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
        "model": "qwen-voice-design",
        "input": {
            "action": "create",
            "target_model": "qwen3-tts-vd-realtime-2026-01-15",
            "voice_prompt": "ニュース放送やドキュメンタリー解説に適した、落ち着いた中年男性アナウンサーの声で、深くて豊かで磁石のようなトーン、一定の話速、明瞭な発音が特徴です。",
            "preview_text": "皆様、こんにちは。夜のニュースへようこそ。",
            "preferred_name": "announcer",
            "language": "zh"
        },
        "parameters": {
            "sample_rate": 24000,
            "response_format": "wav"
        }
    }'

    Python

    import requests
    import base64
    import os
    
    def create_voice_and_play():
        # シンガポールおよび北京リージョンの API キーは異なります。API キーの取得方法: https://www.alibabacloud.com/help/model-studio/get-api-key
        # 環境変数が設定されていない場合、次の行を Model Studio の API キーに置き換えてください: api_key = "sk-xxx"
        api_key = os.getenv("DASHSCOPE_API_KEY")
        
        if not api_key:
            print("エラー: DASHSCOPE_API_KEY 環境変数が見つかりません。まず API キーを設定してください。")
            return None, None, None
        
        # リクエストデータの準備
        headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
        
        data = {
            "model": "qwen-voice-design",
            "input": {
                "action": "create",
                "target_model": "qwen3-tts-vd-realtime-2026-01-15",
                "voice_prompt": "ニュース放送やドキュメンタリー解説に適した、落ち着いた中年男性アナウンサーの声で、深くて豊かで磁石のようなトーン、一定の話速、明瞭な発音が特徴です。",
                "preview_text": "皆様、こんにちは。夜のニュースへようこそ。",
                "preferred_name": "announcer",
                "language": "en"
            },
            "parameters": {
                "sample_rate": 24000,
                "response_format": "wav"
            }
        }
        
        # 以下はシンガポールリージョン向けの URL です。北京リージョンのモデルを使用する場合は、URL を次のように置き換えてください: https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization
        url = "https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customization"
        
        try:
            # リクエストの送信
            response = requests.post(
                url,
                headers=headers,
                json=data,
                timeout=60  # タイムアウト設定を追加
            )
            
            if response.status_code == 200:
                result = response.json()
                
                # 音声名の取得
                voice_name = result["output"]["voice"]
                print(f"音声名: {voice_name}")
                
                # プレビュー音声データの取得
                base64_audio = result["output"]["preview_audio"]["data"]
                
                # Base64 形式の音声データをデコード
                audio_bytes = base64.b64decode(base64_audio)
                
                # 音声ファイルをローカルに保存
                filename = f"{voice_name}_preview.wav"
                
                # 音声データをローカルファイルに書き込み
                with open(filename, 'wb') as f:
                    f.write(audio_bytes)
                
                print(f"音声をローカルファイルに保存しました: {filename}")
                print(f"ファイルパス: {os.path.abspath(filename)}")
                
                return voice_name, audio_bytes, filename
            else:
                print(f"リクエストが失敗しました。ステータスコード: {response.status_code}")
                print(f"レスポンス内容: {response.text}")
                return None, None, None
                
        except requests.exceptions.RequestException as e:
            print(f"ネットワーク要求エラーが発生しました: {e}")
            return None, None, None
        except KeyError as e:
            print(f"レスポンスデータ形式エラー、必須フィールドが不足しています: {e}")
            print(f"レスポンス内容: {response.text if 'response' in locals() else 'No response'}")
            return None, None, None
        except Exception as e:
            print(f"不明なエラーが発生しました: {e}")
            return None, None, None
    
    if __name__ == "__main__":
        print("音声の作成を開始しています...")
        voice_name, audio_data, saved_filename = create_voice_and_play()
        
        if voice_name:
            print(f"\n音声 '{voice_name}' の作成に成功しました")
            print(f"音声ファイルは '{saved_filename}' として保存されました")
            print(f"ファイルサイズ: {os.path.getsize(saved_filename)} バイト")
        else:
            print("\n音声の作成に失敗しました")

    Java

    import com.google.gson.JsonObject;
    import com.google.gson.JsonParser;
    import java.io.*;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.Base64;
    
    public class Main {
        public static void main(String[] args) {
            Main example = new Main();
            example.createVoice();
        }
    
        public void createVoice() {
            // シンガポールおよび北京リージョンの API キーは異なります。API キーの取得方法: https://www.alibabacloud.com/help/model-studio/get-api-key
            // 環境変数が設定されていない場合、次の行を Model Studio の API キーに置き換えてください: String apiKey = "sk-xxx"
            String apiKey = System.getenv("DASHSCOPE_API_KEY");
    
            // JSON リクエストボディ文字列を作成
            String jsonBody = "{\n" +
                    "    \"model\": \"qwen-voice-design\",\n" +
                    "    \"input\": {\n" +
                    "        \"action\": \"create\",\n" +
                    "        \"target_model\": \"qwen3-tts-vd-realtime-2026-01-15\",\n" +
                    "        \"voice_prompt\": \"ニュース放送やドキュメンタリー解説に適した、落ち着いた中年男性アナウンサーの声で、深くて豊かで磁石のようなトーン、一定の話速、明瞭な発音が特徴です。\",\n" +
                    "        \"preview_text\": \"皆様、こんにちは。夜のニュースへようこそ。\",\n" +
                    "        \"preferred_name\": \"announcer\",\n" +
                    "        \"language\": \"en\"\n" +
                    "    },\n" +
                    "    \"parameters\": {\n" +
                    "        \"sample_rate\": 24000,\n" +
                    "        \"response_format\": \"wav\"\n" +
                    "    }\n" +
                    "}";
    
            HttpURLConnection connection = null;
            try {
                // 以下はシンガポールリージョン向けの URL です。北京リージョンのモデルを使用する場合は、URL を次のように置き換えてください: https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization
                URL url = new URL("https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customization");
                connection = (HttpURLConnection) url.openConnection();
    
                // リクエストメソッドおよびヘッダーを設定
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Authorization", "Bearer " + apiKey);
                connection.setRequestProperty("Content-Type", "application/json");
                connection.setDoOutput(true);
                connection.setDoInput(true);
    
                // リクエストボディを送信
                try (OutputStream os = connection.getOutputStream()) {
                    byte[] input = jsonBody.getBytes("UTF-8");
                    os.write(input, 0, input.length);
                    os.flush();
                }
    
                // レスポンスを取得
                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    // レスポンス内容を読み取り
                    StringBuilder response = new StringBuilder();
                    try (BufferedReader br = new BufferedReader(
                            new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
                        String responseLine;
                        while ((responseLine = br.readLine()) != null) {
                            response.append(responseLine.trim());
                        }
                    }
    
                    // JSON レスポンスを解析
                    JsonObject jsonResponse = JsonParser.parseString(response.toString()).getAsJsonObject();
                    JsonObject outputObj = jsonResponse.getAsJsonObject("output");
                    JsonObject previewAudioObj = outputObj.getAsJsonObject("preview_audio");
    
                    // 音声名の取得
                    String voiceName = outputObj.get("voice").getAsString();
                    System.out.println("音声名: " + voiceName);
    
                    // Base64 エンコードされた音声データの取得
                    String base64Audio = previewAudioObj.get("data").getAsString();
    
                    // Base64 音声データをデコード
                    byte[] audioBytes = Base64.getDecoder().decode(base64Audio);
    
                    // 音声をローカルファイルに保存
                    String filename = voiceName + "_preview.wav";
                    saveAudioToFile(audioBytes, filename);
    
                    System.out.println("音声をローカルファイルに保存しました: " + filename);
    
                } else {
                    // エラーレスポンスを読み取り
                    StringBuilder errorResponse = new StringBuilder();
                    try (BufferedReader br = new BufferedReader(
                            new InputStreamReader(connection.getErrorStream(), "UTF-8"))) {
                        String responseLine;
                        while ((responseLine = br.readLine()) != null) {
                            errorResponse.append(responseLine.trim());
                        }
                    }
    
                    System.out.println("リクエストが失敗しました。ステータスコード: " + responseCode);
                    System.out.println("エラーレスポンス: " + errorResponse.toString());
                }
    
            } catch (Exception e) {
                System.err.println("リクエスト中にエラーが発生しました: " + e.getMessage());
                e.printStackTrace();
            } finally {
                if (connection != null) {
                    connection.disconnect();
                }
            }
        }
    
        private void saveAudioToFile(byte[] audioBytes, String filename) {
            try {
                File file = new File(filename);
                try (FileOutputStream fos = new FileOutputStream(file)) {
                    fos.write(audioBytes);
                }
                System.out.println("音声を保存しました: " + file.getAbsolutePath());
            } catch (IOException e) {
                System.err.println("音声ファイルの保存中にエラーが発生しました: " + e.getMessage());
                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-design です。この値を変更しないでください。

    {
        "model": "qwen-voice-design",
        "input": {
            "action": "list",
            "page_size": 10,
            "page_index": 0
        }
    }
  • リクエストパラメーター

    パラメーター

    タイプ

    デフォルト

    必須

    説明

    model

    string

    -

    対応

    音声デザインモデルで、固定値は qwen-voice-design です。

    action

    string

    -

    対応

    操作タイプで、固定値は list です。

    page_index

    integer

    0

    非対応

    ページ番号インデックスです。範囲:[0, 200]。

    page_size

    integer

    10

    非対応

    1 ページあたりのエントリー数です。値は 0 より大きい必要があります。

  • レスポンスパラメーター

    レスポンス例を表示

    {
        "output": {
            "page_index": 0,
            "page_size": 2,
            "total_count": 26,
            "voice_list": [
                {
                    "gmt_create": "2025-12-10 17:04:54",
                    "gmt_modified": "2025-12-10 17:04:54",
                    "language": "zh",
                    "preview_text": "皆様、こんにちは。本日のプログラムへようこそ。",
                    "target_model": "qwen3-tts-vd-realtime-2026-01-15",
                    "voice": "yourVoice1",
                    "voice_prompt": "ニュース放送やドキュメンタリー解説に適した、落ち着いた中年男性アナウンサーの声で、深くて豊かで磁石のようなトーン、一定の話速、明瞭な発音が特徴です。、低音で磁石のような、一定のペース"
                },
                {
                    "gmt_create": "2025-12-10 15:31:35",
                    "gmt_modified": "2025-12-10 15:31:35",
                    "language": "zh",
                    "preview_text": "皆様、こんにちは",
                    "target_model": "qwen3-tts-vd-realtime-2026-01-15",
                    "voice": "yourVoice2",
                    "voice_prompt": "ニュース放送やドキュメンタリー解説に適した、落ち着いた中年男性アナウンサーの声で、深くて豊かで磁石のようなトーン、一定の話速、明瞭な発音が特徴です。"
                }
            ]
        },
        "usage": {},
        "request_id": "yourRequestId"
    }

    以下のパラメーターについて説明します:

    パラメーター

    タイプ

    説明

    voice

    string

    音声名で、音声合成 API の voice パラメーターに直接使用できます。

    target_model

    string

    音声を駆動する音声合成モデルです。対応するモデルは以下のとおりです(2 種類):

    これは、後続の音声合成 API 呼び出しで使用する音声合成モデルと同一である必要があります。そうでない場合、音声合成は失敗します。

    language

    string

    言語コードです。

    有効な値: zh(中国語)、en(英語)、de(ドイツ語)、it(イタリア語)、pt(ポルトガル語)、es(スペイン語)、ja(日本語)、ko(韓国語)、fr(フランス語)、ru(ロシア語)。

    voice_prompt

    string

    音声説明文です。

    preview_text

    string

    プレビューテキスト。

    gmt_create

    string

    音声の作成時刻です。

    gmt_modified

    string

    音声の更新時刻です。

    page_index

    integer

    ページ番号インデックスです。

    page_size

    integer

    1 ページあたりのエントリー数です。

    total_count

    integer

    検索されたデータエントリーの総数です。

    request_id

    string

    リクエスト ID です。

  • サンプルコード

    重要

    model: 音声デザインモデルで、固定値は qwen-voice-design です。この値を変更しないでください。

    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/model-studio/get-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-design",
        "input": {
            "action": "list",
            "page_size": 10,
            "page_index": 0
        }
    }'

    Python

    import os
    import requests
    
    # シンガポールおよび北京リージョンの API キーは異なります。API キーの取得方法: https://www.alibabacloud.com/help/model-studio/get-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-design", # この値を変更しないでください
        "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/model-studio/get-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-design\"," // この値を変更しないでください
                            + "\"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-design です。この値を変更しないでください。

    {
        "model": "qwen-voice-design",
        "input": {
            "action": "query",
            "voice": "voiceName"
        }
    }
  • リクエストパラメーター

    パラメーター

    タイプ

    デフォルト

    必須

    説明

    model

    string

    -

    対応

    音声デザインモデルで、固定値は qwen-voice-design です。

    action

    string

    -

    対応

    操作タイプで、固定値は query です。

    voice

    string

    -

    対応

    照会する音声の名前です。

  • レスポンスパラメーター

    レスポンス例を表示

    データが見つかりました

    {
        "output": {
            "gmt_create": "2025-12-10 14:54:09",
            "gmt_modified": "2025-12-10 17:47:48",
            "language": "zh",
            "preview_text": "皆様、こんにちは",
            "target_model": "qwen3-tts-vd-realtime-2026-01-15",
            "voice": "yourVoice",
            "voice_prompt": "ニュース放送やドキュメンタリー解説に適した、落ち着いた中年男性アナウンサーの声で、深くて豊かで磁石のようなトーン、一定の話速、明瞭な発音が特徴です。"
        },
        "usage": {},
        "request_id": "yourRequestId"
    }

    データが見つからない場合

    照会された音声が存在しない場合、API は HTTP 400 ステータスコードを返し、レスポンスボディには VoiceNotFound エラーコードが含まれます。

    {
        "request_id":"yourRequestId",
        "code":"VoiceNotFound",
        "message":"音声が見つかりません: qwen-tts-vd-announcer-voice-xxxx"
    }

    以下のパラメーターは:

    パラメーター

    タイプ

    説明

    voice

    string

    音声名で、音声合成 API の voice パラメーターに直接使用できます。

    target_model

    string

    音声を駆動する音声合成モデルです。対応するモデルは以下のとおりです(2 種類):

    これは、後続の音声合成 API 呼び出しで使用する音声合成モデルと同一である必要があります。そうでない場合、音声合成は失敗します。

    language

    string

    言語コードです。

    有効な値: zh(中国語)、en(英語)、de(ドイツ語)、it(イタリア語)、pt(ポルトガル語)、es(スペイン語)、ja(日本語)、ko(韓国語)、fr(フランス語)、ru(ロシア語)。

    voice_prompt

    string

    音声説明文です。

    preview_text

    string

    プレビューテキスト。

    gmt_create

    string

    音声の作成時刻です。

    gmt_modified

    string

    音声の更新時刻です。

    request_id

    string

    リクエスト ID です。

  • サンプルコード

    重要

    model: 音声デザインモデルで、固定値は qwen-voice-design です。この値を変更しないでください。

    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/model-studio/get-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-design",
        "input": {
            "action": "query",
            "voice": "voiceName"
        }
    }'

    Python

    import requests
    import os
    
    def query_voice(voice_name):
        """
        特定の音声の情報を照会します。
        :param voice_name: 音声の名前。
        :return: 音声情報の辞書、または見つからない場合は None。
        """
        # シンガポールおよび北京リージョンの API キーは異なります。API キーの取得方法: https://www.alibabacloud.com/help/model-studio/get-api-key
        # 環境変数が設定されていない場合、次の行を Model Studio の API キーに置き換えてください: api_key = "sk-xxx"
        api_key = os.getenv("DASHSCOPE_API_KEY")
        
        # リクエストデータの準備
        headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
        
        data = {
            "model": "qwen-voice-design",
            "input": {
                "action": "query",
                "voice": voice_name
            }
        }
        
        # 以下はシンガポールリージョン向けの URL です。北京リージョンのモデルを使用する場合は、URL を次のように置き換えてください: https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization
        url = "https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customization"
        # リクエストの送信
        response = requests.post(
            url,
            headers=headers,
            json=data
        )
        
        if response.status_code == 200:
            result = response.json()
            
            # エラーメッセージを確認
            if "code" in result and result["code"] == "VoiceNotFound":
                print(f"音声が見つかりません: {voice_name}")
                print(f"エラーメッセージ: {result.get('message', '音声が見つかりません')}")
                return None
            
            # 音声情報を取得
            voice_info = result["output"]
            print(f"音声情報の照会に成功しました:")
            print(f"  音声名: {voice_info.get('voice')}")
            print(f"  作成時刻: {voice_info.get('gmt_create')}")
            print(f"  更新時刻: {voice_info.get('gmt_modified')}")
            print(f"  言語: {voice_info.get('language')}")
            print(f"  プレビュー音声のテキスト: {voice_info.get('preview_text')}")
            print(f"  モデル: {voice_info.get('target_model')}")
            print(f"  音声説明文: {voice_info.get('voice_prompt')}")
            
            return voice_info
        else:
            print(f"リクエストが失敗しました。ステータスコード: {response.status_code}")
            print(f"レスポンス内容: {response.text}")
            return None
    
    def main():
        # 例:音声を照会
        voice_name = "myvoice"  # 照会したい実際の音声名に置き換えてください
        
        print(f"音声を照会しています: {voice_name}")
        voice_info = query_voice(voice_name)
        
        if voice_info:
            print("\n音声の照会に成功しました!")
        else:
            print("\n音声の照会に失敗したか、音声が存在しません。")
    
    if __name__ == "__main__":
        main()

    Java

    import com.google.gson.JsonObject;
    import com.google.gson.JsonParser;
    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) {
            Main example = new Main();
            // 例:音声を照会
            String voiceName = "myvoice"; // 照会したい実際の音声名に置き換えてください
            System.out.println("音声を照会しています: " + voiceName);
            example.queryVoice(voiceName);
        }
    
        public void queryVoice(String voiceName) {
            // シンガポールおよび北京リージョンの API キーは異なります。API キーの取得方法: https://www.alibabacloud.com/help/model-studio/get-api-key
            // 環境変数が設定されていない場合、次の行を Model Studio の API キーに置き換えてください: String apiKey = "sk-xxx"
            String apiKey = System.getenv("DASHSCOPE_API_KEY");
    
            // JSON リクエストボディ文字列を作成
            String jsonBody = "{\n" +
                    "    \"model\": \"qwen-voice-design\",\n" +
                    "    \"input\": {\n" +
                    "        \"action\": \"query\",\n" +
                    "        \"voice\": \"" + voiceName + "\"\n" +
                    "    }\n" +
                    "}";
    
            HttpURLConnection connection = null;
            try {
                // 以下はシンガポールリージョン向けの URL です。北京リージョンのモデルを使用する場合は、URL を次のように置き換えてください: https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization
                URL url = new URL("https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customization");
                connection = (HttpURLConnection) url.openConnection();
    
                // リクエストメソッドおよびヘッダーを設定
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Authorization", "Bearer " + apiKey);
                connection.setRequestProperty("Content-Type", "application/json");
                connection.setDoOutput(true);
                connection.setDoInput(true);
    
                // リクエストボディを送信
                try (OutputStream os = connection.getOutputStream()) {
                    byte[] input = jsonBody.getBytes("UTF-8");
                    os.write(input, 0, input.length);
                    os.flush();
                }
    
                // レスポンスを取得
                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    // レスポンス内容を読み取り
                    StringBuilder response = new StringBuilder();
                    try (BufferedReader br = new BufferedReader(
                            new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
                        String responseLine;
                        while ((responseLine = br.readLine()) != null) {
                            response.append(responseLine.trim());
                        }
                    }
    
                    // JSON レスポンスを解析
                    JsonObject jsonResponse = JsonParser.parseString(response.toString()).getAsJsonObject();
    
                    // エラーメッセージを確認
                    if (jsonResponse.has("code") && "VoiceNotFound".equals(jsonResponse.get("code").getAsString())) {
                        String errorMessage = jsonResponse.has("message") ?
                                jsonResponse.get("message").getAsString() : "音声が見つかりません";
                        System.out.println("音声が見つかりません: " + voiceName);
                        System.out.println("エラーメッセージ: " + errorMessage);
                        return;
                    }
    
                    // 音声情報を取得
                    JsonObject outputObj = jsonResponse.getAsJsonObject("output");
    
                    System.out.println("音声情報の照会に成功しました:");
                    System.out.println("  音声名: " + outputObj.get("voice").getAsString());
                    System.out.println("  作成時刻: " + outputObj.get("gmt_create").getAsString());
                    System.out.println("  更新時刻: " + outputObj.get("gmt_modified").getAsString());
                    System.out.println("  言語: " + outputObj.get("language").getAsString());
                    System.out.println("  プレビュー音声のテキスト: " + outputObj.get("preview_text").getAsString());
                    System.out.println("  モデル: " + outputObj.get("target_model").getAsString());
                    System.out.println("  音声説明文: " + outputObj.get("voice_prompt").getAsString());
    
                } else {
                    // エラーレスポンスを読み取り
                    StringBuilder errorResponse = new StringBuilder();
                    try (BufferedReader br = new BufferedReader(
                            new InputStreamReader(connection.getErrorStream(), "UTF-8"))) {
                        String responseLine;
                        while ((responseLine = br.readLine()) != null) {
                            errorResponse.append(responseLine.trim());
                        }
                    }
    
                    System.out.println("リクエストが失敗しました。ステータスコード: " + responseCode);
                    System.out.println("エラーレスポンス: " + errorResponse.toString());
                }
    
            } catch (Exception e) {
                System.err.println("リクエスト中にエラーが発生しました: " + e.getMessage());
                e.printStackTrace();
            } finally {
                if (connection != null) {
                    connection.disconnect();
                }
            }
        }
    }

音声の削除

音声を削除し、対応するクォータを解放します。

  • 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-design です。この値を変更しないでください。

    {
        "model": "qwen-voice-design",
        "input": {
            "action": "delete",
            "voice": "yourVoice"
        }
    }
  • リクエストパラメーター

    パラメーター

    タイプ

    デフォルト

    必須

    説明

    model

    string

    -

    対応

    音声デザインモデルで、固定値は qwen-voice-design です。

    action

    string

    -

    対応

    操作タイプで、固定値は delete です。

    voice

    string

    -

    はい

    削除する音声です。

  • レスポンスパラメーター

    レスポンス例を表示

    {
        "output": {
            "voice": "yourVoice"
        },
        "usage": {},
        "request_id": "yourRequestId"
    }

    以下のパラメーターについて説明します:

    パラメーター

    タイプ

    説明

    request_id

    string

    リクエスト ID です。

    voice

    string

    削除された音声です。

  • サンプルコード

    重要

    model: 音声デザインモデルで、固定値は qwen-voice-design です。この値を変更しないでください。

    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/model-studio/get-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-design",
        "input": {
            "action": "delete",
            "voice": "yourVoice"
        }
    }'

    Python

    import requests
    import os
    
    def delete_voice(voice_name):
        """
        指定された音声を削除します。
        :param voice_name: 音声の名前。
        :return: 削除が成功した場合、または音声が存在しないがリクエストが成功した場合は True、操作が失敗した場合は False。
        """
        # シンガポールおよび北京リージョンの API キーは異なります。API キーの取得方法: https://www.alibabacloud.com/help/model-studio/get-api-key
        # 環境変数が設定されていない場合、次の行を Model Studio の API キーに置き換えてください: api_key = "sk-xxx"
        api_key = os.getenv("DASHSCOPE_API_KEY")
        
        # リクエストデータの準備
        headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
        
        data = {
            "model": "qwen-voice-design",
            "input": {
                "action": "delete",
                "voice": voice_name
            }
        }
        
        # 以下はシンガポールリージョン向けの URL です。北京リージョンのモデルを使用する場合は、URL を次のように置き換えてください: https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization
        url = "https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customization"
        # リクエストの送信
        response = requests.post(
            url,
            headers=headers,
            json=data
        )
        
        if response.status_code == 200:
            result = response.json()
            
            # エラーメッセージを確認
            if "code" in result and "VoiceNotFound" in result["code"]:
                print(f"音声が存在しません: {voice_name}")
                print(f"エラーメッセージ: {result.get('message', '音声が見つかりません')}")
                return True  # 音声が存在しない場合、操作は成功とみなされます(目的が既に達成されているため)
            
            # 削除が成功したか確認
            if "usage" in result:
                print(f"音声の削除に成功しました: {voice_name}")
                print(f"リクエスト ID: {result.get('request_id', 'N/A')}")
                return True
            else:
                print(f"削除操作から予期しないレスポンス形式が返されました: {result}")
                return False
        else:
            print(f"音声削除リクエストが失敗しました。ステータスコード: {response.status_code}")
            print(f"レスポンス内容: {response.text}")
            return False
    
    def main():
        # 例:音声を削除
        voice_name = "myvoice"  # 削除したい実際の音声名に置き換えてください
        
        print(f"音声を削除しています: {voice_name}")
        success = delete_voice(voice_name)
        
        if success:
            print(f"\n音声 '{voice_name}' の削除が完了しました!")
        else:
            print(f"\n音声 '{voice_name}' の削除に失敗しました!")
    
    if __name__ == "__main__":
        main()

    Java

    import com.google.gson.JsonObject;
    import com.google.gson.JsonParser;
    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) {
            Main example = new Main();
            // 例:音声を削除
            String voiceName = "myvoice"; // 削除したい実際の音声名に置き換えてください
            System.out.println("音声を削除しています: " + voiceName);
            example.deleteVoice(voiceName);
        }
    
        public void deleteVoice(String voiceName) {
            // シンガポールおよび北京リージョンの API キーは異なります。API キーの取得方法: https://www.alibabacloud.com/help/model-studio/get-api-key
            // 環境変数が設定されていない場合、次の行を Model Studio の API キーに置き換えてください: String apiKey = "sk-xxx"
            String apiKey = System.getenv("DASHSCOPE_API_KEY");
    
            // JSON リクエストボディ文字列を作成
            String jsonBody = "{\n" +
                    "    \"model\": \"qwen-voice-design\",\n" +
                    "    \"input\": {\n" +
                    "        \"action\": \"delete\",\n" +
                    "        \"voice\": \"" + voiceName + "\"\n" +
                    "    }\n" +
                    "}";
    
            HttpURLConnection connection = null;
            try {
                // 以下はシンガポールリージョン向けの URL です。北京リージョンのモデルを使用する場合は、URL を次のように置き換えてください: https://dashscope.aliyuncs.com/api/v1/services/audio/tts/customization
                URL url = new URL("https://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customization");
                connection = (HttpURLConnection) url.openConnection();
    
                // リクエストメソッドおよびヘッダーを設定
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Authorization", "Bearer " + apiKey);
                connection.setRequestProperty("Content-Type", "application/json");
                connection.setDoOutput(true);
                connection.setDoInput(true);
    
                // リクエストボディを送信
                try (OutputStream os = connection.getOutputStream()) {
                    byte[] input = jsonBody.getBytes("UTF-8");
                    os.write(input, 0, input.length);
                    os.flush();
                }
    
                // レスポンスを取得
                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    // レスポンス内容を読み取り
                    StringBuilder response = new StringBuilder();
                    try (BufferedReader br = new BufferedReader(
                            new InputStreamReader(connection.getInputStream(), "UTF-8"))) {
                        String responseLine;
                        while ((responseLine = br.readLine()) != null) {
                            response.append(responseLine.trim());
                        }
                    }
    
                    // JSON レスポンスを解析
                    JsonObject jsonResponse = JsonParser.parseString(response.toString()).getAsJsonObject();
    
                    // エラーメッセージを確認
                    if (jsonResponse.has("code") && jsonResponse.get("code").getAsString().contains("VoiceNotFound")) {
                        String errorMessage = jsonResponse.has("message") ?
                                jsonResponse.get("message").getAsString() : "音声が見つかりません";
                        System.out.println("音声が存在しません: " + voiceName);
                        System.out.println("エラーメッセージ: " + errorMessage);
                        // 音声が存在しない場合、操作は成功とみなされます(目的が既に達成されているため)
                    } else if (jsonResponse.has("usage")) {
                        // 削除が成功したか確認
                        System.out.println("音声の削除に成功しました: " + voiceName);
                        String requestId = jsonResponse.has("request_id") ?
                                jsonResponse.get("request_id").getAsString() : "N/A";
                        System.out.println("リクエスト ID: " + requestId);
                    } else {
                        System.out.println("削除操作から予期しないレスポンス形式が返されました: " + response.toString());
                    }
    
                } else {
                    // エラーレスポンスを読み取り
                    StringBuilder errorResponse = new StringBuilder();
                    try (BufferedReader br = new BufferedReader(
                            new InputStreamReader(connection.getErrorStream(), "UTF-8"))) {
                        String responseLine;
                        while ((responseLine = br.readLine()) != null) {
                            errorResponse.append(responseLine.trim());
                        }
                    }
    
                    System.out.println("音声削除リクエストが失敗しました。ステータスコード: " + responseCode);
                    System.out.println("エラーレスポンス: " + errorResponse.toString());
                }
    
            } catch (Exception e) {
                System.err.println("リクエスト中にエラーが発生しました: " + e.getMessage());
                e.printStackTrace();
            } finally {
                if (connection != null) {
                    connection.disconnect();
                }
            }
        }
    }

音声合成

音声デザインで作成した音声を使用してパーソナライズされた音声合成を行うには、「はじめに:音声デザインから音声合成へ」をご参照ください。

音声デザイン音声合成モデル(例:qwen3-tts-vd-realtime-2026-01-15)は専用モデルです。音声デザインで作成した音声のみをサポートしており、Chelsie、Serena、Ethan、Cherry などのシステム音声はサポートしていません。

音声クォータおよび自動クリーンアップルール

  • 合計制限: アカウントごとに最大 1000 音声

    音声の数(total_count)をクエリするには、音声リストのクエリ
  • 自動クリーンアップ: 過去 1 年間に音声合成リクエストで使用されていない音声は、システムによって自動的に削除されます。

課金情報

音声デザインと音声合成は、別々に課金されます。

  • 音声デザイン: 音声の作成 は、$0.2 / 音声 で課金されます。作成に失敗した場合は課金されません。

    説明

    無料クォータ情報(シンガポールリージョンでのみ利用可能):

    • Alibaba Cloud Model Studio を有効化してから 90 日以内に、音声作成を 10 回無料でご利用いただけます。

    • 作成に失敗した場合は、無料クォータから差し引かれません。

    • 音声を削除しても、無料クォータの使用量は復元されません。

    • 無料クォータを使い切った後、または 90 日の有効期間が終了した後は、音声作成は $0.2 / 音声 で課金されます。

  • 音声デザインで作成したカスタム音声を使用した音声合成: 文字数単位で課金されます。詳細については、「リアルタイム音声合成 - Qwen」または「音声合成 - Qwen」をご参照ください。

エラーメッセージ

エラーが発生した場合は、「エラーメッセージ」を参照してトラブルシューティングを行ってください。