https://api.echonova.aiالمطورون
الأصوات والخيارات في تحويل النص إلى كلام
قائمة الأصوات، وما يعنيه كل حقل فيها، وكيف تختار صوتًا حسب اللغة، وكل خيار في الطلب مع نوعه ومداه وقيمته الافتراضية وأثره.
هذه الصفحة جدول مرجعي لتحويل النص إلى كلام: ما تعيده نقطة نهاية الأصوات، وكيف تختار صوتًا، وما يفعله كل حقل في طلب التوليد. تنطبق على POST /v1/text-to-speech/sync و POST /v1/text-to-speech، وهما تقبلان الجسم نفسه.
نقطة نهاية الأصوات
GET https://api.echonova.ai/v1/text-to-speech/voices
يستدعي الطلب بلا أي معاملات. يعيد كل صوت حالته نشطة، الأحدث أولًا، في استجابة واحدة بلا ترقيم صفحات. و data.total هو العدد.
| الحقل | النوع | موجود دائمًا | المعنى |
|---|---|---|---|
id |
string | نعم | القيمة التي ترسلها كـ voiceId. |
name |
string | نعم | معرّف الصوت، مثل ae_ahmed. فريد لكل صوت. |
displayName |
string | نعم | الاسم المعروض، مثل Ahmed. يعود إلى name عندما لا يكون للصوت اسم عرض. |
language |
string | نعم | ar للأصوات العربية، و en للأصوات الإنجليزية. |
gender |
string | اختياري في المخطط؛ كل صوت يحمله | تسمية الجنس، مثل Male. |
previewUrl |
string | لا | معلن في مخطط API وغائب عن الاستجابة. عاين الصوت في البوابة من الأصوات. |
{
"data": {
"items": [
{
"id": "66e5ef3a9c1d2b4f8a7e6c01",
"name": "ae_ahmed",
"displayName": "Ahmed",
"language": "ar",
"gender": "Male"
}
],
"total": 1
},
"success": true,
"statusCode": 200,
"errorMessage": null
}curl https://api.echonova.ai/v1/text-to-speech/voices \
-H "Authorization: Bearer YOUR_API_KEY"import requests
response = requests.get(
"https://api.echonova.ai/v1/text-to-speech/voices",
headers={"Authorization": "Bearer YOUR_API_KEY"},
)
arabic = [v for v in response.json()["data"]["items"] if v["language"] == "ar"]const response = await fetch('https://api.echonova.ai/v1/text-to-speech/voices', {
headers: { Authorization: 'Bearer YOUR_API_KEY' },
});
const { data } = await response.json();
const arabic = data.items.filter((v) => v.language === 'ar');اختيار صوت
صفِّ الأصوات بحسب language في كودك، فالنقطة لا تملك فلاتر. ar يختار الأصوات العربية، و en يختار الإنجليزية.
كائن الصوت لا يتضمن لهجته. اللهجة ثابتة للصوت: ترسل voiceId وحده، ويخرج الصوت بلهجته. لمعرفة لهجة صوت، افتح الأصوات في البوابة. تعرض كل بطاقة اسم الصوت المعروض ولهجته. طابق البطاقة بالـ API عبر displayName، أو عبر name عندما لا يكون للصوت اسم عرض، واستخدم id ذلك الصوت في طلبك.
اللهجات هي egyptian و emirati و saudi و kuwaiti و qatari و omani و lebanese و syrian و iraqi و fusha و american و british، إضافة إلى english وهو اسم قديم. قد يتغير أي اللهجات لها أصوات في وقت بعينه؛ ومصدر الحقيقة هو استدعاء الأصوات. الأصوات الإنجليزية تُبلغ language بقيمة en مهما كانت لهجتها.
مجموعة الأصوات ليست ثابتة. قد يُسحب صوت: يخرج من القائمة، ويحصل أي طلب يسميه على 404 Voice not found. يمكنك تخزين القائمة للراحة، لكن أعِد جلبها عند ظهور هذا الخطأ.
اختر صوتًا مرة واحدة، واحتفظ بقيمة id الخاصة به في إعداداتك، مع طريق للعودة إلى القائمة عندما يتوقف المعرّف عن العمل.
الموصى به
- اجلب القائمة عند بدء التشغيل، واختر بـ
displayNameوlanguage، واحتفظ بقيمةidفي إعداداتك، وأعد الجلب عند404 Voice not found.
الأقل فاعلية
- استدعِ
GET /v1/text-to-speech/voicesقبل كل عملية توليد، وخذ أول صوت عربي أيًا كان في ذلك اليوم.
خيارات الطلب
تقبل نقطتا التوليد جسم JSON بهذه الحقول. تُزال المسافات البيضاء من بداية كل سلسلة ونهايتها قبل التحقق. الحقول غير المعروفة مرفوضة.
| الخيار | النوع | مطلوب | المدى | الافتراضي | الأثر |
|---|---|---|---|---|---|
text |
string | نعم | من 1 إلى 500 حرف بعد الإزالة | لا شيء | النص المراد نطقه. كل حرف يُحتسب، بما فيه المسافات وفواصل الأسطر. |
voiceId |
string | نعم | id من استدعاء الأصوات |
لا شيء | يختار الصوت، ومن خلاله اللغة واللهجة. |
speed |
number | لا | من 0.5 إلى 2 | 1 | يضبط سرعة القراءة. الأقل أبطأ، والأعلى أسرع. |
cfg |
number | لا | من 1 إلى 5 | 2 | مقياس توجيه بلا مصنِّف. اتركه على الافتراضي إلا إذا كنت تضبطه بتجارب استماع خاصة بك. |
numSteps |
number | لا | إحدى القيم 16 أو 32 أو 48 أو 64 أو 128 بالضبط | 48 | عدد خطوات الانتشار. تُقبل هذه القيم الخمس فقط؛ وهي ليست مدى. |
tashkeel |
boolean | لا | true أو false |
false |
يضيف الحركات إلى النص قبل التوليد. راجع الملاحظة أدناه. |
إذا حذفت speed أو cfg أو numSteps، فهذا يعني «استخدم القيمة الافتراضية»، والمهمة تسجّل القيمة التي استُخدمت فعلًا.
عن tashkeel
tashkeelيطبَّق على أصوات الفصحى فقط. على صوت من لهجة أخرى يُنطق النص كما كُتب دون حركات، ولا يفشل الاستدعاء.tashkeelيسري علىPOST /v1/text-to-speech/syncفقط. أماPOST /v1/text-to-speechفيقبل الحقل وينطق النص كما كُتب. للحصول على كلام مشكول، استخدم النقطة المتزامنة.textفي المهمة هو النص الذي أرسلته؛ النص المشكول لا يُعاد.
مثال يضم كل الخيارات
curl -X POST https://api.echonova.ai/v1/text-to-speech/sync \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "الطقس اليوم جميل والسماء صافية في المدينة",
"voiceId": "VOICE_ID",
"speed": 1,
"cfg": 2,
"numSteps": 48,
"tashkeel": true
}'import requests
response = requests.post(
"https://api.echonova.ai/v1/text-to-speech/sync",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"text": "الطقس اليوم جميل والسماء صافية في المدينة",
"voiceId": "VOICE_ID",
"speed": 1,
"cfg": 2,
"numSteps": 48,
"tashkeel": True,
},
)
print(response.json())const response = await fetch('https://api.echonova.ai/v1/text-to-speech/sync', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
text: 'الطقس اليوم جميل والسماء صافية في المدينة',
voiceId: 'VOICE_ID',
speed: 1,
cfg: 2,
numSteps: 48,
tashkeel: true,
}),
});
console.log(await response.json());المخرجات
تنتج النقطتان ملف صوت واحدًا لكل استدعاء، وتعرضه كـ audioUrl: في الاستجابة المتزامنة مباشرة، وفي كائن المهمة عندما تصبح المهمة غير المتزامنة completed.
| المعلومة | القيمة |
|---|---|
ما هو audioUrl |
رابط موقّع إلى ملف الصوت. ينتهي. يعيد GET /v1/text-to-speech/jobs/{jobId} رابطًا جديدًا في كل استدعاء. |
| صيغة الملف | WAV. اسم الملف في الرابط ينتهي بـ .wav. لا يختار أي خيار في الطلب الصيغة. |
durationSeconds |
مدة الصوت بالثواني. تحمل الاستجابة المتزامنة القيمة 0 عندما يتعذر قياس المدة؛ أما كائن المهمة غير المتزامنة فيحذف الحقل حتى تصبح المهمة completed. |
creditsConsumed |
الأرصدة المخصومة لهذا الاستدعاء. |
الرصيد
يُحسب سعر الاستدعاء من حقل text قبل بدء المهمة: كل حرف في text، مع المسافات وفواصل الأسطر، بسعر 1 credit لكل حرف. يُخصم من رصيد مساحة العمل قبل التوليد، ويُعاد إذا فشلت المهمة. الأسعار وأمثلة الحساب وحد الرصيد لكل مفتاح موجودة في الرصيد.
الحدود
| الحد | القيمة | ينطبق على |
|---|---|---|
text |
من 1 إلى 500 حرف بعد الإزالة | POST /v1/text-to-speech/sync و POST /v1/text-to-speech |
speed |
من 0.5 إلى 2 | كلا النقطتين |
cfg |
من 1 إلى 5 | كلا النقطتين |
numSteps |
16 أو 32 أو 48 أو 64 أو 128 | كلا النقطتين |
| الأصوات في كل استجابة | كل الأصوات النشطة، بلا ترقيم صفحات | GET /v1/text-to-speech/voices |
| الطلبات لكل مفتاح | 100 طلب كل 60 ثانية على كل نقطة؛ راجع حدود معدل الطلبات | كل الاستدعاءات |
تشترك النقطتان في حد النص نفسه. الفرق بينهما هو طريقة استلام النتيجة، لا كمية النص التي يقبلانها.
الأخطاء
كل خطأ يستخدم الغلاف المعتاد مع success: false، وتظهر الرسالة في errorMessage. تسرد أخطاء التحقق كل قاعدة فاشلة في رسالة واحدة مفصولة بفواصل.
| الحالة | errorMessage | متى | ماذا تفعل |
|---|---|---|---|
| 400 | text must be longer than or equal to 1 characters, text should not be empty |
text فارغ أو فيه مسافات فقط. عندما يغيب text، يُضاف في البداية text must be shorter than or equal to 500 characters ويُضاف في النهاية text must be a string. |
أرسل حرفًا واحدًا على الأقل غير مسافة. |
| 400 | text must be shorter than or equal to 500 characters |
text تجاوز الحد. |
قسّم النص إلى استدعاءات متعددة. |
| 400 | voiceId should not be empty |
voiceId فارغ. عندما يغيب، يُضاف voiceId must be a string في النهاية. |
أرسل قيمة id من استدعاء الأصوات. |
| 400 | speed must not be less than 0.5, speed must not be greater than 2 |
speed خارج المدى. النمط نفسه ينطبق على cfg بالحدين 1 و 5. |
ابقَ داخل المدى. |
| 400 | speed must be a number conforming to the specified constraints |
speed أو cfg ليس رقمًا. |
أرسل رقم JSON، لا سلسلة. |
| 400 | numSteps must be one of the following values: 16, 32, 48, 64, 128 |
numSteps ليس واحدًا من القيم الخمس. |
أرسل واحدة من القيم الخمس. |
| 400 | tashkeel must be a boolean value |
tashkeel ليس true أو false. |
أرسل قيمة boolean في JSON. |
| 400 | property <name> should not exist |
الجسم يحمل حقلًا لا تعرفه النقطة. | احذفه. |
| 400 | Invalid identifier |
voiceId ليس معرّفًا صحيح البنية. |
انسخ قيمة id تمامًا كما أعادها استدعاء الأصوات. |
| 400 | نص حر للسبب، بحد أقصى 300 حرف | رُفض الطلب لسبب خاص به. نادر. | اقرأ الرسالة وأصلح الطلب. |
| 402 | Insufficient subscription balance |
رصيد مساحة العمل لا يغطي الخصم. | أضف أرصدة إلى مساحة العمل. راجع الرصيد. |
| 403 | This API key does not have access to Text-to-Speech services |
المفتاح يقيّد الخدمات، وتحويل النص إلى كلام ليس منها. | امنح وصول إلى تحويل النص إلى كلام على المفتاح. |
| 404 | Voice not found |
لا يوجد صوت نشط بهذا voiceId. |
اعرض الأصوات من جديد واختر صوتًا نشطًا. |
| 429 | Monthly spending limit exhausted |
حد الرصيد على المفتاح لهذه الدورة كان سيُتجاوز. | ارفع الحد على المفتاح أو أزِله. |
| 503 | Speech generation is temporarily unavailable. Please try again. |
تعذّر توليد الكلام لهذا الطلب. يُعاد الرصيد. | أعد المحاولة بعد انتظار قصير. |
أخطاء المصادقة، أي 401 و403 الأخرى، مدرجة في المصادقة. أما 429 الخاص بمعدل الطلبات فيرد في حدود معدل الطلبات.
الأسئلة الشائعة
كيف أعرف اللهجة التي ينطقها الصوت؟
افتح الأصوات في البوابة؛ تعرض كل بطاقة اللهجة. كائن الصوت في API يحمل language فقط.
لماذا لا يفعل tashkeel شيئًا في مهمتي؟
إما أن الصوت ليس الفصحى، أو أنك استخدمت POST /v1/text-to-speech. تُضاف الحركات عبر POST /v1/text-to-speech/sync مع صوت من الفصحى.
هل أستطيع معاينة صوت عبر API؟
لا. previewUrl غائب عن الاستجابة. عاين الأصوات في البوابة من الأصوات، أو أنشئ جملة قصيرة بـ POST /v1/text-to-speech/sync.
ماذا يغيّر cfg و numSteps؟
كلاهما يضبط التوليد. اتركهما على الافتراضي إلا إذا كنت تقارن المخرجات في تجارب استماع خاصة بك. القيم المقبولة في الجدول أعلاه، وأي قيمة خارجها تُرفض بـ 400.
هل أستطيع الحصول على MP3 أو OGG؟
لا. الصوت بصيغة WAV. حوّله عندك إذا احتجت صيغة أخرى.