التفريغ الصوتي العربي المباشر عبر WebSocket (بديل جاهز لعملاء Deepgram)

إن كنت قد كتبت عميلًا لـDeepgram، فقد كتبت معظم مفرّغ عربي مباشر. غيّر الرابط، وهذا بالضبط ما يعود إليك — وما لا يعود.

فريق نُطقنُشر 3 دقائق قراءة

هاتف ذكي على طاولة حجرية في مقهى يعرض شاشة مكالمة واردة، وبجانبه كوب صغير من شاي الكرك.

تطبيقات تسجيل الاجتماعات وتدوين الملاحظات وسجلات المكالمات والترجمة المباشرة تحتاج كلها الشيء نفسه: صوت يدخل باستمرار، ونص يخرج والناس يتكلمون. وفي العربية كان هذا صعب المنال. يشرح هذا الدليل التفريغ الصوتي العربي المباشر عبر WebSocket في نُطق — الاتصال، والرسائل، والحدود الصريحة التي يحسن معرفتها قبل البناء عليه.

لماذا يصعب إيجاد تفريغ عربي مباشر؟

أغلب واجهات التفريغ المباشر بُنيت للإنجليزية أولًا. وDeepgram، الافتراضي في منصات كثيرة، ليس لديه نموذج عربي مخصص — nova-2 وnova-3 يرفضان ar — فالفرق التي بنت عليه لم يكن لديها طريق إلى العربية. أما نقطة نُطق فتتبع بروتوكول Deepgram المباشر عن قصد: إن كان لديك عميله، فأنت تغيّر رابطًا لا بنية.

كيف تتصل؟

wss://worker.nutq.dev/v1/listen?encoding=linear16&sample_rate=16000&channels=1&language=auto
المعاملمعناه
encoding‏linear16 — صوت PCM بدقة 16 بت، وهو الترميز الوحيد المقبول
sample_rateمن 8000 إلى 48000؛ الافتراضي 16000
channelsعدد القنوات المتداخلة التي ترسلها؛ الافتراضي 1
channelالقناة التي تُفرَّغ، الطرف البعيد في المكالمة مثلًا
language‏auto افتراضيًا؛ أول مقطع كلام طويل يحددها للاتصال كله
modelيُقبل ويُتجاهل — هناك نموذج واحد

المصادقة عبر Authorization: Token <key> (ما يرسله عميل Deepgram)، أو ترويسة Bearer، أو ?key= في الرابط للمنصات التي لا تسمح بترويسات المصافحة. والصيغة الأخيرة تصل إلى سجلات الوصول، فخصّص لها مفتاحًا مستقلًا.

ماذا ترسل؟

  • إطارات ثنائية من صوت PCM الخام بالتردد وعدد القنوات اللذين أعلنتهما، وبأي حجم.
  • ‏{"type":"KeepAlive"} — يُقبل، ولا يُغلق الاتصال بسبب الهدوء.
  • ‏{"type":"Finalize"} — أعد ما هو مخزّن الآن، حين تتوقف وسط الجملة.
  • ‏{"type":"CloseStream"} — أنهِ وأغلق؛ ويعود إطار Metadata بالمدة المحتسبة.

ماذا يعود؟

{
  "type": "Results",
  "start": 14.30,
  "duration": 14.70,
  "is_final": true,
  "speech_final": true,
  "channel": {
    "alternatives": [{
      "transcript": "تعلمت إن مو لازم كل شي يصير بسرعة",
      "confidence": null,
      "words": [],
      "language": "ar"
    }]
  }
}

لاحظ النص: لهجة خليجية كما قيلت، لا فصحى معاد صياغتها. ولماذا يهم ذلك، تجده في اللهجة الخليجية أم الفصحى.

ما الحدود؟

من الأفضل معرفتها قبل تصميم واجهتك:

  • لا نتائج مؤقتة. كل نتيجة نهائية، بعد نحو 700 ملّي ثانية من توقف المتحدث. الكلمات لا تظهر واحدة تلو الأخرى أثناء الكلام.
  • ‏confidence قيمته null. النموذج لا ينتج درجة ثقة معايَرة، فلا نخترع واحدة.
  • ‏words فارغة. لا توقيت لكل كلمة، لكن start وduration في كل نتيجة حقيقيان، فيمكنك القفز إلى لحظة بعينها.
  • الكلام المتصل بلا توقف يُقطع عند نحو 15 ثانية، عند أهدأ نقطة قرب تلك العلامة، فالمتحدث الذي لا يتوقف ينتج نتيجة كل خمس عشرة ثانية تقريبًا.

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

ما التردد والقنوات التي ترسلها؟

أرسل الصوت بتردده الحقيقي. صوت الهاتف 8000 هرتز، فأرسله كذلك مع sample_rate=8000؛ رفع التردد لا يضيف شيئًا ينتفع به النموذج. وأعلن عدد القنوات الذي ترسله فعلًا — إعلان قناة واحدة مع إرسال قناتين يُفرّغ عيّنة من كل اثنتين. وفي تسجيلات المكالمات التي تضع العميل في قناة والموظف في أخرى، اختر بالمعامل channel من تريد تفريغه، أو افتح اتصالين لتحصل على نص لكل طرف.

والترميز الوحيد المقبول linear16. أي ترميز آخر يُرفض عند الاتصال بدل أن يُشغَّل ضجيجًا، فتعرف الخطأ فورًا لا بعد ساعة من نصوص فارغة.

عميل Python بسيط

import asyncio, json, websockets

URL = ("wss://worker.nutq.dev/v1/listen"
       "?encoding=linear16&sample_rate=16000&channels=1&language=auto")

async def main(pcm_frames):
    async with websockets.connect(
        URL, additional_headers={"Authorization": f"Token {NUTQ_API_KEY}"}
    ) as ws:
        async def send():
            for frame in pcm_frames:
                await ws.send(frame)
            await ws.send(json.dumps({"type": "CloseStream"}))

        async def read():
            async for raw in ws:
                m = json.loads(raw)
                if m["type"] == "Results":
                    print(m["channel"]["alternatives"][0]["transcript"])
                elif m["type"] == "Metadata":
                    return

        await asyncio.gather(send(), read())

مباشر أم ملفات؟

WebSocketرفع ملف
الاستخدامالاجتماعات والمكالمات الجارية والملاحظات المباشرةالتسجيلات الموجودة لديك
زمن الاستجابةنتيجة لكل عبارةالملف كله دفعة واحدة
السعر0.15 دولار للساعة0.15 دولار للساعة

للتسجيلات يكفي طلب POST واحد — راجع دليل تحويل الكلام العربي إلى نص. وللوكلاء الهاتفيين، المحرك نفسه موصول بمنصة Vapi في بناء وكيل صوتي عربي. وكل الرسائل في التوثيق، وأول 5 دولارات مجانية عند التسجيل.

أسئلة شائعة

هل توجد واجهة برمجية لتحويل الكلام العربي إلى نص في الوقت الحقيقي؟

نعم. نقطة WebSocket في نُطق تستقبل الصوت المباشر وتعيد النص العربي عند انتهاء كل عبارة، مع الحفاظ على اللهجتين الخليجية والشامية كما قيلتا.

هل أستطيع استخدام عميل Deepgram الموجود لدي؟

نعم. الاتصال يتبع بروتوكول Deepgram المباشر، ويقبل ترويسة Authorization: Token التي يرسلها عميل Deepgram أصلًا. وجّه العميل إلى الرابط الجديد.

هل يعيد نتائج مؤقتة أثناء الكلام؟

لا. كل نتيجة نهائية وتصل بعد انتهاء العبارة، بنحو 700 ملّي ثانية من توقف المتحدث. إن كانت واجهتك تُظهر الكلمات وسط الجملة فخطّط لذلك.

ما صيغة الصوت المقبولة؟

linear16: صوت PCM خام بدقة 16 بت، بتردد من 8000 إلى 48000 هرتز، وبأي عدد من القنوات المتداخلة، وتختار أنت القناة التي تُفرَّغ.

كيف يُحتسب التفريغ المباشر؟

بالثانية من الصوت، بالسعر نفسه لتفريغ الملفات: 0.15 دولار للساعة.

شاركXLinkedInWhatsApp

بقلم فريق نُطق. نُطق واجهة برمجية للكلام العربي بُنيت في الإمارات: تحويل الكلام إلى نص يحافظ على اللهجة الخليجية، وتحويل النص إلى كلام عربي مع استنساخ الصوت.

Read in English

اسمعه على تسجيلاتك أنت.

رصيد مجاني بقيمة 5 دولارات للبداية — نحو 33 ساعة من التفريغ. بلا بطاقة.

كل المقالات