أدلة API

Realtime HTTP

اختر عمليات HTTP للصوت المكتمل أو المباشر المؤطر أو تحويل النص إلى كلام، وتعامل مع بثها بأمان.

عمليات /realtime/http/* هي API مباشرة للمنصة. لا يغلفها SDK 0.18.0. استخدمها فقط من وقت تشغيل موثوق يستطيع حماية x-api-key، وفرض المهل، وتنفيذ تأطير OpenAPI المتحقق منه.

1. اختر العملية وفق دورة حياة الدخل

الدخل والنتيجةالاختياروحدة الطلبإشارة الاكتمال
اجتماع أو بودكاست أو أرشيف طويل أو كبير مكتملBatch REST، وليس عملية Realtime HTTPملف مكتمل واحد ثم الاستعلام عن العملحالات Batch: done أو failed أو cleared
وحدة محادثة واحدة مكتملة حساسة لزمن الاستجابةPOST /realtime/http/sttملف multipart/form-data واحداستجابة NDJSON من نوع STTResponse مع is_final: true
صوت لا يزال يصل عندما تحتاج نصًا مباشرًاPOST /realtime/http/stt-streamجسم واحد من ترويسة 18 بايت وPCM لكل طلبيحدد سجل مرصود مع is_speech_final حد الكلام، ولا يكمل البث إلا سجل مرصود مع is_final
صوت لا يزال يصل عندما تحتاج خطًا زمنيًا للمتحدثينPOST /realtime/http/diarization-streamجسم PCM مؤطر واحد لكل طلب متسلسلسجل مرصود مع is_final: true؛ وقد يبقى ذيل مؤقت نشط
نص يجب تحويله إلى كلامTTS عبر Socket.IO في SDK للخرج القابل للتشغيل؛ وHTTP المباشر لتسجيل البروتوكول فقططلب JSON واحداكتمال SDK؛ ولا يملك HTTP المباشر حد إطار يمكن اكتشافه عمومًا

يبث النسخ Fast أسطر النتيجة، لكن دخله يظل ملفًا كاملاً واحدًا. وهو ليس وسيلة نقل لميكروفون مباشر.

2. جهّز المصادقة والمعرّفات والمهل

  • احصل على API_URL وAPI_KEY الخاصين بالبيئة من تدفق الوصول الموثق. لا تستنتج مضيفًا من بيئة أخرى.
  • أرسل x-api-key في كل طلب من خلفية موثوقة. لا تستطيع شيفرة المتصفح أو الهاتف إبقاء بيانات الاعتماد هذه سرية. يحتاج المفتاح أيضًا إلى القدرة المخصصة: ASR الفوري لـFast وASR الحي، أو diarization لتدفق المتحدثين، أو TTS للتوليف.
  • أنشئ UUID صالحًا لـid. يضعه Fast STT في الاستعلام، ويضعه TTS في JSON، وتحمل الإطارات المباشرة بايتاته الخام الستة عشر. لا تعد استخدام UUID واحد إلا لطلبات البث المباشر نفسه.
  • ضع مهلة اتصال، ومهلة محدودة لكل طلب وقراءة، ومهلة كلية للعملية. تحقق من حالة HTTP قبل تحليل بث النجاح.
  • اجمع NDJSON بين قراءات النقل ولا تقسم إلا عند السطر الجديد. قد تحتوي قراءة شبكة واحدة جزءًا من سطر أو عدة أسطر.

ينطبق API_PATH على عملاء Socket.IO ولا تستخدمه مسارات HTTP هذه.

3. أرسل وحدة مكتملة واحدة للنسخ Fast

أرسل UUID في id وملفًا مكتملاً واحدًا في حقل file متعدد الأجزاء. يطبق Fast اختيار اللغة ونموذج ASR فقط:

المحددالقيم المقبولة
language أو langen، ar، codeswitch، auto
asr أو modelقيمة النموذج المنشورة على البروتوكول

تسبق قيمة language غير الفارغة lang، وتسبق قيمة asr غير الفارغة model. تستخدم اللغة المحذوفة أو auto والنموذج المحذوف إعدادات البيئة الافتراضية. استخدم Batch عندما تحتاج إلى تمييز المتحدثين أو ITN أو التنقيح.

export REQUEST_ID="7f51f2c2-e7bc-41c8-a850-f848df2ddfc8"
curl -N --fail-with-body --connect-timeout 10 --max-time 120 \
  "${API_URL%/}/realtime/http/stt?id=$REQUEST_ID&language=codeswitch&asr=bayan_cs_ar_en" \
  -H "x-api-key: $API_KEY" \
  -F "file=@turn.wav"

تعيد HTTP 200 النوع application/x-ndjson. كل سطر غير فارغ كائن JSON واحد مكتمل؛ مثلاً:

{"id":"7f51f2c2-e7bc-41c8-a850-f848df2ddfc8","seq":0,"transcription":"hello wor","words":[{"start_time":0.0,"end_time":0.45,"word":"hello"}],"is_final":false}
{"id":"7f51f2c2-e7bc-41c8-a850-f848df2ddfc8","seq":0,"transcription":"hello world","words":[{"start_time":0.0,"end_time":0.45,"word":"hello"},{"start_time":0.46,"end_time":0.9,"word":"world"}],"is_final":true}

عالج السجلات بترتيب الوصول المرصود، واحتفظ بـseq للتشخيص فقط؛ فعقد Fast العام الحالي لا يعرّف لها ترتيبًا أو تفرّدًا. عامل is_final: false كحالة مؤقتة، ولا تنه حالة الطلب إلا بعد is_final: true. لا تعامل مقاطع قراءة HTTP الخام كسجلات، ولا تفترض أن كل نص مؤقت يُلحق بما سبقه.

بعد بدء الناتج الجزئي، ينهي أي إخفاق لاحق بث HTTP ‏200 الجزئي من دون إلحاق سجل JSON للخطأ. يكون انتهاء الاستجابة أو الإلغاء أو مهلة التطبيق من دون is_final: true غير مكتمل وملتبس؛ ولا تعرّف العملية عقد إعادة، لذلك لا تعد إرسال الصوت بلا تمييز.

4. أطّر ASR والتمييز المباشرين

تقبل العمليتان المباشرتان application/octet-stream. يحمل جسم كل طلب هذا التخطيط:

إطار دخل HTTP المباشر
UUID
bytes 0..15
نفس بايتات UUID الستة عشر لكل طلب في بث واحد.
Flags
byte 16
البت 0 للبداية والبت 1 للنهاية.
Language
byte 17
0 ar، 1 en، 2 codeswitch، 255 auto.
PCM
bytes 18..end
صوت خام غير فارغ أحادي القناة PCM16 little-endian بتردد 16 kHz وعدد بايتات زوجي ومن دون ترويسة WAV.

استخدم UUID جديدًا غير صفري طوال العملية. اضبط بت البداية في أول طلب، ولا تضبط أي علم في الطلبات الوسطية، واضبط بت النهاية في آخر طلب؛ واضبط العلمين لتدفق من مقطع واحد، وأبق البتات المحجوزة صفرًا. يجب أن يحمل كل طلب صوتًا. يمكن إرسال ملف مؤطر مثل frame.bin باستخدام --data-binary؛ وهو ليس ملف صوت بمفرده لأنه يتضمن ترويسة التحكم ذات 18 بايت.

ابنِ إطارًا صالحًا

تنشئ هذه الأدوات المختبرة افتراضيًا تدفقًا من مقطع واحد، ولذلك تضبط علمي الحدود معًا. لعدة مقاطع، أعد استخدام STREAM_ID، واضبط IS_FINAL=0 في المقطع الأول، واضبط العلمين إلى 0 في المقاطع الوسطية، واضبط IS_FINAL=1 فقط في المقطع الأخير.

http-realtime-frame.ts
import { randomUUID } from 'node:crypto';
import { readFile, writeFile } from 'node:fs/promises';

const languageBytes = {
  ar: 0,
  en: 1,
  codeswitch: 2,
  auto: 255,
} as const;

function uuidBytes(id: string): Uint8Array {
  const hex = id.replaceAll('-', '');
  if (!/^[0-9a-f]{32}$/i.test(hex) || /^0{32}$/.test(hex)) {
    throw new Error('STREAM_ID must be a nonzero UUID');
  }
  return Uint8Array.from(hex.match(/.{2}/g)!, (byte) => Number.parseInt(byte, 16));
}

function frame(
  id: string,
  pcm16le: Uint8Array,
  options: { language: keyof typeof languageBytes; isStart: boolean; isFinal: boolean },
): Uint8Array {
  if (pcm16le.byteLength === 0 || pcm16le.byteLength % 2 !== 0) {
    throw new Error('PCM16 payload must be nonempty and contain an even number of bytes');
  }

  const output = new Uint8Array(18 + pcm16le.byteLength);
  output.set(uuidBytes(id), 0);
  output[16] = (options.isStart ? 1 : 0) | (options.isFinal ? 2 : 0);
  output[17] = languageBytes[options.language];
  output.set(pcm16le, 18);
  return output;
}

async function main(): Promise<void> {
  const inputPath = process.argv[2] ?? 'chunk.pcm';
  const outputPath = process.argv[3] ?? 'frame.bin';
  const streamId = process.env.STREAM_ID ?? randomUUID();
  const pcm = await readFile(inputPath);

  // Defaults build a valid one-chunk stream. For a longer stream, reuse
  // STREAM_ID and set only the boundary flags for each arriving PCM chunk.
  const body = frame(streamId, pcm, {
    language: 'codeswitch',
    isStart: process.env.IS_START !== '0',
    isFinal: process.env.IS_FINAL !== '0',
  });
  await writeFile(outputPath, body);
  console.info({ streamId, bytes: body.byteLength, outputPath });
}

void main().catch((error: unknown) => {
  console.error(error);
  process.exitCode = 1;
});

ASR المباشر

curl -N --fail-with-body --connect-timeout 10 --max-time 30 \
  -X POST "${API_URL%/}/realtime/http/stt-stream" \
  -H "x-api-key: $API_KEY" \
  -H "content-type: application/octet-stream" \
  --data-binary @frame.bin

أرسل طلب POST واحدًا لكل مقطع صوت مؤطر. تحتوي كل استجابة HTTP 200 صفرًا أو أكثر من سجلات NDJSON ذات id وseq وtranscription وwords و is_speech_final وis_final. وينهي أي فشل لاحق بث 200 الجزئي من دون إلحاق سجل خطأ. اجمع البيانات عبر القراءات وحلل الأسطر المكتملة. يحدد is_speech_final حد مقطع كلام مكتشفًا؛ ولا يكمل البث كله إلا سجل مرصود مع is_final: true. لا يثبته علم النهاية في الطلب ولا انتهاء الاستجابة، بما في ذلك 200 فارغة. عامل seq كقيمة معتمة، ووفّق النص المؤقت باستخدام id وترتيب الوصول المرصود كما هو موضح في دليل دورة حياة Realtime.

لا يعرّف العقد العام ما إذا كان ينبغي تداخل طلبات POST للمقاطع أو إرسالها تتابعيًا. استخدم فقط نمط التنسيق المخصص لبيئتك، ولا تستنتج أمان التوجيه من تزامن HTTP العادي.

تنتهي نافذة الاستجابة العادية غير النهائية بعد ثانيتين مع الحفاظ على الجلسة. ويلغي إجهاض طلب POST أو انقضاء مهلة الاستجابة النهائية الجلسة. كما تنتهي صلاحيتها بعد 60 ثانية من دون صوت عميل مقبول أو استجابة من محرك الاستدلال.

المسار POST /realtime/http/realtime-asr مسار توافقي. ينبغي للعملاء الجدد استخدام العملية الأساسية POST /realtime/http/stt-stream.

التمييز المباشر

curl -N --fail-with-body --connect-timeout 10 --max-time 30 \
  -X POST "$API_URL/realtime/http/diarization-stream" \
  -H "x-api-key: $API_KEY" \
  -H "content-type: application/octet-stream" \
  --data-binary @frame.bin

ليس لهذه العملية معاملات استعلام أو نموذج متعدد الأجزاء أو محدد نموذج من العميل. يجب أن يكون بايت اللغة 0 أو 1 أو 2 أو 255، لكن الخدمة تتجاهله بعد التحقق. ضع علم النهاية على آخر إطار صوت حقيقي لأن إطار الإنهاء الفارغ غير صالح. يعيد بث لم يستقبل إطار بدء حالة HTTP 400 مع VALIDATION_REQUIRED_FIELD.

لا تُبقِ أكثر من طلب POST واحد قيد التنفيذ لكل UUID. التقط الصوت بالتزامن في طابور محدود، لكن استخدم مرسلاً واحدًا لتفريغه وإغلاق كل استجابة قبل إرسال الإطار التالي. قد تستبدل الطلبات المتزامنة للـUUID نفسه ملكية الاستجابة؛ ويمكن تشغيل تدفقات UUID المختلفة بالتزامن.

تحتوي كل استجابة HTTP 200 صفرًا أو أكثر من سجلات NDJSON ذات id و final_segments وactive_segments وis_final. وينهي أي فشل لاحق بث 200 الجزئي من دون إلحاق سجل خطأ. اجمع إضافات final_segments غير المشاهدة لأن كل مصفوفة إضافة خاصة بالسجل. استبدل لقطة active_segments السابقة، ثم رتب الخط الزمني الموفق من المقاطع النهائية والنشطة حسب start_time. تسميات المتحدثين نسبية لتدفق واحد وليست هويات، والأزمنة نسبية إلى بدايته.

لا يكمل التدفق إلا سجل مرصود مع is_final: true. لا يثبته علم النهاية في الطلب ولا 200 فارغة ولا EOF ولا مهلة الاستجابة. قد يحتفظ السجل النهائي بذيل نشط غير فارغ؛ أبقه مؤقتًا ولا تحوله ضمنيًا إلى نهائي. تنتهي نافذة الاستجابة العادية غير النهائية بعد ثانيتين مع الحفاظ على الجلسة. ويلغي إجهاض طلب POST أو انقضاء مهلة الاستجابة النهائية الجلسة، وتنتهي صلاحيتها بعد 60 ثانية من دون نشاط العميل أو محرك الاستدلال. لا يوجد عقد لإعادة المقاطع أو الاستئناف أو idempotency. بعد فشل ملتبس، أغلق كل الاستجابات وعلّم الخط الزمني غير مكتمل وتعافَ بـUUID جديد بدلاً من إعادة مقطع قديم.

5. اطلب TTS عبر HTTP مع مراعاة عقد الخرج

يتطلب جسم JSON قيمة id جديدة ونص text يحتوي بعد إزالة الفراغات على حرف Unicode أو رقم واحد على الأقل. الحقول الاختيارية هي model وvoice_id وvoice_references. لاختيار صوت متوقع، أرسل voice_id واحدًا بصيغة UUID أو مرجعًا واحدًا يكون audio فيه RIFF/WAVE بترميز base64 القياسي مع بيانات PCM16 أحادية غير فارغة، ويكون text نصه. المحددان متنافيان. احصل على voice_id عبر listVoices() أو list_voices() في SDK؛ ولا توجد عملية HTTP لسرد الأصوات. اضبط model على nebula صراحة بدل الاعتماد على افتراضي النشر، الذي يرجع إلى nebula عند غيابه.

curl --fail-with-body --connect-timeout 10 --max-time 120 \
  -X POST "$API_URL/realtime/http/tts" \
  -H "x-api-key: $API_KEY" \
  -H "content-type: application/json" \
  --data '{"id":"7f51f2c2-e7bc-41c8-a850-f848df2ddfc8","text":"Hello from HUMAIN Voice","model":"nebula"}' \
  --output tts-frames.bin

تعيد HTTP 200 جسمًا متصلاً من النوع application/octet-stream:

إطار خدمة TTS عبر HTTP
UUID
bytes 0..15
UUID الطلب في 16 بايت خامًا.
Final
byte 16
1 لإطار الخدمة النهائي، وإلا 0.
PCM
bytes 17..end
صوت PCM16 little-endian بتردد 16 kHz.

تلحق الخدمة إطارًا نهائيًا حتى عندما لا يحمل ذلك الإطار PCM إضافيًا. لا يعرّف العقد طول إطار أو فاصلاً. مقاطع قارئ HTTP هي مقاطع نقل ولا يُضمن تطابقها مع حدود إطارات الخدمة، لذلك لا يمكن لعميل عام إزالة 17 بايت من كل قراءة بأمان. الملف tts-frames.bin في المثال تسجيل للبروتوكول، وليس ملف PCM أو WAV قابلاً للتشغيل.

إذا فشل التوليف بعد إرسال بايتات، فإن تدفق 200 الثنائي الجزئي ينتهي فقط: ولا تُلحق أي بيانات JSON منظمة للخطأ. لذلك يترك غياب العلم النهائي القابل لتمييز الحدود أو EOF مبكر أو انتهاء المهلة تسجيلًا غير مكتمل بلا تفسير داخل القناة، ولا يمكن الإبلاغ بـJSON منظم إلا عن فشل يحدث قبل تثبيت الخرج. ويلغي إجهاض طلب HTTP التوليف الجاري له وحده. تُبلَّغ أخطاء النموذج والسعة والاستدلال في عملية HTTP المباشرة بالحالة 500 TTS_SYNTHESIS_FAILED القابلة للإعادة؛ وقد تعيد البوابة 429 بصورة مستقلة. رفض سياسة المحتوى هو 400 TTS_INPUT_NOT_ALLOWED غير قابل للإعادة؛ غيّر النص بدل إعادة إرساله. وإذا تعذر على جهة الإشراف اتخاذ قرار، يفشل التوليف بصورة مغلقة مع 503 TTS_MODERATION_UNAVAILABLE القابل للإعادة؛ فلا تبلغ عن فشل البنية التحتية هذا بوصفه محتوى محظورًا. ولم يعد voice_id المُرسَل من العميل يُطوى في TTS_SYNTHESIS_FAILED (SAU-2258): فـvoice_id غير القابل للتحليل هو 400 VALIDATION_INVALID_UUID، وvoice_id صالح البنية لكنه لا يحدد صوتًا متاحًا هو 400 TTS_VOICE_NOT_FOUND (كلاهما غير قابل للإعادة)؛ وصوت محلول بياناته المخزَّنة ناقصة أو تالفة هو 500 TTS_VOICE_RESOLUTION_FAILED (غير قابل للإعادة)؛ وانقطاع عابر لقاعدة البيانات/التخزين أثناء حل الصوت هو 503 SERVER_DEPENDENCY_FAILURE (قابل للإعادة).

لم تعد مشكلات النص ومرجع الصوت تُطوى بهذه الطريقة. فالنص الذي يتجاوز الحد، ونص المرجع الذي يتجاوز حده، وأكثر من مرجع واحد، ومقطع المرجع الأطول من حد المرجع المضبوط في النشر، كلها 422 غير قابلة للإعادة؛ والمرجع الذي يتجاوز حجمه المفكوك الحد هو 413؛ وأما المرجع المشوه أو إرسال المحددين معًا أو مصفوفة voice_references الفارغة الصريحة فهي 400 غير قابلة للإعادة. ويتم التحقق من جميعها قبل أي بحث عن النموذج أو قبول أو محاسبة، ويحمل كل رفض للحد كائن data يسمي الحد وقيمته المضبوطة والقيمة المرصودة. راجع الأخطاء وحدود المعدل.

إلى أن يملك عميلك المباشر آلية غير ملتبسة لحدود الإطارات، استخدم TTS عبر Socket.IO في SDK ووصفة TTS إلى WAV لخرج قابل للتشغيل. لا تفترض صيغة خرج Socket.IO ذات 24 kHz لهذه العملية عبر HTTP ذات 16 kHz.

6. قيّد حالات الفشل ونظّف كل بث

  1. تحقق من حالة HTTP قبل اختيار محلل نجاح NDJSON أو الثنائي. قد تعيد بوابة النشر 429، بينما قد تطوي الخلفيات الحالية فشل السعة إلى 500 قابلة للإعادة مع ASR_TRANSCRIPTION_FAILED أو DIARIZATION_FAILED أو TTS_SYNTHESIS_FAILED. عامل حالة كل طبقة وجسمها كدليل، ولا تستنتج حصة رقمية أو نافذة إعادة ضبط.
  2. في ErrorResponse، اتخذ القرار من code وretryable لا من صياغة error أو detail أو message.
  3. عند فشل بث مباشر أو انتهاء مهلته، أوقف إرسال الإطارات، وألغِ الطلب، وأغلق قارئ استجابته، وابدأ التعافي بـUUID جديد. استئناف الجلسة بعد الانقطاع غير موثق.
  4. تكون المهلة بعد إرسال الملف متعدد الأجزاء الكامل ملتبسة. لا يعرّف العقد إعادة idempotent، لذلك لا تكرر الطلب بلا تمييز.
  5. إذا انتهى عميل TTS القادر على تمييز الحدود من دون إطار نهائي، فافصل البايتات الجزئية عن الخرج المكتمل وأغلق الاستجابة. لا تستنتج الاكتمال من إغلاق الاتصال وحده.

طبّق إعادة محاولة محدودة فقط عندما يسمح الخطأ المنظم بذلك، وتكون العملية آمنة وفق سياسة تطبيقك، وتبقى المهلة الكلية. راجع الأخطاء وحدود المعدل.

7. انتقل إلى العقد وتحققات الإنتاج

ابدأ بأصغر طلب ممثل للعملية المختارة، وتحقق من إشارتها النهائية الموثقة. أبق مرجع OpenAPI المولد بجانب تنفيذك للمعاملات والمخططات والأخطاء الدقيقة، ثم اختبر المهل، والإطارات غير الصالحة، والانقطاعات، والتنظيف قبل الإطلاق.

في هذه الصفحة