All Products
Search
Document Center

Alibaba Cloud Model Studio:SDK Java sintesis suara CosyVoice

Last Updated:Mar 19, 2026

Parameter dan antarmuka utama SDK Java untuk sintesis suara CosyVoice.

Panduan pengguna: Untuk ikhtisar model dan saran pemilihan, lihat Sintesis suara Real-time - CosyVoice.

Prasyarat

  • Anda telah mengaktifkan Model Studio dan membuat kunci API. Ekspor sebagai variabel lingkungan (jangan hard-coded) untuk mencegah risiko keamanan.

    Catatan

    Untuk akses sementara atau kontrol ketat atas operasi berisiko tinggi (mengakses/menghapus data sensitif), gunakan token otentikasi sementara sebagai gantinya.

    Dibandingkan dengan kunci API jangka panjang, token sementara lebih aman (masa berlaku 60 detik) dan mengurangi risiko kebocoran kunci API.

    Untuk menggunakan token sementara, ganti kunci API yang digunakan untuk otentikasi dalam kode Anda dengan token otentikasi sementara tersebut.

  • Instal versi terbaru SDK DashScope.

Model dan harga

Lihat Sintesis suara Real-time - CosyVoice.

Batasan teks dan format

Batas panjang teks

Aturan penghitungan karakter

  • Karakter Tionghoa (Tionghoa sederhana/tradisional, Kanji Jepang, Hanja Korea) dihitung sebagai dua karakter. Semua karakter lainnya (tanda baca, huruf, angka, Kana, Hangul) dihitung sebagai satu karakter.

  • Tag SSML tidak termasuk dalam perhitungan panjang teks.

  • Contoh:

    • "你好" → 2 (karakter Tionghoa) + 2 (karakter Tionghoa) = 4 karakter

    • "中A文123" → 2 (karakter Tionghoa) + 1 (A) + 2 (karakter Tionghoa) + 1 (1) + 1 (2) + 1 (3) = 8 karakter

    • "中文。" → 2 (karakter Tionghoa) + 2 (karakter Tionghoa) + 1 (.) = 5 karakter

    • "中 文。" → 2 (karakter Tionghoa) + 1 (spasi) + 2 (karakter Tionghoa) + 1 (.) = 6 karakter

    • "<speak>你好</speak>" → 2 (karakter Tionghoa) + 2 (karakter Tionghoa) = 4 karakter

Format encoding

Gunakan encoding UTF-8.

Dukungan ekspresi matematika

Penguraian ekspresi matematika (v3.5-flash, v3.5-plus, v3-flash, v3-plus, v2 saja): Mendukung matematika sekolah dasar dan menengah—operasi dasar, aljabar, geometri.

Catatan

Fitur ini hanya mendukung bahasa Tionghoa.

Lihat Konversi formula LaTeX ke ucapan (hanya untuk bahasa Tionghoa).

SSML dukungan

SSML tersedia untuk voice kustom (desain voice atau kloning) dengan v3.5-flash, v3.5-plus, v3-flash, v3-plus, dan v2, serta untuk voice sistem yang ditandai sebagai didukung dalam daftar voice. Persyaratan:

Mulai

Kelas SpeechSynthesizer menyediakan antarmuka utama untuk sintesis suara dan mendukung metode pemanggilan berikut:

  • Non-streaming: Pemanggilan blocking yang mengirimkan seluruh teks sekaligus dan mengembalikan audio lengkap. Cocok untuk teks pendek.

  • Streaming unidireksional: Pemanggilan non-blocking yang mengirimkan seluruh teks sekaligus dan menerima audio melalui callback. Cocok untuk teks pendek dengan latensi rendah.

  • Streaming bidireksional: Pemanggilan non-blocking yang mengirimkan fragmen teks secara bertahap dan menerima audio melalui callback secara real-time. Cocok untuk teks panjang dengan latensi rendah.

Pemanggilan non-streaming

Mengirimkan tugas sintesis secara sinkron dan mengembalikan hasil lengkap.

image

Buat instance kelas SpeechSynthesizer, bind parameter permintaan, dan panggil metode call untuk mensintesis dan mendapatkan data audio biner.

Panjang teks yang dikirim tidak boleh melebihi 20.000 karakter. Untuk informasi lebih lanjut, lihat metode call dari kelas SpeechSynthesizer.

Penting

Sebelum setiap pemanggilan metode call, Anda harus menginisialisasi ulang instance SpeechSynthesizer.

Klik untuk melihat contoh lengkap

import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisParam;
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;
import com.alibaba.dashscope.utils.Constants;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;

public class Main {
    // Model
    private static String model = "cosyvoice-v3-flash";
    // Voice
    private static String voice = "longanyang";

    public static void streamAudioDataToSpeaker() {
        // Request parameters
        SpeechSynthesisParam param =
                SpeechSynthesisParam.builder()
                        // The API keys for the Singapore and Beijing regions are different. To get an API key, see https://www.alibabacloud.com/help/en/model-studio/get-api-key
                        // If you have not configured environment variables, replace the following line with your Model Studio API key: .apiKey("sk-xxx")
                        .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                        .model(model) // Model
                        .voice(voice) // Voice
                        .build();

        // Synchronous mode: Disable the callback (the second parameter is null).
        SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, null);
        ByteBuffer audio = null;
        try {
            // Block until the audio is returned.
            audio = synthesizer.call("What's the weather like today?");
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // Close the WebSocket connection after the task is complete.
            synthesizer.getDuplexApi().close(1000, "bye");
        }
        if (audio != null) {
            // Save the audio data to a local file named "output.mp3".
            File file = new File("output.mp3");
            // A WebSocket connection must be established when you send text for the first time. Therefore, the first-packet latency includes the time required to establish the connection.
            System.out.println(
                    "[Metric] Request ID: "
                            + synthesizer.getLastRequestId()
                            + ", First-packet latency (ms): "
                            + synthesizer.getFirstPackageDelay());
            try (FileOutputStream fos = new FileOutputStream(file)) {
                fos.write(audio.array());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static void main(String[] args) {
        // The following URL is for the Singapore region. If you use a model in the Beijing region, replace the URL with: wss://dashscope.aliyuncs.com/api-ws/v1/inference
        Constants.baseWebsocketApiUrl = "wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference";
        streamAudioDataToSpeaker();
        System.exit(0);
    }
}

Pemanggilan streaming unidireksional

Mengirimkan tugas sintesis secara asinkron dan menerima audio secara bertahap melalui ResultCallback.

image

Buat instance kelas SpeechSynthesizer, bind parameter permintaan dan antarmuka ResultCallback, lalu panggil metode call untuk mensintesis. Dapatkan hasil sintesis secara real-time melalui metode onEvent dari antarmuka ResultCallback.

Panjang teks yang dikirim tidak boleh melebihi 20.000 karakter. Untuk informasi lebih lanjut, lihat metode call dari kelas SpeechSynthesizer.

Penting

Sebelum setiap pemanggilan metode call, Anda harus menginisialisasi ulang instance SpeechSynthesizer.

Klik untuk melihat contoh lengkap

import com.alibaba.dashscope.audio.tts.SpeechSynthesisResult;
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisParam;
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;
import com.alibaba.dashscope.common.ResultCallback;
import com.alibaba.dashscope.utils.Constants;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.CountDownLatch;

class TimeUtils {
    private static final DateTimeFormatter formatter =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

    public static String getTimestamp() {
        return LocalDateTime.now().format(formatter);
    }
}

public class Main {
    // Model
    private static String model = "cosyvoice-v3-flash";
    // Voice
    private static String voice = "longanyang";

    public static void streamAudioDataToSpeaker() {
        CountDownLatch latch = new CountDownLatch(1);

        // Implement the ResultCallback interface.
        ResultCallback<SpeechSynthesisResult> callback = new ResultCallback<SpeechSynthesisResult>() {
            @Override
            public void onEvent(SpeechSynthesisResult result) {
                // System.out.println("Message received: " + result);
                if (result.getAudioFrame() != null) {
                    // Implement the logic for saving audio data to a local file here.
                    System.out.println(TimeUtils.getTimestamp() + " Audio received");
                }
            }

            @Override
            public void onComplete() {
                System.out.println(TimeUtils.getTimestamp() + " Complete received. Speech synthesis finished.");
                latch.countDown();
            }

            @Override
            public void onError(Exception e) {
                System.out.println("An exception occurred: " + e.toString());
                latch.countDown();
            }
        };

        // Request parameters
        SpeechSynthesisParam param =
                SpeechSynthesisParam.builder()
                        // The API keys for the Singapore and Beijing regions are different. To get an API key, see https://www.alibabacloud.com/help/en/model-studio/get-api-key
                        // If you have not configured environment variables, replace the following line with your Model Studio API key: .apiKey("sk-xxx")
                        .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                        .model(model) // Model
                        .voice(voice) // Voice
                        .build();
        // Pass the callback as the second parameter to enable asynchronous mode.
        SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, callback);
        // This is a non-blocking call that returns null immediately. The actual result is passed asynchronously through the callback interface. The binary audio is returned in real time in the onEvent method of the callback interface.
        try {
            synthesizer.call("What's the weather like today?");
            // Wait for the synthesis to complete.
            latch.await();
            // Wait for all playback threads to finish.
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // Close the WebSocket connection after the task is complete.
            synthesizer.getDuplexApi().close(1000, "bye");
        }
        // A WebSocket connection must be established when you send text for the first time. Therefore, the first-packet latency includes the time required to establish the connection.
        System.out.println(
                "[Metric] Request ID: "
                        + synthesizer.getLastRequestId()
                        + ", First-packet latency (ms): "
                        + synthesizer.getFirstPackageDelay());
    }

    public static void main(String[] args) {
        // The following URL is for the Singapore region. If you use a model in the Beijing region, replace the URL with: wss://dashscope.aliyuncs.com/api-ws/v1/inference
        Constants.baseWebsocketApiUrl = "wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference";
        streamAudioDataToSpeaker();
        System.exit(0);
    }
}

Pemanggilan streaming bidireksional

Kirim teks dalam beberapa chunk dan terima data audio secara bertahap melalui callback ResultCallback yang terdaftar.

Catatan
  • Untuk input streaming, panggil streamingCall beberapa kali untuk mengirimkan fragmen teks secara berurutan. Setelah server menerima fragmen teks, fragmen tersebut secara otomatis dibagi menjadi kalimat:

    • Kalimat lengkap langsung disintesis.

    • Kalimat tidak lengkap dibuffer dan disintesis setelah menjadi lengkap.

    Saat Anda memanggil streamingComplete, server akan memaksa mensintesis semua fragmen teks yang diterima tetapi belum diproses, termasuk kalimat yang tidak lengkap.

  • Interval antar pengiriman fragmen teks tidak boleh melebihi 23 detik, atau akan terjadi pengecualian timeout.

    Panggil metode streamingComplete segera setelah tidak ada lagi teks yang perlu dikirim.

    Server menerapkan mekanisme timeout 23 detik. Konfigurasi ini tidak dapat dimodifikasi di sisi client.
image
  1. Buat instance kelas SpeechSynthesizer

    Buat instance kelas SpeechSynthesizer, lalu bind parameter permintaan dan antarmuka ResultCallback.

  2. Streaming

    Panggil metode streamingCall dari kelas SpeechSynthesizer beberapa kali untuk mengirimkan teks sintesis dalam chunk. Ini mengirimkan teks ke server dalam segmen.

    Saat Anda mengirimkan teks, server mengembalikan hasil sintesis ke client secara real-time melalui metode onEvent dari antarmuka ResultCallback.

    Panjang fragmen teks yang dikirim dalam setiap pemanggilan metode streamingCall (parameter text) tidak boleh melebihi 20.000 karakter. Panjang total semua teks yang dikirim tidak boleh melebihi 200.000 karakter.

  3. Akhiri pemrosesan

    Panggil metode streamingComplete dari kelas SpeechSynthesizer untuk mengakhiri sintesis suara.

    Metode ini memblokir thread saat ini hingga callback onComplete atau onError dari antarmuka ResultCallback dipicu. Setelah itu, thread dibuka blokirnya.

    Pastikan Anda memanggil metode ini. Jika tidak, teks di akhir mungkin tidak dikonversi menjadi suara.

Klik untuk melihat contoh lengkap

import com.alibaba.dashscope.audio.tts.SpeechSynthesisResult;
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisAudioFormat;
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisParam;
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;
import com.alibaba.dashscope.common.ResultCallback;
import com.alibaba.dashscope.utils.Constants;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

class TimeUtils {
    private static final DateTimeFormatter formatter =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

    public static String getTimestamp() {
        return LocalDateTime.now().format(formatter);
    }
}


public class Main {
    private static String[] textArray = {"The streaming text-to-speech SDK ",
            "can convert input text ", "into binary audio data. ", "Compared to non-streaming synthesis, ",
            "streaming offers better real-time performance. ", "You can hear the audio output almost instantly as you type, ",
            "which greatly improves the user experience ", "and reduces waiting time. ",
            "This is ideal for applications that use large ", "language models (LLMs) ",
            "to synthesize speech from a stream of text."};
    private static String model = "cosyvoice-v3-flash"; // Model
    private static String voice = "longanyang"; // Voice

    public static void streamAudioDataToSpeaker() {
        // Configure the callback function.
        ResultCallback<SpeechSynthesisResult> callback = new ResultCallback<SpeechSynthesisResult>() {
            @Override
            public void onEvent(SpeechSynthesisResult result) {
                // System.out.println("Message received: " + result);
                if (result.getAudioFrame() != null) {
                    // Implement the logic for processing audio data here.
                    System.out.println(TimeUtils.getTimestamp() + " Audio received");
                }
            }

            @Override
            public void onComplete() {
                System.out.println(TimeUtils.getTimestamp() + " Complete received. Speech synthesis finished.");
            }

            @Override
            public void onError(Exception e) {
                System.out.println("An exception occurred: " + e.toString());
            }
        };

        // Request parameters
        SpeechSynthesisParam param =
                SpeechSynthesisParam.builder()
                        // The API keys for the Singapore and Beijing regions are different. To get an API key, see https://www.alibabacloud.com/help/en/model-studio/get-api-key
                        // If you have not configured environment variables, replace the following line with your Model Studio API key: .apiKey("sk-xxx")
                        .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                        .model(model)
                        .voice(voice)
                        .format(SpeechSynthesisAudioFormat
                                .PCM_22050HZ_MONO_16BIT) // Use PCM or MP3 for streaming synthesis.
                        .build();
        SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, callback);
        // The call method with a callback will not block the current thread.
        try {
            for (String text : textArray) {
                // Send text fragments and get the binary audio in real time in the onEvent method of the callback interface.
                synthesizer.streamingCall(text);
            }
            // Wait for the streaming speech synthesis to complete.
            synthesizer.streamingComplete();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // Close the WebSocket connection after the task is complete.
            synthesizer.getDuplexApi().close(1000, "bye");
        }

        // A WebSocket connection must be established when you send text for the first time. Therefore, the first-packet latency includes the time required to establish the connection.
        System.out.println(
                "[Metric] Request ID: "
                        + synthesizer.getLastRequestId()
                        + ", First-packet latency (ms): "
                        + synthesizer.getFirstPackageDelay());
    }

    public static void main(String[] args) {
        // The following URL is for the Singapore region. If you use a model in the Beijing region, replace the URL with: wss://dashscope.aliyuncs.com/api-ws/v1/inference
        Constants.baseWebsocketApiUrl = "wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference";
        streamAudioDataToSpeaker();
        System.exit(0);
    }
}

Pemanggilan menggunakan Flowable

Flowable adalah framework alur kerja open source (lisensi Apache 2.0). Lihat Detail API Flowable.

Sebelum menggunakan Flowable, pastikan Anda telah mengintegrasikan library RxJava dan memahami konsep dasar pemrograman reaktif.

Pemanggilan streaming unidireksional

Contoh berikut menunjukkan cara menggunakan antarmuka blockingForEach objek Flowable untuk memblokir dan mendapatkan data SpeechSynthesisResult yang dikembalikan dari setiap stream.

Hasil sintesis lengkap juga tersedia melalui metode getAudioData dari kelas SpeechSynthesizer setelah semua data streaming dari Flowable telah dikembalikan.

Klik untuk melihat contoh lengkap

import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisParam;
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

class TimeUtils {
    private static final DateTimeFormatter formatter =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

    public static String getTimestamp() {
        return LocalDateTime.now().format(formatter);
    }
}

public class Main {
    private static String model = "cosyvoice-v3-flash"; // Model
    private static String voice = "longanyang"; // Voice

    public static void streamAudioDataToSpeaker() throws NoApiKeyException {
        // Request parameters
        SpeechSynthesisParam param =
                SpeechSynthesisParam.builder()
                        // The API keys for the Singapore and Beijing regions are different. To get an API key, see https://www.alibabacloud.com/help/en/model-studio/get-api-key
                        // If you have not configured environment variables, replace the following line with your Model Studio API key: .apiKey("sk-xxx")
                        .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                        .model(model) // Model
                        .voice(voice) // Voice
                        .build();
        SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, null);
        synthesizer.callAsFlowable("What's the weather like today?").blockingForEach(result -> {
            // System.out.println("Message received: " + result);
            if (result.getAudioFrame() != null) {
                // Implement the logic for processing audio data here.
                System.out.println(TimeUtils.getTimestamp() + " Audio received");
            }
        });
        // Close the WebSocket connection after the task is complete.
        synthesizer.getDuplexApi().close(1000, "bye");
        // A WebSocket connection must be established when you send text for the first time. Therefore, the first-packet latency includes the time required to establish the connection.
        System.out.println(
                "[Metric] Request ID: "
                        + synthesizer.getLastRequestId()
                        + ", First-packet latency (ms): "
                        + synthesizer.getFirstPackageDelay());
    }

    public static void main(String[] args) throws NoApiKeyException {
        // The following URL is for the Singapore region. If you use a model in the Beijing region, replace the URL with: wss://dashscope.aliyuncs.com/api-ws/v1/inference
        Constants.baseWebsocketApiUrl = "wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference";
        streamAudioDataToSpeaker();
        System.exit(0);
    }
}

Pemanggilan streaming bidireksional

Contoh berikut menunjukkan cara menggunakan objek Flowable sebagai parameter input untuk memasukkan stream teks. Contoh ini juga menunjukkan cara menggunakan objek Flowable sebagai nilai kembali dan menggunakan antarmuka blockingForEach untuk memblokir dan mendapatkan data SpeechSynthesisResult yang dikembalikan dari setiap stream.

Hasil sintesis lengkap juga tersedia melalui metode getAudioData dari kelas SpeechSynthesizer setelah semua data streaming dari Flowable telah dikembalikan.

Klik untuk melihat contoh lengkap

import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesisParam;
import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

class TimeUtils {
    private static final DateTimeFormatter formatter =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

    public static String getTimestamp() {
        return LocalDateTime.now().format(formatter);
    }
}

public class Main {
    private static String[] textArray = {"The streaming text-to-speech SDK ",
            "can convert input text ", "into binary audio data. ", "Compared to non-streaming synthesis, ",
            "streaming offers better real-time performance. ", "You can hear the audio output almost instantly as you type, ",
            "which greatly improves the user experience ", "and reduces waiting time. ",
            "This is ideal for applications that use large ", "language models (LLMs) ",
            "to synthesize speech from a stream of text."};
    private static String model = "cosyvoice-v3-flash";
    private static String voice = "longanyang";

    public static void streamAudioDataToSpeaker() throws NoApiKeyException {
        // Simulate streaming input.
        Flowable<String> textSource = Flowable.create(emitter -> {
            new Thread(() -> {
                for (int i = 0; i < textArray.length; i++) {
                    emitter.onNext(textArray[i]);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                emitter.onComplete();
            }).start();
        }, BackpressureStrategy.BUFFER);

        // Request parameters
        SpeechSynthesisParam param =
                SpeechSynthesisParam.builder()
                        // The API keys for the Singapore and Beijing regions are different. To get an API key, see https://www.alibabacloud.com/help/en/model-studio/get-api-key
                        // If you have not configured environment variables, replace the following line with your Model Studio API key: .apiKey("sk-xxx")
                        .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                        .model(model) // Model
                        .voice(voice) // Voice
                        .build();
        SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, null);
        synthesizer.streamingCallAsFlowable(textSource).blockingForEach(result -> {
            if (result.getAudioFrame() != null) {
                // Implement the logic for playing audio here.
                System.out.println(
                        TimeUtils.getTimestamp() +
                                " Binary audio size: " + result.getAudioFrame().capacity());
            }
        });
        synthesizer.getDuplexApi().close(1000, "bye");
        // A WebSocket connection must be established when you send text for the first time. Therefore, the first-packet latency includes the time required to establish the connection.
        System.out.println(
                "[Metric] Request ID: "
                        + synthesizer.getLastRequestId()
                        + ", First-packet latency (ms): "
                        + synthesizer.getFirstPackageDelay());
    }

    public static void main(String[] args) throws NoApiKeyException {
        // The following URL is for the Singapore region. If you use a model in the Beijing region, replace the URL with: wss://dashscope.aliyuncs.com/api-ws/v1/inference
        Constants.baseWebsocketApiUrl = "wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference";
        streamAudioDataToSpeaker();
        System.exit(0);
    }
}

Pemanggilan konkurensi tinggi

SDK Java DashScope menggunakan teknologi kolam koneksi OkHttp3 untuk mengurangi overhead pembentukan koneksi berulang. Untuk informasi lebih lanjut, lihat Skenario konkurensi tinggi.

Parameter permintaan

Gunakan metode berantai SpeechSynthesisParam untuk mengonfigurasi parameter seperti model dan voice. Berikan objek parameter yang telah dikonfigurasi ke konstruktor kelas SpeechSynthesizer.

Klik untuk melihat contoh

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // Model
    .voice("longanyang") // Voice
    .format(SpeechSynthesisAudioFormat.WAV_8000HZ_MONO_16BIT) // Audio encoding format and sample rate
    .volume(50) // Volume. Valid values: [0, 100].
    .speechRate(1.0f) // Speech rate. Valid values: [0.5, 2].
    .pitchRate(1.0f) // Pitch. Valid values: [0.5, 2].
    .build();

Parameter

Tipe

Wajib

Deskripsi

model

String

Ya

model sintesis suara. Setiap versi model memerlukan voice yang kompatibel:

  • cosyvoice-v3.5-flash/cosyvoice-v3.5-plus: Tidak tersedia voice sistem. Hanya voice kustom dari desain voice atau kloning voice yang didukung.

  • cosyvoice-v3-flash/cosyvoice-v3-plus: Gunakan voice seperti longanyang.

  • cosyvoice-v2: Gunakan voice seperti longxiaochun_v2.

  • Untuk daftar lengkap voice, lihat Daftar voice.

voice

String

Ya

Voice yang digunakan untuk sintesis suara.

Jenis voice yang didukung:

  • Voice sistem: Untuk informasi lebih lanjut, lihat Daftar voice.

  • Suara yang dikloning: Disesuaikan menggunakan fitur kloning suara. Pastikan akun yang sama digunakan untuk kloning suara dan sintesis suara saat menggunakan suara yang dikloning.

    Untuk voice kloning, model harus sesuai dengan model pembuatan voice (target_model).

  • Suara yang didesain: Disesuaikan melalui fitur Desain suara. Saat menggunakan suara yang didesain, pastikan akun yang sama digunakan baik untuk desain suara maupun sintesis suara.

    Untuk voice desain, model harus sesuai dengan model pembuatan voice (target_model).

format

enum

Tidak

Format encoding audio dan laju sampel.

Default adalah format MP3 dengan laju sampel 22,05 kHz.

Catatan

Laju sampel default merepresentasikan laju optimal untuk voice yang dipilih. Output menggunakan laju ini secara default, tetapi downsampling dan upsampling didukung.

Format encoding audio dan laju sampel berikut didukung:

  • Format encoding audio dan laju sampel yang didukung oleh semua model:

    • SpeechSynthesisAudioFormat.WAV_8000HZ_MONO_16BIT: Format WAV, laju sampel 8 kHz

    • SpeechSynthesisAudioFormat.WAV_16000HZ_MONO_16BIT: Format WAV, laju sampel 16 kHz

    • SpeechSynthesisAudioFormat.WAV_22050HZ_MONO_16BIT: Format WAV, laju sampel 22,05 kHz

    • SpeechSynthesisAudioFormat.WAV_24000HZ_MONO_16BIT: Format WAV, laju sampel 24 kHz

    • SpeechSynthesisAudioFormat.WAV_44100HZ_MONO_16BIT: Format WAV, laju sampel 44,1 kHz

    • SpeechSynthesisAudioFormat.WAV_48000HZ_MONO_16BIT: Format WAV, laju sampel 48 kHz

    • SpeechSynthesisAudioFormat.MP3_8000HZ_MONO_128KBPS: Format MP3, laju sampel 8 kHz

    • SpeechSynthesisAudioFormat.MP3_16000HZ_MONO_128KBPS: Format MP3, laju sampel 16 kHz

    • SpeechSynthesisAudioFormat.MP3_22050HZ_MONO_256KBPS: Format MP3, laju sampel 22,05 kHz

    • SpeechSynthesisAudioFormat.MP3_24000HZ_MONO_256KBPS: Format MP3, laju sampel 24 kHz

    • SpeechSynthesisAudioFormat.MP3_44100HZ_MONO_256KBPS: Format MP3, laju sampel 44,1 kHz

    • SpeechSynthesisAudioFormat.MP3_48000HZ_MONO_256KBPS: Format MP3, laju sampel 48 kHz

    • SpeechSynthesisAudioFormat.PCM_8000HZ_MONO_16BIT: Format PCM, laju sampel 8 kHz

    • SpeechSynthesisAudioFormat.PCM_16000HZ_MONO_16BIT: Format PCM, laju sampel 16 kHz

    • SpeechSynthesisAudioFormat.PCM_22050HZ_MONO_16BIT: Format PCM, laju sampel 22,05 kHz

    • SpeechSynthesisAudioFormat.PCM_24000HZ_MONO_16BIT: Format PCM, laju sampel 24 kHz

    • SpeechSynthesisAudioFormat.PCM_44100HZ_MONO_16BIT: Format PCM, laju sampel 44,1 kHz

    • SpeechSynthesisAudioFormat.PCM_48000HZ_MONO_16BIT: Format PCM, laju sampel 48 kHz

  • Jika format audionya Opus, sesuaikan bitrate dengan menggunakan parameter bit_rate. Ini hanya berlaku untuk DashScope 2.21.0 dan yang lebih baru.

    • SpeechSynthesisAudioFormat.OGG_OPUS_8KHZ_MONO_32KBPS: Format Opus, laju sampel 8 kHz, bitrate 32 kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_16KHZ_MONO_16KBPS: Format Opus, laju sampel 16 kHz, bitrate 16 kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_16KHZ_MONO_32KBPS: Format Opus, laju sampel 16 kHz, bitrate 32 kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_16KHZ_MONO_64KBPS: Format Opus, laju sampel 16 kHz, bitrate 64 kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_24KHZ_MONO_16KBPS: Format Opus, laju sampel 24 kHz, bitrate 16 kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_24KHZ_MONO_32KBPS: Format Opus, laju sampel 24 kHz, bitrate 32 kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_24KHZ_MONO_64KBPS: Format Opus, laju sampel 24 kHz, bitrate 64 kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_48KHZ_MONO_16KBPS: Format Opus, laju sampel 48 kHz, bitrate 16 kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_48KHZ_MONO_32KBPS: Format Opus, laju sampel 48 kHz, bitrate 32 kbps

    • SpeechSynthesisAudioFormat.OGG_OPUS_48KHZ_MONO_64KBPS: Format Opus, laju sampel 48 kHz, bitrate 64 kbps

volume

int

Tidak

Volume.

Default: 50.

Rentang valid: [0, 100]. Nilai berskala linear—0 berarti senyap, 50 adalah default, 100 adalah maksimum.

speechRate

float

Tidak

Laju bicara.

Nilai default: 1,0.

Nilai valid: [0,5, 2,0]. Nilai 1,0 adalah laju bicara standar. Nilai kurang dari 1,0 memperlambat bicara, dan nilai lebih dari 1,0 mempercepatnya.

pitchRate

float

Tidak

Pengali pitch. Hubungan dengan pitch yang dirasakan tidak linear maupun logaritmik—lakukan pengujian untuk menemukan nilai yang sesuai.

Nilai default: 1,0.

Nilai yang valid: [0,5–2,0]. Nilai 1,0 merupakan pitch alami suara. Nilai di atas 1,0 meningkatkan pitch, sedangkan nilai di bawah 1,0 menurunkannya.

bit_rate

int

Tidak

Bitrate audio dalam kbps. Jika format audionya Opus, sesuaikan bitrate dengan menggunakan parameter bit_rate.

Nilai default: 32.

Nilai valid: [6, 510].

Catatan

Atur parameter bit_rate menggunakan metode parameter atau metode parameters dari instance SpeechSynthesisParam:

Atur menggunakan metode parameter

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // Model
    .voice("longanyang") // Voice
    .parameter("bit_rate", 32)
    .build();

Atur menggunakan metode parameters

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // Model
    .voice("longanyang") // Voice
    .parameters(Collections.singletonMap("bit_rate", 32))
    .build();

enableWordTimestamp

boolean

Tidak

Menentukan apakah akan mengaktifkan timestamp tingkat kata.

Nilai default: false.

  • true

  • false

Fitur ini hanya tersedia untuk voice kloning model cosyvoice-v3-flash, cosyvoice-v3-plus, dan cosyvoice-v2, serta untuk voice sistem yang ditandai sebagai didukung dalam daftar voice.

Hasil timestamp hanya tersedia melalui antarmuka callback.

seed

int

Tidak

Seed acak yang digunakan selama generasi. Seed berbeda menghasilkan hasil sintesis berbeda. Jika model, teks, voice, dan parameter lainnya identik, menggunakan seed yang sama akan mereproduksi output yang sama.

Nilai default: 0.

Nilai valid: [0, 65535].

languageHints

List

Tidak

Menentukan bahasa target untuk sintesis suara guna meningkatkan efek sintesis.

Gunakan saat pelafalan atau kualitas sintesis buruk untuk angka, singkatan, simbol, atau bahasa yang kurang umum:

  • Angka tidak dibaca seperti yang diharapkan. Misalnya, "hello, this is 110" dibaca sebagai "hello, this is one one zero" bukan "hello, this is yāo yāo líng".

  • Simbol '@' salah dilafalkan sebagai 'ai te' bukan 'at'.

  • Kualitas sintesis untuk bahasa yang kurang umum buruk dan terdengar tidak alami.

Nilai valid:

  • zh: Tionghoa

  • en: Inggris

  • fr: Prancis

  • de: Jerman

  • ja: Jepang

  • ko: Korea

  • ru: Rusia

  • pt: Portugis

  • th: Bahasa Thailand

  • id: Bahasa Indonesia

  • vi: Vietnam

Catatan: Parameter ini berupa array, tetapi versi saat ini hanya memproses elemen pertama. Oleh karena itu, kami menyarankan hanya mengirimkan satu nilai.

Penting

Parameter ini menentukan bahasa target untuk sintesis suara. Pengaturan ini independen dari bahasa audio sampel yang digunakan untuk kloning voice. Untuk mengatur bahasa sumber untuk tugas kloning, lihat API Kloning/Desain Voice CosyVoice.

instruction

String

Tidak

Menetapkan instruksi untuk mengontrol efek sintesis seperti dialek, emosi, atau gaya bicara. Fitur ini hanya tersedia untuk voice kloning model cosyvoice-v3.5-flash, cosyvoice-v3.5-plus, dan cosyvoice-v3-flash, serta untuk voice sistem yang ditandai mendukung Instruct dalam daftar voice.

Batas panjang: 100 karakter.

Karakter Tionghoa (termasuk Tionghoa sederhana dan tradisional, Kanji Jepang, dan Hanja Korea) dihitung sebagai dua karakter. Semua karakter lainnya, seperti tanda baca, huruf, angka, dan Kana/Hangul Jepang/Korea, dihitung sebagai satu karakter.

Persyaratan penggunaan (berbeda-beda tergantung model):

  • v3.5-flash dan v3.5-plus: Instruksi bahasa alami apa pun untuk mengontrol emosi, laju bicara, dll.

    Penting

    cosyvoice-v3.5-flash dan cosyvoice-v3.5-plus tidak memiliki voice sistem. Hanya voice kustom dari desain voice atau kloning voice yang didukung.

    Contoh instruksi:

    Speak in a very excited and high-pitched tone, expressing the ecstasy and excitement of a great success.
    Please maintain a medium-slow speech rate, with an elegant and intellectual tone, giving a sense of calm and reassurance.
    The tone should be full of sorrow and nostalgia, with a slight nasal quality, as if narrating a heartbreaking story.
    Please try to speak in a breathy voice, with a very low volume, creating a sense of intimate and mysterious whispering.
    The tone should be very impatient and annoyed, with a faster speech rate and minimal pauses between sentences.
    Please imitate a kind and gentle elder, with a steady speech rate and a voice full of care and affection.
    The tone should be sarcastic and disdainful, with emphasis on keywords and a slightly rising intonation at the end of sentences.
    Please speak in an extremely fearful and trembling voice.
    The tone should be like a professional news anchor: calm, objective, and articulate, with a neutral emotion.
    The tone should be lively and playful, with a clear smile, making the voice sound energetic and sunny.
  • cosyvoice-v3-flash: Persyaratan berikut harus dipenuhi:

    • Voice kloning: Gunakan bahasa alami apa pun untuk mengontrol efek sintesis suara.

      Contoh instruksi:

      Please speak in Cantonese. (Supported dialects: Cantonese, Northeastern, Gansu, Guizhou, Henan, Hubei, Jiangxi, Minnan, Ningxia, Shanxi, Shaanxi, Shandong, Shanghainese, Sichuan, Tianjin, Yunnan.)
      Please say a sentence as loudly as possible.
      Please say a sentence as slowly as possible.
      Please say a sentence as quickly as possible.
      Please say a sentence very softly.
      Can you speak a little slower?
      Can you speak very quickly?
      Can you speak very slowly?
      Can you speak a little faster?
      Please say a sentence very angrily.
      Please say a sentence very happily.
      Please say a sentence very fearfully.
      Please say a sentence very sadly.
      Please say a sentence very surprisedly.
      Please try to sound as firm as possible.
      Please try to sound as angry as possible.
      Please try an approachable tone.
      Please speak in a cold tone.
      Please speak in a majestic tone.
      I want to experience a natural tone.
      I want to see how you express a threat.
      I want to see how you express wisdom.
      I want to see how you express seduction.
      I want to hear you speak in a lively way.
      I want to hear you speak with passion.
      I want to hear you speak in a steady manner.
      I want to hear you speak with confidence.
      Can you talk to me with excitement?
      Can you show an arrogant emotion?
      Can you show an elegant emotion?
      Can you answer the question happily?
      Can you give a gentle emotional demonstration?
      Can you talk to me in a calm tone?
      Can you answer me in a deep way?
      Can you talk to me with a gruff attitude?
      Tell me the answer in a sinister voice.
      Tell me the answer in a resilient voice.
      Narrate in a natural and friendly chat style.
      Speak in the tone of a radio drama podcaster.
    • Voice sistem: Instruksi harus menggunakan format dan konten tetap. Untuk informasi lebih lanjut, lihat daftar voice.

enable_aigc_tag

boolean

Tidak

Menentukan apakah akan menambahkan identifier AIGC tak terlihat ke audio yang dihasilkan. Saat diatur ke true, identifier tak terlihat disematkan ke audio dalam format yang didukung (WAV, MP3, dan Opus).

Nilai default: false.

Hanya cosyvoice-v3-flash, cosyvoice-v3-plus, dan cosyvoice-v2 yang mendukung fitur ini.

Catatan

Atur parameter enable_aigc_tag menggunakan metode parameter atau metode parameters dari instance SpeechSynthesisParam:

Atur menggunakan metode parameter

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // Model
    .voice("longanyang") // Voice
    .parameter("enable_aigc_tag", true)
    .build();

Atur menggunakan metode parameters

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // Model
    .voice("longanyang") // Voice
    .parameters(Collections.singletonMap("enable_aigc_tag", true))
    .build();

aigc_propagator

String

Tidak

Menetapkan field ContentPropagator dalam identifier AIGC tak terlihat untuk mengidentifikasi propagator konten. Parameter ini hanya berlaku saat enable_aigc_tag bernilai true.

Nilai default: UID Alibaba Cloud.

Hanya cosyvoice-v3-flash, cosyvoice-v3-plus, dan cosyvoice-v2 yang mendukung fitur ini.

Catatan

Atur parameter aigc_propagator menggunakan metode parameter atau metode parameters dari instance SpeechSynthesisParam:

Atur menggunakan metode parameter

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // Model
    .voice("longanyang") // Voice
    .parameter("enable_aigc_tag", true)
    .parameter("aigc_propagator", "xxxx")
    .build();

Atur menggunakan metode parameters

Map<String, Object> map = new HashMap();
map.put("enable_aigc_tag", true);
map.put("aigc_propagator", "xxxx");

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // Model
    .voice("longanyang") // Voice
    .parameters(map)
    .build();

aigc_propagate_id

String

Tidak

Menetapkan field PropagateID dalam identifier AIGC tak terlihat untuk mengidentifikasi secara unik perilaku propagasi tertentu. Parameter ini hanya berlaku saat enable_aigc_tag bernilai true.

Nilai default: ID permintaan dari permintaan sintesis suara saat ini.

Hanya cosyvoice-v3-flash, cosyvoice-v3-plus, dan cosyvoice-v2 yang mendukung fitur ini.

Catatan

Atur parameter aigc_propagate_id menggunakan metode parameter atau metode parameters dari instance SpeechSynthesisParam:

Atur menggunakan metode parameter

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // Model
    .voice("longanyang") // Voice
    .parameter("enable_aigc_tag", true)
    .parameter("aigc_propagate_id", "xxxx")
    .build();

Konfigurasi via parameters

Map<String, Object> map = new HashMap();
map.put("enable_aigc_tag", true);
map.put("aigc_propagate_id", "xxxx");

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // Model
    .voice("longanyang") // Voice
    .parameters(map)
    .build();

hotFix

ParamHotFix

Tidak

Konfigurasi hotpatching teks. Memungkinkan Anda menyesuaikan pelafalan kata tertentu atau mengganti teks sebelum sintesis. Fitur ini hanya tersedia untuk voice kloning cosyvoice-v3-flash.

Deskripsi parameter:

  • ParamHotFix.PronunciationItem: Menyesuaikan pelafalan. Menentukan anotasi pinyin untuk sebuah kata guna memperbaiki pelafalan default yang tidak akurat.

  • ParamHotFix.ReplaceItem: Mengganti teks. Mengganti kata tertentu dengan teks target sebelum sintesis suara. Teks yang diganti digunakan untuk sintesis aktual.

Contoh:

List<ParamHotFix.PronunciationItem> pronunciationItems = new ArrayList<>();
pronunciationItems.add(new ParamHotFix.PronunciationItem("weather", "tian1 qi4"));

List<ParamHotFix.ReplaceItem> replaceItems = new ArrayList<>();
replaceItems.add(new ParamHotFix.ReplaceItem("today", "gold day"));

ParamHotFix paramHotFix = new ParamHotFix();
paramHotFix.setPronunciation(pronunciationItems);
paramHotFix.setReplace(replaceItems);

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
                        .model("cosyvoice-v3-flash") // Model
                        .voice("your_voice") // Replace with a cloned voice for cosyvoice-v3-flash
                        .hotFix(paramHotFix)
                        .build();

enable_markdown_filter

boolean

false

Menentukan apakah akan mengaktifkan penyaringan Markdown. Saat diaktifkan, sistem secara otomatis menghapus simbol Markdown dari teks input sebelum mensintesis suara, mencegahnya dibaca keras. Fitur ini hanya tersedia untuk voice kloning cosyvoice-v3-flash.

Nilai default: false.

Nilai valid:

  • true

  • false

Catatan

Atur parameter enable_markdown_filter menggunakan metode parameter atau metode parameters dari instance SpeechSynthesisParam:

Atur menggunakan metode parameter

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // Model
    .voice("your_voice") // Replace with a cloned voice for cosyvoice-v3-flash
    .parameter("enable_markdown_filter", true)
    .build();

Atur menggunakan metode parameters

Map<String, Object> map = new HashMap();
map.put("enable_markdown_filter", true);

SpeechSynthesisParam param = SpeechSynthesisParam.builder()
    .model("cosyvoice-v3-flash") // Model
    .voice("your_voice") // Replace with a cloned voice for cosyvoice-v3-flash
    .parameters(map)
    .build();

Antarmuka utama

SpeechSynthesizer kelas

Impor kelas SpeechSynthesizer menggunakan import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;. Kelas ini menyediakan antarmuka utama untuk sintesis suara.

Antarmuka/Metode

Parameter

Nilai kembali

Deskripsi

public SpeechSynthesizer(SpeechSynthesisParam param, ResultCallback<SpeechSynthesisResult> callback)

Instance SpeechSynthesizer

Konstruktor.

  • Pemanggilan streaming (unidireksional atau bidireksional): Atur callback ke antarmuka ResultCallback.

  • Pemanggilan non-streaming atau Flowable: Atur callback ke null.

public ByteBuffer call(String text)

text: Teks yang akan disintesis (UTF-8).

ByteBuffer atau null

Mengonversi teks (teks biasa atau dengan SSML) menjadi suara.

Saat membuat instance SpeechSynthesizer, ada dua kasus:

Penting

Sebelum setiap pemanggilan metode call, Anda harus menginisialisasi ulang instance SpeechSynthesizer.

public void streamingCall(String text)

text: Teks yang akan disintesis (UTF-8).

Tidak ada

Mengirimkan teks sebagai stream. SSML tidak didukung.

Panggil antarmuka ini beberapa kali untuk mengirimkan teks ke server dalam beberapa bagian. Hasil sintesis dikembalikan melalui metode onEvent dari antarmuka ResultCallback.

Untuk alur pemanggilan detail dan contoh referensi, lihat Pemanggilan streaming bidireksional.

public void streamingComplete() throws RuntimeException

Tidak ada

Tidak ada

Mengakhiri sintesis suara streaming.

Metode ini memblokir hingga salah satu kondisi berikut terjadi:

  • Server menyelesaikan sintesis (sukses).

  • Sesi terputus (gagal).

  • Timeout 10 menit tercapai (otomatis membuka blokir).

Untuk alur pemanggilan detail dan contoh referensi, lihat Pemanggilan streaming bidireksional.

Penting

Saat melakukan pemanggilan streaming bidireksional, pastikan untuk memanggil metode ini agar tidak kehilangan bagian dari suara yang disintesis.

public Flowable<SpeechSynthesisResult> callAsFlowable(String text)

text: Teks yang akan disintesis, dalam format UTF-8.

Hasil sintesis, dikemas dalam Flowable<SpeechSynthesisResult>.

Mengonversi input teks non-streaming (teks yang berisi SSML tidak didukung) menjadi output suara streaming secara real-time. Hasil sintesis dikembalikan dalam stream dalam objek Flowable.

Untuk alur pemanggilan detail dan contoh referensi, lihat Pemanggilan menggunakan Flowable.

boolean getDuplexApi().close(int code, String reason)

code: Kode Penutupan WebSocket

reason: Alasan penutupan

Untuk informasi tentang cara mengonfigurasi parameter ini, lihat dokumen Protokol WebSocket.

true

Setelah tugas selesai, Anda harus menutup koneksi WebSocket terlepas dari apakah terjadi pengecualian atau tidak. Ini mencegah kebocoran koneksi. Untuk informasi tentang cara menggunakan kembali koneksi guna meningkatkan efisiensi, lihat Skenario konkurensi tinggi.

public Flowable<SpeechSynthesisResult> streamingCallAsFlowable(Flowable<String> textStream)

textStream: Instance Flowable yang mengemas teks yang akan disintesis.

Hasil sintesis, dikemas dalam Flowable<SpeechSynthesisResult>.

Mengonversi input teks streaming (teks yang berisi SSML tidak didukung) menjadi output suara streaming secara real-time. Hasil sintesis dikembalikan dalam stream dalam objek Flowable.

Untuk alur pemanggilan detail dan contoh referensi, lihat Pemanggilan menggunakan Flowable.

public String getLastRequestId()

Tidak ada

ID permintaan dari tugas sebelumnya.

Mendapatkan ID permintaan dari tugas sebelumnya. Gunakan ini setelah memulai tugas baru dengan memanggil call, streamingCall, callAsFlowable, atau streamingCallAsFlowable.

public long getFirstPackageDelay()

Tidak ada

Latensi paket pertama dari tugas saat ini.

Mengembalikan latensi paket pertama dalam milidetik (waktu dari pengiriman teks hingga menerima audio pertama). Panggil setelah tugas selesai.

Faktor yang memengaruhi latensi paket pertama:

  • Waktu untuk membentuk koneksi WebSocket (pada pemanggilan pertama)

  • Waktu pemuatan voice (berbeda-beda tergantung voice)

  • Beban layanan (antrian mungkin terjadi pada jam sibuk)

  • Latensi jaringan

Latensi tipikal:

  • Menggunakan kembali koneksi dengan voice sudah dimuat: sekitar 500 ms

  • Koneksi pertama atau pergantian voice: bisa mencapai 1.500 hingga 2.000 ms

Jika latensi secara konsisten melebihi 2.000 ms:

  1. Gunakan fitur kolam koneksi untuk skenario konkurensi tinggi guna membentuk koneksi terlebih dahulu.

  2. Periksa kualitas koneksi jaringan Anda.

  3. Hindari melakukan pemanggilan pada jam sibuk.

ResultCallback antarmuka

Untuk pemanggilan streaming (unidireksional atau bidireksional), dapatkan hasil melalui ResultCallback. Impor: import com.alibaba.dashscope.common.ResultCallback;.

Klik untuk melihat contoh

ResultCallback<SpeechSynthesisResult> callback = new ResultCallback<SpeechSynthesisResult>() {
    @Override
    public void onEvent(SpeechSynthesisResult result) {
        System.out.println("Request ID: " + result.getRequestId());
        // Process audio chunks in real time (e.g., play or write to a buffer).
    }

    @Override
    public void onComplete() {
        System.out.println("Task complete");
        // Handle synthesis completion logic (e.g., release the player).
    }

    @Override
    public void onError(Exception e) {
        System.out.println("Task failed: " + e.getMessage());
        // Handle exceptions (network errors or server-side error codes).
    }
};

Antarmuka/Metode

Parameter

Nilai kembali

Deskripsi

public void onEvent(SpeechSynthesisResult result)

result: Instance SpeechSynthesisResult.

Tidak ada

Dipanggil saat server mendorong data audio.

Gunakan getAudioFrame untuk mengambil audio biner.

Panggil metode getUsage dari SpeechSynthesisResult untuk mendapatkan jumlah karakter yang dikenai biaya dalam permintaan saat ini sejauh ini.

public void onComplete()

Tidak ada

Tidak ada

Dipanggil secara asinkron setelah semua data sintesis telah dikembalikan dan sintesis suara selesai.

public void onError(Exception e)

e: Informasi pengecualian.

Tidak ada

Dipanggil secara asinkron saat terjadi pengecualian.

Kami menyarankan untuk mengimplementasikan logika pencatatan pengecualian lengkap dan pembersihan resource dalam metode onError.

Tanggapan

Server mengembalikan data audio biner:

  • Pemanggilan non-streaming: Proses data audio biner yang dikembalikan oleh metode call dari kelas SpeechSynthesizer.

  • Pemanggilan streaming unidireksional atau pemanggilan streaming bidireksional: Proses parameter (bertipe SpeechSynthesisResult) dari metode onEvent dari antarmuka ResultCallback.

    Antarmuka utama SpeechSynthesisResult adalah sebagai berikut:

    Antarmuka/Metode

    Parameter

    Nilai kembali

    Deskripsi

    public ByteBuffer getAudioFrame()

    Tidak ada

    Data audio biner

    Mengembalikan audio biner untuk segmen saat ini (mungkin kosong jika tidak ada data baru).

    Gabungkan segmen menjadi file lengkap atau stream ke pemutar yang kompatibel.

    Penting
    • Dalam sintesis suara streaming, untuk format terkompresi seperti MP3 dan Opus, data audio tersegmentasi harus diputar menggunakan pemutar streaming. Jangan memutarnya frame per frame, karena ini menyebabkan decoding gagal.

      Pemutar streaming termasuk FFmpeg, PyAudio (Python), AudioFormat (Java), dan MediaSource (JavaScript).
    • Saat menggabungkan data audio menjadi file audio lengkap, tulis ke file yang sama dalam mode append.

    • Untuk audio WAV dan MP3 dari sintesis suara streaming, hanya frame pertama yang berisi informasi header. Frame berikutnya hanya berisi data audio.

    public String getRequestId()

    Tidak ada

    ID permintaan dari tugas.

    Mendapatkan ID permintaan dari tugas. Saat Anda mendapatkan data audio biner dengan memanggil getAudioFrame, nilai kembali dari metode getRequestId adalah null.

    public SpeechSynthesisUsage getUsage()

    Tidak ada

    SpeechSynthesisUsage: Jumlah karakter yang dikenai biaya dalam permintaan saat ini sejauh ini.

    Mengembalikan SpeechSynthesisUsage atau null.

    Metode getCharacters dari SpeechSynthesisUsage mengembalikan jumlah karakter yang dikenai biaya dalam permintaan saat ini sejauh ini. Gunakan SpeechSynthesisUsage yang diterima terakhir sebagai nilai akhir.

    public Sentence getTimestamp()

    Tidak ada

    Sentence: Kalimat yang dikenai biaya dalam permintaan saat ini sejauh ini.

    Anda perlu mengaktifkan fitur timestamp tingkat kata enableWordTimestamp.

    Mengembalikan Sentence atau null.

    Metode Sentence:

    • getIndex: Mendapatkan nomor kalimat, dimulai dari 0.

    • getWords: Mendapatkan array karakter List<Word> yang membentuk kalimat. Gunakan Sentence yang diterima terakhir sebagai nilai akhir.

    Metode Word:

    • getText: Mendapatkan teks karakter.

    • getBeginIndex: Mendapatkan indeks posisi awal karakter dalam kalimat, dimulai dari 0.

    • getEndIndex: Mendapatkan indeks posisi akhir karakter dalam kalimat, dimulai dari 1.

    • getBeginTime: Mendapatkan timestamp awal audio yang sesuai dengan karakter, dalam milidetik.

    • getEndTime: Mendapatkan timestamp akhir audio yang sesuai dengan karakter, dalam milidetik.

Kode kesalahan

Jika terjadi kesalahan, lihat Pesan kesalahan untuk troubleshooting.

Contoh lainnya

Untuk contoh lainnya, lihat GitHub.

FAQ

Fitur, penagihan, dan pembatasan laju

T: Apa yang bisa saya lakukan jika pelafalan tidak akurat?

Gunakan SSML untuk memperbaiki pelafalan.

T: Sintesis suara ditagih berdasarkan jumlah karakter. Bagaimana cara memeriksa panjang teks untuk setiap permintaan sintesis?

Troubleshooting

Jika terjadi kesalahan kode, lihat Kode kesalahan untuk troubleshooting.

T: Bagaimana cara mendapatkan ID permintaan?

Dapatkan dengan salah satu cara berikut:

T: Mengapa fitur SSML gagal?

Troubleshooting:

  1. Verifikasi batasan dan kendala.

  2. Instal versi terbaru SDK DashScope.

  3. Pastikan Anda menggunakan antarmuka yang benar: hanya metode call dari kelas SpeechSynthesizer yang mendukung SSML.

  4. Pastikan teks yang akan disintesis dalam format teks biasa dan memenuhi persyaratan format. Untuk informasi lebih lanjut, lihat Pengantar bahasa markup SSML.

T: Mengapa durasi audio sintesis TTS berbeda dengan durasi yang ditampilkan pada file WAV? Misalnya, file WAV menunjukkan 7 detik tetapi audio aktual kurang dari 5 detik?

TTS menggunakan mekanisme sintesis streaming, yang berarti mensintesis dan mengembalikan data secara progresif. Akibatnya, header file WAV berisi nilai perkiraan, yang mungkin memiliki margin kesalahan. Jika Anda memerlukan durasi yang tepat, Anda dapat mengatur format ke PCM dan secara manual menambahkan informasi header WAV setelah mendapatkan hasil sintesis lengkap. Ini akan memberikan durasi yang lebih akurat.

T: Mengapa audio tidak bisa diputar?

Periksa skenario berikut satu per satu:

  1. Audio disimpan sebagai file lengkap (misalnya xx.mp3).

    1. Konsistensi format: Verifikasi format permintaan sesuai dengan ekstensi file (misalnya, WAV dengan .wav, bukan .mp3).

    2. Kompatibilitas pemutar: Verifikasi bahwa pemutar Anda mendukung format dan laju sampel file audio. Beberapa pemutar mungkin tidak mendukung laju sampel tinggi atau encoding audio tertentu.

  2. Audio diputar dalam stream.

    1. Simpan stream audio sebagai file lengkap dan coba putar dengan pemutar. Jika file tidak bisa diputar, lihat metode troubleshooting untuk skenario 1.

    2. Jika file diputar normal, masalahnya mungkin pada implementasi pemutaran streaming Anda. Verifikasi bahwa pemutar Anda mendukung pemutaran streaming.

      Alat dan library umum yang mendukung pemutaran streaming termasuk FFmpeg, PyAudio (Python), AudioFormat (Java), dan MediaSource (JavaScript).

T: Mengapa pemutaran audio tersendat-sendat?

Periksa skenario berikut satu per satu:

  1. Periksa kecepatan pengiriman teks: Pastikan interval antar segmen teks masuk akal. Hindari situasi di mana segmen berikutnya tidak dikirim segera setelah segmen audio sebelumnya selesai diputar.

  2. Periksa kinerja fungsi callback:

    • Hindari logika bisnis berat dalam fungsi callback—hal ini dapat menyebabkan pemblokiran.

    • Callback berjalan di thread WebSocket. Pemblokiran mencegah penerimaan paket tepat waktu dan menyebabkan pemutaran audio tersendat.

    • Kami menyarankan menulis data audio ke buffer terpisah dan memprosesnya di thread lain untuk menghindari pemblokiran thread WebSocket.

  3. Periksa stabilitas jaringan: Pastikan koneksi jaringan Anda stabil untuk menghindari gangguan transmisi audio atau penundaan yang disebabkan oleh fluktuasi jaringan.

T: Mengapa sintesis suara memakan waktu lama?

Ikuti langkah-langkah berikut untuk troubleshooting:

  1. Periksa interval input

    Periksa interval input. Jika Anda menggunakan sintesis suara streaming, verifikasi apakah interval antar pengiriman segmen teks terlalu lama (misalnya, penundaan beberapa detik). Interval yang lama meningkatkan total waktu sintesis.

  2. Analisis metrik kinerja.

    • Latensi paket pertama: Biasanya sekitar 500 ms.

    • RTF (RTF = Total waktu sintesis / Durasi audio): Biasanya kurang dari 1,0.

T: Bagaimana cara menangani pelafalan salah dalam suara yang disintesis?

Gunakan tag <phoneme> SSML untuk menentukan pelafalan yang benar.

T: Mengapa sebagian teks di akhir tidak dikonversi menjadi suara, atau mengapa tidak ada suara yang dikembalikan?

Periksa apakah Anda telah memanggil metode streamingComplete dari kelas SpeechSynthesizer. Selama sintesis suara, server mulai mensintesis hanya setelah mencache cukup teks. Jika Anda tidak memanggil streamingComplete, teks yang tersisa di buffer mungkin tidak disintesis.

Izin dan otentikasi

T: Bagaimana cara membatasi kunci API saya hanya untuk layanan sintesis suara CosyVoice saja (isolasi izin)?

Buat ruang kerja dan berikan otorisasi hanya ke model tertentu untuk membatasi cakupan kunci API. Untuk informasi lebih lanjut, lihat Mengelola ruang kerja.

Pertanyaan lainnya

Lihat QA di GitHub.