All Products
Search
Document Center

Alibaba Cloud Model Studio:Referensi API kloning suara

Last Updated:Sep 02, 2026

Kloning suara dari rekaman audio berdurasi 10–20 detik tanpa pelatihan. Dokumen ini mencakup parameter dan penggunaan API kloning suara. Untuk pemanggilan model, lihat Qwen-Omni-Realtime atau Non-real-time (Qwen-Omni) .

PentingDokumen ini hanya berlaku untuk API kloning suara Qwen-Omni dan Qwen-Omni-Realtime. Jika Anda menggunakan model text-to-speech, lihat Sintesis ucapan.

PentingAlibaba Cloud Model Studio telah merilis domain khusus ruang kerja untuk wilayah China (Beijing) dan Singapura. Domain khusus baru ini memberikan performa lebih unggul dan stabilitas lebih tinggi untuk permintaan inferensi. Kami merekomendasikan migrasi ke domain baru:

  • China (Beijing): dari https://dashscope.aliyuncs.com ke https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com
  • Singapura: dari https://dashscope-intl.aliyuncs.com ke https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com

{WorkspaceId} adalah ID ruang kerja Anda, yang dapat ditemukan pada halaman Workspace Details di Konsol Alibaba Cloud Model Studio. Domain yang telah ada tetap berfungsi sepenuhnya.

Persyaratan audio

Input audio berkualitas tinggi menghasilkan kloning yang lebih baik.

Item

Requirement

Supported formats

WAV (16-bit), MP3, M4A

Duration

Direkomendasikan 10 hingga 20 detik. Maksimum: 60 detik.

File size

< 10 MB

Sample rate

>= 24 kHz

Channels

Mono

Content

Audio harus berisi minimal 3 detik ucapan jelas yang berkelanjutan tanpa suara latar. Sisa durasi boleh mencakup jeda singkat (<=2 detik). Hindari musik latar, kebisingan, atau suara lain sepanjang rekaman. Gunakan audio ucapan normal sebagai input. Jangan unggah lagu atau rekaman bernyanyi.

Languages

Chinese (zh), English (en), German (de), Italian (it), Portuguese (pt), Spanish (es), Japanese (ja), Korean (ko), French (fr), Russian (ru), Thai (th), Indonesian (id), Arabic (ar), Czech (cs), Danish (da), Dutch (nl), Finnish (fi), Hebrew (he), Hindi (hi), Icelandic (is), Malay (ms), Norwegian (no), Persian (fa), Polish (pl), Swedish (sv), Tagalog (tl), Turkish (tr), Urdu (ur), Vietnamese (vi)

Dialek Tiongkok: Dongbei, Shannxi, Sichuan, Henan, Changsha, Tianjin, Hangzhou, Liaoning, Shenyang, Anshan

Memulai dengan cepat

1. Alur kerja

Kloning suara mengikuti alur kerja "buat terlebih dahulu, lalu gunakan":

  1. Buat suara

    Panggil API Create a voice dan unggah klip audio. Sistem menganalisis audio dan membuat suara kloning kustom. Anda harus menentukantarget_modelpada langkah ini untuk mendeklarasikan model omni mana yang akan menggerakkan suara tersebut.

    Jika Anda sudah memiliki suara yang dibuat (panggil API List voices untuk memeriksa), lewati langkah ini dan lanjutkan ke langkah berikutnya.

  2. Gunakan suara dalam percakapan

    Panggil API Omni (realtime atau non-realtime) dan masukkan suara yang diperoleh pada langkah sebelumnya. Model omni yang ditentukan pada langkah ini harus sesuai dengantarget_modeldari langkah sebelumnya.

2. Konfigurasi model dan prasyarat

Pilih model dan lengkapi prasyarat sebelum memulai.

Konfigurasi model

Kloning suara memerlukan dua model:

  • Model kloning suara: qwen-voice-enrollment

  • Model omni yang menggerakkan suara:

    • qwen3.5-omni-plus-realtime
    • qwen3.5-omni-flash-realtime
    • qwen3.5-omni-plus
    • qwen3.5-omni-flash

Prasyarat

  1. Dapatkan Kunci API: Dapatkan Kunci API. Untuk keamanan, konfigurasikan Kunci API sebagai Variabel lingkungan.
  2. Instal SDK: Pastikan Anda telah menginstal SDK DashScope terbaru.
  3. Siapkan audio untuk kloning: Audio harus memenuhi Persyaratan audio.

3. Contoh end-to-end

Contoh ini melakukan kloning suara dan menggunakannya dalam percakapan.

Prinsip utama: target_model yang ditentukan selama kloning harus sesuai dengan model dalam pemanggilan API Omni berikutnya. Jika tidak, sintesis gagal. Ganti file contoh voice.mp3 dengan audio Anda sendiri.

Realtime

Berlaku untuk model seri Qwen3.5-Omni-Realtime. Untuk informasi lebih lanjut, lihat Qwen-Omni-Realtime.

# Persyaratan: dashscope >= 1.23.9, pyaudio
import os
import requests
import base64
import pathlib
import time
import pyaudio
from dashscope.audio.qwen_omni import MultiModality, OmniRealtimeCallback, OmniRealtimeConversation
import dashscope
# Wilayah China (Beijing). Ganti {WorkspaceId} dengan ID ruang kerja Bailian Anda. URL bervariasi berdasarkan wilayah.
dashscope.base_http_api_url = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1"

# ======= Konfigurasi =======
DEFAULT_TARGET_MODEL = "qwen3.5-omni-plus-realtime"  # Harus menggunakan model yang sama untuk kloning dan percakapan
DEFAULT_PREFERRED_NAME = "guanyu"
DEFAULT_AUDIO_MIME_TYPE = "audio/mpeg"
VOICE_FILE_PATH = "voice.mp3"  # Jalur ke file audio lokal untuk kloning suara

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:
    """
    Buat suara kustom dan kembalikan parameter suara.
    """
    # Kunci API berbeda antara wilayah Singapura dan Beijing. Dapatkan Kunci API: https://www.alibabacloud.com/help/en/model-studio/get-api-key
    # Jika Anda belum mengatur variabel lingkungan, ganti baris berikut dengan: 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 audio tidak ditemukan: {file_path}")

    base64_str = base64.b64encode(file_path_obj.read_bytes()).decode()
    data_uri = f"data:{audio_mime_type};base64,{base64_str}"

    # Berikut adalah URL wilayah Singapura. Ganti {WorkspaceId} dengan ID ruang kerja aktual Anda. URL bervariasi berdasarkan wilayah.
    url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization"
    payload = {
        "model": "qwen-voice-enrollment",
        "input": {
            "action": "create",
            "target_model": target_model,
            "preferred_name": preferred_name,
            "audio": {"data": data_uri}
        }
    }
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }

    resp = requests.post(url, json=payload, headers=headers)
    if resp.status_code != 200:
        raise RuntimeError(f"Gagal membuat suara: {resp.status_code}, {resp.text}")

    try:
        return resp.json()["output"]["voice"]
    except (KeyError, ValueError) as e:
        raise RuntimeError(f"Gagal mengurai respons suara: {e}")

class SimpleCallback(OmniRealtimeCallback):
    def __init__(self, pya):
        self.pya = pya
        self.out = None
    def on_open(self):
        self.out = self.pya.open(
            format=pyaudio.paInt16,
            channels=1,
            rate=24000,
            output=True
        )
    def on_event(self, response):
        if response['type'] == 'response.audio.delta':
            self.out.write(base64.b64decode(response['delta']))
        elif response['type'] == 'conversation.item.input_audio_transcription.completed':
            print(f"[User] {response['transcript']}")
        elif response['type'] == 'response.audio_transcript.done':
            print(f"[LLM] {response['transcript']}")

if __name__ == '__main__':
    # Jika Anda belum mengatur variabel lingkungan, ganti baris berikut dengan: dashscope.api_key = "sk-xxx"
    dashscope.api_key = os.getenv("DASHSCOPE_API_KEY")
    # Berikut adalah URL wilayah Singapura. Ganti {WorkspaceId} dengan ID ruang kerja aktual Anda. URL bervariasi berdasarkan wilayah.
    url = "wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime"

    # Langkah 1: Kloning suara
    voice = create_voice(VOICE_FILE_PATH)
    print(f"Kloning suara selesai. Suara: {voice}")

    # Langkah 2: Mulai percakapan real-time dengan suara hasil kloning
    pya = pyaudio.PyAudio()
    callback = SimpleCallback(pya)
    conv = OmniRealtimeConversation(model=DEFAULT_TARGET_MODEL, callback=callback, url=url)
    conv.connect()
    conv.update_session(
        output_modalities=[MultiModality.AUDIO, MultiModality.TEXT],
        voice=voice  # Gunakan suara hasil kloning
    )
    mic = pya.open(format=pyaudio.paInt16, channels=1, rate=16000, input=True)
    print("Percakapan dimulai. Bicaralah ke mikrofon Anda (Ctrl+C untuk keluar)...")
    try:
        while True:
            audio_data = mic.read(3200, exception_on_overflow=False)
            conv.append_audio(base64.b64encode(audio_data).decode())
            time.sleep(0.01)
    except KeyboardInterrupt:
        conv.close()
        mic.close()
        callback.out.close()
        pya.terminate()
        print("\nPercakapan diakhiri")
import com.alibaba.dashscope.audio.omni.*;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
import com.google.gson.Gson;
import com.google.gson.JsonObject;

import javax.sound.sampled.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Base64;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;

public class Main {
        // Wilayah China (Beijing). Ganti {WorkspaceId} dengan ID ruang kerja Bailian Anda. URL bervariasi berdasarkan wilayah.
        Constants.baseHttpApiUrl = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1";
    // ===== Konstanta =====
    // Gunakan model yang sama untuk kloning suara dan percakapan real-time
    private static final String TARGET_MODEL = "qwen3.5-omni-plus-realtime";
    private static final String PREFERRED_NAME = "guanyu";
    // Jalur relatif ke file audio lokal untuk kloning suara
    private static final String AUDIO_FILE = "voice.mp3";
    private static final String AUDIO_MIME_TYPE = "audio/mpeg";

    // Hasilkan URI data
    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;
    }

    // Panggil API untuk membuat suara
    public static String createVoice() throws Exception {
        // Kunci API untuk wilayah Singapura dan Beijing berbeda. Dapatkan Kunci API: https://www.alibabacloud.com/help/en/model-studio/get-api-key
        // Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan: 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) + "\""
                        +     "}"
                        + "}"
                        + "}";

        // Berikut adalah URL wilayah Singapura. Ganti {WorkspaceId} dengan ID ruang kerja aktual Anda. URL bervariasi berdasarkan wilayah.
        String url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization";
        HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("Authorization", "Bearer " + apiKey);
        con.setRequestProperty("Content-Type", "application/json");
        con.setDoOutput(true);

        try (OutputStream os = con.getOutputStream()) {
            os.write(jsonPayload.getBytes(StandardCharsets.UTF_8));
        }

        int status = con.getResponseCode();
        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(status >= 200 && status < 300 ? con.getInputStream() : con.getErrorStream(),
                        StandardCharsets.UTF_8))) {
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                response.append(line);
            }
            if (status == 200) {
                JsonObject jsonObj = new Gson().fromJson(response.toString(), JsonObject.class);
                return jsonObj.getAsJsonObject("output").get("voice").getAsString();
            }
            throw new IOException("Gagal membuat suara: " + status + " - " + response);
        }
    }

    // Pemutar audio sederhana
    static class SimpleAudioPlayer {
        private final SourceDataLine line;
        private final Queue<byte[]> audioQueue = new ConcurrentLinkedQueue<>();
        private final Thread playerThread;
        private final AtomicBoolean shouldStop = new AtomicBoolean(false);

        public SimpleAudioPlayer() throws LineUnavailableException {
            AudioFormat format = new AudioFormat(24000, 16, 1, true, false);
            line = AudioSystem.getSourceDataLine(format);
            line.open(format);
            line.start();
            playerThread = new Thread(() -> {
                while (!shouldStop.get()) {
                    byte[] audio = audioQueue.poll();
                    if (audio != null) {
                        line.write(audio, 0, audio.length);
                    } else {
                        try { Thread.sleep(10); } catch (InterruptedException ignored) {}
                    }
                }
            }, "AudioPlayer");
            playerThread.start();
        }

        public void play(String base64Audio) {
            audioQueue.add(Base64.getDecoder().decode(base64Audio));
        }

        public void close() {
            shouldStop.set(true);
            try { playerThread.join(1000); } catch (InterruptedException ignored) {}
            line.drain();
            line.close();
        }
    }

    public static void main(String[] args) {
        try {
            // 1. Kloning suara: buat suara kustom
            String voice = createVoice();
            System.out.println("Kloning suara selesai. Suara: " + voice);

            // 2. Gunakan suara hasil kloning dalam percakapan real-time
            SimpleAudioPlayer player = new SimpleAudioPlayer();
            AtomicBoolean shouldStop = new AtomicBoolean(false);

            OmniRealtimeParam param = OmniRealtimeParam.builder()
                    .model(TARGET_MODEL)
                    // Kunci API untuk wilayah Singapura dan Beijing berbeda. Dapatkan Kunci API: https://www.alibabacloud.com/help/en/model-studio/get-api-key
                    // Jika Anda belum mengonfigurasi variabel lingkungan, ganti baris berikut dengan: .apikey("sk-xxx")
                    .apikey(System.getenv("DASHSCOPE_API_KEY"))
                    // Berikut adalah URL wilayah Singapura. Ganti {WorkspaceId} dengan ID ruang kerja aktual Anda. URL bervariasi berdasarkan wilayah.
                    .url("wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/realtime")
                    .build();

            OmniRealtimeConversation conversation = new OmniRealtimeConversation(param, new OmniRealtimeCallback() {
                @Override public void onOpen() { System.out.println("Koneksi terbentuk"); }
                @Override public void onClose(int code, String reason) {
                    System.out.println("Koneksi ditutup (" + code + "): " + reason);
                    shouldStop.set(true);
                }
                @Override public void onEvent(JsonObject event) {
                    String type = event.get("type").getAsString();
                    if ("response.audio.delta".equals(type)) {
                        player.play(event.get("delta").getAsString());
                    } else if ("conversation.item.input_audio_transcription.completed".equals(type)) {
                        System.out.println("[User] " + event.get("transcript").getAsString());
                    } else if ("response.audio_transcript.done".equals(type)) {
                        System.out.println("[LLM] " + event.get("transcript").getAsString());
                    }
                }
            });

            conversation.connect();
            conversation.updateSession(OmniRealtimeConfig.builder()
                    .modalities(Arrays.asList(OmniRealtimeModality.AUDIO, OmniRealtimeModality.TEXT))
                    .voice(voice)  // Gunakan suara kustom hasil kloning
                    .enableTurnDetection(true)
                    .enableInputAudioTranscription(true)
                    .build()
            );

            System.out.println("Percakapan dimulai. Bicaralah ke mikrofon (Ctrl+C untuk keluar)...");
            AudioFormat format = new AudioFormat(16000, 16, 1, true, false);
            TargetDataLine mic = AudioSystem.getTargetDataLine(format);
            mic.open(format);
            mic.start();

            ByteBuffer buffer = ByteBuffer.allocate(3200);
            while (!shouldStop.get()) {
                int bytesRead = mic.read(buffer.array(), 0, buffer.capacity());
                if (bytesRead > 0) {
                    conversation.appendAudio(Base64.getEncoder().encodeToString(buffer.array()));
                }
                Thread.sleep(20);
            }

            conversation.close(1000, "Keluar normal");
            player.close();
            mic.close();
            System.out.println("\nPercakapan diakhiri");
        } catch (NoApiKeyException e) {
            System.err.println("KUNCI API tidak ditemukan. Atur variabel lingkungan DASHSCOPE_API_KEY.");
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.exit(0);
    }
}

Non-realtime

Berlaku untuk model seri Qwen3.5-Omni. Untuk informasi lebih lanjut, lihat Non-real-time (Qwen-Omni).

# Persyaratan: dashscope >= 1.23.9, soundfile, numpy
import os
import requests
import base64
import pathlib
import numpy as np
import soundfile as sf
import dashscope
# Wilayah China (Beijing). Ganti {WorkspaceId} dengan ID ruang kerja Bailian Anda. URL bervariasi berdasarkan wilayah.
dashscope.base_http_api_url = "https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1"

# ======= Konfigurasi =======
DEFAULT_TARGET_MODEL = "qwen3.5-omni-plus"  # Kloning suara dan panggilan non-realtime harus menggunakan model yang sama
DEFAULT_PREFERRED_NAME = "guanyu"
DEFAULT_AUDIO_MIME_TYPE = "audio/mpeg"
VOICE_FILE_PATH = "voice.mp3"  # Jalur ke file audio lokal untuk kloning suara

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:
    """
    Buat suara kustom dan kembalikan parameter suara.
    """
    # Kunci API berbeda antara wilayah Singapura dan Beijing. Dapatkan Kunci API: https://www.alibabacloud.com/help/en/model-studio/get-api-key
    # Jika variabel lingkungan belum dikonfigurasi, ganti baris berikut dengan: 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 audio tidak ditemukan: {file_path}")

    base64_str = base64.b64encode(file_path_obj.read_bytes()).decode()
    data_uri = f"data:{audio_mime_type};base64,{base64_str}"

    # Berikut adalah URL wilayah Singapura. Ganti {WorkspaceId} dengan ID ruang kerja aktual Anda. URL bervariasi berdasarkan wilayah.
    url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization"
    payload = {
        "model": "qwen-voice-enrollment",
        "input": {
            "action": "create",
            "target_model": target_model,
            "preferred_name": preferred_name,
            "audio": {"data": data_uri}
        }
    }
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }

    resp = requests.post(url, json=payload, headers=headers)
    if resp.status_code != 200:
        raise RuntimeError(f"Gagal membuat suara: {resp.status_code}, {resp.text}")

    try:
        return resp.json()["output"]["voice"]
    except (KeyError, ValueError) as e:
        raise RuntimeError(f"Gagal mengurai respons suara: {e}")

if __name__ == '__main__':
    # Berikut adalah URL wilayah Singapura. Ganti {WorkspaceId} dengan ID ruang kerja aktual Anda. URL bervariasi berdasarkan wilayah.
    dashscope.base_http_api_url = 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1'

    # 1. Kloning suara: buat suara kustom
    voice = create_voice(VOICE_FILE_PATH)
    print(f"Kloning suara selesai. Suara: {voice}")

    # 2. Percakapan non-realtime dengan suara hasil kloning
    messages = [{"role": "user", "content": [{"text": "Hello, please introduce yourself"}]}]

    response = dashscope.MultiModalConversation.call(
        # Jika variabel lingkungan belum dikonfigurasi, ganti dengan: api_key="sk-xxx"
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        model=DEFAULT_TARGET_MODEL,
        messages=messages,
        modalities=["text", "audio"],
        audio={"voice": voice, "format": "wav"},  # Gunakan suara hasil kloning
        stream=True
    )

    print("Respons model:")
    audio_base64_string = ""
    for r in response:
        try:
            content = r.output.choices[0].message.content
            for item in content:
                if isinstance(item, dict):
                    if "audio" in item:
                        audio_base64_string += item["audio"].get("data", "")
                    elif "text" in item:
                        print(item["text"], end="")
        except Exception:
            pass

    if audio_base64_string:
        wav_bytes = base64.b64decode(audio_base64_string)
        audio_np = np.frombuffer(wav_bytes, dtype=np.int16)
        sf.write("audio_cloned.wav", audio_np, samplerate=24000)
        print("\nAudio disimpan ke: audio_cloned.wav")
import com.google.gson.Gson;
import com.google.gson.JsonObject;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class Main {
    // ===== Konstanta =====
    // Kloning suara dan panggilan non-realtime harus menggunakan model yang sama
    private static final String TARGET_MODEL = "qwen3.5-omni-plus";
    private static final String PREFERRED_NAME = "guanyu";
    // Jalur ke file audio lokal untuk kloning suara
    private static final String AUDIO_FILE = "voice.mp3";
    private static final String AUDIO_MIME_TYPE = "audio/mpeg";

    // Tulis data PCM sebagai file WAV standar
    public static void writeWav(String path, byte[] pcmData, int sampleRate) throws IOException {
        int channels = 1, bitsPerSample = 16;
        int byteRate = sampleRate * channels * bitsPerSample / 8;
        int blockAlign = channels * bitsPerSample / 8;
        ByteBuffer header = ByteBuffer.allocate(44).order(ByteOrder.LITTLE_ENDIAN);
        header.put("RIFF".getBytes()); header.putInt(36 + pcmData.length);
        header.put("WAVE".getBytes()); header.put("fmt ".getBytes());
        header.putInt(16); header.putShort((short) 1); header.putShort((short) channels);
        header.putInt(sampleRate); header.putInt(byteRate);
        header.putShort((short) blockAlign); header.putShort((short) bitsPerSample);
        header.put("data".getBytes()); header.putInt(pcmData.length);
        try (FileOutputStream fos = new FileOutputStream(path)) {
            fos.write(header.array());
            fos.write(pcmData);
        }
    }

    // Hasilkan URI data dari file
    public static String toDataUrl(String filePath) throws IOException {
        byte[] bytes = Files.readAllBytes(Paths.get(filePath));
        String encoded = Base64.getEncoder().encodeToString(bytes);
        return "data:" + AUDIO_MIME_TYPE + ";base64," + encoded;
    }

    // Panggil API untuk membuat suara
    public static String createVoice() throws Exception {
        // Kunci API berbeda antara wilayah Singapura dan Beijing. Dapatkan Kunci API: https://www.alibabacloud.com/help/en/model-studio/get-api-key
        // Jika variabel lingkungan belum dikonfigurasi, ganti baris berikut dengan: 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) + "\""
                        +     "}"
                        + "}"
                        + "}";

        // Berikut adalah URL wilayah Singapura. Ganti {WorkspaceId} dengan ID ruang kerja aktual Anda. URL bervariasi berdasarkan wilayah.
        String url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization";
        HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("Authorization", "Bearer " + apiKey);
        con.setRequestProperty("Content-Type", "application/json");
        con.setDoOutput(true);

        try (OutputStream os = con.getOutputStream()) {
            os.write(jsonPayload.getBytes(StandardCharsets.UTF_8));
        }

        int status = con.getResponseCode();
        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(status >= 200 && status < 300 ? con.getInputStream() : con.getErrorStream(),
                        StandardCharsets.UTF_8))) {
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                response.append(line);
            }
            if (status == 200) {
                JsonObject jsonObj = new Gson().fromJson(response.toString(), JsonObject.class);
                return jsonObj.getAsJsonObject("output").get("voice").getAsString();
            }
            throw new IOException("Gagal membuat suara: " + status + " - " + response);
        }
    }

    public static void main(String[] args) {
        try {
            // Kunci API berbeda antara wilayah Singapura dan Beijing. Dapatkan Kunci API: https://www.alibabacloud.com/help/en/model-studio/get-api-key
            // Jika variabel lingkungan belum dikonfigurasi, ganti baris berikut dengan: String apiKey = "sk-xxx"
            String apiKey = System.getenv("DASHSCOPE_API_KEY");

            // 1. Kloning suara: buat suara kustom
            String voice = createVoice();
            System.out.println("Kloning suara selesai. Suara: " + voice);

            // 2. Percakapan non-realtime dengan suara hasil kloning (API kompatibel OpenAI)
            String requestBody = "{"
                    + "\"model\": \"" + TARGET_MODEL + "\","
                    + "\"messages\": [{\"role\": \"user\", \"content\": \"Hello, please introduce yourself\"}],"
                    + "\"modalities\": [\"text\", \"audio\"],"
                    + "\"audio\": {\"voice\": \"" + voice + "\", \"format\": \"wav\"},"
                    + "\"stream\": true,"
                    + "\"stream_options\": {\"include_usage\": true}"
                    + "}";

            // Berikut adalah URL wilayah Singapura. Ganti {WorkspaceId} dengan ID ruang kerja aktual Anda. URL bervariasi berdasarkan wilayah.
            String url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions";
            HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
            con.setRequestMethod("POST");
            con.setRequestProperty("Authorization", "Bearer " + apiKey);
            con.setRequestProperty("Content-Type", "application/json");
            con.setDoOutput(true);

            try (OutputStream os = con.getOutputStream()) {
                os.write(requestBody.getBytes(StandardCharsets.UTF_8));
            }

            // 3. Uraikan respons SSE streaming
            StringBuilder audioBase64 = new StringBuilder();
            System.out.println("Respons model:");

            try (BufferedReader br = new BufferedReader(
                    new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8))) {
                String line;
                while ((line = br.readLine()) != null) {
                    if (!line.startsWith("data: ") || line.equals("data: [DONE]")) continue;
                    String json = line.substring(6);
                    JsonObject chunk = new Gson().fromJson(json, JsonObject.class);
                    if (!chunk.has("choices") || chunk.getAsJsonArray("choices").size() == 0) continue;

                    JsonObject delta = chunk.getAsJsonArray("choices").get(0)
                            .getAsJsonObject().getAsJsonObject("delta");
                    if (delta.has("content") && !delta.get("content").isJsonNull()) {
                        System.out.print(delta.get("content").getAsString());
                    }
                    if (delta.has("audio") && !delta.get("audio").isJsonNull()) {
                        JsonObject audio = delta.getAsJsonObject("audio");
                        if (audio.has("data")) {
                            audioBase64.append(audio.get("data").getAsString());
                        }
                    }
                }
            }

            // 4. Simpan file audio (API mengembalikan data PCM mentah, perlu header WAV)
            if (audioBase64.length() > 0) {
                byte[] pcmBytes = Base64.getDecoder().decode(audioBase64.toString());
                writeWav("audio_cloned.wav", pcmBytes, 24000);
                System.out.println("\nAudio disimpan ke: audio_cloned.wav");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Referensi API

Gunakan akun yang sama untuk semua API.

Create a voice

Unggah audio untuk kloning suara dan buat suara kustom.

  • URL

    North China 2 (Beijing):

POST https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/audio/tts/customization

Singapura:

POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization
  • Request headers

    Parameter

    Type

    Required

    Description

    Authorization

    string

    Supported

    Token otentikasi dalam format Bearer <your_api_key>. Ganti <your_api_key> dengan Kunci API Anda yang sebenarnya.

    Content-Type

    string

    Supported

    Jenis media badan permintaan. Atur ke application/json.

  • Badan permintaan mencakup semua parameter. Abaikan bidang opsional sesuai kebutuhan. Perhatikan perbedaan antara:

    Pentingmodel: Model kloning suara. Atur ke qwen-voice-enrollment.

    target_model: Model omni yang menggerakkan suara. Nilai ini harus sesuai dengan model yang digunakan dalam pemanggilan API multimodal real-time berikutnya. Jika tidak, sintesis akan gagal.

{
    "model": "qwen-voice-enrollment",
    "input": {
        "action": "create",
        "target_model": "qwen3.5-omni-plus-realtime",
        "preferred_name": "guanyu",
        "audio": {
            "data": "https://xxx.wav"
        },
        "text": "Opsional. Transkrip audio dalam audio.data.",
        "language": "Opsional. Bahasa audio dalam audio.data, seperti zh."
    }
}
  • Request parameters
    ParameterTypeDefaultRequiredDescription

    model

    string

    Supported

    Model kloning suara. Atur ke qwen-voice-enrollment.

    action

    string

    Supported

    Jenis aksi. Atur ke create.

    target_model

    string

    Supported

    Model omni yang menggerakkan suara:

    • qwen3.5-omni-plus-realtime
    • qwen3.5-omni-flash-realtime
    • qwen3.5-omni-plus
    • qwen3.5-omni-flash

    Ini harus sesuai dengan model omni yang digunakan dalam pemanggilan API berikutnya. Jika tidak, sintesis gagal.

    preferred_name

    string

    Supported

    Nama yang mudah dibaca untuk suara. Karakter yang diizinkan: angka, huruf, garis bawah. Maksimum: 16 karakter.

    Kata kunci ini muncul dalam nama suara akhir. Misalnya, jika kata kunci adalah "guanyu", nama suara yang dihasilkan adalah "qwen-omni-vc-guanyu-voice-20250812105009984-838b".

    audio.data

    string

    Supported

    Audio untuk kloning (ikuti Panduan perekaman saat merekam, dan pastikan audio memenuhi Persyaratan audio).

    Kirimkan data audio dengan salah satu cara berikut:

    1. Data URL

      Format: data:<mediatype>;base64,<data>

      • <mediatype>: Jenis MIME

        • WAV: audio/wav
        • MP3: audio/mpeg
        • M4A: audio/mp4
      • <data>: String yang dienkripsi Base64 dari audio

        Pengodean Base64 memperbesar ukuran file. Pastikan hasil pengodeannya tidak melebihi 10 MB.

      • Contoh: data:audio/wav;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4LjI5LjEwMAAAAAAAAAAAAAAA//PAxABQ/BXRbMPe4IQAhl9

        Lihat contoh kode

        import base64, pathlib
        
        # input.mp3 adalah file audio lokal untuk kloning suara. Ganti dengan jalur file Anda sendiri. Pastikan file memenuhi persyaratan audio.
        file_path = pathlib.Path("input.mp3")
        base64_str = base64.b64encode(file_path.read_bytes()).decode()
        data_uri = f"data:audio/mpeg;base64,{base64_str}"
        
        import java.nio.file.*;
        import java.util.Base64;
        
        public class Main {
            /**
             * filePath adalah file audio lokal untuk kloning suara. Ganti dengan jalur file Anda sendiri. Pastikan file memenuhi persyaratan audio.
             */
            public static String toDataUrl(String filePath) throws Exception {
                byte[] bytes = Files.readAllBytes(Paths.get(filePath));
                String encoded = Base64.getEncoder().encodeToString(bytes);
                return "data:audio/mpeg;base64," + encoded;
            }
        
            // Contoh penggunaan
            public static void main(String[] args) throws Exception {
                System.out.println(toDataUrl("input.mp3"));
            }
        }
        
    2. URL audio (kami merekomendasikan mengunggah audio Anda ke OSS)

      • Ukuran file tidak boleh melebihi 10 MB.
      • URL harus dapat diakses publik tanpa otentikasi.

    text

    string

    Unsupported

    Transkrip yang sesuai dengan audio dalam audio.data.

    Jika disediakan, server memvalidasi audio terhadap teks. Jika ketidaksesuaian terlalu besar, akan dikembalikan Audio.PreprocessError.

    language

    string

    Unsupported

    Bahasa audio dalam audio.data.

    Nilai yang didukung: zh (Tiongkok), en (Inggris), de (Jerman), it (Italia), pt (Portugis), es (Spanyol), ja (Jepang), ko (Korea), fr (Prancis), ru (Rusia), th (Thailand), id (Indonesia), ar (Arab), cs (Ceko), da (Denmark), nl (Belanda), fi (Finlandia), he (Ibrani), hi (Hindi), is (Islandia), ms (Melayu), no (Norwegia), fa (Persia), pl (Polandia), sv (Swedia), tl (Tagalog), tr (Turki), ur (Urdu), vi (Vietnam).

    Dialek Tiongkok: Dongbei, Shannxi, Sichuan, Henan, Changsha, Tianjin, Hangzhou, Liaoning, Shenyang, Anshan.

    Atur ini ke bahasa sebenarnya dari audio yang digunakan untuk kloning.

  • Response parameters

    Lihat contoh respons

    {
        "output": {
            "voice": "yourVoice",
            "target_model": "qwen3.5-omni-plus-realtime"
        },
        "usage": {
            "count": 1
        },
        "request_id": "yourRequestId"
    }
    

    Parameter respons utama:

    Parameter

    Type

    Description

    voice

    string

    Nama suara. Gunakan nilai ini langsung sebagai parameter voice dalam API multimodal real-time.

    target_model

    string

    Model omni yang menggerakkan suara:

    • qwen3.5-omni-plus-realtime

    • qwen3.5-omni-flash-realtime

    Ini harus sesuai dengan model yang digunakan dalam pemanggilan API multimodal real-time berikutnya. Jika tidak, sintesis gagal.

    request_id

    string

    ID Permintaan.

    count

    integer

    Jumlah operasi "buat suara" yang ditagih untuk permintaan ini. Biayanya adalah $ count × 0.01.

    Saat membuat suara, count selalu 1.

  • Sample code

    Pentingmodel: Model kloning suara. Atur ke qwen-voice-enrollment.

    target_model: Model omni yang menggerakkan suara. Nilai ini harus sesuai dengan model yang digunakan dalam pemanggilan API multimodal real-time berikutnya. Jika tidak, sintesis akan gagal.

    curl

    Jika Anda belum mengatur Kunci API sebagai variabel lingkungan, ganti $DASHSCOPE_API_KEY dalam contoh dengan Kunci API Anda yang sebenarnya.

    # ======= Penting =======
    # Berikut adalah URL wilayah Singapura. Ganti {WorkspaceId} dengan ID ruang kerja aktual Anda. URL bervariasi berdasarkan wilayah.
    # Kunci API berbeda antar wilayah. Dapatkan Kunci API: https://www.alibabacloud.com/help/en/model-studio/get-api-key
    # === Hapus komentar ini sebelum menjalankan ===
    
    curl --location --request POST 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization' \
    --header 'Authorization: Bearer $DASHSCOPE_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "qwen-voice-enrollment",
        "input": {
            "action": "list",
            "page_size": 10,
            "page_index": 0
        }
    }'
    

    python

    import os
    import requests
    
    # Kunci API berbeda antar wilayah. Dapatkan Kunci API: https://www.alibabacloud.com/help/en/model-studio/get-api-key
    # Jika Anda belum mengatur variabel lingkungan, ganti baris berikut dengan: api_key = "sk-xxx"
    api_key = os.getenv("DASHSCOPE_API_KEY")
    # Berikut adalah URL wilayah Singapura. Ganti {WorkspaceId} dengan ID ruang kerja aktual Anda. URL bervariasi berdasarkan wilayah.
    url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization"
    
    payload = {
        "model": "qwen-voice-enrollment", # Jangan ubah
        "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("Status HTTP:", response.status_code)
    
    if response.status_code == 200:
        data = response.json()
        voice_list = data["output"]["voice_list"]
    
        print("Daftar suara:")
        for item in voice_list:
            print(f"- Suara: {item['voice']}  Dibuat: {item['gmt_create']}  Model: {item['target_model']}")
    else:
        print("Permintaan gagal:", 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) {
            // Kunci API berbeda antar wilayah. Dapatkan Kunci API: https://www.alibabacloud.com/help/en/model-studio/get-api-key
            // Jika Anda belum mengatur variabel lingkungan, ganti baris berikut dengan: String apiKey = "sk-xxx"
            String apiKey = System.getenv("DASHSCOPE_API_KEY");
            // Berikut adalah URL wilayah Singapura. Ganti {WorkspaceId} dengan ID ruang kerja aktual Anda. URL bervariasi berdasarkan wilayah.
            String apiUrl = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization";
    
            // Badan permintaan JSON
            String jsonPayload =
                    "{"
                            + "\"model\": \"qwen-voice-enrollment\"," // Jangan ubah
                            + "\"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("Status HTTP: " + status);
                System.out.println("JSON Respons: " + 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 Daftar suara:");
                    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("- Suara: %s  Dibuat: %s  Model: %s\n",
                                voice, gmtCreate, targetModel);
                    }
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

List voices

Kueri suara yang telah Anda buat dengan pagination.

  • URL

    North China 2 (Beijing):

POST https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/audio/tts/customization

Singapura:

POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization
  • Request headers

    Parameter

    Type

    Required

    Description

    Authorization

    string

    Supported

    Token otentikasi dalam format Bearer <your_api_key>. Ganti <your_api_key> dengan Kunci API Anda yang sebenarnya.

    Content-Type

    string

    Supported

    Jenis media badan permintaan. Atur ke application/json.

  • Request parameters

    Parameter

    Type

    Default

    Required

    Description

    model

    string

    -

    Supported

    Model kloning suara. Atur ke qwen-voice-enrollment.

    action

    string

    -

    Supported

    Jenis aksi. Atur ke list.

    page_index

    integer

    0

    Unsupported

    Indeks nomor halaman. Nilai valid: 0 hingga 1.000.000.

    page_size

    integer

    10

    Unsupported

    Jumlah item per halaman. Nilai valid: 0 hingga 1.000.000.

  • Response parameters

    Lihat contoh respons

    {
        "output": {
            "voice_list": [
                {
                    "voice": "yourVoice1",
                    "gmt_create": "2025-08-11 17:59:32",
                    "target_model": "qwen3.5-omni-plus-realtime"
                },
                {
                    "voice": "yourVoice2",
                    "gmt_create": "2025-08-11 17:38:10",
                    "target_model": "qwen3.5-omni-plus-realtime"
                }
            ]
        },
        "usage": {
            "count": 0
        },
        "request_id": "yourRequestId"
    }
    

    Parameter respons utama:

    Parameter

    Type

    Description

    voice

    string

    Nama suara. Gunakan nilai ini langsung dalam parameter voice API multimodal real-time.

    gmt_create

    string

    Waktu saat suara dibuat.

    target_model

    string

    Model omni yang menggerakkan suara:

    • qwen3.5-omni-plus-realtime

    • qwen3.5-omni-flash-realtime

    • qwen3.5-omni-plus

    • qwen3.5-omni-flash

    Ini harus sesuai dengan model omni yang digunakan dalam pemanggilan API berikutnya. Jika tidak, sintesis gagal.

    request_id

    string

    ID Permintaan.

    count

    integer

    Permintaan ini dikenai biaya berdasarkan jumlah aktual operasi 'Buat Suara'. Biaya untuk permintaan ini adalah $ count × 0.01 .

    Menampilkan daftar suara gratis. count selalu 0.

  • Sample code

    Pentingmodel: Model kloning suara. Nilainya tetap qwen-voice-enrollment. Jangan ubah nilai ini.

    cURL

    Jika Anda belum mengatur Kunci API sebagai variabel lingkungan, ganti $DASHSCOPE_API_KEY dalam contoh dengan Kunci API Anda yang sebenarnya.

    # ======= Penting =======
    # Berikut adalah URL wilayah Singapura. Ganti {WorkspaceId} dengan ID ruang kerja aktual Anda. URL bervariasi berdasarkan wilayah.
    # Kunci API berbeda antar wilayah. Dapatkan Kunci API: https://www.alibabacloud.com/help/en/model-studio/get-api-key
    # === Hapus komentar ini sebelum menjalankan ===
    
    curl --location --request POST 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization' \
    --header 'Authorization: Bearer $DASHSCOPE_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "qwen-voice-enrollment",
        "input": {
            "action": "list",
            "page_size": 10,
            "page_index": 0
        }
    }'
    

    Python

    import os
    import requests
    
    # Kunci API berbeda antar wilayah. Dapatkan Kunci API: https://www.alibabacloud.com/help/en/model-studio/get-api-key
    # Jika Anda belum mengatur variabel lingkungan, ganti baris berikut dengan: api_key = "sk-xxx"
    api_key = os.getenv("DASHSCOPE_API_KEY")
    # Berikut adalah URL wilayah Singapura. Ganti {WorkspaceId} dengan ID ruang kerja aktual Anda. URL bervariasi berdasarkan wilayah.
    url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization"
    
    payload = {
        "model": "qwen-voice-enrollment", # Jangan ubah
        "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("Status HTTP:", response.status_code)
    
    if response.status_code == 200:
        data = response.json()
        voice_list = data["output"]["voice_list"]
    
        print("Daftar suara:")
        for item in voice_list:
            print(f"- Suara: {item['voice']}  Dibuat: {item['gmt_create']}  Model: {item['target_model']}")
    else:
        print("Permintaan gagal:", 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) {
            // Kunci API berbeda antar wilayah. Dapatkan Kunci API: https://www.alibabacloud.com/help/en/model-studio/get-api-key
            // Jika Anda belum mengatur variabel lingkungan, ganti baris berikut dengan: String apiKey = "sk-xxx"
            String apiKey = System.getenv("DASHSCOPE_API_KEY");
            // Berikut adalah URL wilayah Singapura. Ganti {WorkspaceId} dengan ID ruang kerja aktual Anda. URL bervariasi berdasarkan wilayah.
            String apiUrl = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization";
    
            // Badan permintaan JSON
            String jsonPayload =
                    "{"
                            + "\"model\": \"qwen-voice-enrollment\"," // Jangan ubah
                            + "\"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("Status HTTP: " + status);
                System.out.println("JSON Respons: " + 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 Daftar suara:");
                    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("- Suara: %s  Dibuat: %s  Model: %s\n",
                                voice, gmtCreate, targetModel);
                    }
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

Delete a voice

Hapus suara tertentu dan bebaskan kuota yang terkait.

  • URL

    North China 2 (Beijing):

POST https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/audio/tts/customization

Singapura:

POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization
  • Request headers

    Parameter

    Type

    Required

    Description

    Authorization

    string

    Supported

    Token otentikasi dalam format Bearer <your_api_key>. Ganti <your_api_key> dengan Kunci API Anda yang sebenarnya.

    Content-Type

    string

    Supported

    Jenis media badan permintaan. Atur ke application/json.

  • Request body

    Abaikan bidang opsional sesuai kebutuhan.

    Pentingmodel: Model kloning suara. Nilainya tetap qwen-voice-enrollment. Jangan ubah nilai ini.

{
    "model": "qwen-voice-enrollment",
    "input": {
        "action": "delete",
        "voice": "yourVoice"
    }
}
  • Request parameters

    Parameter

    Type

    Default

    Required

    Description

    model

    string

    -

    Supported

    Model kloning suara. Atur ke qwen-voice-enrollment.

    action

    string

    -

    Supported

    Jenis aksi. Atur ke delete.

    voice

    string

    -

    Supported

    Suara yang akan dihapus.

  • Response parameters

    Lihat contoh respons

    {
        "usage": {
            "count": 0
        },
        "request_id": "yourRequestId"
    }
    

    Parameter respons utama:

    Parameter

    Type

    Description

    request_id

    string

    ID Permintaan.

    count

    integer

    Permintaan ini dikenai biaya berdasarkan jumlah aktual operasi 'Buat Suara'. Biaya untuk permintaan ini adalah $ count × 0.01 .

    Menghapus suara gratis. count selalu 0.

  • Sample code

    Pentingmodel: Model kloning suara. Nilainya tetap qwen-voice-enrollment. Jangan ubah nilai ini.

    cURL

    Jika Anda belum mengatur Kunci API sebagai variabel lingkungan, ganti $DASHSCOPE_API_KEY dalam contoh dengan Kunci API Anda yang sebenarnya.

    # ======= Penting =======
    # Berikut adalah URL wilayah Singapura. Ganti {WorkspaceId} dengan ID ruang kerja aktual Anda. URL bervariasi berdasarkan wilayah.
    # Kunci API berbeda antar wilayah. Dapatkan Kunci API: https://www.alibabacloud.com/help/en/model-studio/get-api-key
    # === Hapus komentar ini sebelum menjalankan ===
    
    curl --location --request POST 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization' \
    --header 'Authorization: Bearer $DASHSCOPE_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
        "model": "qwen-voice-enrollment",
        "input": {
            "action": "delete",
            "voice": "yourVoice"
        }
    }'
    

    Python

    import os
    import requests
    
    # Kunci API berbeda antar wilayah. Dapatkan Kunci API: https://www.alibabacloud.com/help/en/model-studio/get-api-key
    # Jika Anda belum mengatur variabel lingkungan, ganti baris berikut dengan: api_key = "sk-xxx"
    api_key = os.getenv("DASHSCOPE_API_KEY")
    # Berikut adalah URL wilayah Singapura. Ganti {WorkspaceId} dengan ID ruang kerja aktual Anda. URL bervariasi berdasarkan wilayah.
    url = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization"
    
    voice_to_delete = "yourVoice"  # Ganti dengan nama suara yang sebenarnya
    
    payload = {
        "model": "qwen-voice-enrollment", # Jangan ubah
        "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("Status HTTP:", response.status_code)
    
    if response.status_code == 200:
        data = response.json()
        request_id = data["request_id"]
    
        print(f"Berhasil dihapus")
        print(f"ID Permintaan: {request_id}")
    else:
        print("Permintaan gagal:", 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) {
            // Kunci API berbeda antar wilayah. Dapatkan Kunci API: https://www.alibabacloud.com/help/en/model-studio/get-api-key
            // Jika Anda belum mengatur variabel lingkungan, ganti baris berikut dengan: String apiKey = "sk-xxx"
            String apiKey = System.getenv("DASHSCOPE_API_KEY");
            // Berikut adalah URL wilayah Singapura. Ganti {WorkspaceId} dengan ID ruang kerja aktual Anda. URL bervariasi berdasarkan wilayah.
            String apiUrl = "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/audio/tts/customization";
            String voiceToDelete = "yourVoice"; // Ganti dengan nama suara yang sebenarnya
    
            // Bangun badan permintaan JSON
            String jsonPayload =
                    "{"
                            + "\"model\": \"qwen-voice-enrollment\"," // Jangan ubah
                            + "\"input\": {"
                            +     "\"action\": \"delete\","
                            +     "\"voice\": \"" + voiceToDelete + "\""
                            + "}"
                            + "}";
    
            try {
                // Buat koneksi 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);
    
                // Kirim badan permintaan
                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("Status HTTP: " + status);
                System.out.println("JSON Respons: " + 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("Berhasil dihapus");
                    System.out.println("ID Permintaan: " + requestId);
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

Use in conversation

Untuk menggunakan suara hasil kloning dalam percakapan, lihat Memulai dengan cepat.

Kuota suara dan pembersihan otomatis

Batas total: 1.000 suara per akun.

Tidak tersedia endpoint khusus untuk penghitungan. Gunakan API List voices untuk menghitung jumlah suara Anda.

Pembersihan otomatis: Suara yang tidak digunakan selama satu tahun akan dihapus secara otomatis.

Penagihan

Kloning suara dan pemanggilan model ditagih secara terpisah:

  • Kloning suara: dikenai biaya sebesar $0,01/suara. Pembuatan yang gagal tidak dikenai biaya.

    CatatanKuota gratis (hanya berlaku untuk wilayah China Beijing dan wilayah Internasional Singapura):

    • 1.000 pembuatan suara gratis dalam 90 hari setelah mengaktifkan Model Studio.
    • Pembuatan yang gagal tidak mengurangi kuota gratis.
    • Menghapus suara tidak mengembalikan kuota gratis.
    • Setelah kuota gratis habis atau periode 90 hari berakhir, pembuatan suara dikenai biaya sebesar $0,01/suara.
  • Percakapan menggunakan suara hasil kloning: ditagih berdasarkan penggunaan token untuk pemanggilan model. Untuk detail selengkapnya, lihat Harga inferensi model.

Hak cipta dan kepatuhan hukum

Anda bertanggung jawab atas kepemilikan dan penggunaan legal suara yang Anda unggah. Baca Perjanjian Layanan.

Panduan perekaman

Peralatan perekaman

Gunakan mikrofon peredam kebisingan atau rekam dengan ponsel dari jarak dekat di lingkungan yang tenang.

Lingkungan perekaman

Lokasi

  • Rekam di ruang tertutup kecil berukuran 10 meter persegi atau kurang.
  • Pilih ruangan dengan bahan penyerap suara, seperti busa akustik, karpet, atau gorden.
  • Hindari ruang besar terbuka, ruang konferensi, atau ruang kelas yang memiliki gema tinggi.

Kontrol kebisingan

  • Kebisingan luar ruangan: Tutup pintu dan jendela untuk menghalangi suara lalu lintas, konstruksi, dan suara eksternal lainnya.
  • Kebisingan dalam ruangan: Matikan AC, kipas, dan ballast lampu neon.
  • Rekam suara latar dengan ponsel Anda, lalu putar kembali dengan volume tinggi untuk mengidentifikasi sumber kebisingan tersembunyi.

Kontrol gema

  • Gema menyebabkan audio terdengar sumbang dan mengurangi kejelasan.
  • Kurangi pantulan dari permukaan halus dengan menutup gorden, membuka pintu lemari pakaian, serta menutupi meja dan rak menggunakan pakaian atau selimut.
  • Gunakan benda tidak beraturan, seperti rak buku dan furnitur berlapis, untuk menciptakan pantulan difus.

Penyusunan naskah

  • Sesuaikan naskah dengan skenario penggunaan target—misalnya, gunakan gaya dialog layanan pelanggan untuk skenario layanan pelanggan.
  • Pastikan naskah tidak mengandung konten sensitif atau ilegal (seperti materi politik, pornografi, atau kekerasan), karena hal tersebut dapat menyebabkan kegagalan kloning.
  • Hindari frasa pendek (seperti "halo" atau "ya"); gunakan kalimat lengkap.
  • Pertahankan koherensi semantik dan hindari jeda yang sering saat membaca. Disarankan untuk berbicara minimal 3 detik berturut-turut tanpa gangguan.
  • Anda dapat menyampaikan emosi target (seperti ramah atau serius), tetapi hindari penyampaian yang terlalu dramatis atau teatrikal. Pertahankan nada yang alami.

Langkah-langkah yang direkomendasikan

Berikut contoh penerapan menggunakan kamar tidur biasa:

  1. Tutup pintu dan jendela untuk menghalangi kebisingan eksternal.
  2. Matikan AC, kipas, dan peralatan lainnya.
  3. Tutup gorden untuk mengurangi pantulan dari kaca.
  4. Tutup permukaan meja dengan kain atau selimut untuk mengurangi pantulan.
  5. Pahami naskah, tentukan nada karakter, dan sampaikan secara alami.
  6. Pertahankan jarak sekitar 10 cm dari perangkat perekam untuk menghindari distorsi plosif atau sinyal lemah.

Pesan kesalahan

Jika Anda mengalami kesalahan, lihat Kode Kesalahan untuk pemecahan masalah.