全部产品
Search
文档中心

Alibaba Cloud Model Studio:SDK Java sintesis ucapan CosyVoice

更新时间:Jan 28, 2026

Topik ini menjelaskan parameter dan detail antarmuka SDK Java CosyVoice untuk sintesis ucapan.

Penting

Untuk menggunakan model di wilayah China (Beijing), buka halaman Kunci API untuk wilayah China (Beijing).

Panduan pengguna: Untuk informasi lebih lanjut tentang model dan panduan pemilihan model, lihat Sintesis ucapan Real-time - CosyVoice.

Prasyarat

  • Anda telah mengaktifkan Model Studio dan membuat Kunci API. Untuk mencegah risiko keamanan, ekspor Kunci API sebagai Variabel lingkungan alih-alih menyematkannya langsung di kode Anda.

    Catatan

    Untuk memberikan izin akses sementara kepada aplikasi atau pengguna pihak ketiga, atau jika Anda ingin mengontrol secara ketat operasi berisiko tinggi seperti mengakses atau menghapus data sensitif, kami menyarankan Anda menggunakan token otentikasi sementara.

    Dibandingkan dengan Kunci API jangka panjang, token otentikasi sementara lebih aman karena masa berlakunya singkat (60 detik). Token ini cocok untuk skenario panggilan sementara dan dapat secara efektif mengurangi risiko kebocoran Kunci API.

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

  • Instal versi terbaru SDK DashScope.

Model dan harga

Model

Harga

Kuota gratis (Catatan)

cosyvoice-v3-plus

$0,286706 per 10.000 karakter

Tidak ada kuota gratis

cosyvoice-v3-flash

$0,14335 per 10.000 karakter

cosyvoice-v2

$0,286706 per 10.000 karakter

Batasan teks dan format

Batas panjang teks

Aturan penghitungan karakter

  • Satu karakter Han (termasuk Han Cina sederhana atau tradisional, kanji Jepang, dan hanja Korea) dihitung sebagai 2 karakter. Semua karakter lainnya, seperti tanda baca, huruf, angka, serta kana atau hangul Jepang/Korea, dihitung sebagai 1 karakter.

  • Tag SSML tidak termasuk dalam perhitungan panjang teks.

  • Contoh:

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

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

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

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

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

Format pengkodean

Gunakan pengkodean UTF-8.

Dukungan ekspresi matematika

Fitur penguraian ekspresi matematika saat ini hanya tersedia untuk model cosyvoice-v2, cosyvoice-v3-flash, dan cosyvoice-v3-plus. Fitur ini mendukung ekspresi matematika umum dari sekolah dasar dan menengah, seperti aritmetika dasar, aljabar, dan geometri.

Lihat Formula LaTeX ke Ucapan.

SSML dukungan

Fitur Bahasa Markup Sintesis Ucapan (SSML) saat ini hanya tersedia untuk voice kloning model cosyvoice-v3-flash, cosyvoice-v3-plus, dan cosyvoice-v2, serta voice sistem yang ditandai sebagai didukung dalam daftar voice. Syarat-syarat berikut harus dipenuhi:

Memulai

Kelas SpeechSynthesizer menyediakan antarmuka untuk sintesis ucapan dan mendukung metode panggilan berikut:

  • Panggilan non-streaming: Panggilan blocking yang mengirimkan seluruh teks sekaligus dan langsung mengembalikan audio lengkap. Metode ini cocok untuk skenario sintesis teks pendek.

  • Panggilan streaming unidireksional: Panggilan non-blocking yang mengirimkan seluruh teks sekaligus dan menggunakan fungsi callback untuk menerima data audio, yang mungkin dikirimkan dalam beberapa bagian. Metode ini cocok untuk skenario sintesis teks pendek yang memerlukan latensi rendah.

  • Panggilan streaming bidireksional: Panggilan non-blocking yang mengirimkan teks secara bertahap dan menggunakan fungsi callback untuk menerima aliran audio hasil sintesis secara bertahap secara real-time. Metode ini cocok untuk skenario sintesis teks panjang yang memerlukan latensi rendah.

Panggilan non-streaming

Kirimkan tugas sintesis ucapan secara sinkron untuk langsung mendapatkan hasil lengkap.

image

Buat instans kelas SpeechSynthesizer, atur parameter permintaan, lalu panggil metode call untuk melakukan sintesis dan mendapatkan data audio biner.

Panjang teks tidak boleh melebihi 2.000 karakter. Lihat metode call dari kelas SpeechSynthesizer.

Penting

Sebelum setiap pemanggilan metode call, Anda harus membuat instans SpeechSynthesizer yang baru.

Klik untuk melihat contoh lengkap

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

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() {
        // Parameter permintaan
        SpeechSynthesisParam param =
                SpeechSynthesisParam.builder()
                        // Jika Kunci API belum dikonfigurasi sebagai variabel lingkungan, hapus komentar baris berikut dan ganti your-api-key dengan Kunci API Anda.
                        // .apiKey("your-api-key")
                        .model(model) // Model
                        .voice(voice) // Voice
                        .build();

        // Mode sinkron: Nonaktifkan callback (parameter kedua bernilai null).
        SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, null);
        ByteBuffer audio = null;
        try {
            // Blokir hingga audio dikembalikan.
            audio = synthesizer.call("What's the weather like today?");
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // Tutup koneksi WebSocket setelah tugas selesai.
            synthesizer.getDuplexApi().close(1000, "bye");
        }
        if (audio != null) {
            // Simpan data audio ke file lokal bernama "output.mp3".
            File file = new File("output.mp3");
            // Koneksi WebSocket harus dibuat saat teks dikirim pertama kali. Oleh karena itu, latensi paket pertama mencakup waktu pembuatan koneksi.
            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) {
        streamAudioDataToSpeaker();
        System.exit(0);
    }
}

Panggilan streaming unidireksional

Kirimkan tugas sintesis ucapan secara asinkron dan terima segmen ucapan secara real-time frame demi frame dengan mendaftarkan callback ResultCallback.

image

Buat instans kelas SpeechSynthesizer, atur parameter permintaan dan antarmuka ResultCallback, lalu panggil metode call untuk melakukan sintesis audio. Metode onEvent dari antarmuka ResultCallback menyediakan hasil sintesis secara real-time.

Panjang teks tidak boleh melebihi 2.000 karakter. Lihat metode call dari kelas SpeechSynthesizer.

Penting

Sebelum setiap pemanggilan metode call, Anda harus membuat instans SpeechSynthesizer yang baru.

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 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);

        // Implementasikan antarmuka ResultCallback.
        ResultCallback<SpeechSynthesisResult> callback = new ResultCallback<SpeechSynthesisResult>() {
            @Override
            public void onEvent(SpeechSynthesisResult result) {
                // System.out.println("Message received: " + result);
                if (result.getAudioFrame() != null) {
                    // Implementasikan logika untuk menyimpan data audio ke file lokal di sini.
                    System.out.println(TimeUtils.getTimestamp() + " Audio received");
                }
            }

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

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

        // Parameter permintaan
        SpeechSynthesisParam param =
                SpeechSynthesisParam.builder()
                        // Jika Anda belum mengonfigurasi Kunci API sebagai variabel lingkungan, hapus komentar baris berikut dan ganti "your-api-key" dengan Kunci API Anda.
                        // .apiKey("your-api-key")
                        .model(model) // Model
                        .voice(voice) // Voice
                        .build();
        // Kirimkan callback sebagai parameter kedua untuk mengaktifkan mode asinkron.
        SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, callback);
        // Ini adalah panggilan non-blocking yang langsung mengembalikan null. Hasil aktual dikirimkan secara asinkron melalui antarmuka callback. Ambil data audio biner secara real-time di metode onEvent antarmuka callback.
        try {
            synthesizer.call("What's the weather like today?");
            // Tunggu hingga sintesis selesai.
            latch.await();
            // Tunggu hingga semua thread pemutaran selesai.
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // Tutup koneksi WebSocket setelah tugas selesai.
            synthesizer.getDuplexApi().close(1000, "bye");
        }
        // Koneksi WebSocket harus dibuat saat teks dikirim pertama kali. Oleh karena itu, latensi paket pertama mencakup waktu pembuatan koneksi.
        System.out.println(
                "[Metric] Request ID: "
                        + synthesizer.getLastRequestId()
                        + ", First-packet latency (ms): "
                        + synthesizer.getFirstPackageDelay());
    }

    public static void main(String[] args) {
        streamAudioDataToSpeaker();
        System.exit(0);
    }
}

Panggilan streaming bidireksional

Kirimkan teks dalam beberapa bagian dan terima data segmen ucapan secara real-time frame demi frame dengan mendaftarkan callback ResultCallback.

Catatan
  • Untuk input streaming, Anda dapat memanggil streamingCall beberapa kali untuk mengirimkan fragmen teks secara berurutan. Setelah server menerima fragmen teks tersebut, server akan secara otomatis membagi teks menjadi kalimat:

    • Kalimat lengkap akan langsung disintesis.

    • Kalimat yang belum lengkap akan disimpan dalam cache hingga lengkap, lalu disintesis.

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

  • Interval antar pengiriman fragmen teks tidak boleh melebihi 23 detik. Jika tidak, akan terjadi pengecualian "request timeout after 23 seconds".

    Jika tidak ada lagi teks yang akan dikirim, panggil streamingComplete untuk segera mengakhiri tugas.

    Server menerapkan timeout 23 detik, yang tidak dapat dimodifikasi oleh klien.
image
  1. Buat instans kelas SpeechSynthesizer.

    Buat instans kelas SpeechSynthesizer dan atur parameter permintaan dan antarmuka ResultCallback.

  2. Kirimkan data secara streaming

    Panggil metode streamingCall dari kelas SpeechSynthesizer beberapa kali untuk mengirimkan teks yang akan disintesis ke server secara bertahap.

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

    Untuk setiap pemanggilan metode streamingCall, panjang segmen teks (yaitu text) tidak boleh melebihi 2.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 tugas sintesis ucapan.

    Metode ini akan memblokir thread saat ini hingga callback onComplete atau onError dari antarmuka ResultCallback dipicu, setelah itu thread akan dibebaskan.

    Anda harus memanggil metode ini. Jika tidak, fragmen teks terakhir mungkin tidak berhasil dikonversi menjadi ucapan.

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 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 {
    private static String[] textArray = {"The streaming text-to-speech SDK, ",
            "can convert input text ", "into binary audio data. ", "Compared to non-streaming speech synthesis, ",
            "streaming synthesis offers the advantage of stronger ", "real-time performance. Users can hear ",
            "nearly synchronous speech output while inputting text, ", "greatly enhancing the interactive experience ",
            "and reducing user waiting time. ", "It is suitable for scenarios that call large ", "language models (LLMs) to perform ",
            "speech synthesis by ", "streaming text input."};
    private static String model = "cosyvoice-v3-flash"; // Model
    private static String voice = "longanyang"; // Voice

    public static void streamAudioDataToSpeaker() {
        // Konfigurasikan fungsi callback.
        ResultCallback<SpeechSynthesisResult> callback = new ResultCallback<SpeechSynthesisResult>() {
            @Override
            public void onEvent(SpeechSynthesisResult result) {
                // System.out.println("Message received: " + result);
                if (result.getAudioFrame() != null) {
                    // Implementasikan logika untuk memproses data audio di sini.
                    System.out.println(TimeUtils.getTimestamp() + " Audio received");
                }
            }

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

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

        // Parameter permintaan
        SpeechSynthesisParam param =
                SpeechSynthesisParam.builder()
                        // Jika Kunci API belum diatur sebagai variabel lingkungan, hapus komentar baris berikut dan ganti your-api-key dengan kunci Anda.
                        // .apiKey("your-api-key")
                        .model(model)
                        .voice(voice)
                        .format(SpeechSynthesisAudioFormat
                                .PCM_22050HZ_MONO_16BIT) // Sintesis streaming menggunakan PCM atau MP3.
                        .build();
        SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, callback);
        // Metode call dengan callback tidak memblokir thread saat ini.
        try {
            for (String text : textArray) {
                // Kirimkan segmen teks dan terima audio biner secara real-time dari metode onEvent antarmuka callback.
                synthesizer.streamingCall(text);
            }
            // Tunggu hingga sintesis ucapan streaming selesai.
            synthesizer.streamingComplete();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // Setelah tugas selesai, tutup koneksi WebSocket.
            synthesizer.getDuplexApi().close(1000, "bye");
        }

        // Koneksi WebSocket dibuat saat segmen teks pertama dikirim. Oleh karena itu, latensi paket pertama mencakup waktu pembuatan koneksi.
        System.out.println(
                "[Metric] Request ID: "
                        + synthesizer.getLastRequestId()
                        + ", First-packet latency (ms): "
                        + synthesizer.getFirstPackageDelay());
    }

    public static void main(String[] args) {
        streamAudioDataToSpeaker();
        System.exit(0);
    }
}

Panggilan melalui Flowable

Flowable adalah framework open-source untuk manajemen alur kerja dan proses bisnis yang dirilis di bawah lisensi Apache 2.0. Untuk informasi lebih lanjut tentang cara menggunakan Flowable, lihat Detail API Flowable.

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

Panggilan streaming unidireksional

Contoh berikut menunjukkan cara menggunakan antarmuka blockingForEach objek Flowable untuk memblokir thread saat ini dan mengambil data SpeechSynthesisResult yang dikembalikan dalam setiap aliran.

Anda juga dapat memperoleh hasil sintesis lengkap menggunakan metode getAudioData dari kelas SpeechSynthesizer setelah aliran Flowable selesai.

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 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 {
        // Parameter permintaan
        SpeechSynthesisParam param =
                SpeechSynthesisParam.builder()
                        // Jika Kunci API belum dikonfigurasi sebagai variabel lingkungan, hapus komentar baris berikut dan ganti your-api-key dengan Kunci API Anda.
                        // .apiKey("your-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("Received message: " + result);
            if (result.getAudioFrame() != null) {
                // Implementasikan logika untuk memproses data audio di sini.
                System.out.println(TimeUtils.getTimestamp() + " Audio received");
            }
        });
        // Tutup koneksi WebSocket setelah tugas selesai.
        synthesizer.getDuplexApi().close(1000, "bye");
        // Koneksi WebSocket harus dibuat saat teks dikirim pertama kali. Oleh karena itu, latensi paket pertama mencakup waktu pembuatan koneksi.
        System.out.println(
                "[Metric] Request ID: "
                        + synthesizer.getLastRequestId()
                        + ", First-packet latency (ms): "
                        + synthesizer.getFirstPackageDelay());
    }

    public static void main(String[] args) throws NoApiKeyException {
        streamAudioDataToSpeaker();
        System.exit(0);
    }
}

Panggilan streaming bidireksional

Contoh berikut menunjukkan cara menggunakan objek Flowable sebagai parameter input untuk aliran teks. Contoh ini juga menunjukkan cara menggunakan objek Flowable sebagai nilai kembalian dan menggunakan antarmuka blockingForEach untuk memblokir thread saat ini dan mengambil data SpeechSynthesisResult yang dikembalikan dalam setiap aliran.

Anda juga dapat memperoleh hasil sintesis lengkap menggunakan metode getAudioData dari kelas SpeechSynthesizer setelah aliran Flowable selesai.

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 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 speech synthesis, ",
            "streaming synthesis offers the advantage of stronger ", "real-time performance. Users can hear ",
            "nearly synchronous speech output while inputting text, ", "greatly enhancing the interactive experience ",
            "and reducing user waiting time. ", "It is suitable for scenarios that call large ", "language models (LLMs) to perform ",
            "speech synthesis by ", "streaming text input."};
    private static String model = "cosyvoice-v3-flash";
    private static String voice = "longanyang";

    public static void streamAudioDataToSpeaker() throws NoApiKeyException {
        // Simulasikan input streaming.
        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);

        // Parameter permintaan
        SpeechSynthesisParam param =
                SpeechSynthesisParam.builder()
                        // Jika Kunci API belum dikonfigurasi sebagai variabel lingkungan, hapus komentar baris berikut dan ganti yourApikey dengan Kunci API Anda.
                        // .apiKey("yourApikey")
                        .model(model) // Model
                        .voice(voice) // Voice
                        .build();
        SpeechSynthesizer synthesizer = new SpeechSynthesizer(param, null);
        synthesizer.streamingCallAsFlowable(textSource).blockingForEach(result -> {
            if (result.getAudioFrame() != null) {
                // Implementasikan logika untuk memutar audio di sini.
                System.out.println(
                        TimeUtils.getTimestamp() +
                                " Binary audio size: " + result.getAudioFrame().capacity());
            }
        });
        synthesizer.getDuplexApi().close(1000, "bye");
        // Koneksi WebSocket harus dibuat saat teks dikirim pertama kali. Oleh karena itu, latensi paket pertama mencakup waktu pembuatan koneksi.
        System.out.println(
                "[Metric] Request ID: "
                        + synthesizer.getLastRequestId()
                        + ", First-packet latency (ms): "
                        + synthesizer.getFirstPackageDelay());
    }

    public static void main(String[] args) throws NoApiKeyException {
        streamAudioDataToSpeaker();
        System.exit(0);
    }
}

Panggilan konkurensi tinggi

SDK Java DashScope menggunakan teknologi kolam koneksi OkHttp3 untuk mengurangi overhead dari pembuatan koneksi berulang. Lihat Skenario konkurensi tinggi.

Parameter permintaan

Gunakan metode berantai SpeechSynthesisParam untuk mengonfigurasi parameter, seperti model dan voice, lalu kirimkan 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) // Format pengkodean audio dan laju sampel
    .volume(50) // Volume. Rentang nilai: [0, 100].
    .speechRate(1.0f) // Laju ucapan. Rentang nilai: [0.5, 2].
    .pitchRate(1.0f) // Pitch. Rentang nilai: [0.5, 2].
    .build();

Parameter

Tipe

Wajib

Deskripsi

model

String

Ya

model sintesis ucapan.

Model yang berbeda memerlukan voice yang sesuai:

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

  • cosyvoice-v2: Gunakan voice seperti longxiaochun_v2.

  • Untuk daftar lengkap, lihat Daftar voice.

voice

String

Ya

Voice yang digunakan untuk sintesis ucapan.

Voice sistem dan voice kloning didukung:

  • Voice sistem: Lihat Daftar voice.

  • Voice kloning: Sesuaikan voice menggunakan fitur kloning suara. Saat menggunakan voice kloning, pastikan akun yang sama digunakan untuk kloning suara dan sintesis ucapan. Untuk langkah-langkah detail, lihat API kloning suara CosyVoice.

    Saat menggunakan voice kloning, nilai parameter model dalam permintaan harus persis sama dengan versi model yang digunakan untuk membuat voice tersebut (parameter target_model).

format

enum

Tidak

Format pengkodean audio dan laju sampel.

Jika Anda tidak menentukan format, audio hasil sintesis akan memiliki laju sampel 22,05 kHz dan dalam format MP3.

Catatan

Laju sampel default adalah laju optimal untuk voice saat ini. Secara default, output menggunakan laju sampel ini. Downsampling dan upsampling juga didukung.

Format pengkodean audio dan laju sampel berikut tersedia:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • Jika format audionya Opus, Anda dapat menyesuaikan bitrate menggunakan parameter bit_rate. Ini hanya berlaku untuk DashScope versi 2.21.0 dan yang lebih baru.

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

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

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

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

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

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

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

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

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

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

volume

int

Tidak

Volume.

Nilai default: 50.

Rentang nilai: [0, 100]. Nilai 50 adalah volume standar. Volume memiliki hubungan linear dengan nilai ini. 0 berarti senyap dan 100 adalah volume maksimum.

speechRate

float

Tidak

Laju ucapan.

Nilai default: 1.0.

Rentang nilai: [0.5, 2.0]. Nilai 1.0 adalah laju standar. Nilai kurang dari 1.0 memperlambat ucapan, dan nilai lebih dari 1.0 mempercepatnya.

pitchRate

float

Tidak

Pitch. Nilai ini adalah pengali untuk penyesuaian pitch. Hubungan antara nilai ini dan pitch yang dirasakan tidak sepenuhnya linear atau logaritmik. Uji nilai-nilai berbeda untuk menemukan yang terbaik.

Nilai default: 1.0.

Rentang nilai: [0.5, 2.0]. Nilai 1.0 adalah pitch alami voice. Nilai lebih dari 1.0 meningkatkan pitch, dan nilai kurang dari 1.0 menurunkannya.

bit_rate

int

Tidak

Bitrate audio dalam kbps. Jika format audionya Opus, Anda dapat menyesuaikan bitrate menggunakan parameter bit_rate.

Nilai default: 32.

Rentang nilai: [6, 510].

Catatan

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

Atur menggunakan parameter

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

Atur menggunakan 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 karakter.

Nilai default: false.

  • true

  • false

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

Hasil timestamp hanya dapat diperoleh melalui antarmuka callback.

seed

int

Tidak

Seed bilangan acak yang digunakan selama generasi, yang memvariasikan efek sintesis. Jika versi model, teks, voice, dan parameter lainnya sama, menggunakan seed yang sama akan menghasilkan hasil sintesis yang identik.

Nilai default: 0.

Rentang nilai: [0, 65535].

languageHints

List

Tidak

Menentukan bahasa target untuk sintesis ucapan guna meningkatkan efek sintesis.

Gunakan parameter ini ketika pelafalan angka, singkatan, atau simbol, atau ketika efek sintesis untuk bahasa non-Cina tidak sesuai harapan.

Nilai yang valid:

  • zh: Cina

  • en: Inggris

  • fr: Prancis

  • de: Jerman

  • ja: Jepang

  • ko: Korea

  • ru: Rusia

Catatan: Meskipun parameter ini berupa array, versi saat ini hanya memproses elemen pertama. Oleh karena itu, Anda hanya boleh mengirimkan satu nilai.

Penting

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

instruction

String

Tidak

Atur instruction untuk mengontrol efek seperti dialek, emosi, atau karakter. Hanya tersedia untuk voice kloning model cosyvoice-v3-flash dan cosyvoice-v3-plus, serta voice sistem yang ditandai sebagai mendukung instruct dalam Daftar Voice.

Batasan:

  • Instruksi harus mengikuti format tetap dalam bahasa Cina (lihat deskripsi di bawah)

  • Tidak berpengaruh jika tidak diatur. Tidak ada nilai default.

Fitur:

  • Menentukan dialek

    • Batasan voice: Hanya voice kloning.

    • Format: "请用<方言>表达。" (Catatan: Jangan menghilangkan titik (。) di akhir, dan harus menggunakan bahasa Cina. Ganti "<方言>" dengan dialek tertentu, seperti 广东话).

    • Contoh: "请用广东话表达。"

    • Dialek: 广东话 (Kanton), 东北话 (Dongbei), 甘肃话 (Gansu), 贵州话 (Guizhou), 河南话 (Henan), 湖北话 (Hubei), 江西话 (Jiangxi), 闽南话 (Minnan), 宁夏话 (Ningxia), 山西话 (Shanxi), 陕西话 (Shaanxi), 山东话 (Shandong), 上海话 (Shanghainese), 四川话 (Sichuan), 天津话 (Tianjin), dan 云南话 (Yunnan).

  • Menentukan emosi

    • Batasan voice:

      • Suara hasil kloning.

      • Voice sistem yang ditandai sebagai mendukung instruct dalam Daftar Voice.

    • Format:

      • Voice kloning:

        Klik untuk melihat format (Harus menggunakan bahasa Cina)

        • 请尽可能非常大声地说一句话。 (Silakan ucapkan sebuah kalimat sekeras mungkin)

        • 请用尽可能慢地语速说一句话。 (Silakan ucapkan sebuah kalimat selambat mungkin)

        • 请用尽可能快地语速说一句话。 (Silakan ucapkan sebuah kalimat secepat mungkin)

        • 请非常轻声地说一句话。 (Silakan ucapkan sebuah kalimat sangat pelan)

        • 你可以慢一点说吗 (Bisakah kamu berbicara sedikit lebih lambat)

        • 你可以非常快一点说吗 (Bisakah kamu berbicara sangat cepat)

        • 你可以非常慢一点说吗 (Bisakah kamu berbicara sangat lambat)

        • 你可以快一点说吗 (Bisakah kamu berbicara sedikit lebih cepat)

        • 请非常生气地说一句话。 (Silakan ucapkan sebuah kalimat dengan sangat marah)

        • 请非常开心地说一句话。 (Silakan ucapkan sebuah kalimat dengan sangat senang)

        • 请非常恐惧地说一句话。 (Silakan ucapkan sebuah kalimat dengan sangat takut)

        • 请非常伤心地说一句话。 (Silakan ucapkan sebuah kalimat dengan sangat sedih)

        • 请非常惊讶地说一句话。 (Silakan ucapkan sebuah kalimat dengan sangat terkejut)

        • 请尽可能表现出坚定的感觉。 (Usahakan terdengar setegas mungkin.)

        • 请尽可能表现出愤怒的感觉。 (Silakan coba terdengar semarah mungkin)

        • 请尝试一下亲和的语调。 (Silakan coba nada yang ramah)

        • 请用冷酷的语调讲话。 (Silakan berbicara dengan nada dingin)

        • 请用威严的语调讲话。 (Silakan berbicara dengan nada megah)

        • 我想体验一下自然的语气。 (Saya ingin merasakan nada alami)

        • 我想看看你如何表达威胁。 (Saya ingin melihat bagaimana kamu mengungkapkan ancaman)

        • 我想看看你怎么表现智慧。 (Saya ingin melihat bagaimana kamu mengungkapkan kebijaksanaan)

        • 我想看看你怎么表现诱惑。 (Saya ingin melihat bagaimana kamu mengungkapkan godaan)

        • 我想听听用活泼的方式说话。 (Saya ingin mendengar kamu berbicara dengan cara yang ceria)

        • 我想听听你用激昂的感觉说话。 (Saya ingin mendengar kamu berbicara dengan penuh semangat)

        • 我想听听用沉稳的方式说话的样子。 (Saya ingin mendengar bagaimana kamu berbicara dengan tenang)

        • 我想听听你用自信的感觉说话。 (Saya ingin mendengar kamu berbicara dengan percaya diri)

        • 你能用兴奋的感觉和我交流吗? (Bisakah kamu berkomunikasi dengan saya dengan nada bersemangat)

        • 你能否展示狂傲的情绪表达? (Bisakah Anda menunjukkan ekspresi emosi yang arogan?)

        • 你能展现一下优雅的情绪吗? (Bisakah Anda menunjukkan emosi yang elegan?)

        • 你可以用幸福的方式回答问题吗? (Bisakah kamu menjawab pertanyaan dengan cara yang bahagia)

        • 你可以做一个温柔的情感演示吗? (Bisakah kamu memberikan demonstrasi emosi lembut)

        • 能用冷静的语调和我谈谈吗? (Bisakah kamu berbicara dengan saya dengan nada tenang)

        • 能用深沉的方法回答我吗? (Bisakah kamu memberikan jawaban yang mendalam)

        • 能用粗犷的情绪态度和我对话吗? (Bisakah Anda berbicara dengan saya menggunakan sikap emosional yang kasar?)

        • 用阴森的声音告诉我这个答案。 (Beritahu saya jawabannya dengan suara suram)

        • 用坚韧的声音告诉我这个答案。 (Beritahu saya jawabannya dengan suara tangguh)

        • 用自然亲切的闲聊风格叙述。 (Ceritakan dengan gaya obrolan santai yang alami dan ramah)

        • 用广播剧博客主的语气讲话。 (Berbicaralah dengan nada podcaster drama radio)

      • Voice sistem: Format instruksi emosi berbeda dari di atas, lihat Daftar Voice sebagai gantinya.

  • Menentukan skenario, peran, atau identitas

enable_aigc_tag

boolean

Tidak

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

Nilai default: false.

Fitur ini hanya tersedia untuk model cosyvoice-v3-flash, cosyvoice-v3-plus, dan cosyvoice-v2.

Catatan

Atur parameter enable_aigc_tag menggunakan metode parameter atau parameters dari instans 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

Mengatur bidang ContentPropagator dalam pengenal AIGC tak terlihat untuk menentukan propagator konten. Pengaturan ini hanya berlaku saat enable_aigc_tag bernilai true.

Nilai default: UID Alibaba Cloud.

Fitur ini hanya tersedia untuk model cosyvoice-v3-flash, cosyvoice-v3-plus, dan cosyvoice-v2.

Catatan

Atur aigc_propagator menggunakan metode parameter atau parameters dari instans 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

Mengatur bidang PropagateID dalam pengenal AIGC tak terlihat untuk mengidentifikasi secara unik perilaku propagasi tertentu. Bidang ini hanya berlaku saat enable_aigc_tag diatur ke true.

Nilai default: Request ID dari permintaan sintesis ucapan saat ini.

Fitur ini hanya tersedia untuk model cosyvoice-v3-flash, cosyvoice-v3-plus, dan cosyvoice-v2.

Catatan

Atur aigc_propagate_id menggunakan metode parameter atau parameters dari instans 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();

Atur menggunakan metode 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();

Antarmuka utama

Kelas SpeechSynthesizer

Kelas SpeechSynthesizer menyediakan antarmuka utama untuk sintesis ucapan dan diimpor menggunakan import com.alibaba.dashscope.audio.ttsv2.SpeechSynthesizer;.

Antarmuka/Metode

Parameter

Nilai kembali

Deskripsi

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

Instans SpeechSynthesizer

Konstruktor.

public ByteBuffer call(String text)

text: Teks yang akan disintesis (UTF-8)

ByteBuffer atau null

Mengonversi segmen teks menjadi ucapan. Teks dapat berupa teks biasa atau teks yang berisi SSML.

Saat Anda membuat instans SpeechSynthesizer, ada dua kemungkinan:

Penting

Sebelum setiap pemanggilan metode call, Anda harus membuat instans SpeechSynthesizer yang baru.

public void streamingCall(String text)

text: Teks yang akan disintesis (UTF-8)

Tidak ada

Mengirimkan teks untuk sintesis secara streaming. Teks yang berisi SSML tidak didukung.

Anda dapat memanggil antarmuka ini beberapa kali untuk mengirimkan teks untuk sintesis ke server secara bertahap. Metode onEvent dari antarmuka ResultCallback mengembalikan hasil sintesis.

Untuk alur panggilan detail dan contoh referensi, lihat Panggilan streaming bidireksional.

public void streamingComplete() throws RuntimeException

Tidak ada

Tidak ada

Mengakhiri sintesis ucapan streaming.

Metode ini memblokir thread pemanggil hingga salah satu kondisi berikut terjadi:

  • Server menyelesaikan sintesis audio terakhir (berhasil).

  • Sesi streaming terputus secara abnormal (gagal).

  • Ambang batas timeout 10 menit tercapai (pemblokiran otomatis dibatalkan).

Untuk proses panggilan detail dan contoh referensi, lihat Panggilan streaming bidireksional.

Penting

Saat melakukan panggilan streaming bidireksional, panggil metode ini untuk menghindari bagian ucapan hasil sintesis yang hilang.

public Flowable<SpeechSynthesisResult> callAsFlowable(String text)

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

Hasil sintesis, dikemas dalam Flowable<SpeechSynthesisResult>.

Mengonversi input teks non-streaming menjadi output ucapan streaming secara real-time. Teks yang berisi SSML tidak didukung. Hasil sintesis dikembalikan dalam aliran di dalam objek Flowable.

Untuk proses panggilan detail dan contoh referensi, lihat Panggilan melalui Flowable.

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

code: Kode Penutupan WebSocket

reason: Alasan penutupan

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

true

Setelah tugas selesai, tutup koneksi WebSocket, baik terjadi pengecualian maupun tidak, untuk menghindari kebocoran koneksi. Untuk informasi tentang cara menggunakan kembali koneksi guna meningkatkan efisiensi, lihat Skenario konkurensi tinggi.

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

textStream: Instans Flowable yang mengemas teks yang akan disintesis.

Hasil sintesis dikemas dalam Flowable<SpeechSynthesisResult>.

Mengonversi input teks streaming menjadi output ucapan streaming secara real-time. Teks yang berisi SSML tidak didukung. Hasil sintesis dikembalikan sebagai aliran dalam objek Flowable.

Untuk proses panggilan detail dan contoh referensi, lihat Panggilan melalui Flowable.

public String getLastRequestId()

Tidak ada

Request ID dari tugas sebelumnya.

Mendapatkan Request ID dari tugas sebelumnya. Anda dapat menggunakan metode ini setelah memulai tugas baru dengan memanggil call, streamingCall, callAsFlowable, atau streamingCallAsFlowable.

public long getFirstPackageDelay()

Tidak ada

Latensi paket pertama untuk tugas saat ini.

Mendapatkan latensi paket pertama tugas saat ini, yang biasanya sekitar 500 ms. Gunakan metode ini setelah tugas selesai.

Latensi paket pertama adalah waktu antara saat teks mulai dikirim dan saat paket audio pertama diterima, diukur dalam milidetik.

Koneksi WebSocket harus dibuat saat teks dikirim pertama kali. Oleh karena itu, latensi paket pertama mencakup waktu pembuatan koneksi. Jika koneksi digunakan kembali dalam skenario konkurensi tinggi, waktu koneksi tidak termasuk.

Antarmuka callback (ResultCallback)

Saat Anda melakukan panggilan streaming unidireksional atau panggilan streaming bidireksional, Anda dapat mengambil hasil sintesis dari antarmuka ResultCallback. Antarmuka ini diimpor menggunakan 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("RequestId: " + result.getRequestId());
        // Proses potongan audio secara real-time, misalnya untuk pemutaran atau menulis ke buffer.
    }

    @Override
    public void onComplete() {
        System.out.println("Task completed");
        // Tangani logika pasca-sintesis, seperti melepaskan pemutar.
    }

    @Override
    public void onError(Exception e) {
        System.out.println("Task failed: " + e.getMessage());
        // Tangani pengecualian, seperti kesalahan jaringan atau kode kesalahan sisi server.
    }
};

Antarmuka/Metode

Parameter

Nilai kembali

Deskripsi

public void onEvent(SpeechSynthesisResult result)

result: Instans SpeechSynthesisResult

Tidak ada

Dipanggil secara asinkron saat server mendorong data sintesis ucapan.

Anda dapat memanggil metode getAudioFrame dari SpeechSynthesisResult untuk mendapatkan data 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

Callback dipanggil secara asinkron setelah semua data sintetis dikembalikan (sintesis ucapan selesai).

public void onError(Exception e)

e: Informasi pengecualian

Tidak ada

Antarmuka ini dipanggil secara asinkron saat terjadi pengecualian.

Implementasikan logika pencatatan pengecualian lengkap dan pembersihan resource di metode onError.

Respons

Server mengembalikan data audio biner:

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

  • Panggilan streaming unidireksional atau panggilan streaming bidireksional: Proses parameter 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 data audio biner dari segmen sintesis streaming saat ini. Ini mungkin kosong jika tidak ada data baru yang tiba.

    Gabungkan data audio biner menjadi file audio lengkap untuk pemutaran, atau putar secara real-time dengan pemutar yang mendukung pemutaran streaming.

    Penting
    • Dalam sintesis ucapan streaming, untuk format terkompresi seperti MP3 dan Opus, gunakan pemutar streaming untuk memutar segmen audio. Jangan memutarnya frame demi frame untuk menghindari kegagalan decoding.

      Pemutar yang mendukung pemutaran streaming termasuk ffmpeg, pyaudio (Python), AudioFormat (Java), dan MediaSource (JavaScript).
    • Saat menggabungkan data audio menjadi file audio lengkap, tambahkan data tersebut ke file yang sama.

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

    public String getRequestId()

    Tidak ada

    Request ID dari tugas.

    Mendapatkan Request ID tugas. Saat Anda memanggil getAudioFrame untuk mendapatkan data audio biner, nilai kembalian 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 yang telah digunakan sejauh ini dalam permintaan saat ini. Gunakan SpeechSynthesisUsage yang diterima terakhir sebagai hitungan akhir.

    public Sentence getTimestamp()

    Tidak ada

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

    Anda harus mengaktifkan fitur timestamp tingkat kata enableWordTimestamp.

    Mengembalikan Sentence atau null.

    Metode Sentence:

    • getIndex: Mendapatkan nomor kalimat, dimulai dari 0.

    • getWords: Mendapatkan array kata yang membentuk kalimat, List<Word>. Gunakan Sentence yang diterima terakhir sebagai hasil akhir.

    Metode Word:

    • getText: Mendapatkan teks karakter.

    • getBeginIndex: Mendapatkan indeks 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

Untuk informasi troubleshooting, lihat Pesan kesalahan.

Contoh lainnya

Untuk contoh lainnya, lihat GitHub.

FAQ

Fitur, penagihan, dan pembatasan laju

T: Apa yang bisa saya lakukan untuk memperbaiki pelafalan yang tidak akurat?

Anda dapat menggunakan SSML untuk menyesuaikan output sintesis ucapan.

T: Sintesis ucapan ditagih berdasarkan jumlah karakter teks. Bagaimana cara melihat atau mendapatkan panjang teks untuk setiap sintesis?

Troubleshooting

Jika terjadi kesalahan kode, lihat Kode kesalahan untuk informasi troubleshooting.

T: Bagaimana cara mendapatkan Request ID?

Anda dapat mengambilnya dengan salah satu dari dua cara berikut:

T: Mengapa fitur SSML gagal?

Lakukan langkah-langkah berikut untuk troubleshooting masalah ini:

  1. Verifikasi bahwa Batasan dan kendala sudah benar.

  2. Instal versi terbaru SDK DashScope.

  3. Pastikan Anda menggunakan antarmuka yang benar. SSML hanya didukung oleh metode call dari kelas SpeechSynthesizer.

  4. Pastikan teks untuk sintesis dalam bentuk teks biasa dan memenuhi persyaratan format. Lihat Bahasa markup SSML.

T: Mengapa audio tidak bisa diputar?

Lakukan troubleshooting berdasarkan skenario berikut:

  1. Audio disimpan sebagai file lengkap, seperti file .mp3.

    1. Konsistensi format audio: Pastikan format audio yang ditentukan dalam parameter permintaan sesuai dengan ekstensi file. Misalnya, pemutaran mungkin gagal jika format audio diatur ke WAV dalam parameter permintaan tetapi file memiliki ekstensi .mp3.

    2. Kompatibilitas pemutar: Pastikan pemutar Anda mendukung format dan laju sampel file audio. Misalnya, beberapa pemutar mungkin tidak mendukung laju sampel tinggi atau pengkodean audio tertentu.

  2. Audio diputar dalam mode streaming.

    1. Simpan aliran audio sebagai file lengkap dan coba putar. Jika file gagal diputar, lihat langkah troubleshooting untuk skenario pertama.

    2. Jika file dapat diputar dengan benar, masalahnya mungkin terletak pada implementasi pemutaran streaming. Pastikan 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?

Lakukan troubleshooting berdasarkan skenario berikut:

  1. Periksa kecepatan pengiriman teks: Pastikan interval pengiriman teks wajar. Hindari penundaan dalam mengirimkan segmen teks berikutnya setelah audio untuk segmen sebelumnya selesai diputar.

  2. Periksa kinerja fungsi callback:

    • Periksa apakah fungsi callback berisi logika bisnis berlebihan yang dapat menyebabkannya terblokir.

    • Fungsi callback berjalan di thread WebSocket. Jika thread ini terblokir, hal ini dapat mengganggu kemampuan WebSocket untuk menerima paket jaringan, sehingga menyebabkan audio tersendat.

    • Untuk menghindari pemblokiran thread WebSocket, tulis data audio ke buffer audio terpisah lalu gunakan thread lain untuk membaca dan memprosesnya.

  3. Periksa stabilitas jaringan: Pastikan koneksi jaringan Anda stabil untuk mencegah gangguan atau penundaan transmisi audio akibat fluktuasi jaringan.

T: Mengapa sintesis ucapan lambat (waktu sintesis lama)?

Lakukan langkah troubleshooting berikut:

  1. Periksa interval input

    Jika Anda menggunakan sintesis ucapan streaming, periksa apakah interval pengiriman teks terlalu lama. Misalnya, penundaan beberapa detik sebelum mengirimkan segmen berikutnya akan meningkatkan total waktu sintesis.

  2. Analisis metrik kinerja

    • Latensi paket pertama: Biasanya sekitar 500 ms.

    • Faktor Waktu Nyata (RTF): Dihitung sebagai Total Waktu Sintesis / Durasi Audio. RTF biasanya kurang dari 1,0.

T: Bagaimana cara menangani pelafalan yang salah dalam ucapan hasil sintesis?

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

T: Mengapa tidak ada ucapan yang dikembalikan? Mengapa teks di akhir tidak berhasil dikonversi menjadi ucapan? (Ucapan hasil sintesis hilang)

Periksa apakah Anda telah memanggil metode streamingComplete dari kelas SpeechSynthesizer. Selama sintesis ucapan, server menyimpan teks dalam cache dan baru mulai sintesis setelah jumlah teks yang cukup tersimpan dalam cache. Jika Anda tidak memanggil metode streamingComplete, teks yang tersisa dalam cache mungkin tidak disintesis menjadi ucapan.

Izin dan otentikasi

T: Saya ingin Kunci API saya hanya digunakan untuk layanan sintesis ucapan CosyVoice, bukan untuk model Model Studio lainnya (isolasi izin). Apa yang harus saya lakukan?

Anda dapat membuat ruang kerja dan hanya mengotorisasi model tertentu untuk membatasi cakupan Kunci API. Lihat Kelola ruang kerja.

Pertanyaan lainnya

Lihat Q&A di GitHub.