https://api.echonova.aiالمطورون
صيغ تحويل الكلام إلى نص ومخرجاته
ما تقبله نقطتا الرفع، والفحوصات التي تعمل قبل بدء المهمة، وكل حقل تحمله الاستجابات، وتحديد المتحدثين، وتنزيلات TXT وSRT وJSON، ومعنى durationSeconds.
هذه الصفحة جدول مرجعي لنقطتي رفع تحويل الكلام إلى نص: POST /v1/speech-to-text/sync وPOST /v1/speech-to-text. تبيّن ما يجب أن يستوفيه الطلب، وأي صوت يُفكّ ترميزه، وكل حقل تحمله الاستجابات، وما يتضمنه النص المفرّغ وما لا يتضمنه. وتشرح أيضًا تحديد المتحدثين، ونقطة النهاية GET /v1/speech-to-text/jobs/{jobId}/export التي تنزّل المهمة المكتملة بصيغة TXT، أو ترجمة SRT، أو JSON.
المدخلات المقبولة
تقبل نقطتا الرفع جزءًا واحدًا من نوع multipart/form-data اسمه file. تجري الواجهة هذه الفحوصات، بهذا الترتيب، قبل أن يُخصم أي رصيد أو يبدأ أي تفريغ:
| الفحص | القاعدة | الرفض | الحالة |
|---|---|---|---|
| الحجم | 150 ميجابايت أو أقل | File too large |
413 |
| وجود الجزء | يوجد جزء اسمه file |
File is required |
400 |
| نوع المحتوى | يبدأ Content-Type للجزء بـ audio/، مع مقارنة غير حساسة لحالة الأحرف |
Unsupported file type: <type>. Please upload an audio file. |
400 |
| المدة | 10 دقائق أو أقل، في نقطتي الرفع كلتيهما | Audio exceeds the 10-minute limit. |
400 |
يعمل فحص الحجم أثناء استقبال جسم الطلب، فيُقطع الرفع الكبير قبل تشغيل الفحوصات الأخرى. أما فحص المدة فيقرأ البيانات الوصفية للملف. فإذا تعذّر قراءة المدة، يمر الفحص ويُقبل الملف.
يعكس <type> في رفض نوع المحتوى ما وضعه عميلك على الجزء. تعني القيمة application/octet-stream أن العميل خمّن نوعًا عامًا، وتعني text/plain أن الجزء لم يحمل ترويسة Content-Type أصلًا. اضبط نوع الجزء بنفسك:
curl -X POST "https://api.echonova.ai/v1/speech-to-text/sync" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@audio.wav;type=audio/wav"import requests
with open("audio.wav", "rb") as audio:
response = requests.post(
"https://api.echonova.ai/v1/speech-to-text/sync",
headers={"Authorization": "Bearer YOUR_API_KEY"},
files={"file": ("audio.wav", audio, "audio/wav")},
)
print(response.json())import { readFile } from 'node:fs/promises';
const formData = new FormData();
formData.append('file', new Blob([await readFile('audio.wav')], { type: 'audio/wav' }), 'audio.wav');
const response = await fetch('https://api.echonova.ai/v1/speech-to-text/sync', {
method: 'POST',
headers: { Authorization: 'Bearer YOUR_API_KEY' },
body: formData,
});
console.log(await response.json());| الحاوية | Content-Type الذي ترسله |
|---|---|
| WAV | audio/wav |
| MP3 | audio/mpeg |
| OGG | audio/ogg |
أي صوت يُفكّ ترميزه
تقرأ الفحوصات السابقة وسم النوع، لا البايتات. يحدث فك الترميز بعدها: تُعاد عينة الصوت إلى 16 kHz أحادي القناة، وتُحسب قنوات الملف الستيريو بالمتوسط، بدلًا من الاحتفاظ بقناة واحدة.
تُفكّ ملفات WAV وFLAC وOGG وMP3. قبل أن تعتمد على M4A أو MP4 أو 3GP أو WebM أو أي حاوية أخرى، أرسل ملفًا تجريبيًا قصيرًا. الملف الذي لا يمكن فك ترميزه يجتاز كل الفحوصات السابقة، ثم يفشل بعدها بإحدى طريقتين:
| نقطة النهاية | ما تراه | الرصيد |
|---|---|---|
POST /v1/speech-to-text/sync |
503 مع Transcription is temporarily unavailable. Please try again. ولا يُذكر السبب. |
يُسترد |
POST /v1/speech-to-text |
تنتهي المهمة بحالة failed، ويحمل حقل error السبب، الذي يبدأ بـ Audio could not be decoded. Supported: WAV, FLAC, OGG/Opus, MP3…. ويُرسل Webhook بالحدث job.failed. |
يُسترد |
الصوت الأقصر من 50 ms يُرفض برسالة تبدأ بـ Audio is too short تليها المدة المقاسة. يظهر هذا بالطريقتين نفسيهما.
لمعرفة سبب فشل ملف، أرسله إلى POST /v1/speech-to-text: يحمل حقل error في المهمة السبب، أما نقطة النهاية المتزامنة فلا تفعل.
اللغة
تقبل نقطتا الرفع حقل نموذج اختياريًا اسمه language. أرسل auto (الافتراضي) أو ar أو en. تُقلَّم القيمة وتُقرأ دون اعتبار لحالة الأحرف، فالقيمتان AR وen مقبولتان. أي قيمة أخرى تعطي 400 مع الرسالة language must be one of: auto, ar, en. وحقول النموذج الإضافية الأخرى تُتجاهل.
| القيمة | تُستخدم لـ |
|---|---|
auto |
ترك الخدمة تقرر. وهي العربية حاليًا، وتتعامل كذلك مع الكلام المختلط بين العربية والإنجليزية، والكلام الإنجليزي الواضح. |
ar |
الكلام العربي، والكلام المختلط بين العربية والإنجليزية. |
en |
الكلام الإنجليزي كله. العربية المُرسلة بقيمة en تخرج مشوّهة. |
تحديد المتحدثين
تقبل نقطتا الرفع حقل نموذج اختياريًا اسمه identify_speakers. أرسل true لتعرف من يتكلم ومتى: تحمل المهمة المكتملة حينها النص المفرّغ أيضًا في مقاطع موقّتة segments، يحمل كل منها speaker، إضافةً إلى قائمة speakers بمدة كلام كل متحدث. القيمة الافتراضية false. تُقلَّم القيمة وتُقرأ دون اعتبار لحالة الأحرف، وتُقبل true وfalse و1 و0، والقيمة الفارغة تُعدّ false. أي قيمة أخرى تعطي 400 مع الرسالة identify_speakers must be true or false. طلب المتحدثين لا يغيّر المبلغ المخصوم.
curl -X POST "https://api.echonova.ai/v1/speech-to-text" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@call.mp3;type=audio/mpeg" \
-F "language=ar" \
-F "identify_speakers=true"import requests
with open("call.mp3", "rb") as audio:
response = requests.post(
"https://api.echonova.ai/v1/speech-to-text",
headers={"Authorization": "Bearer YOUR_API_KEY"},
files={"file": ("call.mp3", audio, "audio/mpeg")},
data={"language": "ar", "identify_speakers": "true"},
)
print(response.json())import { readFile } from 'node:fs/promises';
const formData = new FormData();
formData.append('file', new Blob([await readFile('call.mp3')], { type: 'audio/mpeg' }), 'call.mp3');
formData.append('language', 'ar');
formData.append('identify_speakers', 'true');
const response = await fetch('https://api.echonova.ai/v1/speech-to-text', {
method: 'POST',
headers: { Authorization: 'Bearer YOUR_API_KEY' },
body: formData,
});
console.log(await response.json());يُسمّى المتحدثون spk0 وspk1 وهكذا، مرقّمين بترتيب أول مرة يتكلمون فيها. يُستخدم المعرّف نفسه في كل مقطع وفي speakers، فتستطيع أن تعدّ المتحدثين أو تلوّنهم أو تسمّيهم بنفسك. ويحوّل التنزيل المعرّفات إلى Speaker 1 وSpeaker 2 وهكذا.
المقطع:
| الحقل | النوع | القيمة |
|---|---|---|
start |
number | موضع بداية المقطع، بالثواني من بداية الصوت. |
end |
number | موضع نهاية المقطع، بالثواني من بداية الصوت. |
text |
string | ما قيل في هذا المقطع. تُكتب الأعداد كما في transcription. |
speaker |
string or null |
معرّف المتحدث، مثل spk0. وnull حين تعذّر نسبة هذا المقطع إلى متحدث. |
تُرتَّب المقاطع حسب start. المتحدث:
| الحقل | النوع | القيمة |
|---|---|---|
id |
string | معرّف المتحدث الذي تستخدمه المقاطع. |
talkTime |
number | مدة كلام هذا المتحدث، بالثواني. |
يسجّل identifySpeakers في المهمة ما طلبته، لا ما عاد فعلًا. قد لا يكون تحديد المتحدثين متاحًا لك بعد. وإلى أن يتاح، تكتمل المهمة المُنشأة مع identify_speakers=true بنصها المفرّغ كاملًا، وتكون segments وspeakers فارغتين. والتسجيل الذي تعذّر التمييز بين متحدثيه يعود بالطريقة نفسها. لتعرف هل تحمل المهمة بيانات المتحدثين، تحقّق من أن segments ليست فارغة، لا من identifySpeakers. المهام التي أُنشئت قبل وجود الحقل تظهر false و[] و[].
يحمل Webhook الحدث job.completed الحقل transcription، لا المقاطع ولا المتحدثين. اقرأ المهمة، أو نزّلها، للحصول عليهم.
حقول الاستجابة
تُغلَّف كل استجابة بالغلاف المعتاد، والحقول أدناه موجودة داخل data. يعيد POST الناجح الرمز HTTP 200.
الاستدعاء المتزامن
يعيد POST /v1/speech-to-text/sync المهمة المكتملة:
| الحقل | النوع | القيمة |
|---|---|---|
jobId |
string | معرّف المهمة التي أنشأها الاستدعاء. |
status |
string | completed. |
transcription |
string | النص المفرّغ. |
durationSeconds |
number or null |
مدة الصوت بالثواني، مع الكسور العشرية. |
creditsConsumed |
number | الأرصدة المخصومة للاستدعاء. |
language |
string | اللغة التي طُلب بها التفريغ. |
numbersAsDigits |
boolean | هل كُتبت الأعداد المنطوقة أرقامًا. |
identifySpeakers |
boolean | هل أُرسل الاستدعاء مع identify_speakers=true. |
segments |
array | النص المفرّغ في مقاطع موقّتة، لكل منها المتحدث الخاص به. فارغة ما لم تحمل المهمة بيانات المتحدثين. انظر تحديد المتحدثين. |
speakers |
array | المتحدثون الذين سُمعوا، بترتيب ظهورهم الأول. فارغة ما لم تحمل المهمة بيانات المتحدثين. |
{
"jobId": "66e3f2a1c9d4b8a1f0e12345",
"status": "completed",
"transcription": "مرحبا بكم في إيكونوڤا",
"durationSeconds": 15.51,
"creditsConsumed": 26,
"language": "ar",
"numbersAsDigits": true,
"identifySpeakers": false,
"segments": [],
"speakers": []
}الاستدعاء غير المتزامن
يعيد POST /v1/speech-to-text معرّف المهمة وحالتها فقط:
| الحقل | النوع | القيمة |
|---|---|---|
jobId |
string | المعرّف الذي يُستعلم عنه. |
status |
string | processing بمجرد قبول الملف. |
المهمة
يعيد GET /v1/speech-to-text/jobs/{jobId} مهمة واحدة، ويعيد GET /v1/speech-to-text/jobs الحقل items، وهو قائمة بهذه المهام، إضافةً إلى total، وهو عدد مهام الـ API في مساحة العمل. تُرتَّب القوائم من الأحدث إلى الأقدم، وتُقسَّم إلى صفحات بالمعاملين offset (0 أو أكثر، والافتراضي 0) وlimit (من 1 إلى 100، والافتراضي 20).
| الحقل | النوع | القيمة |
|---|---|---|
id |
string | معرّف المهمة. |
status |
string | pending أو processing أو completed أو failed. |
transcription |
string | النص المفرّغ. يظهر فقط حين تكون المهمة completed، وهو غائب قبل ذلك وفي المهمة الفاشلة. |
durationSeconds |
number or null |
انظر أدناه. |
creditsConsumed |
number | الأرصدة المخصومة عند إنشاء المهمة. لا يغيّرها الاسترداد، فالمهمة الفاشلة تحتفظ بالرقم الذي خُصم منها. |
error |
string | يظهر فقط في المهمة الفاشلة، ويحمل سبب الفشل. والمهمة التي بقيت processing لأكثر من 10 دقائق تحمل Job timed out — AI server did not respond. |
language |
string | اللغة التي طُلب بها التفريغ. وauto للمهام التي أُنشئت قبل وجود الحقل. |
numbersAsDigits |
boolean | هل كُتبت الأعداد المنطوقة أرقامًا. وtrue للمهام التي أُنشئت قبل وجود الحقل. |
identifySpeakers |
boolean | هل أُنشئت المهمة مع identify_speakers=true. وfalse للمهام التي أُنشئت قبل وجود الحقل. |
segments |
array | النص المفرّغ في مقاطع موقّتة، لكل منها المتحدث الخاص به. فارغة ما لم تحمل المهمة بيانات المتحدثين، وفارغة دائمًا قبل أن تصبح المهمة completed. |
speakers |
array | المتحدثون الذين سُمعوا، بترتيب ظهورهم الأول. فارغة ما لم تحمل المهمة بيانات المتحدثين. |
createdAt |
string | الطابع الزمني بصيغة ISO 8601 لوقت إنشاء المهمة. |
{
"id": "66e3f2a1c9d4b8a1f0e12346",
"status": "completed",
"transcription": "السلام عليكم، كيف حالك؟ بخير، الحمد لله.",
"durationSeconds": 6.4,
"creditsConsumed": 11,
"language": "ar",
"numbersAsDigits": true,
"identifySpeakers": true,
"segments": [
{ "start": 0.38, "end": 4.12, "text": "السلام عليكم، كيف حالك؟", "speaker": "spk0" },
{ "start": 4.3, "end": 6.4, "text": "بخير، الحمد لله.", "speaker": "spk1" }
],
"speakers": [
{ "id": "spk0", "talkTime": 3.74 },
{ "id": "spk1", "talkTime": 2.1 }
],
"createdAt": "2026-09-15T10:21:04.512Z"
}يستطيع أي مفتاح في مساحة العمل له وصول إلى تحويل الكلام إلى نص أن يسرد مهامها ويقرأها ويحذفها، حتى المهام التي أنشأها مفتاح حُذف لاحقًا. تعيد نقطة النهاية الخاصة بالمهمة الرمز 404 مع STT Job not found لمهمة تعود إلى مساحة عمل أخرى، أو أُنشئت من البوابة.
معنى durationSeconds
durationSeconds هو مدة الصوت بالثواني. يختلف مصدر الرقم حسب نقطة النهاية وحالة المهمة:
| الموضع | مصدر القيمة |
|---|---|
| الاستجابة المتزامنة | المدة المقاسة أثناء التفريغ. إذا لم تُقَس، فالمدة المقروءة من البيانات الوصفية للملف، أو التقدير المبني على الحجم أدناه، مقرّبة إلى ثانية كاملة. |
مهمة غير متزامنة وهي pending أو processing |
تقدير مقروء من البيانات الوصفية للملف قبل بدء المهمة. إذا لم تحمل البيانات الوصفية مدة، فحجم الملف بالبايت مقسومًا على 16 000، مقرّبًا للأعلى. |
مهمة غير متزامنة بعد أن تصبح completed |
المدة المقاسة أثناء التفريغ، تحل محل التقدير. |
تُحتسب الأرصدة حسب مدة الصوت، بمعدل 100 credits في الدقيقة. يُحسب الخصم من البيانات الوصفية للمدة، أو من التقدير المبني على الحجم، قبل بدء المهمة، ويُقرَّب إلى رصيد كامل، بحد أدنى 1. قد تكون durationSeconds المقاسة هي المدة نفسها عادةً، لكن creditsConsumed هو دائمًا المبلغ المخصوم فعلًا. استخدمه، لا durationSeconds، عند مطابقة الإنفاق. الأسعار موجودة في صفحة الرصيد.
اكتب الملفات برأس صحيح حتى تُقرأ المدة. الملف الذي لا تُقرأ مدته يُسعَّر حسب حجمه، ولا يُصحَّح هذا السعر لاحقًا.
الموصى به
- ملفات
audio/wavأوaudio/mpegأوaudio/oggكتبها مُرمِّز، برأس كامل ومدة معروفة.
الأقل فاعلية
- بث خام من مقبس، يُرفع بوصفه
audio/wavبلا رأس، ويُسعَّر بثانية واحدة لكل 16 000 بايت، مهما كانت مدته الحقيقية.
ما يتضمنه النص المفرّغ
النص المفرّغ سلسلة واحدة، والمدة رقم واحد. والمهمة المُنشأة مع identify_speakers=true التي تحمل بيانات المتحدثين تحمل النص المفرّغ أيضًا في مقاطع موقّتة، على كل منها متحدث؛ انظر تحديد المتحدثين. لا تحمل أي استجابة طوابع زمنية للكلمات، ولا درجات ثقة. لا يعود إلا اللغة التي طلبتها، وتظهر كحقل language في الاستجابة المتزامنة وفي المهمة. إذا احتجت إلى طوابع زمنية لمهمة لا تحمل بيانات المتحدثين، فقسّم الصوت من جهتك قبل الرفع، واحتفظ بالإزاحات.
التنزيل بصيغة TXT أو SRT أو JSON
تعيد GET /v1/speech-to-text/jobs/{jobId}/export المهمة المكتملة في ملف. وبخلاف نقاط النهاية الأخرى، النجاح هو الملف نفسه، لا الغلاف { data, ... }. أما الخطأ فيبقى كائن الخطأ المعتاد، لذلك تحقّق من رمز الحالة قبل أن تحفظ جسم الاستجابة. مرجع نقطة النهاية في تنزيل مهمة مكتملة لتحويل الكلام إلى نص.
| معامل الاستعلام | مطلوب | القيم |
|---|---|---|
format |
نعم | txt أو srt أو json. |
lang |
لا | en (الافتراضي) أو ar، وهي لغة تسميات المتحدثين: Speaker 1 أو المتحدث 1. لا تترجم النص المفرّغ. |
curl "https://api.echonova.ai/v1/speech-to-text/jobs/JOB_ID/export?format=srt&lang=en" \
-H "Authorization: Bearer YOUR_API_KEY" \
-o call.srtimport requests
response = requests.get(
"https://api.echonova.ai/v1/speech-to-text/jobs/JOB_ID/export",
headers={"Authorization": "Bearer YOUR_API_KEY"},
params={"format": "srt", "lang": "en"},
)
response.raise_for_status()
with open("call.srt", "wb") as out:
out.write(response.content)import { writeFile } from 'node:fs/promises';
const response = await fetch('https://api.echonova.ai/v1/speech-to-text/jobs/JOB_ID/export?format=srt&lang=en', {
headers: { Authorization: 'Bearer YOUR_API_KEY' },
});
if (!response.ok) throw new Error((await response.json()).errorMessage);
await writeFile('call.srt', await response.text());format |
Content-Type |
الجسم |
|---|---|---|
txt |
text/plain; charset=utf-8 |
transcription الخاص بالمهمة كما هو تمامًا. |
srt |
application/x-subrip; charset=utf-8 |
ترجمة SubRip، تُبنى كما هو موضح أدناه. |
json |
application/json; charset=utf-8 |
النص المفرّغ والمتحدثون والمقاطع، كما أدناه. |
يحمل كل تنزيل Content-Disposition: attachment واسم ملف مأخوذًا من اسم الملف المرفوع، مع استبدال امتداد الصوت بامتداد الصيغة: call.mp3 يُنزَّل باسم call.srt. والاسم الذي ليس ASCII بسيطًا، كالاسم العربي، يأتي أيضًا في filename* بصيغة RFC 5987 وترميز UTF-8، إلى جانب filename بأحرف ASCII للعملاء الأقدم. ويستطيع كود المتصفح الذي يستدعي الواجهة من أصل آخر قراءة هذه الترويسة.
Content-Disposition: attachment; filename="transcript.srt"; filename*=UTF-8''%D9%85%D9%83%D8%A7%D9%84%D9%85%D8%A9.srtيستطيع أي مفتاح في مساحة العمل له وصول إلى تحويل الكلام إلى نص أن ينزّل مهام الـ API فيها، كما في GET /v1/speech-to-text/jobs/{jobId}. لا يكون للمهمة ملف إلا وهي completed؛ انتظر job.completed أو استعلم عن المهمة أولًا.
SRT
تُبنى المقاطع النصية للترجمة (cues) من مقاطع المهمة:
- يستمر كل مقطع ترجمة 7 ثوانٍ على الأكثر، ويحمل سطرين على الأكثر، في كل منهما 42 حرفًا على الأكثر. تُعدّ الأحرف كما يعدّها القارئ، لا بالبايت، فتحصل العربية على المساحة نفسها التي تحصل عليها الإنجليزية.
- يُقسَّم المقطع الأطول عند علامات ترقيم الجمل والعبارات أولًا (
.!?؟،,;؛…:)، ثم بين الكلمات. لا تُقسَم الكلمة أبدًا، ولا يتغير النص إلا في المسافات وفواصل الأسطر. - تتقاسم مقاطع الترجمة المأخوذة من مقطع واحد مدته بنسبة طولها بالأحرف. لا توجد توقيتات للكلمات، لذلك توقيتات مقاطع الترجمة داخل المقطع تقديرية: قريبة بما يكفي للمتابعة أثناء القراءة، لكنها ليست دقيقة على مستوى الإطار. تبدأ مقاطع الترجمة وتنتهي حيث يبدأ المقطع وينتهي، ولا تتداخل أبدًا.
- حين يكون للمقطع متحدث، يبدأ كل مقطع ترجمة منه بتسمية المتحدث بين قوسين معقوفين:
[Speaker 1]معlang=en، و[المتحدث 1]معlang=ar. يُرقَّم المتحدثون 1 و2 و3 بترتيب أول مرة يتكلمون فيها. وتُحسب التسمية ضمن طول السطر. - المهمة التي لا مقاطع لها، لأن المتحدثين لم يُطلبوا أو لم يُحدَّدوا، تُنزَّل كمقطع ترجمة واحد من
00:00:00,000حتىdurationSecondsالخاصة بها، يحمل النص المفرّغ كله. - الملف بترميز UTF-8، بنهايات أسطر
\n، وطوابع زمنية بصيغةHH:MM:SS,mmm، وسطر فارغ بين كل مقطعي ترجمة.
ثلاثة مقاطع، آخرها طوله 12.7 ثانية، تُنزَّل مع lang=en هكذا:
1
00:00:00,380 --> 00:00:04,120
[Speaker 1] السلام عليكم، كيف حالك؟
2
00:00:04,300 --> 00:00:06,400
[Speaker 2] بخير، الحمد لله.
3
00:00:06,900 --> 00:00:11,425
[Speaker 2] عندي سؤال عن الفاتورة الأخيرة،
4
00:00:11,425 --> 00:00:15,659
[Speaker 2] المبلغ أعلى من الشهر الماضي.
5
00:00:15,659 --> 00:00:19,600
[Speaker 2] هل يمكنك أن تشرح لي السبب؟JSON
يحتفظ تنزيل JSON بالمقاطع كما هي في المهمة، دون تقسيمها إلى مقاطع ترجمة، ويضيف التسميات:
| الحقل | النوع | القيمة |
|---|---|---|
id |
string | معرّف المهمة. |
fileName |
string | اسم الملف المرفوع. |
durationSeconds |
number or null |
كما في المهمة. |
language |
string or null |
اللغة التي طُلب بها التفريغ. |
text |
string | النص المفرّغ، وهو نفسه transcription. |
speakers |
array | id وlabel وtalkTime لكل متحدث، بالترقيم نفسه المستخدم في SRT. فارغة حين لا تحمل المهمة بيانات المتحدثين. |
segments |
array | start وend وspeaker وspeakerLabel وtext لكل مقطع. وتكون speaker وspeakerLabel بقيمة null حين يكون المتحدث غير معروف. |
{
"id": "66e3f2a1c9d4b8a1f0e12346",
"fileName": "call.mp3",
"durationSeconds": 19.6,
"language": "ar",
"text": "السلام عليكم، كيف حالك؟ بخير، الحمد لله. عندي سؤال عن الفاتورة الأخيرة، المبلغ أعلى من الشهر الماضي. هل يمكنك أن تشرح لي السبب؟",
"speakers": [
{
"id": "spk0",
"label": "Speaker 1",
"talkTime": 3.74
},
{
"id": "spk1",
"label": "Speaker 2",
"talkTime": 14.8
}
],
"segments": [
{
"start": 0.38,
"end": 4.12,
"speaker": "spk0",
"speakerLabel": "Speaker 1",
"text": "السلام عليكم، كيف حالك؟"
},
{
"start": 4.3,
"end": 6.4,
"speaker": "spk1",
"speakerLabel": "Speaker 2",
"text": "بخير، الحمد لله."
},
{
"start": 6.9,
"end": 19.6,
"speaker": "spk1",
"speakerLabel": "Speaker 2",
"text": "عندي سؤال عن الفاتورة الأخيرة، المبلغ أعلى من الشهر الماضي. هل يمكنك أن تشرح لي السبب؟"
}
]
}أخطاء التنزيل
| الحالة | errorMessage |
متى |
|---|---|---|
400 |
format must be one of the following values: txt, srt, json |
format مفقود، أو يحمل قيمة أخرى، مثل vtt. |
400 |
lang must be one of the following values: en, ar |
lang يحمل قيمة غير en أو ar. |
400 |
Job is not completed |
المهمة pending أو processing أو failed. |
400 |
Invalid identifier |
jobId ليس من 24 خانة سداسية عشرية. |
400 |
property <name> should not exist |
الاستعلام يحمل معاملًا غير format وlang. |
404 |
STT Job not found |
معرّف المهمة غير معروف، أو أن المهمة تخص مساحة عمل أخرى، أو أنها أُنشئت من البوابة. |
تنطبق أيضًا أخطاء المصادقة وحدود المعدل التي تخص كل نقطة نهاية؛ وهي في صفحة الأخطاء. لا يُخصم أي رصيد مقابل التنزيل.
الأعداد
تُكتب الأعداد العربية المنطوقة أرقامًا افتراضيًا. رقم هاتف يُقال صفر واحد واحد خمسة يعود بالشكل 0115، والعبارة مية وخمسين جنيه تعود 150 جنيه. تبقى الكلمات التي هي أيضًا كلمات عربية عادية كلمات، فلا يتحول واحد صاحبي ("صديق لي") إلى 1.
لإبقاء الأعداد كما نُطقت تمامًا، أرسل numbers_as_digits=false مع الرفع. لا تُحوَّل النصوص الإنجليزية أبدًا. تُبلغ المهمة بالإعداد الذي أُنشئت به عبر الحقل numbersAsDigits.
الأسئلة الشائعة
لماذا أعطاني ملف سيئ الرمز 503 في نقطة، وفشلًا للمهمة في نقطة أخرى؟
تُسترد الأرصدة في النقطتين كلتيهما. تُبلغ نقطة النهاية المتزامنة عن كل فشل في التفريغ بالرمز 503 دون سبب، أما المهمة غير المتزامنة فتحمل السبب في error. استخدم POST /v1/speech-to-text حين تحتاج إلى معرفة السبب.
هل يُخصم رصيد عن رفع مرفوض؟
لا. تجري كل الفحوصات في الجدول أعلاه قبل خصم أي رصيد.
أي لغة يكون بها النص المفرّغ؟
أرسل language: القيمة auto (الافتراضي) تترك الخدمة تقرر. وهي العربية حاليًا، وتتعامل كذلك مع الكلام المختلط بين العربية والإنجليزية، والكلام الإنجليزي الواضح. استخدم ar للكلام العربي والمختلط. استخدم en فقط للكلام الإنجليزي كله. العربية المُرسلة بقيمة en تخرج مشوّهة. وأي قيمة أخرى تعطي 400.
هل أحصل على طوابع زمنية أو تسميات للمتحدثين؟
أرسل identify_speakers=true مع الرفع. المهمة التي تحمل بيانات المتحدثين تحمل segments، ولكل منها بداية ونهاية ومتحدث، وتحوّلها GET /v1/speech-to-text/jobs/{jobId}/export?format=srt إلى ترجمة بتسميات المتحدثين. لا توجد طوابع زمنية للكلمات.
لماذا تكون segments وspeakers فارغة مع أنني أرسلت identify_speakers=true؟
قد لا يكون تحديد المتحدثين متاحًا لك بعد، أو تعذّر التمييز بين المتحدثين في التسجيل. النص المفرّغ كامل في الحالتين، ويحمل تنزيل SRT مقطع ترجمة واحدًا للملف كله.
هل أستطيع تنزيل ترجمة WebVTT؟
لا. صيغ التنزيل هي txt وsrt وjson؛ والقيمة format=vtt تعطي 400.
لماذا تختلف durationSeconds عن المبلغ الذي خُصم مني؟
يُحسب الخصم قبل بدء المهمة، من البيانات الوصفية للملف أو من حجمه. أما durationSeconds في مهمة مكتملة فهي المدة المقاسة أثناء التفريغ. طابق الإنفاق على creditsConsumed.