تبدیل متن به گفتار — Text-to-speech
آشا تبدیل متن به گفتار (TTS) را از طریق endpoint اختصاصیِ /v1/audio/speech که با OpenAI Audio Speech API سازگار است پشتیبانی میکند. متن بفرستید و خروجیِ صوت خام در فرمت دلخواه بگیرید.
کشف مدلها
مدلهای TTS را از چند راه میتوانید پیدا کنید:
از طریق API
همهٔ مدلها را با endpoint سازگار با OpenAI یعنی
GET /v1/models فهرست کنید. مدلهای سنتز گفتار
با حالتِ text->audio در
architecture.modality قابل شناساییاند:
curl "https://app.asha-ai.ir/v1/models"
در صفحهٔ مدلها
در فهرست مدلها با فیلتر «صوتی» (Audio) مدلهای صوتی — از جمله سنتز گفتار — را ببینید. این فیلتر سمتِ کلاینت و بر اساس نوع مدل در داشبورد اعمال میشود.
استفاده از API
درخواست POST به
/v1/audio/speech با متنی که میخواهید سنتز کنید
بفرستید. پاسخ یک جریانِ بایت خامِ صوت است (نه JSON)، پس میتوانید مستقیم در فایل یا پخشکننده
صوتی استفاده کنید.
مثال ساده
import os
import requests
response = requests.post(
url="https://app.asha-ai.ir/v1/audio/speech",
headers={
"Authorization": f"Bearer {os.environ['ASHA_API_KEY']}",
"Content-Type": "application/json",
},
json={
"model": "~openai/gpt-4o-mini-tts",
"input": "Hello! This is a text-to-speech test.",
"voice": "alloy",
"response_format": "mp3",
},
)
response.raise_for_status()
with open("output.mp3", "wb") as f:
f.write(response.content)
generation_id = response.headers.get("X-Generation-Id")
print(f"Audio saved. Generation ID: {generation_id}")
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
func main() {
payload := map[string]any{
"model": "~openai/gpt-4o-mini-tts",
"input": "Hello! This is a text-to-speech test.",
"voice": "alloy",
"response_format": "mp3",
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "https://app.asha-ai.ir/v1/audio/speech", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ASHA_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
raw, _ := io.ReadAll(resp.Body)
panic(fmt.Sprintf("TTS error %d: %s", resp.StatusCode, raw))
}
out, _ := os.Create("output.mp3")
defer out.Close()
_, _ = io.Copy(out, resp.Body)
fmt.Println("Generation ID:", resp.Header.Get("X-Generation-Id"))
}
const response = await fetch("https://app.asha-ai.ir/v1/audio/speech", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ASHA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "~openai/gpt-4o-mini-tts",
input: "Hello! This is a text-to-speech test.",
voice: "alloy",
response_format: "mp3",
}),
});
if (!response.ok) {
const err = await response.json();
throw new Error(`TTS error ${response.status}: ${JSON.stringify(err)}`);
}
const audioBuffer = await response.arrayBuffer();
const generationId = response.headers.get("X-Generation-Id");
console.log(`Generation ID: ${generationId}`);
// Save audioBuffer to a file or play it directly
const response = await fetch("https://app.asha-ai.ir/v1/audio/speech", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ASHA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "~openai/gpt-4o-mini-tts",
input: "Hello! This is a text-to-speech test.",
voice: "alloy",
response_format: "mp3",
}),
});
if (!response.ok) {
const err = await response.json();
throw new Error(`TTS error ${response.status}: ${JSON.stringify(err)}`);
}
const audioBuffer = await response.arrayBuffer();
const generationId = response.headers.get("X-Generation-Id");
console.log(`Generation ID: ${generationId}`);
// Save audioBuffer to a file or play it directly
curl https://app.asha-ai.ir/v1/audio/speech
-H "Content-Type: application/json"
-H "Authorization: Bearer $ASHA_API_KEY"
--output output.mp3
-d '{
"model": "~openai/gpt-4o-mini-tts",
"input": "Hello! This is a text-to-speech test.",
"voice": "alloy",
"response_format": "mp3"
}'
پارامترهای درخواست
| پارامتر | نوع | الزامی | شرح |
|---|---|---|---|
model | string | بله | مدل TTS (مثل ~openai/gpt-4o-mini-tts، ~mistralai/voxtral-mini-tts) |
input | string | بله | متنی که باید گفتار شود |
voice | string | وابسته به ارائهدهنده | شناسهٔ صدا؛ صداها بسته به مدل متفاوتاند، پس در صفحهٔ همان مدل چک کنید. این پارامتر را فقط وقتی حذف کنید که ارائهدهندهٔ انتخابشده صدا را مستند کرده باشد |
response_format | string | خیر | فرمت خروجی صدا: mp3 یا pcm؛ پیشفرض pcm |
speed | number | خیر | ضریب سرعت پخش؛ فقط مدلهایی که پشتیبانی میکنند (مثل OpenAI TTS)؛ پیشفرض 1.0 |
input_references | array | خیر | محتویات مرجع برای کلونسازی صدای بدونوضعیت: یک بخش input_audio با نمونهٔ صدا و اختیاری یک بخش text با رونوشت؛ به «کلونسازی صدا» مراجعه کنید |
provider | object | خیر | پیکربندی عبور پارامترهای مختص ارائهدهنده |
وقتی voice حذف شود، آشا درخواست را فقط به ارائهدهندههایی
میفرستد که adapterشان صدای پیشفرضِ سمت ارائهدهنده را پشتیبانی میکند. برای بقیهٔ
ارائهدهندهها درخواست با خطای اعتبارسنجی رد میشود.
کلونسازی صدا
برخی مدلها کلونسازی صدای بدونوضعیت را پشتیبانی میکنند: یک نمونهٔ کوتاه از صدای مرجع را مستقیم با درخواست TTS میفرستید و گفتارِ تولیدشده همان صدا را تقلید میکند. هیچ مرحلهٔ جداگانهٔ ساخت صدا یا آپلود لازم نیست.
صدای مرجع را بهصورت بخش input_audio با base64 در
input_references بفرستید (URI با
data:audio/...;base64, هم کار میکند) و اختیاری
رونوشتش را بهصورت بخش text اضافه کنید:
{
"model": "~fish-audio/s2.1-pro",
"input": "Hello from my cloned voice!",
"response_format": "mp3",
"input_references": [
{ "type": "input_audio", "input_audio": { "data": "data:audio/wav;base64,UklGRuQXDAB..." } },
{ "type": "text", "text": "This is the transcript of the reference audio." }
]
}
برخی ارائهدهندههای یک مدل کلونکنندهٔ صدا ممکن است کلونسازی را پشتیبانی نکنند؛ فیلدِ
supports_voice_cloning را در
endpoints API چک کنید.
- فرمتهای صوتی پشتیبانیشده برای نمونهٔ مرجع، به ارائهدهنده بستگی دارد.
input_referencesحداکثر یک بخشinput_audioو یک بخشtextمیپذیرد و بهinput_audioنیاز دارد.- صدای مرجع به ۲۰ MiB base64 محدود است (۱۵ MiB صوت decodeشده)؛ درخواستهای بزرگتر با خطای 400 رد میشوند.
گزینههای مختص ارائهدهنده
با پارامتر provider گزینههای مختص ارائهدهنده را
بفرستید؛ با نام ارائهدهنده کلید میخورند و فقط گزینههای ارائهدهندهٔ جورشده منتقل میشوند:
{
"model": "~openai/gpt-4o-mini-tts",
"input": "Hello world",
"voice": "alloy",
"provider": {
"options": {
"openai": {
"instructions": "Speak in a warm, friendly tone."
}
}
}
}
Azure (MAI-Voice-2)
Azure TTS درونزمینه از SSML استفاده میکند اما کاملاً انتزاع شده است؛ فقط به پارامترهای استاندارد
نیاز دارید. پارامتر voice نام صدای Azure را میگیرد
(مثل en-US-Harper:MAI-Voice-2) و
speed پشتیبانی میشود (بازه: 0.5 تا 2.0).
برای سنتز بیانی، style و اختیاری styledegree را از گزینههای provider بفرستید:
{
"model": "~microsoft/mai-voice-2",
"input": "Welcome to the event!",
"voice": "en-US-Harper:MAI-Voice-2",
"response_format": "mp3",
"speed": 1.0,
"provider": {
"options": {
"azure": {
"style": "cheerful",
"styledegree": 1.2
}
}
}
}
| گزینه | نوع | شرح |
|---|---|---|
style | string | سبک بیانی (مثل cheerful، sad، angry، excited). سبکهای در دسترس به صدا بستگی دارد |
styledegree | number | شدت اثر سبک؛ پیشفرض 1.0؛ مقدار بالاتر بیان را زیاد میکند |
قالب پاسخ
endpoint TTS یک جریانِ بایتِ صوتِ خام برمیگرداند، نه JSON. پاسخ این هدرها را دارد:
| هدر | شرح |
|---|---|
Content-Type | نوع MIME صدا: audio/mpeg برای mp3 و audio/pcm برای pcm |
X-Generation-Id | شناسهٔ یکتای تولید برای ردیابی و دیباگ |
فرمتهای خروجی
| فرمت | Content-Type | شرح |
|---|---|---|
mp3 | audio/mpeg | صدای فشرده با حجم کمتر؛ برای ذخیره و پخش |
pcm | audio/pcm | صوت خامِ بدون فشردهسازی؛ تأخیر کمتر، مناسب خطوط جریان بلادرنگ |
قیمتگذاری
مدلهای TTS بهازای هر کاراکتر متنِ ورودی قیمتگذاری میشوند. قیمت بسته به مدل و ارائهدهنده متفاوت است. هزینهٔ هر کاراکتر را در فهرست مدلها یا از طریق Models API ببینید.
سازگاری با OpenAI SDK
endpoint TTS کاملاً با SDK رسمی OpenAI سازگار است؛ فقط Base URL را عوض کنید:
import os
from openai import OpenAI
client = OpenAI(
base_url="https://app.asha-ai.ir/v1",
api_key=os.environ["ASHA_API_KEY"],
)
# Non-streaming: get the full audio response
response = client.audio.speech.create(
model="~openai/gpt-4o-mini-tts",
input="The quick brown fox jumps over the lazy dog.",
voice="nova",
response_format="mp3",
)
response.write_to_file("output.mp3")
# Streaming: process audio chunks as they arrive
with client.audio.speech.with_streaming_response.create(
model="~openai/gpt-4o-mini-tts",
input="The quick brown fox jumps over the lazy dog.",
voice="nova",
response_format="mp3",
) as response:
response.stream_to_file("output.mp3")
import fs from "fs";
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://app.asha-ai.ir/v1",
apiKey: process.env.ASHA_API_KEY,
});
const response = await client.audio.speech.create({
model: "~openai/gpt-4o-mini-tts",
input: "The quick brown fox jumps over the lazy dog.",
voice: "nova",
response_format: "mp3",
});
const buffer = Buffer.from(await response.arrayBuffer());
await fs.promises.writeFile("output.mp3", buffer);
console.log("Audio saved to output.mp3");
بهترین روشها
- فرمت درست را انتخاب کنید — برای ذخیره و پخش عمومی از
mp3و برای خطوط جریان بلادرنگِ حساس به تأخیر ازpcmاستفاده کنید. - انتخاب صدا — ارائهدهندههای مختلف صداهای متفاوتی دارند؛ مستندات مدل را ببینید یا صداها را آزمایش کنید.
- طول ورودی — برای متنهای خیلی بلند، ورودی را به بخشهای کوچکتر تقسیم و خروجیها را بههم بچسبانید؛ این کار قابلیت اطمینان را بالا و تأخیرِ اولین بخش صدا را کم میکند.
- پارامتر
speed— فقط برخی ارائهدهندهها (مثل OpenAI) پشتیبانی میکنند؛ بقیه ساکت نادیدهاش میگیرند.
عیبیابی
فایل صوتی خالی یا خراب؟
- مطمئن شوید
response_formatبا روش ذخیرهٔ فایل جور است (خروجیpcmرا با پسوند.mp3ذخیره نکنید) - کد وضعیت پاسخ را چک کنید؛ پاسخهای غیر-200 بدنهٔ JSON خطا دارند نه صوت
مدل پیدا نمیشود؟
- از فهرست مدلها مدلهای TTS را پیدا کنید
- درستی نام مدل را چک کنید (مثل
~openai/gpt-4o-mini-tts)
صدا در دسترس نیست؟
- صداهای در دسترس بسته به ارائهدهنده متفاوتاند؛ مستندات ارائهدهنده را برای شناسههای صدا ببینید
- هر مدل مجموعه صدای خودش را دارد؛ فهرست کامل را در صفحهٔ همان مدل ببینید
سؤالات متداول
خروجی TTS چه فرمتی دارد؟
خروجی یک جریان بایت خام صوتی است (نه JSON)؛ با response_format میتوانید mp3 یا pcm بگیرید.
آیا میتوانم صدای دلخواه را کلون کنم؟
بله؛ مدلهای پشتیبان کلونسازی بدونوضعیت دارند: نمونهٔ صدا را با input_references بفرستید و همان صدا تقلید میشود.
قیمت TTS چگونه حساب میشود؟
بهازای هر کاراکتر متن ورودی؛ قیمت هر مدل در models یا Models API به تومان مشخص است.
آیا با OpenAI SDK کار میکند؟
بله؛ endpoint سازگار با OpenAI Audio Speech API است؛ فقط base_url را عوض کنید.
سرعت پخش را چطور تغییر دهم؟
با پارامتر speed؛ اما فقط مدلهایی که پشتیبانی میکنند (مثل OpenAI)؛ بقیه نادیده میگیرند.
برای متون خیلی بلند چه کنم؟
متن را به بخشهای کوچک تقسیم کنید، هر بخش را جدا تولید و خروجیها را بههم بچسبانید؛ هم مطمئنتر است هم اولین بخش صدا سریعتر میرسد.