All Products
Search
Document Center

Alibaba Cloud Model Studio:SDK Python sintesis suara CosyVoice

Last Updated:Jul 03, 2026

Gunakan SDK Python DashScope untuk mengintegrasikan sintesis suara real-time CosyVoice ke dalam aplikasi Anda melalui mode non-streaming, streaming satu arah, atau streaming dua arah.

Panduan pengguna: Untuk deskripsi model dan rekomendasi pemilihan, lihat Sintesis suara.

Titik akhir layanan

SDK menggunakan titik akhir wilayah Beijing secara default. Untuk beralih ke wilayah lain, ubah dashscope.base_websocket_api_url sebelum inisialisasi.

Singapura

wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference

Ganti {WorkspaceId} dengan workspace ID Anda yang sebenarnya.

Tiongkok (Beijing)

wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api-ws/v1/inference

Ganti {WorkspaceId} dengan workspace ID Anda yang sebenarnya.

Beralih ke wilayah Singapura:

import dashscope

# Setel di awal kode Anda
dashscope.base_websocket_api_url = 'wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference'
Penting

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

  • Tiongkok (Beijing): dari dashscope.aliyuncs.com ke {WorkspaceId}.cn-beijing.maas.aliyuncs.com

  • Singapura: dari dashscope-intl.aliyuncs.com ke {WorkspaceId}.ap-southeast-1.maas.aliyuncs.com

Ganti {WorkspaceId} dengan Workspace ID Anda yang sebenarnya. Domain lama tetap berfungsi penuh.

SpeechSynthesizer

Jalur paket: dashscope.audio.tts_v2.SpeechSynthesizer

Konstruktor

SpeechSynthesizer(
    model: str,
    voice: str,
    format: AudioFormat = AudioFormat.MP3_22050HZ_MONO_256KBPS,
    volume: int = 50,
    speech_rate: float = 1.0,
    pitch_rate: float = 1.0,
    callback: ResultCallback = None)

call() - non-streaming

Signature metode:

def call(self, text: str) -> bytes

Parameter:

Parameter

Tipe

Wajib

Deskripsi

text

str

Ya

Teks lengkap yang akan disintesis. Panjang maksimum: 20.000 karakter.

Nilai kembalian: bytes yang berisi data audio lengkap.

Deskripsi: Pemanggilan blocking ini mengembalikan data audio lengkap sekaligus. Metode ini paling cocok untuk teks pendek yang tidak memerlukan streaming real-time. Inisialisasi ulang instans SpeechSynthesizer sebelum setiap pemanggilan.

streaming_call() - streaming

Signature metode:

def streaming_call(self, text: str) -> None

Parameter:

Parameter

Tipe

Wajib

Deskripsi

text

str

Ya

Segmen teks yang akan disintesis. Panggil metode ini beberapa kali untuk menambahkan teks. Maksimum per pemanggilan: 20.000 karakter. Maksimum kumulatif: 200.000 karakter.

Deskripsi: Pemanggilan streaming dua arah ini menerima teks dalam segmen dan mengirimkan audio hasil sintesis melalui callback secara real-time. Metode ini ideal untuk integrasi dengan model bahasa besar di mana teks dihasilkan secara progresif. Panggil streaming_complete() setelah mengirimkan seluruh teks.

streaming_complete() - akhiri streaming

Signature metode:

def streaming_complete(self) -> None

Deskripsi: Memberi tahu server bahwa seluruh teks telah dikirim. Memblokir thread saat ini hingga sisa teks disintesis dan seluruh data audio dikembalikan. Gagal memanggil metode ini dapat menyebabkan teks akhir tidak dikonversi menjadi suara.

get_last_request_id() - dapatkan ID permintaan

Signature metode:

def get_last_request_id(self) -> str

Nilai kembalian: str yang berisi ID permintaan dari permintaan terbaru. Gunakan ini untuk troubleshooting dan pelacakan.

get_first_package_delay() - dapatkan latensi paket pertama

Signature metode:

def get_first_package_delay(self) -> int

Nilai kembalian: int yang merepresentasikan penundaan dalam milidetik dari pengiriman teks hingga menerima chunk audio pertama. Panggil ini setelah sintesis selesai.

get_response() - dapatkan pesan respons

Signature metode:

def get_response(self) -> str

Nilai kembalian: str yang berisi pesan respons dalam format JSON dari tugas sintesis terbaru, termasuk status permintaan dan informasi output.

Parameter konstruktor

Parameter berikut ditetapkan melalui konstruktor SpeechSynthesizer untuk mengontrol model, suara, format, dan karakteristik audio.

Parameter

Tipe

Wajib

Deskripsi

model

str

Ya

Nama model.

voice

str

Ya

voice string (required)

Suara yang digunakan untuk sintesis suara.

  • Suara sistem: Lihat Daftar Suara CosyVoice

  • Suara kloning: Suara kustom yang dibuat melalui kloning suara

  • Suara kustom: Suara kustom yang dibuat melalui desain suara

format

enum

Tidak

Format encoding audio dan laju sampel.

Default: AudioFormat.MP3_22050HZ_MONO_256KBPS.

Enum AudioFormat terletak di dashscope.audio.tts_v2 dan mendukung format MP3, WAV, PCM, dan lainnya.

volume

int

Tidak

Tingkat volume.

Nilai default: 50.

Nilai valid: [0, 100].

speech_rate

float

Tidak

Laju bicara.

Nilai default: 1.0.

Nilai valid: [0.5, 2.0].

pitch_rate

float

Tidak

Pitch.

Nilai default: 1.0.

Nilai valid: [0.5, 2.0].

bit_rate

int

Tidak

Bitrate audio dalam kbps. Saat format audio adalah opus, gunakan bit_rate untuk menyesuaikan bitrate.

Nilai default: 32.

Nilai valid: [6, 510].

Catatan

Setel bit_rate melalui parameter additional_params:

synthesizer = SpeechSynthesizer(
          model="cosyvoice-v3-flash",
          voice="longanyang",
          additional_params={"bit_rate": 128000}
      )

word_timestamp_enabled

bool

Tidak

Menentukan apakah akan mengaktifkan timestamp tingkat kata.

Nilai default: false.

Hanya tersedia dalam mode keluaran streaming. Suara yang didukung: suara kloning dari cosyvoice-v3.5-plus, cosyvoice-v3.5-flash, cosyvoice-v3-flash, cosyvoice-v3-plus, dan cosyvoice-v2, serta suara sistem yang ditandai sebagai didukung di Daftar Suara CosyVoice. Suara kloning dari model lain tidak mendukung fitur ini.

Catatan

Setel word_timestamp_enabled melalui parameter additional_params:

synthesizer = SpeechSynthesizer(
          model="cosyvoice-v3-flash",
          voice="your_voice",
          additional_params={"word_timestamp_enabled": True}
      )

seed

int

Tidak

Seed acak untuk mengontrol variasi pada output sintesis. Ketika versi model, teks, suara, dan parameter lainnya tidak berubah, penggunaan seed yang sama menghasilkan hasil identik.

Nilai default: 0.

Nilai valid: [0, 65535].

language_hints

list[str]

Tidak

Penting
  • Parameter ini berupa array, tetapi versi saat ini hanya memproses elemen pertama. Berikan satu nilai saja.

  • Parameter ini menentukan bahasa target untuk sintesis suara. Parameter ini tidak terkait dengan bahasa sampel audio yang digunakan dalam kloning suara. Untuk mengatur bahasa sumber untuk tugas kloning, lihat referensi API kloning suara.

Menentukan bahasa target untuk sintesis suara guna meningkatkan kualitas output.

Saat pelafalan angka, ekspansi singkatan, pembacaan simbol, atau sintesis bahasa minoritas tidak sesuai harapan, gunakan parameter ini. Contohnya:

  • Pelafalan angka tidak sesuai: "hello, this is 110" dibaca sebagai "hello, this is one zero" alih-alih pelafalan Mandarin yang diharapkan

  • Pelafalan simbol tidak akurat: "@" dibaca sebagai ekuivalen Mandarin alih-alih "at"

  • Kualitas sintesis bahasa minoritas buruk dengan hasil tidak alami

Nilai valid:

  • zh: Bahasa Tiongkok

  • en: Inggris

  • fr: Prancis

  • de: Jerman

  • ja: Jepang

  • ko: Korea

  • ru: Rusia

  • pt: Portugis

  • th: Thai

  • id: Bahasa Indonesia

  • vi: Bahasa Vietnam

instruction

str

Tidak

Mengontrol karakteristik sintesis seperti dialek, emosi, atau gaya berbicara.

Untuk detail penggunaan, lihat Kontrol berbasis instruksi.

enable_aigc_tag

bool

Tidak

Menentukan apakah akan menyematkan watermark AIGC ke dalam audio yang dihasilkan. Saat diatur ke true, watermark disematkan ke dalam file audio dengan format yang didukung (wav/mp3/opus).

Nilai default: false.

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

Catatan

Setel enable_aigc_tag, aigc_propagator, dan aigc_propagate_id melalui parameter additional_params:

synthesizer = SpeechSynthesizer(
          model="cosyvoice-v3-flash",
          voice="longanyang",
          additional_params={
              "enable_aigc_tag": True,
              "aigc_propagator": "your_propagator",
              "aigc_propagate_id": "your_propagate_id"
          }
      )

aigc_propagator

str

Tidak

Menyetel bidang ContentPropagator dalam watermark AIGC, mengidentifikasi propagator konten. 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.

Setel melalui parameter additional_params. Lihat contoh enable_aigc_tag.

aigc_propagate_id

str

Tidak

Menyetel bidang PropagateID dalam watermark AIGC, mengidentifikasi secara unik tindakan propagasi tertentu. 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.

Setel melalui parameter additional_params. Lihat contoh enable_aigc_tag.

hot_fix

dict

Tidak

Mengonfigurasi koreksi pelafalan dan penggantian teks yang diterapkan sebelum sintesis.

Fitur ini tidak didukung oleh cosyvoice-v2.

Parameter:

  • pronunciation: Pelafalan kustom. Menentukan anotasi pinyin untuk kata-kata guna memperbaiki pelafalan default yang tidak akurat.

  • replace: Penggantian teks. Mengganti kata-kata tertentu dengan teks target sebelum sintesis. Teks yang diganti digunakan sebagai input sintesis sebenarnya.

Contoh:

synthesizer = SpeechSynthesizer(
    model="cosyvoice-v3-flash",
    voice="your_voice", # Ganti dengan suara kloning cosyvoice-v3-flash Anda
    hot_fix={
        "pronunciation": [{"weather": "tian1 qi4"}],
        "replace": [{"today": "gold day"}]
    }
)

enable_markdown_filter

bool

Tidak

Penting

Hanya suara kloning dari cosyvoice-v3-flash yang mendukung fitur ini.

Menentukan apakah akan mengaktifkan penyaringan Markdown. Saat diaktifkan, sistem secara otomatis menghapus simbol markup Markdown dari teks input sebelum sintesis, sehingga simbol tersebut tidak dibaca keras-keras.

Nilai default: false.

Nilai valid:

  • true: Aktifkan penyaringan Markdown

  • false: Nonaktifkan penyaringan Markdown

Catatan

Setel enable_markdown_filter melalui parameter additional_params:

synthesizer = SpeechSynthesizer(
          model="cosyvoice-v3-flash",
          voice="your_voice", # Ganti dengan suara kloning cosyvoice-v3-flash Anda
          additional_params={"enable_markdown_filter": True}
      )

callback

ResultCallback

Tidak

Instans callback untuk menerima audio hasil sintesis dan notifikasi event secara asinkron. Saat diatur, call() berjalan dalam mode streaming dan mengirimkan audio melalui callback on_data. Saat tidak diatur, call() berjalan dalam mode non-streaming dan mengembalikan audio lengkap sebagai bytes.

ResultCallback

Jalur paket: dashscope.audio.tts_v2.ResultCallback

on_open() - koneksi terbentuk

Signature metode:

def on_open(self) -> None

Dipicu saat: Koneksi WebSocket berhasil dibentuk. Gunakan callback ini untuk menginisialisasi aliran output audio atau membuka sumber daya file.

on_event() - menerima respons server

Signature metode:

def on_event(self, message: str) -> None

Parameter:

Parameter

Tipe

Wajib

Deskripsi

message

str

Ya

Event respons server dalam format JSON yang berisi header (informasi permintaan) dan payload (informasi output). Bidang payload.output berisi tipe event, teks asli, dan detail lainnya. Lihat bidang output dalam pesan on_event.

Dipicu saat: Respons server diterima. Pesan berupa string JSON yang berisi output event sintesis (tipe event, teks asli, informasi kalimat). Urai dengan json.loads(message) dan akses payload.output untuk detailnya.

on_complete() - sintesis selesai

Signature metode:

def on_complete(self) -> None

Dipicu saat: Seluruh teks telah disintesis dan seluruh data audio telah dikirimkan melalui on_data. Gunakan callback ini untuk memanggil get_first_package_delay() guna mendapatkan metrik performa.

on_data() - menerima data audio

Signature metode:

def on_data(self, data: bytes) -> None

Parameter:

Parameter

Tipe

Wajib

Deskripsi

data

bytes

Ya

Chunk data biner audio dalam format yang ditentukan oleh parameter format konstruktor.

Dipicu saat: Chunk data audio diterima. Callback ini dipanggil beberapa kali selama sintesis. Gunakan untuk menulis data ke file atau mengirimkannya ke perangkat pemutaran.

on_error() - terjadi kesalahan

Signature metode:

def on_error(self, message: str) -> None

Parameter:

Parameter

Tipe

Wajib

Deskripsi

message

str

Ya

Deskripsi kesalahan yang berisi kode kesalahan dan alasan detail.

Dipicu saat: Terjadi kesalahan selama sintesis. Koneksi ditutup secara otomatis setelah callback ini dijalankan. Catat kesalahan untuk troubleshooting.

on_close() - koneksi ditutup

Signature metode:

def on_close(self) -> None

Dipicu saat: Koneksi WebSocket ditutup (baik normal maupun karena kesalahan). Gunakan callback ini untuk melepaskan sumber daya seperti perangkat pemutaran audio.

Bidang output dalam pesan on_event

Pesan JSON yang diterima oleh callback on_event berisi bidang payload.output dengan informasi event sintesis. Gunakan bidang ini untuk melacak progres sintesis dan mengambil detail per kalimat. Struktur bidang output adalah sebagai berikut:

Bidang

Tipe

Deskripsi

type

str

Tipe event. Nilai: sentence-begin (sintesis kalimat dimulai), sentence-synthesis (sintesis kalimat sedang berlangsung), atau sentence-end (sintesis kalimat selesai).

original_text

str

Teks asli dari kalimat saat ini. Dikembalikan dalam event sentence-begin dan sentence-end.

sentence

dict

Informasi kalimat. Berisi index (nomor urut kalimat) dan words (daftar kata dengan informasi timestamp saat word_timestamp_enabled aktif).

Contoh pesan:

{
  "header": {
    "task_id": "xxx",
    "event": "result-generated",
    "attributes": {}
  },
  "payload": {
    "output": {
      "type": "sentence-begin",
      "original_text": "How is the weather today?",
      "sentence": {
        "index": 0,
        "words": []
      }
    }
  }
}

Contoh penguraian:

import json

def on_event(self, message):
    data = json.loads(message)
    output = data.get('payload', {}).get('output', {})
    event_type = output.get('type', '')
    original_text = output.get('original_text', '')
    if event_type:
        print(f'Tipe event: {event_type}, Teks asli: {original_text}')

Contoh kode

SDK mendukung mode sintesis berikut:

  • Non-streaming: Pemanggilan blocking yang mengirimkan teks lengkap sekaligus dan mengembalikan audio lengkap secara langsung. Paling cocok untuk sintesis suara teks pendek.

  • Streaming satu arah: Pemanggilan non-blocking yang mengirimkan teks lengkap sekaligus dan mengirimkan data audio (mungkin dalam chunk) melalui fungsi callback. Paling cocok untuk skenario teks pendek yang memerlukan latensi rendah.

  • Streaming dua arah: Pemanggilan non-blocking yang mengirimkan teks dalam beberapa segmen dan mengirimkan audio hasil sintesis secara inkremental melalui fungsi callback secara real-time. Paling cocok untuk skenario teks panjang yang memerlukan latensi rendah.

Non-streaming

Teks yang dikirim dalam satu pemanggilan tidak boleh melebihi 20.000 karakter. Melebihi batas ini menyebabkan kesalahan.

Penting

Lakukan inisialisasi ulang instans SpeechSynthesizer sebelum setiap call.

# coding=utf-8

import dashscope
from dashscope.audio.tts_v2 import *
import os

# API Key untuk wilayah Singapura dan Beijing berbeda. Dapatkan API Key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# Jika variabel lingkungan belum dikonfigurasi, ganti baris berikut dengan API Key Model Studio Anda: dashscope.api_key = "sk-xxx"
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')

# Konfigurasi berikut untuk wilayah Singapura. Ganti "{WorkspaceId}" dengan workspace ID Anda yang sebenarnya. Konfigurasi berbeda tiap wilayah.
dashscope.base_websocket_api_url='wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference'

# Model
model = "cosyvoice-v3-flash"
# Voice
voice = "longanyang"

# Buat instans SpeechSynthesizer, teruskan parameter permintaan seperti model dan voice di konstruktor
synthesizer = SpeechSynthesizer(model=model, voice=voice)
# Kirim teks untuk sintesis dan dapatkan audio biner
audio = synthesizer.call("How is the weather today?")
# Pengiriman teks pertama memerlukan pembentukan koneksi WebSocket, sehingga latensi paket pertama mencakup waktu pembentukan koneksi
print('[Metric] requestId: {}, first packet latency: {} ms'.format(
    synthesizer.get_last_request_id(),
    synthesizer.get_first_package_delay()))

# Simpan audio ke file lokal
with open('output.mp3', 'wb') as f:
    f.write(audio)

Streaming satu arah

Teks yang dikirim dalam satu pemanggilan tidak boleh melebihi 20.000 karakter. Melebihi batas ini menyebabkan kesalahan.

Penting

Inisialisasi ulang instans SpeechSynthesizer sebelum setiap pemanggilan call.

# coding=utf-8

import os
import json
import dashscope
from dashscope.audio.tts_v2 import *

from datetime import datetime

def get_timestamp():
    now = datetime.now()
    formatted_timestamp = now.strftime("[%Y-%m-%d %H:%M:%S.%f]")
    return formatted_timestamp

# API Key untuk wilayah Singapura dan Beijing berbeda. Dapatkan API Key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# Jika variabel lingkungan belum dikonfigurasi, ganti baris berikut dengan API Key Model Studio Anda: dashscope.api_key = "sk-xxx"
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')

# Konfigurasi berikut untuk wilayah Singapura. Ganti "{WorkspaceId}" dengan workspace ID Anda yang sebenarnya. Konfigurasi berbeda tiap wilayah.
dashscope.base_websocket_api_url='wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference'

# Model
model = "cosyvoice-v3-flash"
# Voice
voice = "longanyang"

# Definisikan antarmuka callback
class Callback(ResultCallback):
    _player = None
    _stream = None

    def on_open(self):
        self.file = open("output.mp3", "wb")
        print("Koneksi terbentuk: " + get_timestamp())

    def on_complete(self):
        print("Sintesis suara selesai, seluruh hasil diterima: " + get_timestamp())
        # Setelah tugas selesai (callback on_complete dipicu), Anda dapat memanggil get_first_package_delay untuk mendapatkan latensi
        # Pengiriman teks pertama memerlukan pembentukan koneksi WebSocket, sehingga latensi paket pertama mencakup waktu pembentukan koneksi
        print('[Metric] requestId: {}, first packet latency: {} ms'.format(
            synthesizer.get_last_request_id(),
            synthesizer.get_first_package_delay()))

    def on_error(self, message: str):
        print(f"Kesalahan sintesis suara: {message}")

    def on_close(self):
        print("Koneksi ditutup: " + get_timestamp())
        self.file.close()

    def on_event(self, message):
        # Urai event sisi server dan dapatkan informasi output
        data = json.loads(message)
        output = data.get('payload', {}).get('output', {})
        event_type = output.get('type', '')
        original_text = output.get('original_text', '')
        if event_type:
            print(f"Tipe event: {event_type}, teks asli: {original_text}")

    def on_data(self, data: bytes) -> None:
        print(get_timestamp() + " Panjang audio biner: " + str(len(data)))
        self.file.write(data)

callback = Callback()

# Buat instans SpeechSynthesizer, teruskan parameter permintaan seperti model dan voice di konstruktor
synthesizer = SpeechSynthesizer(
    model=model,
    voice=voice,
    callback=callback,
)

# Kirim teks untuk sintesis dan dapatkan audio biner secara real-time melalui metode callback on_data
synthesizer.call("How is the weather today?")

Streaming dua arah

Teks yang dikirim per pemanggilan tidak boleh melebihi 20.000 karakter. Teks kumulatif tidak boleh melebihi 200.000 karakter.

  • Saat input streaming, panggil streaming_call beberapa kali untuk mengirimkan segmen teks secara berurutan. Server secara otomatis melakukan segmentasi kalimat pada teks yang diterima:

    • Kalimat lengkap langsung disintesis

    • Kalimat tidak lengkap dibuffer hingga lengkap

    Saat streaming_complete dipanggil, server memaksa mensintesis seluruh teks yang diterima namun belum diproses (termasuk kalimat tidak lengkap).

  • Interval antar segmen teks tidak boleh melebihi 23 detik. Jika tidak, akan muncul exception "request timeout after 23 seconds".

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

    Penting

    Selalu panggil streaming_complete. Gagal melakukannya dapat menyebabkan teks akhir tidak dikonversi menjadi suara.

    Server menerapkan timeout 23 detik. Nilai ini tidak dapat diubah di sisi klien.
# coding=utf-8
#
# Instruksi instalasi pyaudio:
# Untuk macOS, jalankan perintah berikut:
#   brew install portaudio
#   pip install pyaudio
# Untuk Debian/Ubuntu, jalankan perintah berikut:
#   sudo apt-get install python-pyaudio python3-pyaudio
#   atau
#   pip install pyaudio
# Untuk CentOS, jalankan perintah berikut:
#   sudo yum install -y portaudio portaudio-devel && pip install pyaudio
# Untuk Microsoft Windows, jalankan perintah berikut:
#   python -m pip install pyaudio

import os
import time
import pyaudio
import json
import dashscope
from dashscope.api_entities.dashscope_response import SpeechSynthesisResponse
from dashscope.audio.tts_v2 import *

from datetime import datetime

def get_timestamp():
    now = datetime.now()
    formatted_timestamp = now.strftime("[%Y-%m-%d %H:%M:%S.%f]")
    return formatted_timestamp

# API Key untuk wilayah Singapura dan Beijing berbeda. Dapatkan API Key: https://www.alibabacloud.com/help/zh/model-studio/get-api-key
# Jika variabel lingkungan belum dikonfigurasi, ganti baris berikut dengan API Key Model Studio Anda: dashscope.api_key = "sk-xxx"
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')

# Konfigurasi berikut untuk wilayah Singapura. Ganti "{WorkspaceId}" dengan workspace ID Anda yang sebenarnya. Konfigurasi berbeda tiap wilayah.
dashscope.base_websocket_api_url='wss://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api-ws/v1/inference'

# Model
model = "cosyvoice-v3-flash"
# Voice
voice = "longanyang"

# Definisikan antarmuka callback
class Callback(ResultCallback):
    _player = None
    _stream = None

    def on_open(self):
        print("Koneksi terbentuk: " + get_timestamp())
        self._player = pyaudio.PyAudio()
        self._stream = self._player.open(
            format=pyaudio.paInt16, channels=1, rate=22050, output=True
        )

    def on_complete(self):
        print("Sintesis suara selesai, seluruh hasil diterima: " + get_timestamp())

    def on_error(self, message: str):
        print(f"Kesalahan sintesis suara: {message}")

    def on_close(self):
        print("Koneksi ditutup: " + get_timestamp())
        # Hentikan pemutar
        self._stream.stop_stream()
        self._stream.close()
        self._player.terminate()

    def on_event(self, message):
        # Urai event sisi server dan dapatkan informasi output
        data = json.loads(message)
        output = data.get('payload', {}).get('output', {})
        event_type = output.get('type', '')
        original_text = output.get('original_text', '')
        if event_type:
            print(f"Tipe event: {event_type}, teks asli: {original_text}")

    def on_data(self, data: bytes) -> None:
        print(get_timestamp() + " Panjang audio biner: " + str(len(data)))
        self._stream.write(data)

callback = Callback()

test_text = [
    "Streaming text-to-speech SDK,",
    "converts input text",
    "into binary audio data.",
    "Compared with non-streaming speech synthesis,",
    "streaming synthesis offers better real-time performance.",
    "Users hear near-synchronous audio output while typing,",
    "greatly improving interaction experience",
    "and reducing wait time.",
    "Ideal for large language model (LLM) integration,",
    "where text is streamed for speech synthesis.",
]

# Buat instans SpeechSynthesizer, teruskan parameter permintaan seperti model dan voice di konstruktor
synthesizer = SpeechSynthesizer(
    model=model,
    voice=voice,
    format=AudioFormat.PCM_22050HZ_MONO_16BIT,
    callback=callback,
)

# Kirim teks untuk sintesis streaming. Dapatkan audio biner secara real-time melalui metode callback on_data
for text in test_text:
    synthesizer.streaming_call(text)
    time.sleep(0.1)
# Akhiri sintesis suara streaming
synthesizer.streaming_complete()

# Pengiriman teks pertama memerlukan pembentukan koneksi WebSocket, sehingga latensi paket pertama mencakup waktu pembentukan koneksi
print('[Metric] requestId: {}, first packet latency: {} ms'.format(
    synthesizer.get_last_request_id(),
    synthesizer.get_first_package_delay()))