DashScope Python SDK を使用して、非ストリーミング、一方向ストリーミング、または双方向ストリーミングモードで CosyVoice リアルタイム音声合成をアプリケーションに統合できます。
ユーザーガイド: モデルの説明と選定の推奨については、「音声合成」をご参照ください。
サービスエンドポイント
SDK は、デフォルトで北京リージョンのエンドポイントを使用します。別のリージョンに切り替えるには、初期化の前に dashscope.base_websocket_api_url を変更します。
インターナショナル
インターナショナルのデプロイメントスコープを選択した場合、モデル推論のコンピューティングリソースは、中国本土を除く世界中で動的にスケジュールされます。静的データは、選択したリージョンに保存されます。サポートされているリージョン:Singapore。
wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference
中国本土
中国本土のデプロイメントスコープを選択した場合、モデル推論のコンピューティングリソースは中国本土に制限されます。静的データは、選択したリージョンに保存されます。サポートされているリージョン:China (Beijing)。
wss://dashscope.aliyuncs.com/api-ws/v1/inference
Singapore リージョンへの切り替え:
import dashscope
# コードの先頭で設定します
dashscope.base_websocket_api_url = 'wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference'SpeechSynthesizer
パッケージパス: dashscope.audio.tts_v2.SpeechSynthesizer
コンストラクター
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() (非ストリーミング)
メソッドシグネチャ:
def call(self, text: str) -> bytesパラメータ:
パラメータ | タイプ | 必須 | 説明 |
text | str | はい | 合成するテキスト全体です。最大長:20,000 文字。 |
戻り値: 完全な音声データを含む bytes。
説明:このブロッキング呼び出しは、完全なオーディオデータを一度に返します。リアルタイムストリーミングが不要な短いテキストに最適です。各呼び出しの前に SpeechSynthesizer インスタンスを再初期化してください。
streaming_call():ストリーミング
メソッドシグネチャ:
def streaming_call(self, text: str) -> Noneパラメータ:
パラメータ | タイプ | 必須 | 説明 |
text | str | はい | 合成するテキストセグメントです。このメソッドを複数回呼び出してテキストを追加します。1 回の呼び出しあたりの最大長:20,000 文字。累積最大長:200,000 文字。 |
説明:この双方向ストリーミング呼び出しは、セグメント単位でテキストを受け取り、リアルタイムでコールバックを通じて合成されたオーディオを配信します。テキストが段階的に生成される大規模言語モデルとの統合に最適です。すべてのテキストを送信した後、streaming_complete() を呼び出してください。
streaming_complete() - ストリーミングの終了
メソッドシグネチャ:
def streaming_complete(self) -> None説明:すべてのテキストが送信されたことをサーバーに通知します。残りのテキストが合成され、すべてのオーディオデータが返されるまで現在のスレッドをブロックします。このメソッドを呼び出さないと、末尾のテキストが音声に変換されない可能性があります。
get_last_request_id() - リクエスト ID の取得
メソッドシグネチャ:
def get_last_request_id(self) -> str戻り値: 最新のリクエストのリクエスト ID を含む str。トラブルシューティングとトレースに使用します。
get_first_package_delay() - 初回パケット遅延の取得
メソッドシグネチャ:
def get_first_package_delay(self) -> int戻り値: int。テキストを送信してから最初のオーディオチャンクを受信するまでの遅延 (ミリ秒) です。合成完了後に呼び出します。
get_response() - レスポンスメッセージを取得する
メソッドシグネチャ:
def get_response(self) -> str戻り値: str。リクエストステータスと出力情報を含む、最新の合成タスクからの JSON 形式のレスポンスメッセージ。
コンストラクターパラメータ
以下のパラメータは、SpeechSynthesizer コンストラクターを通じて設定し、モデル、音声、形式、およびオーディオ特性を制御します。
パラメータ | タイプ | 必須 | 説明 |
model | str | はい | モデル名です。 |
voice | str | はい | voice 音声合成に使用するボイスです。
|
format | enum | いいえ | 音声エンコーディング形式とサンプルレート。 デフォルト値: AudioFormat enum は |
volume | int | いいえ | 音量レベルです。 デフォルト値:50。 有効な値:[0, 100]。 |
speech_rate | float | いいえ | 話速です。 デフォルト値:1.0。 有効な値:[0.5, 2.0]。 |
pitch_rate | float | いいえ | ピッチです。 デフォルト値:1.0。 有効な値:[0.5, 2.0]。 |
bit_rate | int | いいえ | kbps 単位のオーディオのビットレートです。オーディオ形式が opus の場合は、 デフォルト値:32。 有効な値:[6, 510]。 説明
|
word_timestamp_enabled | bool | いいえ | 単語レベルのタイムスタンプを有効にするかどうかを指定します。 デフォルト値:false。 cosyvoice-v3-flash、cosyvoice-v3-plus、cosyvoice-v2 モデルを使用するクローン音声、および「音声リスト」でサポート対象としてマークされているシステム音声でのみ利用可能です。 説明
|
seed | int | いいえ | 合成結果のばらつきを制御するためのランダムシードです。モデルバージョン、テキスト、ボイス、その他のパラメーターが同一の場合、同じシードを使用すると同一の結果になります。 デフォルト値:0。 有効な値:[0, 65535]。 |
language_hints | list[str] | いいえ | 重要
出力品質を向上させるため、音声合成のターゲット言語を指定します。 数字の発音、略語の展開、記号の読み上げ、またはマイナー言語の合成が期待どおりにならない場合は、このパラメーターを使用します。例:
有効な値:
|
instruction | str | いいえ | 方言、感情、話し方などの合成特性を制御します。 使用方法の詳細については、「指示ベースの制御」をご参照ください。 |
enable_aigc_tag | bool | No | 生成されたオーディオに AIGC ウォーターマークを埋め込むかどうかを指定します。true に設定すると、サポートされている形式 (wav/mp3/opus) のオーディオファイルにウォーターマークが埋め込まれます。 デフォルト値:false。 この機能は cosyvoice-v3-flash、cosyvoice-v3-plus、cosyvoice-v2 でのみサポートされています。 説明
|
aigc_propagator | str | いいえ | AIGC ウォーターマークの デフォルト値:Alibaba Cloud UID。 この機能は cosyvoice-v3-flash、cosyvoice-v3-plus、cosyvoice-v2 でのみサポートされています。
|
aigc_propagate_id | str | いいえ | AIGC ウォーターマークの デフォルト値:現在の音声合成リクエストのリクエスト ID。 この機能は cosyvoice-v3-flash、cosyvoice-v3-plus、cosyvoice-v2 でのみサポートされています。
|
hot_fix | dict | いいえ | 合成前に適用する発音補正とテキスト置換を設定します。この機能は、cosyvoice-v3-flash のクローンボイスでのみサポートされています。 パラメーター:
例: |
enable_markdown_filter | bool | No | 重要 この機能は、cosyvoice-v3-flash のクローンボイスでのみサポートされています。 Markdown フィルタリングを有効にするかどうかを指定します。有効にすると、システムは合成前に入力テキストから Markdown のマークアップ記号を自動的に除去し、読み上げを防ぎます。 デフォルト値:false。 有効な値:
説明
|
callback | ResultCallback | いいえ |
|
ResultCallback
パッケージパス: dashscope.audio.tts_v2.ResultCallback
on_open() - 接続の確立
メソッドシグネチャ:
def on_open(self) -> None呼び出されるタイミング: WebSocket 接続が正常に確立されたとき。このコールバックを使用して、オーディオ出力ストリームを初期化したり、ファイルリソースを開いたりします。
on_event() - サーバー応答の受信
メソッドシグネチャ:
def on_event(self, message: str) -> Noneパラメーター:
パラメーター | 型 | 必須 | 説明 |
message | str | はい |
|
呼び出されるタイミング: サーバー応答を受信したとき。メッセージは、合成イベントの出力 (イベントタイプ、原文、文の情報) を含む JSON 文字列です。json.loads(message) で解析し、payload.output にアクセスして詳細を取得します。
on_complete() - 合成完了
メソッドシグネチャ:
def on_complete(self) -> None呼び出されるタイミング: すべてのテキストが合成され、すべてのオーディオデータが on_data を通じて配信されたとき。このコールバックを使用して get_first_package_delay() を呼び出し、パフォーマンスメトリクスを取得します。
on_data() - オーディオデータの受信
メソッドシグネチャ:
def on_data(self, data: bytes) -> Noneパラメーター:
パラメーター | 型 | 必須 | 説明 |
data | bytes | はい | コンストラクターの format パラメーターで指定された形式のオーディオバイナリデータのチャンク。 |
呼び出されるタイミング: オーディオデータのチャンクを受信したとき。このコールバックは、合成中に複数回呼び出されます。このコールバックを使用して、データをファイルに書き込んだり、再生デバイスに供給したりします。
on_error() - エラーの発生
メソッドシグネチャ:
def on_error(self, message: str) -> Noneパラメーター:
パラメーター | 型 | 必須 | 説明 |
message | str | はい | エラーコードと詳細な理由を含むエラーの説明。 |
呼び出されるタイミング: 合成中にエラーが発生したとき。このコールバックが呼び出された後、接続は自動的にクローズされます。トラブルシューティングのためにエラーをログに記録してください。
on_close() - 接続のクローズ
メソッドシグネチャ:
def on_close(self) -> None呼び出されるタイミング: WebSocket 接続がクローズされたとき (正常時、エラー時を問わず)。このコールバックを使用して、オーディオ再生デバイスなどのリソースを解放します。
on_event メッセージの output フィールド
on_event コールバックが受信する JSON メッセージには、合成イベント情報を含む payload.output フィールドが含まれています。このフィールドを使用して、合成の進捗を追跡し、文ごとの詳細を取得します。output フィールドの構造は次のとおりです。
フィールド | タイプ | 説明 |
type | str | イベントタイプ。値: |
original_text | str | 現在の文の原文。 |
sentence | dict | 文の情報には、 |
メッセージの例
{
"header": {
"task_id": "xxx",
"event": "result-generated",
"attributes": {}
},
"payload": {
"output": {
"type": "sentence-begin",
"original_text": "How is the weather today?",
"sentence": {
"index": 0,
"words": []
}
}
}
}解析の例
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'Event type: {event_type}, Original text: {original_text}')コード例
SDK は、以下の合成モードをサポートしています:
ノンストリーミング:完全なテキストを一度に送信し、完全な音声を直接返すブロッキング呼び出しです。短いテキストの音声合成に最も適しています。
単方向ストリーミング:完全なテキストを一度に送信し、コールバック関数を介して音声データ (チャンク単位の場合もあります) を配信する非ブロッキング呼び出しです。低レイテンシーが求められる短いテキストのシナリオに最も適しています。
双方向ストリーミング:テキストを複数のセグメントで送信し、コールバック関数を介してリアルタイムで段階的に合成された音声を配信する非ブロッキング呼び出しです。低レイテンシーが求められる長いテキストのシナリオに最も適しています。
非ストリーミング
1 回の呼び出しで送信されるテキストは 20,000 文字を超えてはなりません。この制限を超えるとエラーが発生します。
各 call の前に SpeechSynthesizer インスタンスを再初期化してください。
# coding=utf-8
import dashscope
from dashscope.audio.tts_v2 import *
import os
# Singapore リージョンと Beijing リージョンの API キーは異なります。API キーの取得:https://www.alibabacloud.com/help/model-studio/get-api-key
# 環境変数が設定されていない場合は、次の行の "sk-xxx" をご自身の Model Studio API キーに置き換えてください。
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')
# 以下は Singapore リージョンの URL です。Beijing リージョンのモデルを使用する場合は、URL を次のように置き換えてください:wss://dashscope.aliyuncs.com/api-ws/v1/inference
dashscope.base_websocket_api_url='wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference'
# モデル
model = "cosyvoice-v3-flash"
# 音声
voice = "longanyang"
# SpeechSynthesizer をインスタンス化し、コンストラクターでモデルや音声などのリクエストパラメーターを渡します
synthesizer = SpeechSynthesizer(model=model, voice=voice)
# 合成用のテキストを送信し、バイナリオーディオを取得します
audio = synthesizer.call("How is the weather today?")
# 最初のテキスト送信には WebSocket 接続の確立が必要なため、初回パケットレイテンシーには接続セットアップ時間が含まれます
print('[Metric] requestId: {}, first packet latency: {} ms'.format(
synthesizer.get_last_request_id(),
synthesizer.get_first_package_delay()))
# オーディオをローカルファイルに保存します
with open('output.mp3', 'wb') as f:
f.write(audio)単方向ストリーミング
1 回の呼び出しで送信されるテキストは 20,000 文字を超えてはなりません。この制限を超えるとエラーが発生します。
各 call の前に SpeechSynthesizer インスタンスを再初期化してください。
# 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
# Singapore リージョンと Beijing リージョンの API キーは異なります。API キーの取得:https://www.alibabacloud.com/help/model-studio/get-api-key
# 環境変数が設定されていない場合は、次の行の "sk-xxx" をご自身の Model Studio API キーに置き換えてください。
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')
# 以下は Singapore リージョンの URL です。Beijing リージョンのモデルを使用する場合は、URL を次のように置き換えてください:wss://dashscope.aliyuncs.com/api-ws/v1/inference
dashscope.base_websocket_api_url='wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference'
# モデル
model = "cosyvoice-v3-flash"
# 音声
voice = "longanyang"
# コールバックインターフェイスを定義します
class Callback(ResultCallback):
_player = None
_stream = None
def on_open(self):
self.file = open("output.mp3", "wb")
print("接続確立:" + get_timestamp())
def on_complete(self):
print("音声合成完了、すべての結果を受信しました:" + get_timestamp())
# タスク完了後 (on_complete コールバックがトリガーされた後)、get_first_package_delay を呼び出してレイテンシーを取得できます
# 最初のテキスト送信には WebSocket 接続の確立が必要なため、初回パケットレイテンシーには接続セットアップ時間が含まれます
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"音声合成エラー:{message}")
def on_close(self):
print("接続クローズ:" + get_timestamp())
self.file.close()
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"イベントタイプ:{event_type}, 元のテキスト:{original_text}")
def on_data(self, data: bytes) -> None:
print(get_timestamp() + " バイナリオーディオの長さ:" + str(len(data)))
self.file.write(data)
callback = Callback()
# SpeechSynthesizer をインスタンス化し、コンストラクターでモデルや音声などのリクエストパラメーターを渡します
synthesizer = SpeechSynthesizer(
model=model,
voice=voice,
callback=callback,
)
# 合成用のテキストを送信し、on_data コールバックメソッドを通じてリアルタイムでバイナリオーディオを取得します
synthesizer.call("How is the weather today?")双方向ストリーミング
1 回の呼び出しで送信されるテキストは 20,000 文字を超えてはなりません。累積テキストは 200,000 文字を超えてはなりません。
ストリーミング入力中は、
streaming_callを複数回呼び出して、テキストセグメントを順番に送信します。サーバーは受信したテキストに対して自動的に文分割を実行します。完全な文は即座に合成されます。
不完全な文は完全になるまでバッファリングされます。
streaming_completeが呼び出されると、サーバーは受信したがまだ処理されていないすべてのテキスト (不完全な文を含む) を強制的に合成します。テキストセグメント間の間隔は 23 秒を超えてはなりません。超えると、"request timeout after 23 seconds" 例外が発生します。
送信するテキストがない場合は、速やかに
streaming_completeを呼び出してタスクを終了してください。重要必ず
streaming_completeを呼び出してください。呼び出さないと、末尾のテキストが音声に変換されない可能性があります。サーバーは 23 秒のタイムアウトを強制します。この値はクライアント側で変更できません。
# coding=utf-8
#
# pyaudio のインストール手順:
# macOS の場合、次のコマンドを実行します:
# brew install portaudio
# pip install pyaudio
# Debian/Ubuntu の場合、次のコマンドを実行します:
# sudo apt-get install python-pyaudio python3-pyaudio
# または
# pip install pyaudio
# CentOS の場合、次のコマンドを実行します:
# sudo yum install -y portaudio portaudio-devel && pip install pyaudio
# Microsoft Windows の場合、次のコマンドを実行します:
# python -m pip install pyaudio
import 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
# Singapore リージョンと Beijing リージョンの API キーは異なります。API キーの取得:https://www.alibabacloud.com/help/model-studio/get-api-key
# 環境変数が設定されていない場合は、次の行の "sk-xxx" をご自身の Model Studio API キーに置き換えてください。
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')
# 以下は Singapore リージョンの URL です。Beijing リージョンのモデルを使用する場合は、URL を次のように置き換えてください:wss://dashscope.aliyuncs.com/api-ws/v1/inference
dashscope.base_websocket_api_url='wss://dashscope-intl.aliyuncs.com/api-ws/v1/inference'
# モデル
model = "cosyvoice-v3-flash"
# 音声
voice = "longanyang"
# コールバックインターフェイスを定義します
class Callback(ResultCallback):
_player = None
_stream = None
def on_open(self):
print("接続確立:" + 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("音声合成完了、すべての結果を受信しました:" + get_timestamp())
# タスク完了後 (on_complete コールバックがトリガーされた後)、get_first_package_delay を呼び出してレイテンシーを取得できます
# 最初のテキスト送信には WebSocket 接続の確立が必要なため、初回パケットレイテンシーには接続セットアップ時間が含まれます
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"音声合成エラー:{message}")
def on_close(self):
print("接続クローズ:" + get_timestamp())
# プレーヤーを停止します
self._stream.stop_stream()
self._stream.close()
self._player.terminate()
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"イベントタイプ:{event_type}, 元のテキスト:{original_text}")
def on_data(self, data: bytes) -> None:
print(get_timestamp() + " バイナリオーディオの長さ:" + str(len(data)))
self._stream.write(data)
callback = Callback()
test_text = [
"ストリーミングテキスト読み上げSDKは、",
"入力テキストを",
"バイナリオーディオデータに変換します。",
"非ストリーミング音声合成と比較して、",
"ストリーミング合成はより優れたリアルタイム性能を提供します。",
"ユーザーは入力中にほぼ同期したオーディオ出力を聞くことができ、",
"インタラクション体験が大幅に向上し、",
"待ち時間が短縮されます。",
"大規模言語モデル (LLM) との統合に最適で、",
"テキストがストリーミングされて音声合成されます。",
]
# SpeechSynthesizer をインスタンス化し、コンストラクターでモデルや音声などのリクエストパラメーターを渡します
synthesizer = SpeechSynthesizer(
model=model,
voice=voice,
format=AudioFormat.PCM_22050HZ_MONO_16BIT,
callback=callback,
)
# ストリーミング合成用のテキストを送信します。on_data コールバックメソッドを通じてリアルタイムでバイナリオーディオを取得します
for text in test_text:
synthesizer.streaming_call(text)
time.sleep(0.1)
# ストリーミング音声合成を終了します
synthesizer.streaming_complete()